From 72ca7f736e3d6789896e22aaad2da30946a050be Mon Sep 17 00:00:00 2001 From: Filip Komar Date: Thu, 20 Jun 2013 21:47:39 +0000 Subject: first license test (bug # 10424) --- en/about/license/php-mo.php | 232 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 en/about/license/php-mo.php (limited to 'en/about/license/php-mo.php') diff --git a/en/about/license/php-mo.php b/en/about/license/php-mo.php new file mode 100644 index 000000000..616440735 --- /dev/null +++ b/en/about/license/php-mo.php @@ -0,0 +1,232 @@ + + * + * NB: + * - If no $output_file specified, output filename is same as $input_file (but .mo) + * - Returns true/false for success/failure + * - No warranty, but if it breaks, please let me know + * + * More info: + * https://github.com/josscrowcroft/php.mo + * + * Based on php-msgfmt by Matthias Bauer (Copyright © 2007), a command-line PHP tool + * for converting .po files to .mo. + * (http://wordpress-soc-2007.googlecode.com/svn/trunk/moeffju/php-msgfmt/msgfmt.php) + * + * License: GPL v3 http://www.opensource.org/licenses/gpl-3.0.html + */ + +/** + * The main .po to .mo function + */ +function phpmo_convert($input, $output = false) { + if ( !$output ) + $output = str_replace( '.po', '.mo', $input ); + + $hash = phpmo_parse_po_file( $input ); + if ( $hash === false ) { + return false; + } else { + phpmo_write_mo_file( $hash, $output ); + return true; + } +} + +function phpmo_clean_helper($x) { + if (is_array($x)) { + foreach ($x as $k => $v) { + $x[$k] = phpmo_clean_helper($v); + } + } else { + if ($x[0] == '"') + $x = substr($x, 1, -1); + $x = str_replace("\"\n\"", '', $x); + $x = str_replace('$', '\\$', $x); + } + return $x; +} + +/* Parse gettext .po files. */ +/* @link http://www.gnu.org/software/gettext/manual/gettext.html#PO-Files */ +function phpmo_parse_po_file($in) { + // read .po file + $fh = fopen($in, 'r'); + if ($fh === false) { + // Could not open file resource + return false; + } + + // results array + $hash = array (); + // temporary array + $temp = array (); + // state + $state = null; + $fuzzy = false; + $num = 0; // qq + + // iterate over lines + while(($line = fgets($fh, 65536)) !== false) { + $num++; // qq + $line = trim($line); + if ($line === '') + continue; + + $array_of_splited_string = preg_split('/\s/', $line, 2); + $key = $array_of_splited_string[0]; + $data = (isset($array_of_splited_string[1]) ? $array_of_splited_string[1] : ''); + +// echo PHP_EOL . ' $key: ' . $key . ' ' . PHP_EOL . '$data: ' . $data . ' ' . PHP_EOL . '$line: ' . $line . PHP_EOL; + + switch ($key) { + case '#,' : // flag... + $fuzzy = in_array('fuzzy', preg_split('/,\s*/', $data)); + case '#' : // translator-comments + case '#.' : // extracted-comments + case '#:' : // reference... + case '#|' : // msgid previous-untranslated-string + // start a new entry + if (sizeof($temp) && array_key_exists('msgid', $temp) && array_key_exists('msgstr', $temp)) { + if (!$fuzzy) + $hash[] = $temp; + $temp = array (); + $state = null; + $fuzzy = false; + } + break; + case 'msgctxt' : + // context + case 'msgid' : + // untranslated-string + case 'msgid_plural' : + // untranslated-string-plural + $state = $key; + $temp[$state] = $data; + break; + case 'msgstr' : + // translated-string + $state = 'msgstr'; + $temp[$state][] = $data; + break; + default : + if (strpos($key, 'msgstr[') !== FALSE) { + // translated-string-case-n + $state = 'msgstr'; + $temp[$state][] = $data; + } else { + // continued lines + switch ($state) { + case 'msgctxt' : + case 'msgid' : + case 'msgid_plural' : + $temp[$state] .= "\n" . $line; + break; + case 'msgstr' : + $temp[$state][sizeof($temp[$state]) - 1] .= "\n" . $line; + break; + default : + // parse error + fclose($fh); + echo ' $line: ' . $line . ' $key: ' . $key . ' $num: ' . $num . ' $data: ' . $data . ' $state: ' . $state . ' '; // qq + return FALSE; + } + } + break; + } + } + fclose($fh); + + // add final entry + if ($state == 'msgstr') + $hash[] = $temp; + + // Cleanup data, merge multiline entries, reindex hash for ksort + $temp = $hash; + $hash = array (); + foreach ($temp as $entry) { + foreach ($entry as & $v) { + $v = phpmo_clean_helper($v); + if ($v === FALSE) { + // parse error + return FALSE; + } + } + $hash[$entry['msgid']] = $entry; + } + + return $hash; +} + +/* Write a GNU gettext style machine object. */ +/* @link http://www.gnu.org/software/gettext/manual/gettext.html#MO-Files */ +function phpmo_write_mo_file($hash, $out) { + // sort by msgid + ksort($hash, SORT_STRING); + // our mo file data + $mo = ''; + // header data + $offsets = array (); + $ids = ''; + $strings = ''; + + foreach ($hash as $entry) { + $id = $entry['msgid']; + if (isset ($entry['msgid_plural'])) + $id .= "\x00" . $entry['msgid_plural']; + // context is merged into id, separated by EOT (\x04) + if (array_key_exists('msgctxt', $entry)) + $id = $entry['msgctxt'] . "\x04" . $id; + // plural msgstrs are NUL-separated + $str = implode("\x00", $entry['msgstr']); + // keep track of offsets + $offsets[] = array ( + strlen($ids + ), strlen($id), strlen($strings), strlen($str)); + // plural msgids are not stored (?) + $ids .= $id . "\x00"; + $strings .= $str . "\x00"; + } + + // keys start after the header (7 words) + index tables ($#hash * 4 words) + $key_start = 7 * 4 + sizeof($hash) * 4 * 4; + // values start right after the keys + $value_start = $key_start +strlen($ids); + // first all key offsets, then all value offsets + $key_offsets = array (); + $value_offsets = array (); + // calculate + foreach ($offsets as $v) { + list ($o1, $l1, $o2, $l2) = $v; + $key_offsets[] = $l1; + $key_offsets[] = $o1 + $key_start; + $value_offsets[] = $l2; + $value_offsets[] = $o2 + $value_start; + } + $offsets = array_merge($key_offsets, $value_offsets); + + // write header + $mo .= pack('Iiiiiii', 0x950412de, // magic number + 0, // version + sizeof($hash), // number of entries in the catalog + 7 * 4, // key index offset + 7 * 4 + sizeof($hash) * 8, // value index offset, + 0, // hashtable size (unused, thus 0) + $key_start // hashtable offset + ); + // offsets + foreach ($offsets as $offset) + $mo .= pack('i', $offset); + // ids + $mo .= $ids; + // strings + $mo .= $strings; + + file_put_contents($out, $mo); +} +?> \ No newline at end of file -- cgit v1.2.1