diff options
Diffstat (limited to 'debian/gettext-kde/gettext-kde-0.10.35/src')
32 files changed, 13940 insertions, 0 deletions
diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/ChangeLog b/debian/gettext-kde/gettext-kde-0.10.35/src/ChangeLog new file mode 100644 index 00000000..20f34d98 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/ChangeLog @@ -0,0 +1,1504 @@ +1998-04-30 Ulrich Drepper <[email protected]> + + * dir-list.c: Update Peter Miller's mail address. + * dir-list.h: Likewise. + * message.c: Likewise. + * message.h: Likewise. + * msgcmp.c: Likewise. + * msgcomm.c: Likewise. + * msgmerge.c: Likewise. + * po-gram.h: Likewise. + * po-gram.y: Likewise. + * po-hash.h: Likewise. + * po-hash.y: Likewise. + * po-lex.c: Likewise. + * po-lex.h: Likewise. + * po.c: Likewise. + * po.h: Likewise. + * str-list.c: Likewise. + * str-list.h: Likewise. + * xget-lex.c: Likewise. + * xget-lex.h: Likewise. + +1998-04-30 Ulrich Drepper <[email protected]> + + * msgfmt.c: Fix typo in --help text. + Reported by [email protected]. + +1998-04-03 01:18 1998 Philippe De Muyter <[email protected]> + + * str-list.h (stddef.h): Include that file only if STDC_HEADERS. + Otherwise include sys/types.h and stdio.h. + * msgmerge.c (string.h): Include that file if HAVE_STRING_H, not + if STDC_HEADERS. + +1998-04-29 Ulrich Drepper <[email protected]> + + * message.c: Use unsigned char for various local variables. + * xgettext.c (comment_tag): Define as unsigned char *. + For loosing Solaris systems. Patches by Jim Meyering. + + * msgfmt.c: Use extra braces in if to shut up gcc. + * po-lex.h: Don't declare function po_gram_error and + gram_error_at_line if macros with the same names are defined. + * Makefile.am (MAINTAINERCLEANFILES): New variable. + Patches by Jim Meyering. + +1998-04-27 Ulrich Drepper <[email protected]> + + * xgettext.c: Update year and bug report address. Add little + explanation in --help messages. + * msgfmt.c: Likewise. + + * msgmerge.c: Update year and bug report address. + * msgcomm.c: Likewise. + * msgcmp.c: Likewise. + * msgunfmt.c: Likewise. + +1997-08-31 22:20 Ulrich Drepper <[email protected]> + + * msgfmt.c (format_directive_message): Count fuzzy messages as + fuzzy, even if they are not written to the output file. + +1997-08-18 13:47 Philippe De Muyter <[email protected]> + + * msgcomm.c (sys/types.h): File included. + +1997-08-15 12:38 Ulrich Drepper <[email protected]> + + * xgettext.c: Include <sys/param.h> to define MIN/MAX for HP/UX. + Patch by Kaveh R. Ghazi <[email protected]>. + + * msgfmt.c: Change DEFAULT_ALIGNMENT to DEFAULT_OUTPUT_ALIGNMENT + to avoid clash with macro with same name in obstack.c. + Reported by Akim Demaille <[email protected]>. + +1997-08-01 15:48 Ulrich Drepper <[email protected]> + + * Makefile.am (AUTOMAKE_OPTIONS): Require version 1.2. + +1997-05-07 04:21 Ulrich Drepper <[email protected]> + + * msgcomm.c (main): Print author in --version message. + * msgunfmt.c: Likewise. + * msgcmp.c: Likewise. + * msgmerge.c: Likewise. + * msgfmt.c: Likewise. + * xgettext.c: Likewise. + * gettextp.c: Likewise. + +1997-05-01 02:33 Ulrich Drepper <[email protected]> + + * msgcmp.c (main): Update copyright. + * msgunfmt.c (main): Likewise. + * msgcomm.c (main): Likewise. + * msgmerge.c (main): Likewise. + * msgfmt.c (main): Likewise. + * gettextp.c (main): Likewise. + + * msgcomm.c: Fix comment about default output (Jan Djarv). Split + help message. + +1997-03-31 16:09 Ulrich Drepper <[email protected]> + + * msgcomm.c (usage): Use program_name as argument for print to + print message, not stdout. + Patch by Jan Djarv <[email protected]>. + +Mon Mar 10 06:18:58 1997 Ulrich Drepper <[email protected]> + + * xgettext.c: Implement generic language scanner handling. + + * xget-lex.c (phase7_getc): Better comments. + (phase5_get): Print warnings about unterminated strings and + character constants. + + * po-lex.c (po_gram_error): Don't count continuation lines in + messages as errors. + (gram_error_at_line): Likewise. + * po-lex.h: Likewise for macro versions. + + * po-hash.y: Correct typo. + + * msgunfmt.c: Implement --force-po option. + + * msgmerge.c: Implement --force-po, --no-location, and + --add-location options. + + * msgfmt.c (format_directive_message): If messages are duplicated + and translations are different this is a fatal error. + + * msgcmp.c (compare_directive_message): Use correct format for + continuation line in message. + + * message.h: Add prototype for message_list_delete_nth. + + * message.c: Add message_list_delete_nth function. + + * Makefile.am (bin_PROGRAMS): Add msgcomm. (l): New variable. + Set to `l' is using libtool. (LDADD): Change for the needs of + libtool. (msgcomm_SOURCES): New variable. + + * msgcomm.c: New file. + +Wed Dec 4 01:58:10 1996 Ulrich Drepper <[email protected]> + + * Makefile.am (LDADD): Change for use of libtool. + +Tue Dec 3 18:08:46 1996 Ulrich Drepper <[email protected]> + + * xget-lex.c (phase7_getc): Return \n when newline is seen, not + P7_NEWLINE. + + * xgettext.c (main): Implement --foreign-user flag. + + * msgcmp.c (main): Change --version output to what is required by + GNU standards. (usage): Correct bug report address. + * msgfmt.c: Likewise. + * msgunfmt.c: Likewise. + * msgmerge.c: Likewise. + * xgettext.c: Likewise. + * gettextp.c: Likewise. + +Sat Sep 14 04:28:09 1996 Ulrich Drepper <[email protected]> + + * msgunfmt.c (usage): Put bug report address in separate string. + * msgmerge.c (usage): Likewise. + * msgcmp.c (usage): Likewise. + * xgettext.c (usage): Likewise. + * msgfmt.c (usage): Likewise. + * gettextp.c (usage): Likewise. + +Thu Sep 12 21:40:48 1996 Andreas Schwab <[email protected]> + + * msgfmt.c (check_pair): Fix error messages. + +Sat Aug 31 14:05:29 1996 Ulrich Drepper <[email protected]> + + * msgunfmt.c (usage): Add hint about where to report bugs to. + * msgmerge.c (usage): Likewise. + * msgcmp.c (usage): Likewise. + * xgettext.c (usage): Likewise. + * msgfmt.c (usage): Likewise. + * gettextp.c (usage): Likewise. + +Sat Aug 31 04:49:38 1996 Ulrich Drepper <[email protected]> + + * gettextp.c: Don't include <libintl.h> since this can generate + conflicts. + +Mon Jul 15 02:21:25 1996 Ulrich Drepper <[email protected]> + + * msgfmt.c: Major change: msgfmt now does not write fuzzy messages + out by default. The option -f/--use-fuzzy must be used to + explicitely tell to do it. + +Sat Jul 13 20:23:34 1996 Ulrich Drepper <[email protected]> + + * xget-lex.c (phase6_get): Reset selected comments on every + preprocessor directive. + +Fri Jul 12 12:38:49 1996 Ulrich Drepper <[email protected]> + + * xgettext.c (main): Remove `v' from short option list. + +Sat Jul 6 11:22:47 1996 Kaveh R. Ghazi <[email protected]> + + * message.c (message_merge): Add some casts to (char *) in alloca + calls. Make KNOWN_FIELDS array static. + +Sat Jul 6 11:15:43 1996 Jim Meyering <[email protected]> + + * msgfmt.c (check_pair): Correct English in Message. + +Fri Jul 5 17:27:11 1996 Ulrich Drepper <[email protected]> + + * message.c (message_merge): Terminate string for UNKNOWN fields + in header entry. + + * message.c (message_merge): Don't print POT-Revision-Date twice. + + * msgfmt.c: Implement --statistics. + Suggested by Santiago Vila Doncel. + + * msgfmt.c: and change message checking so that tests for leading + and trailing \n are always performed. + Suggested by Fran�ois Pinard. + +Wed Jun 19 02:42:52 1996 Ulrich Drepper <[email protected]> + + * message.c (message_merge): Implement sorting of header entry + lines. + +Sat Jun 15 19:46:50 1996 Ulrich Drepper <[email protected]> + + * msgmerge.c (usage): Correct -w option in help string (was -W). + +Tue Jun 11 15:28:44 1996 Ulrich Drepper <[email protected]> + + * xget-lex.c, xget-lex.h (xgettext_lex_comment): Change parameter + type to size_t. + + * po-lex.h, po-lex.c (gram_max_allowed_errors): Change type to + size_t. + + * message.c, message.h (message_page_width_set): Change parameter + type to size_t. + + * Makefile.am (AUTOMAKE_OPTIONS): Add variable. Must be defined + in all subdirs. + +Mon Jun 10 02:53:52 1996 Marcus Daniels <[email protected]> + + * dir-list.c: Include system.h in order to get size_t and NULL. + +Thu Jun 6 01:59:31 1996 Ulrich Drepper <[email protected]> + + * str-list.h: Include <stddef.h> to get size_t defined. + Reported by Philippe Defert. + + * Makefile.am (LDADD): Remove `@INTLLIBS@ ../lib/libnlsut.a + @LIBS@'. This is not necessary anymore. + +Wed Jun 5 00:00:08 1996 Ulrich Drepper <[email protected]> + + * xgettext.c, msgunfmt.c (usage): Correct --page-width to --width + in usage string. + + * open-po.c (open_po_file): Implement search path for PO files. + + * xget-lex.c (xgettext_lex_open): Implement search path for PO + files. Patch by Peter Miller. + + * message.h (struct message_ty): Add do_wrap member. + Add prototypes for parse_c_width_description_string and + message_page_width_set. + + * xgettext.c: Implement --width option to specify width for which + line wrapping is done. Change --directory option implement search + path instead of single directory. Patch by Peter Miller. + + * message.c (wrap): Implement no-wrap special comment. If given + no wrapping is performed. + + * gettextp.c, msgcmp.c, msgfmt.c, msgmerge.c, msgunfmt.c, + xgettext.c: Add `no-wrap' comments at usage message strings. + + * msgcmp.c: Implement --directory to specify search path for .po + files. Patch by Peter Miller. + +Tue Jun 4 23:57:59 1996 Ulrich Drepper <[email protected]> + + * msgfmt.c: Implement --width option to specify width for which + line wrapping is done. Patch by Peter Miller. + + * msgmerge.c: Implement --width option to specify width for which + line wrapping is done. Implement --directory to specify search + path for .po files. Patch by Peter Miller. + + * msgunfmt.c: Implement --width option to specify width for which + line wrapping is done. Patch by Peter Miller. + +Tue Jun 4 00:12:25 1996 Ulrich Drepper <[email protected]> + + * po-hash.y: Add new clause where in GNU style format the name is + `file'. + + * Makefile.am (noinst_HEADERS): Add dir-list.h. + (msgcmp_SOURCES, msgfmt_SOURCES, msgmerge_SOURCES, xgettext_SOURCES): + Add dir-list.c + +Mon Jun 3 00:43:07 1996 Ulrich Drepper <[email protected]> + + * message.h: Add new parameter for message_list_print. + + * msgmerge.c, msgunfmt.c (main): Add new parameter to + message_list_print. Set to 0 because we don't need to know about + the reasoning. + + * xgettext.c: Implement new option --debug which determines + whether a difference is made between c-format and + possible-c-format. Default is to print c-format for both cases. + + * message.c (make_c_format_description_string): Take additional + parameter DEBUG. If nonzero, distinguish between c-format and + possible-c-format. + + * message.c (message_print_obsolete): Copy precious translator + comment to output file. Reported by Santiago Vila Doncel. + + * dir-list.c: Include file now is called dir-list.h, not + dir_list.h. + + * message.c: Include <limits.h>. + + * Makefile.am (EXTRA_DIST): Add variable to distribute po-gram.y + and po-hash.y. + + * Makefile.am (msgfmt_SOURCES): Fix typo: msgfmt.o -> msgfmt.c. + +Sat Jun 1 04:33:48 1996 Ulrich Drepper <[email protected]> + + * Makefile.in: Remove support for tupdate. msgmerge is stable + now. + +Wed Apr 10 01:20:49 1996 Ulrich Drepper <drepper@myware> + + * message.c (message_print_obsolete): Don't print + c-format/no-c-format flags for obsolete entries. + + * xgettext.c (construct_header): Change DIST to ZONE in header + entry template. + + * message.c (message_merge): Insert POT-Creation-Date field before + PO-Revision-Date. + +Tue Apr 9 17:13:34 1996 Ulrich Drepper <drepper@myware> + + * xgettext.c (construct_header): Move POT-Creation-Date line + before PO-Revision-Date line. + +Fri Apr 5 12:07:19 1996 Ulrich Drepper <drepper@myware> + + * msgmerge.c: Implement --quiet option to prevent dots printed as + progress report. + (merge): Don't print dots if `quiet'. + + * msgmerge.c (merge): Nicer statistics message. + + * message.c (message_merge): Update POT-Creation-Date field in + header entry from contents in reference file. + + * msgfmt.c (format_directive_message): Better test for unchanged + fields in header entry. + + * xgettext.c (difftm): Is back. + (construct_header): Print distance to GMT in POT file time stamp. + + * xgettext.c (construct_header): Print leading comment and fuzzy + flag. + + * message.c (message_print): Allow translator comment to fill more + than one line. + + * xgettext.c (construct_header): Introduce POT-Creation-Date + field. + +Fri Apr 5 03:05:07 1996 Ulrich Drepper <drepper@myware> + + * msgmerge.c (merge): Rename empty in missing. There might be + more empty messages which are not missed. + + * msgmerge.c (merge): Terminate `.' line if no verbose output is + selected. + + * msgmerge.c (main): Implement -v option to increase verbosity + level. + (merge): Print `.' to signal ongoing work. + Unless verbosity level > 1 don't print information about fuzzy and + missing matches. Instead print statistics at the end. + Suggested by Fran�ois Pinard and Santiago Vila Doncel. + +Thu Apr 4 11:59:20 1996 Ulrich Drepper <drepper@myware> + + * xgettext.c (difftm): Remove unused function. + (construct_header): Don't fill Last-Translator field with information + about curent user but instead constant text mentioning xgettext. + + * message.c (message_list_search_fuzzy): Initialize mp before + using it. + + * message.c (message_print): Normalize printed messages even more. + Don't print fuzzy flag is msgstr is empty. + + * message.c (message_list_search_fuzzy): Don't try to match + against msgid if none if the msgstr of this message in non-empty. + +Thu Apr 4 01:57:37 1996 Ulrich Drepper <drepper@myware> + + * msgfmt.c (format_directive_message): When testing header entry + also check whether they still contain the initial values. + Suggested by Fran�ois Pinard. + +Tue Apr 2 16:19:42 1996 Ulrich Drepper <drepper@myware> + + * xgettext.c (main): Add "warning" to message about unknown input + file type. + + * Makefile.in (all-gettext): New goal. Same as all. + + * xgettext.c (usage): Rearange help strings. One of them was too + long for some dumb catgets programs. Reported by Marcus Daniels. + + * msgfmt.c (format_directive_message): Check for standard header + entry fields. + + * xgettext.c (construct_header): MIME-VERSION should be written + MIME-Version. + + * msgmerge.c (main): Don't recognize -f option anymore. This is + the default now. + + * msgfmt.c (format_debrief): New function. Warn if no header + entry is found. + (format_directive_message): Remember if header entry is found. + +Tue Apr 2 11:12:15 1996 Ulrich Drepper <drepper@myware> + + * msgfmt.c (format_constructor): New function. Initialize + is_c_format field. + (format_directive_message): Clear is_c_format field for next message + at the end. + + * xgettext.c, po-lex.h, po-lex.c, po-gram.y, msgmerge.c, msgfmt.c, + msgcmp.c: Use gram_error_at_line instead of gram_error_with_loc + and error_at_line instead of error_with_loc. Roland does not like + my English. + +Tue Apr 2 03:27:34 1996 Ulrich Drepper <drepper@myware> + + * msgunfmt.c (main): Removed -S option. People should think twice + before using this and so are forced to use the long version. + +Tue Apr 2 03:25:56 1996 Fran�ois Pinard <[email protected]> + + * msgunfmt.c (usage): Remove Tab character from message. + +Tue Apr 2 03:15:16 1996 Marcus Daniels <[email protected]> + + * message.c (significant_c_format_p): If is_c_format is `no' this + is significant. + +Tue Apr 2 03:12:24 1996 Kaveh R. Ghazi <[email protected]> + + * po.c (po_comment_filepos): Make definition static as declaration + was before. + + * msgunfmt.c (usage): Add missing \n to help string. + +Mon Apr 1 02:37:45 1996 Ulrich Drepper <drepper@myware> + + * xgettext.c (main): When recognizing file type, default to C + instead of regarding it as an error. Suggested by Marcus Daniels. + + * po.c (po_callback_comment): For now recognize #! also as special + comment. + + * msgmerge.c (merge): Remove --force option. We now always write + the result. It makes no sense to reject the output because some + messages are not matching. + + * po-lex.c (po-gram_error, gram_error_with_loc): Use + error_message_count instead of gram_nerrors. + (gram_nerrors): Remove definition. + + * po-lex.h (po-gram_error, gram_error_with_loc): Use + error_message_count instead of gram_nerrors. + + * xgettext.c: Remove verbose option and variable. + (test_whether_c_format): Don't return `possible' is string + contains no format specifier. + +Sun Mar 31 23:23:40 1996 Ulrich Drepper <drepper@myware> + + * xget-lex.c (xgettext_lex): Fix typo. Reported by Fran�ois + Pinard. + +Thu Mar 28 19:01:22 1996 Ulrich Drepper <drepper@myware> + + * po.c (po_callback_comment): Correct handling of special + comments. Give whole comment to callback function instead of + tokenized form. + +Thu Mar 28 18:37:49 1996 Ulrich Drepper <drepper@myware> + + * xgettext.c (remember_a_message): Always look through comments + because we have to look for c-format comments. + + * message.h, msgmerge.c, xgettext.c, message.c, msgfmt.c: + Implement more detailed C format string handling. Basically coded + by Marcus Daniels. + +Thu Mar 28 16:52:56 1996 Marcus Daniels <[email protected]> + + * Makefile.in (MSGFMT_OBJ): Add message.o. + +Wed Mar 27 03:16:01 1996 Ulrich Drepper <drepper@myware> + + * xget-lex.c (xgettext_lex): Correct implementation of comments + grouped with messages. + +Tue Mar 26 21:23:54 1996 Ulrich Drepper <drepper@myware> + + * po.c (po_callback_comment): Remove unused variable string. + Include <ctype.h> because isspace is used. + + * message.h (message_list_print): Undo change of Mon Mar 25 + 03:34:44 1996. Don't print trailing comment. Remove additional + argument. + + * message.c (message_list_print): Undo change of Mon Mar 25 + 03:34:44 1996. Don't print trailing comment. We now have a + correct implementation of obsolete entry handling. + * msgmerge.c: Ditto. + + * po-lex.h: Add prototype for po_lex_pass_obsolete_entries. + + * po-lex.c (po_gram_lex): Implement handling of comments for + obsolete entries (#~). + + * msgunfmt.c, xgettext.c (main): Undo change of Mon Mar 25 + 03:34:44 1996. Remove added argument to message_list_print again. + + * po-lex.c (po_gram_lex): Small optimization in string collection. + + * message.c (message_print_obsolete): Obsolete messages are now + preceded by #~ on each line. + + * xgettext.c (remember_a_message): Fix bug with dereferencing + dangling pointer. This caused xgettext test 1 to fail. + + * xgettext.c (construct_header): Update format for file header. + + * xgettext.c (extract_directive_message): Don't report error when + message variant exists but the value is the same. Reported by + Roland McGrath. + + * message.c (wrap): Only write characters in escape notation if + explicitely wanted or if it is one of the well known escapes like + \n. + + * msgunfmt.c (main): Adopt interface to GNU coding standard. All + given files on command line are input files. Output by default is + written to standard output and can be redirected using -o. + +Mon Mar 25 04:25:42 1996 Ulrich Drepper <drepper@myware> + + * message.c, message.h (message_list_print): Parameter filename is + const. + + * message.c (wrap): Change line break behaviour a bit. While it + is reasonable to break long line containing #: comments + immediately when reaching the the limit, this could lead to unnice + results for the strings in msgid and msgstr. The programmer + usually knows why the lines are that long. + + So we break for now after reaching 2 * PAGE_WIDTH instead of + PAGE_WIDTH. + + * message.c (message_list_print): Print blank line before trailing + comments. + + * message.c (message_print_obsolete): Don't print anything for + obsolete entries with empty msgstr. + +Mon Mar 25 03:34:44 1996 Ulrich Drepper <drepper@myware> + + * msgunfmt.c (main): Make program by default read from stdin and + by default write to stdout in the appropriate argument is not + given. Suggested by Franc,ois Pinard. + + * msgfmt.c (format_directive_domain): Only check for correct + format string elements is special comment contains c-format. + + * msgfmt.c: Use sizeof instead of strlen to determine length of + constant string. + + * xgettext.c: Implement generation of c-format special comments. + + * msgunfmt.c (main): Call message_list_print with additional + argument set to NULL. + + * xgettext.c (main): Call message_list_print with additional + argument set to NULL; + (extract_class_ty): We don't have field comment_special anymore, but + instead flags fuzzy and c_format. + (extract_constructor): Reset fields fuzzy and c_format. + (extract_directive_message): Set flags according to special comments, + not string list. + (extract_comment_special): Set flags according to special comment. + + * message.h (message_ty): We don't have field comment_special + anymore. Instead flags fuzzy and c_format. + (message_comment_special_append): Remove prototype. + (message_list_print): Add new argument to prototype. + + * message.c (message_alloc): We don't have the comment_special, + but fuzzy and c_format. + (message_comment_special_append): Remove function. We now have flags. + (message_copy, message_merge): Copy fuzzy and c_format flag + appropriately. + (message_print, message_print_obsolete): Print special comment using + flags, not string list. + (message_list_print): Additional argument with trailing comments. + Printed at the end if not NULL. + + * msgmerge.c (merge_class_ty): New fields fuzzy and c_format for + flags; + (trailing_comments): New global variable for list of trailing + comments in definition file. + (grammar): Takes an additional argument which if NULL gets the list of + trailing comments assigned to. + (main): Call message_list_print with additional argument of trailing + comments. + (merge_comment_special): Recognize fuzzy and c-format special comment. + +Sun Mar 24 17:35:26 1996 Ulrich Drepper <drepper@myware> + + * xgettext.c (usage): Option --output-suffix does not exist + anymore. + + * msgmerge.c (usage): --strict does not have short form -S. + + * message.h (message_ty): New field `obsolete'. + + * msgmerge.c (merge): Change behaviour not not matched entries. + Instead of giving a message write them out at the end of the + regular output and precede each line with `# '. + + * message.c (message_list_print): Handle obsolete entries + separately by printing them at the end and preceded by `# '. + (message_print_obsolete): New function to print obsolete entries. + + * Makefile.in ($(PROGRAMS)): Add generated libraries as + dependencies for programs. + + * Makefile.in (PROGRAMS): Remove msgjoin. + +Sun Mar 24 01:03:32 1996 Ulrich Drepper <drepper@myware> + + * xgettext.c (extract_comment_filepos): Only add line comment if + requested by -n option. + + * po.c (po_callback_comment): Short by one bug in special comment + entry copying. + + * po.c (po_callback_comment): Handle special comments. Separate + them into a list of comma separate entries. + + * message.c (message_print): Format of lines containing fuzzy + comments et.al. is now `#, xxx'. + + * Makefile.in: msgjoin program is not anymore generated. + + * xgettext.c: First step to implementing general input file + handling. The program now recognizes the file type by the file + name extension and uses the appropriate function. For now two + file types are recognized: C/C++ and PO. Especially handling PO + files make the msgjoin program obsolete. + +Sat Mar 23 01:50:00 1996 Ulrich Drepper <drepper@myware> + + * msgfmt.c (verbose): Rename to verbose_level. + (main): Increment verbose_level each time -v option is given. + (format_directive_domain): Print some of the diagnostic messages only + if verbosity level is > 1. Suggested by Franc,ois Pinard for a + better interface to PO mode. + + * xgettext.c (scan_c_file): Extract all string if `extract-all' + option is given. Reported by Roland McGrath. + +Thu Mar 14 14:55:20 1996 Ulrich Drepper <drepper@myware> + + * msgfmt.c (format_comment_special): Be prepared that special + comment contains more than one entry, separated by commas. + + * message.c (message_print): Special comments are now written in a + line, separated by commas. + + * msgmerge.c (merge): Replace `INEXACT' with `fuzzy'. + +Thu Mar 14 11:50:48 1996 Marcus Daniels <[email protected]> + + * po-hash.h (po_hash): Change __P to PARAMS in prototype. + +Fri Mar 1 13:35:01 1996 Ulrich Drepper <drepper@myware> + + * msgfmt.c (main): Set error_one_per_line to 1 to prevent more + than one error message per line. Suggested by Franc,ois Pinard. + + * po-lex.h (po_gram_error): Don't write source file name in fatal + message. + (po_gram_error_with_loc): Ditto. + + * po-lex.c (lex_close): Don't write source file name in fatal + message. + (po_gram_error): Ditto. + (po_gram_error_with_loc): Ditto. + +Fri Mar 1 00:30:49 1996 Ulrich Drepper <drepper@myware> + + * po-lex.h: Use PARAMS instead of __P in header declarations. + + * msgcmp.c (compare_methods): Set new field comment_special to + NULL. + + * msgjoin.c (join_methods): Set new field comment_special to NULL. + + * xgettext.c (exclude_methods): Set new field comment_special to + NULL. + + * po.h (struct po_method_ty): New field comment_special. + (po_directive_domain, po_directive_message, po_parse_brief, + po_parse_debrief, po_comment, po_comment_dot, po_comment_filepos): + Remove prototypes. Now are local functions. + + * po.c (po_parse_brief, po_parse_debrief, po_directive_domain, + po_directive_message, po_comment, po_comment_dot, + po_comment_filepos): Declare functions as local and add + prototypes. + (po_comment_special): New function. + (po_callback_comment): For special comments call po_comment_special. + + * msgmerge.c (usage): Add --force in help message. + (merge_methods): Set special comment callback to NULL. + + * po-lex.c (lex_open): Don't set pass_comments to 0. This has to + be done in upper layer functions. + (po_gram_lex): Also pass #! comments up. + + * msgfmt.c (main): Make lexer pass comments up. + (format_comment_special): New function. Warns about `#! INEXACT' + comments. + (format_methods): Add callback for special comment. + +Wed Feb 14 01:56:14 1996 Ulrich Drepper <drepper@myware> + + * xgettext.c (main): Remove option --output-suffix. When default + domain name is "-" write to stdout. + +Mon Feb 12 02:20:09 1996 Ulrich Drepper <drepper@myware> + + * xgettext.c (main): Implement --output-suffix parameter to + determine alternative form of suffix for output file. + + * xgettext.c, msgjoin.c, msgmerge.c, msgunfmt.c (main): Add + additional argument to message_list_print call: control output in + case of empty PO file. + * message.c (message_list_print): Implement FORCE parameter. + * message.h: Change prototype. + +Sun Jan 21 17:24:56 1996 Ulrich Drepper <drepper@myware> + + * Makefile.in (install-exec): Include empty else case for case + when Perl is not available. Reported by John David Anglin. + +Sat Dec 23 12:41:43 1995 Jun Young <[email protected]> + + * gettextp.c (usage): Short option for version info is -V. + +Tue Dec 19 22:10:12 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (Makefile, tupdate): Explicitly use $(SHELL) for + running shell scripts. + +Sat Dec 9 17:06:11 1995 Ulrich Drepper <drepper@myware> + + * xgettext.c, xget-lex.h, xget-lex.c, str-list.h, po.h, po.c, + po-lex.c, po-hash.y, po-gram.h, open-po.c, msgunfmt.c, msgmerge.c, + msgjoin.c, msgfmt.c, msgcmp.c, message.h, message.c, gettextp.c: + Use PARAMS instead of __P. Suggested by Roland McGrath. + +Fri Dec 8 01:38:40 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (PROGRAMS): Add definitions for new msgjoin program. + + * msgjoin.c: Initial revision. + +Wed Dec 6 18:43:14 1995 Ulrich Drepper <drepper@myware> + + * open-po.c (open_po_file): Recognize /dev/stdin as name for + stdin. Recognize .pot as valid extension. + +Wed Dec 6 18:05:11 1995 Ulrich Drepper <drepper@myware> + + * msgmerge.c (main): Sort options in getopt loop. + +Mon Dec 4 15:37:22 1995 Ulrich Drepper <drepper@myware> + + * msgmerge.c: (main): Remove unused variable `exit_status'. + +Sun Dec 3 02:51:31 1995 Ulrich Drepper <drepper@myware> + + * xget-lex.h: [xgettext_token_type_ty]: We now have two keyword + types and also the comma is important. + + * xgettext.c (remember_a_message): + Correct handling of -c option. This is not a + string to prepend to output. Instead it selects single strings to + include (instead of all). Reported by Marcus Daniels. + (scan_c_file): Extend state machine. We have to retrieve the second + argument for the keywords `dgettext' and `dcgetetxt`. + + * xget-lex.c (phase5_get): Recognize ','. + (xgettext_lex): Pass ',' on caller. + Return different value for keywords `dgetetxt' and `dcgettext`. + + * xget-lex.c (xgettext_lex): `gettext_noop' is an default keyword. + + * msgunfmt.c (usage): + Message should not contain TABs. Reported by Franc,ois Pinard. + + * msgunfmt.c (usage): + Correct typo: Uniforun -> Uniforum. Reported by Franc,ois Pinard. + +Mon Nov 20 21:12:52 1995 Ulrich Drepper <drepper@myware> + + * po-lex.c, message.c: Some more pretty printing. + + * message.c (wrap): Don't support '\a' and '\v'. + + * xget-lex.c (phase7_getc): Don't support '\v'. + + * po-lex.c (control_sequence): Don't support '\v'. + + * gettextp.c (expand_escape): Don't support \a and \v. + + * msgcmp.c (compare): Really define static. + +Thu Nov 16 22:42:33 1995 Ulrich Drepper <drepper@myware> + + * msgmerge.c (merge): Remove additional parameter in in prototype. + + * xgettext.c: Reomved unused type definition. Patch by Peter Miller. + + * xget-lex.c: Correct some comments and better implementation of + -k option. Patch by Peter Miller. + + * po.h: Fix typos. By Peter Miller. + + * po-lex.c (po_gram_lex): Prevent accumulation of #! comments. + + * po-gram.y (comments): Remove unused rule. + + * msgmerge.c: Implement new options sort-by-file and sort-output. + Patches by Peter Miller. + + * msgcmp.c (domain): Remove unused global variable. + (domain_directive): Remove unused function. + + * message.h: Fix comment for MESSAGE_DOMAIN_DEFAULT definition. + + * message.c (message_print): Correct typo. + Clarify comments about ANSI escape sequences. + Patches by Peter Miller. + + * Makefile.in (DISTFILES): Remove $(COMSRCS). + (MSGFMT_OBJ): Correct indentation. Patches by Peter Miller. + +Sun Nov 12 12:52:29 1995 Ulrich Drepper <drepper@myware> + + * xgettext.c (line, string, comment): Remove unused global variables. + (read_name_from_file): Remove unused variable `cp'. + + * msgmerge.c (merge): Add missing return statement. + + * msgfmt.c (check_pair): Correctly pair comparisons. + + * msgcmp.c (domain_list, mlp): Remove unused global variables. + +Sat Nov 11 21:39:17 1995 Ulrich Drepper <drepper@myware> + + * message.c (message_list_print): + Prevent output if we have no (real) entry. + + * xgettext.c (remember_a_message): Implement exclude file handling. + +Sat Nov 11 17:38:05 1995 Ulrich Drepper <drepper@myware> + + * msgunfmt.c: Fix message. + + * xgettext.c: Use string handling from str-list and .po file + handling use xget-lex et.al. + + * xget-lex.h, xget-lex.c, str-list.h, str-list.c, po.h: + Initial revision. + + * po-lex.h: Allow variable upper limit of errors. + New prototypes. + + * po-lex.c: Allow variable upper limit of errors. + Make comment's text available to the caller. + + * po.c, po-hash.y, po-hash.h: Initial revision. + + * po-gram.y: Add handling of comments. + + * po-gram.h: Remove all but one declaration. + + * msgunfmt.c, msgmerge.c: Initial revision. + + * msgfmt.c: Adopt for new interface to parser. + + * msgcmp.c: Move lot's of general code to other files. + + * message.h, message.c: + Extended functionality for Peter Miller's pseudo-OO programming. + + * Makefile.in: Rewrite after adding rules for new programs. + +Fri Nov 10 10:01:37 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (PROGRAMS): Add new programs msgmerge and msgunfmt. + +Thu Nov 9 01:29:46 1995 Ulrich Drepper <drepper@myware> + + * gettextp.c (usage): Split message in two parts. + + * xgettext.c (usage): Split message in three parts. + + * xgettext.c (main): + Print warning if --files-from option and file names on command + line are given. + + * xgettext.c (long_options): + Mixed up `default-domain' and `directory' values. + +Wed Nov 8 23:31:34 1995 Ulrich Drepper <drepper@myware> + + * xgettext.c: Implement -D and -f option. + +Tue Nov 7 13:44:44 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (LIBS): One @LIBS@ must be @INTLLIBS@. + + * Makefile.in (LIBS): Correct definition. We must be prepared to + use two different libintl.a libraries. + (po-gram.gen.c): Don't use $< in non-implicit rule. + + * Makefile.in (install-exec): Use `test -n' instead of + `test XXX != ""'. Proposed by Franc,ois Pinard. + +Sun Nov 5 23:59:03 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (INSTALL_PROGRAM): Do not specify mode. + +Sun Nov 5 21:13:57 1995 Ulrich Drepper <drepper@myware> + + * xgettext.c, msgfmt.c: + Comments describing what has to be done should start with FIXME. + +Sun Nov 5 19:39:56 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (dist-gettext): Make synonym for dist. + +Sun Nov 5 18:11:15 1995 Ulrich Drepper <drepper@myware> + + * po-lex.h (gram_error, gram_error_with_loc): + Don't define macros when !__STDC__ + even when using gcc. + + * po-lex.c (gram_error, gram_error_with_loc): + Compile if !__STDC__ even if using gcc. + + * Makefile.in (po-gram.gen.c po-gram.gen.h): + Remove file prior of generation. + +Sun Nov 5 11:39:21 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (dist): Suppress error message when ln failed. + Get files from $(srcdir) explicitly. + + * xgettext.c (process_c_source): + Make gettext_noop the forth builtin marker. + +Fri Nov 3 00:57:52 1995 Ulrich Drepper <drepper@myware> + + * msgfmt.c (main): Don't free fname when no suffix was added. + +Thu Nov 2 22:55:44 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (dist): Also remove msgcmp. + +Tue Oct 31 22:27:52 1995 Ulrich Drepper <drepper@myware> + + * msgfmt.c: New option --strict: Only if this is given the .mo + file ending is forced. + + * msgfmt.c (message_directive): + Call error_with_loc with correct parameters. + + * msgfmt.c (message_directive): + Ignores empty message does not count as fatal error. + + * Makefile.in (po-gram.gen.c): + Add g suffix to make multiple substitution in one + line possible. + +Mon Oct 30 22:35:41 1995 Ulrich Drepper <drepper@myware> + + * po-gram.h: + Don't give defines for translation of yy* symbols. This is not enough + to be able to have more than one parser. See src/Makefile for the way + we chose. + + * Makefile.in (po-gram.gen.c): + Rewrite generated source while copying. This is the + only portable way to get more than one parser in the same program. + Patch by Peter Miller. + +Sun Oct 29 10:49:59 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (INSTALL_SCRIPT): New variable. + (install-exec): Install tupdate using INSTALL_SCRIPT to prevent error + when using strip flag. + +Sat Oct 28 14:39:33 1995 Ulrich Drepper <drepper@myware> + + * po-gram.h: Include <sys/types.h>. + + * xgettext.c (main): + Honour -n option even if --omit-header is given. By Peter Miller. + + * msgcmp.c (check_domain_coverage): + No double space in message. By Peter Miller. + + * msgcmp.c (grammar): + Close input file after coverage check. Patch by Peter Miller. + +Wed Sep 27 20:27:26 1995 Ulrich Drepper <drepper@myware> + + * msgcmp.c: + Don't try to include <string.h>. This is done in "system.h". + + * po-lex.c (gram_error, gram_error_with_loc): + Add argument definition for K&R style. + (gram_error, gram_error_with_loc): We increase gram_nerrors, + not nerrors. Reported by Francesco Potorti`. + +Tue Sep 26 10:03:29 1995 Ulrich Drepper <drepper@myware> + + * po-gram.h (yyparse): Add redefinition to gram_parse. + + * Makefile.in (YFLAGS): + Don't use -p option. Stupid old yaccs do not know it. + + * po-lex.c: Include po-gram.h to get redefinitions of yy* symbols. + + * po-gram.h (yylex, yylval, yyerror): + Redefine these symbols to gram_* because the + yacc is now called without -p option. + + * Makefile.in (LIBS): + Undid last change. On some systems libintl.a is not + completely self-contained. alloca() is miisong e.g. on HP-UX. + +Mon Sep 25 22:35:55 1995 Ulrich Drepper <drepper@myware> + + * msgfmt.c (add_mo_suffix): Fix typo. + + * po-lex.h: Include <sys/types.h>. + (lex_open): Argument is now `const char *'. + + * msgfmt.c (add_mo_suffix): + Allow .gmo suffix. Great idea by Marcus Daniels. + +Sat Sep 23 08:20:54 1995 Ulrich Drepper <drepper@myware> + + * po-gram.y, po-lex.c: Include error.h. + + * open-po.c (open_po_file): + Remove unused variables `path_dir' and `open_po_file'. + +Thu Sep 21 15:30:36 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (LIBS): + using libnlsut.a twice is not necessary anymore. libintl.a is + selfcontained. + + * gettextp.c (main): + Use dcgettext__ and bindtextdomain__ instead of __dcgettext + and __bindtextdomain. + + * msgfmt.c, xgettext.c (exit_status): + New variables. Contains exit status for the case the program + ends normally. Changed when non-fatal error messages are given. + +Wed Sep 20 09:16:57 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (xgettext): No also link po-gram.gen.o and po-lex.o. + + * po-lex.c: Pretty print comments. + Do some CSE in computation of hex value. + + * xgettext.c (read_po_file): Now use the generated scanner. + (domain_directive, message_directive): New functions needed for + scanner. + (add_id_str): Correct test for exclude files. The messages in the + exclude table are in raw format, not C format. + (write_out_domain): Check for zero messages and don't write anything in + this case. + + * po-lex.c (lex_open): Argument NAME is now const. + (gram_error): Move VARARGS1 comment to right place. + (control_sequence): Pretty print some comments. + +Mon Sep 18 21:23:55 1995 Ulrich Drepper <drepper@myware> + + * msgfmt.c (add_mo_suffix): Really check for not .mo suffix. + + * xgettext.c (write_out_domain): + Write file names in #: lines to file, not stdout. + + * po-gram.y (grammar): + Remove function. This allows sharing this file in different + programs. + + * domain.h (msg_domain): Member DOMAIN_NAME is now const. + + * Makefile.in (PROGRAMS): Add msgcmp. + (HEADERS): Add message.h. + (SOURCES): Add message.c and msgcmp.c. + (OBJECTS): Add message.o and msgcmp.o. + (msgcmp): Rule to construct program. + + * message.h, message.c: Initial revision + + * msgfmt.c (grammar): Close comment so that function is seen. + (message_directive): MSGID and MSGSTR are not const. + + * msgcmp.c: Initial revision + + * po-gram.h (message_directive): + MSGID and MSGSTR argument are not const. + + * po-gram.h (grammar): Remove prototype. Is now locally defined. + + * po-lex.h (gram_error, gram_error_with_loc): + Protect the instructions by do while (0). + + * msgfmt.c (grammar): + Define function here. This allows sharing the grammar file + with the msgcmp program. + + * msgfmt.c (domain_directive): Free memory of NAME if not needed. + (new_domain): Do not duplicate filename, use it as it is. + + * msgfmt.c (message_directive): + Free parameter string memory here if necessary. + Was done in po-gram.y before. + + * po-gram.h: Remove comment after closing #endif. + + * po-gram.h (grammar): Name parameter in prototype. + +Sun Sep 17 23:29:30 1995 Ulrich Drepper <drepper@myware> + + * xgettext.c (read_po_file): We don't have a search path anymore, + so third argument to open_po_file is not needed anymore. Reduce + argument list by this parameter, too. + + * po-lex.c (lex_open): + We don't have a search path anymore, so third argument to + ope_po_file is not needed anymore. + + * open-po.c (open_po_file): Remove unused `use_path' parameter. + + * Makefile.in (HEADERS): Add po-gram.h and po-lex.h. + + * po-gram.h, po-lex.h: Initial revision + + * Makefile.in (YACC, YFLAGS): New program used for .po file grammar. + (SOURCES): Add po-gram.y and po-lex.c. + (GENHEADERS, GENSOURCES): New variables for generated headers + and sources. + (OBJECTS): Add po-gram.gen.o and po-lex.o. + Add rules for new files and add to dependency list for msgfmt. + + * po-lex.c, po-gram.y: Initial revision + + * xgettext.c: Remove input path handling. + Adapt for new hashing functions return values. + + * msgfmt.c: + Rewrite .po file handling. Use Peter Millers .po file Yacc grammar. + + * open-po.c: Remove handling of input path. + + * xgettext.c (write_out_domain): + Split #: lines each 80 columns. Based on a patch by + Peter Miller. + + * Makefile.in: hash.[ch] moved from src/ to lib/ subdirectory. + +Wed Aug 23 21:13:11 1995 Ulrich Drepper <drepper@myware> + + * tupdate.in: Don't print comment in front of obsolete entries. + +Tue Aug 22 22:16:31 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (AR, RANLIB): Remove definition. Not needed here. + Reported by Franc,ois Pinard. + +Sat Aug 19 17:38:22 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (install-src): + Make behave like install. I.e. really install the catalogs. + +Sat Aug 19 00:57:07 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (SCRIPTS): + New variable. Contains names of scipts to be generated and + installed. For now it is tupdate. + (PROGRAMS): Remove tupdate. + (all): Also depend on $(SCRIPTS). + +Fri Aug 18 13:02:04 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (PROGRAMS): Add tupdate. + (tupdate): New rule. Rebuild tupdate if tupdate.in or + ../config.status changed. + + * tupdate.in: Correct case where message is new: no really print msgid. + Better help message by Franc,ois Pinard. + Recognize #\t as comment. + Print comment for now obsolete entries. + Handle real comments (translator comments and tupdate generate obsolete + entries). + + * gettextp.c (usage): Better help message. + (usage): Add -s description to help screen. + +Mon Aug 14 23:50:48 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (install-src): New no-op goal. + +Thu Aug 10 11:26:45 1995 Ulrich Drepper <drepper@myware> + + * tupdate.in: Don't print two " in front of commented out msgstrs. + +Wed Aug 9 09:10:30 1995 Ulrich Drepper <drepper@myware> + + * hash.c: + Better implementation. Rehashing is now much faster because the + hashing value stored in the `used' field is reused. + (insert_entry): Split into two function. `insert_entry_2' now does the + the work while in `insert_entry' the checks are done. + (lookup_2): New function. Expects the search key to be NUL + terminated. This is the case when the key is already in the + hash table when rehashing. + + * msgfmt.c (write_table): + Third argument to `iterate_table' is now a `const' pointer. + + * hash.h (iterate_table): Third arguemtn is `const' pointer. + + * xgettext.c (struct id_str): Make fields `const' pointers. + +Fri Aug 4 22:45:39 1995 Ulrich Drepper <drepper@myware> + + * msgfmt.c (main): Fix typo: me -> we. + + * msgfmt.c (output_file_open): Remove this unused variable. + Reported by Jim Meyering. + + * Makefile.in (dist): Remove `copying instead' message. + + * gettextp.c: Start to implement non-Uniforum behaviour. + Implemented new mode where gettext behaves like `echo', + while translating the messages available in the specified test. + New option: -d, -e, -E, also available in normal mode: + -E: ignored. + -e: enable expansion of some escape sequences. + -d: specify text domain to use. + New option: -s: enable `echo' mode. + +Thu Aug 3 18:25:37 1995 Ulrich Drepper <drepper@myware> + + * msgfmt.c (usage): + Fix typo: anormalies -> anomalies. + Reported by Karl Anders O/ygard. + +Wed Aug 2 18:51:08 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (ID, TAGS): Do not use $^. + + * xgettext.c (write-header): Add `Content-Type' field. + +Tue Aug 1 20:07:58 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (distclean): Remove ID file. + + * Makefile.in (TAGS, ID): Use $^ as command argument. + (TAGS): Give etags -o option t write to current directory, + not $(srcdir). + (ID): Use $(srcdir) instead os $(top_srcdir)/src. + +Mon Jul 31 20:57:48 1995 Ulrich Drepper <drepper@myware> + + * msgfmt.c (process_po_file): + Quote msgstr in message "empty `msgstr' entry ignored". + Report by Karl Anders O/ygard. + +Sun Jul 30 12:14:29 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (LIBS): Always use ../intl/libintl.a. + (all): Always depend on ../intl/libintl.a. + +Tue Jul 25 00:15:01 1995 Ulrich Drepper <drepper@myware> + + * msgfmt.c (process_po_file): Correct problem with empty lines. + +Sun Jul 23 22:47:56 1995 Ulrich Drepper <drepper@myware> + + * msgfmt.c (process_po_file): + Give a message when a sole msgid is found at the end of file. + +Wed Jul 19 01:52:13 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (PROGRAMS): Always compile all three programs. + + * gettextp.c: Include libgettext.h explicitly, in addition to + libintl.h. On system having libintl.h provided by the C library + this assures to have the prototypes for the function defined in + GNU gettext library. + Use __bindtextdomain and __dgettext instead of bindtextdomain and + dgettext resp. + Swap arguments in bindtextdomain call. + +Tue Jul 18 23:57:16 1995 Ulrich Drepper <drepper@myware> + + * xgettext.c (add_id_str): + `free(msgstr)' can fail on system not allowing free(0). + Reported by Francesco Potorti`. + +Tue Jul 18 19:43:41 1995 Ulrich Drepper <drepper@myware> + + * xgettext.c (getpwuid): + Define prototype if !defined _POSIX_VERSION. + + * hash.c: Don't include malloc.h and string.h because it will be + done in system.h. + + * msgfmt.c: Don't include malloc.h because it will be done in + system.h. + +Sat Jul 15 00:45:31 1995 Ulrich Drepper <drepper@myware> + + * xgettext.c (main): + Disable line_comment option when omit_header is selected. + (write_out_domain): Don't write empty line if !line_comment. + + * Makefile.in (DISTFILES): + Due shorted file names now distribute tupdate.in. + (install, clean): Handle tupdate, not tupdate.perl. + + * tupdate.in: Rename tupdate.perl.in to tupdate.in to fit in 14 + character file systems. + +Thu Jul 13 22:21:22 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (install): Test whether Perl was found before + installing. + + * tupdate.perl.in: Make die message more GNU-like. + + * gettextp.c (usage): + Protect prototypes with __P and use K&R form for parameters. + + * xgettext.c (main): + Don't use 100u; poor K&R compilers need (unsigned) 100. + + * open-po.c (xstrdup): Protect prototype with __P. + + * msgfmt.c (usage, new_domain, process_po_file, compare_id, + write_table, check_pair): Protect prototypes with __P. + + * hash.c (xmalloc): Protect prototype with __P. + +Thu Jul 13 01:39:47 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in (check): New no-op goal. + +Wed Jul 12 10:40:54 1995 Ulrich Drepper <drepper@myware> + + * tupdate.perl.in: Implement --help and --version options + + * xgettext.c: Add --string-limit option to specify limit on string + length. + Only warned when verbose mode is selected. + Add --verbose option. + Help message now correctly says --version == -V. + +Tue Jul 11 22:57:54 1995 Ulrich Drepper <drepper@myware> + + * xgettext.c (usage): Split help string because it breaks 1024 + byte limit. + + * Makefile.in (install-exec): Install tupdate. + + * xgettext.c (stdlib.h): Protect inclusion by STDC_HEADERS. + (assert): No assertions anymore. + (HAVE_STRTOUL): strtoul is now substituted when not available. + Add warning about too long strings (some systems have limits + for strings in their compiler and/or tools). E.g. Sinix's + gencat program. + + * msgfmt.c (printf.h): Include always + (assert): No assertions anymore (all bugs are gone :-). + (HAVE_STRTOUL): Not needed anymore because we substitute + strtoul if not present. + + * Makefile.in (DISTFILES,distclean): tupdate.perl is now found here. + +Tue Jul 11 01:31:03 1995 Ulrich Drepper <drepper@myware> + + * Makefile.in: msgfmt.o depends on ../lib/printf.h. + + * msgfmt.c: protect inclusion of malloc.h and stdlib.h. + Don't use GCC's `case b ... e:' feature (NeXT's gcc is + gcc-2.xx but does not understand this. Grrr!). + + * open-po.c: Protect inclusion of string.h and stdlib.h. + + * hash.c: Pretty print #define. + (init_hash, insert_entry): Cast result of calloc. + (insert_entry): Remove non-ANSI `(type *) var = ...' by + `*(type **) &var = ...'. + (compute_hashval): Cast constant to unsigned long (default: int). + Has effects on 64-bit machines. + +Tue Jul 4 00:39:58 1995 Ulrich Drepper <drepper@myware> + + * xgettext.c: Don't write "Version:" field for msgid "". + +Mon Jul 3 23:02:04 1995 Ulrich Drepper <drepper@myware> + + * xgettext.c, msgfmt.c: Better comment. + + * Makefile.in: Pretty print with Franc,ois. + Fix typo in dependencies. + Even more dependency corrections. + Correct dependencies of open-po.c. + Remove unneeded $(srcdir) from Makefile.in dependency. + (LIBS): Correct for building in different directory. + (INCLUDES): Correct for building in different directory. + (DEFS): Rename DEF_MSG_DOM_DIR to LOCALEDIR. + (INCLUDE): Don't use -I paths when not needed. + + * hash.c: Include malloc.c and protect string.h inclusion. + + * gettextp.c: Protect include of stdlib.h declare prototype for + getenv if not __STDC__. + Include system.h for EXIT_FAILURE. + (main, usage): Replace DEF_MSG_DOM_DIR by LOCALEDIR. + + * open-po.c: Include system.h for EXIT_FAILURE. + + * msgfmt.c: Fix typo in !__STDC__ path. + (process_po_file): Change for new .po file format. + + * xgettext.c (main): Rename DEF_MSG_DOM_DIR to LOCALEDIR. + Update to new .po file format because Solaris' msgfmt can only + handle ANSI C style multi-line strings. + +Sun Jul 2 21:31:00 1995 Ulrich Drepper <drepper@myware> + + * gettextp.c: gettextp.c (usage): Fix typo in help message. + Reported by Franc,ois Pinard. + +Sun Jul 2 02:12:41 1995 Ulrich Drepper <drepper@myware> + + * First official release. This directory contains the + source code for the programs specified in the Uniforum proposal + for internationalization. diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/Makefile.am b/debian/gettext-kde/gettext-kde-0.10.35/src/Makefile.am new file mode 100644 index 00000000..895869f6 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/Makefile.am @@ -0,0 +1,75 @@ +## Makefile for program src directory in GNU NLS utilities package. +## Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2, or (at your option) +## any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +## Process this file with automake to produce Makefile.in. + +AUTOMAKE_OPTIONS = 1.2 gnits + +bin_PROGRAMS = gettext msgcmp msgfmt msgmerge msgunfmt xgettext msgcomm + +noinst_HEADERS = domain.h message.h po-gram.h po-hash.h po-lex.h po.h \ +str-list.h xget-lex.h po-gram.gen.h po-hash.gen.h dir-list.h + +EXTRA_DIST = po-gram.y po-hash.y + +datadir = $(prefix)/@DATADIRNAME@ +localedir = $(datadir)/locale + +l = @l@ + +INCLUDES = -I$(srcdir) -I.. -I$(top_srcdir)/lib -I../intl -I$(top_srcdir)/intl +DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@ +LDADD = ../lib/libnlsut.a ../intl/libintl.$la + +SED = sed +YACC = @YACC@ +YFLAGS = -d + +# Source dependecies. +gettext_SOURCES = gettextp.c +msgcmp_SOURCES = message.c msgcmp.c open-po.c po-gram.gen.c po-hash.gen.c \ +po-lex.c po.c str-list.c dir-list.c +msgfmt_SOURCES = msgfmt.c open-po.c po-gram.gen.c po-hash.gen.c po-lex.c po.c \ +str-list.c message.c dir-list.c +msgmerge_SOURCES = message.c msgmerge.c open-po.c po-gram.gen.c po-hash.gen.c \ +po-lex.c po.c str-list.c dir-list.c +msgunfmt_SOURCES = message.c msgunfmt.c str-list.c +xgettext_SOURCES = message.c open-po.c po-gram.gen.c po-hash.gen.c po-lex.c \ +po.c str-list.c xget-lex.c xgettext.c dir-list.c +msgcomm_SOURCES = msgcomm.c message.c po-gram.gen.c po-hash.gen.c po-lex.c \ +open-po.c po.c str-list.c dir-list.c + +MAINTAINERCLEANFILES = po-gram.gen.c po-gram.gen.h po-hash.gen.c po-hash.gen.h + +# Some rules for yacc handling. +po-gram.gen.c po-gram.gen.h: po-gram.y + $(YACC) $(YFLAGS) $(srcdir)/po-gram.y + if test -s y.tab.c && test -s y.tab.h; then \ + rm -f $(srcdir)/po-gram.gen.c $(srcdir)/po-gram.gen.h; \ + $(SED) 's/[yY][yY]/po_gram_/g' < y.tab.c > $(srcdir)/po-gram.gen.c; \ + $(SED) 's/[yY][yY]/po_gram_/g' < y.tab.h > $(srcdir)/po-gram.gen.h; \ + fi + rm -f y.tab.c y.tab.h + +po-hash.gen.c po-hash.gen.h: po-hash.y + $(YACC) $(YFLAGS) $(srcdir)/po-hash.y + if test -s y.tab.c && test -s y.tab.h; then \ + rm -f $(srcdir)/po-hash.gen.c $(srcdir)/po-hash.gen.h; \ + $(SED) 's/[yY][yY]/po_hash_/g' < y.tab.c > $(srcdir)/po-hash.gen.c; \ + $(SED) 's/[yY][yY]/po_hash_/g' < y.tab.h > $(srcdir)/po-hash.gen.h; \ + fi + rm -f y.tab.c y.tab.h diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/Makefile.in b/debian/gettext-kde/gettext-kde-0.10.35/src/Makefile.in new file mode 100644 index 00000000..8ea49e4d --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/Makefile.in @@ -0,0 +1,454 @@ +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = /bin/sh + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_VERSION = @ACLOCAL_VERSION@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +DATADIRNAME = @DATADIRNAME@ +EMACS = @EMACS@ +GENCAT = @GENCAT@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GT_NO = @GT_NO@ +GT_YES = @GT_YES@ +INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ +INSTOBJEXT = @INSTOBJEXT@ +INTLDEPS = @INTLDEPS@ +INTLLIBS = @INTLLIBS@ +INTLOBJS = @INTLOBJS@ +LD = @LD@ +LIBOBJS = @LIBOBJS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +NM = @NM@ +PACKAGE = @PACKAGE@ +POFILES = @POFILES@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +aclocaldir = @aclocaldir@ +lispdir = @lispdir@ + +AUTOMAKE_OPTIONS = 1.2 gnits + +bin_PROGRAMS = gettext msgcmp msgfmt msgmerge msgunfmt xgettext msgcomm + +noinst_HEADERS = domain.h message.h po-gram.h po-hash.h po-lex.h po.h \ +str-list.h xget-lex.h po-gram.gen.h po-hash.gen.h dir-list.h + +EXTRA_DIST = po-gram.y po-hash.y + +datadir = $(prefix)/@DATADIRNAME@ +localedir = $(datadir)/locale + +l = @l@ + +INCLUDES = -I$(srcdir) -I.. -I$(top_srcdir)/lib -I../intl -I$(top_srcdir)/intl +DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@ +LDADD = ../lib/libnlsut.a ../intl/libintl.$la + +SED = sed +YACC = @YACC@ +YFLAGS = -d + +# Source dependecies. +gettext_SOURCES = gettextp.c +msgcmp_SOURCES = message.c msgcmp.c open-po.c po-gram.gen.c po-hash.gen.c \ +po-lex.c po.c str-list.c dir-list.c +msgfmt_SOURCES = msgfmt.c open-po.c po-gram.gen.c po-hash.gen.c po-lex.c po.c \ +str-list.c message.c dir-list.c +msgmerge_SOURCES = message.c msgmerge.c open-po.c po-gram.gen.c po-hash.gen.c \ +po-lex.c po.c str-list.c dir-list.c +msgunfmt_SOURCES = message.c msgunfmt.c str-list.c +xgettext_SOURCES = message.c open-po.c po-gram.gen.c po-hash.gen.c po-lex.c \ +po.c str-list.c xget-lex.c xgettext.c dir-list.c +msgcomm_SOURCES = msgcomm.c message.c po-gram.gen.c po-hash.gen.c po-lex.c \ +open-po.c po.c str-list.c dir-list.c + +MAINTAINERCLEANFILES = po-gram.gen.c po-gram.gen.h po-hash.gen.c po-hash.gen.h +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +PROGRAMS = $(bin_PROGRAMS) + +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +gettext_OBJECTS = gettextp.o +gettext_LDADD = $(LDADD) +gettext_DEPENDENCIES = ../lib/libnlsut.a ../intl/libintl.$la +gettext_LDFLAGS = +msgcmp_OBJECTS = message.o msgcmp.o open-po.o po-gram.gen.o \ +po-hash.gen.o po-lex.o po.o str-list.o dir-list.o +msgcmp_LDADD = $(LDADD) +msgcmp_DEPENDENCIES = ../lib/libnlsut.a ../intl/libintl.$la +msgcmp_LDFLAGS = +msgfmt_OBJECTS = msgfmt.o open-po.o po-gram.gen.o po-hash.gen.o \ +po-lex.o po.o str-list.o message.o dir-list.o +msgfmt_LDADD = $(LDADD) +msgfmt_DEPENDENCIES = ../lib/libnlsut.a ../intl/libintl.$la +msgfmt_LDFLAGS = +msgmerge_OBJECTS = message.o msgmerge.o open-po.o po-gram.gen.o \ +po-hash.gen.o po-lex.o po.o str-list.o dir-list.o +msgmerge_LDADD = $(LDADD) +msgmerge_DEPENDENCIES = ../lib/libnlsut.a ../intl/libintl.$la +msgmerge_LDFLAGS = +msgunfmt_OBJECTS = message.o msgunfmt.o str-list.o +msgunfmt_LDADD = $(LDADD) +msgunfmt_DEPENDENCIES = ../lib/libnlsut.a ../intl/libintl.$la +msgunfmt_LDFLAGS = +xgettext_OBJECTS = message.o open-po.o po-gram.gen.o po-hash.gen.o \ +po-lex.o po.o str-list.o xget-lex.o xgettext.o dir-list.o +xgettext_LDADD = $(LDADD) +xgettext_DEPENDENCIES = ../lib/libnlsut.a ../intl/libintl.$la +xgettext_LDFLAGS = +msgcomm_OBJECTS = msgcomm.o message.o po-gram.gen.o po-hash.gen.o \ +po-lex.o open-po.o po.o str-list.o dir-list.o +msgcomm_LDADD = $(LDADD) +msgcomm_DEPENDENCIES = ../lib/libnlsut.a ../intl/libintl.$la +msgcomm_LDFLAGS = +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) +LINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) -o $@ +HEADERS = $(noinst_HEADERS) + +DIST_COMMON = ChangeLog Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +SOURCES = $(gettext_SOURCES) $(msgcmp_SOURCES) $(msgfmt_SOURCES) $(msgmerge_SOURCES) $(msgunfmt_SOURCES) $(xgettext_SOURCES) $(msgcomm_SOURCES) +OBJECTS = $(gettext_OBJECTS) $(msgcmp_OBJECTS) $(msgfmt_OBJECTS) $(msgmerge_OBJECTS) $(msgunfmt_OBJECTS) $(xgettext_OBJECTS) $(msgcomm_OBJECTS) + +all: Makefile $(PROGRAMS) $(HEADERS) + +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnits --include-deps src/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-binPROGRAMS: + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +distclean-binPROGRAMS: + +maintainer-clean-binPROGRAMS: + +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(bin_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + done + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +gettext: $(gettext_OBJECTS) $(gettext_DEPENDENCIES) + @rm -f gettext + $(LINK) $(gettext_LDFLAGS) $(gettext_OBJECTS) $(gettext_LDADD) $(LIBS) + +msgcmp: $(msgcmp_OBJECTS) $(msgcmp_DEPENDENCIES) + @rm -f msgcmp + $(LINK) $(msgcmp_LDFLAGS) $(msgcmp_OBJECTS) $(msgcmp_LDADD) $(LIBS) + +msgfmt: $(msgfmt_OBJECTS) $(msgfmt_DEPENDENCIES) + @rm -f msgfmt + $(LINK) $(msgfmt_LDFLAGS) $(msgfmt_OBJECTS) $(msgfmt_LDADD) $(LIBS) + +msgmerge: $(msgmerge_OBJECTS) $(msgmerge_DEPENDENCIES) + @rm -f msgmerge + $(LINK) $(msgmerge_LDFLAGS) $(msgmerge_OBJECTS) $(msgmerge_LDADD) $(LIBS) + +msgunfmt: $(msgunfmt_OBJECTS) $(msgunfmt_DEPENDENCIES) + @rm -f msgunfmt + $(LINK) $(msgunfmt_LDFLAGS) $(msgunfmt_OBJECTS) $(msgunfmt_LDADD) $(LIBS) + +xgettext: $(xgettext_OBJECTS) $(xgettext_DEPENDENCIES) + @rm -f xgettext + $(LINK) $(xgettext_LDFLAGS) $(xgettext_OBJECTS) $(xgettext_LDADD) $(LIBS) + +msgcomm: $(msgcomm_OBJECTS) $(msgcomm_DEPENDENCIES) + @rm -f msgcomm + $(LINK) $(msgcomm_LDFLAGS) $(msgcomm_OBJECTS) $(msgcomm_LDADD) $(LIBS) + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = src + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done +dir-list.o: dir-list.c ../config.h ../lib/system.h dir-list.h str-list.h +gettextp.o: gettextp.c ../config.h ../lib/getopt.h ../lib/error.h \ + ../lib/system.h ../intl/libgettext.h +message.o: message.c ../config.h ../lib/fstrcmp.h message.h po-lex.h \ + ../lib/error.h str-list.h ../lib/system.h ../intl/libgettext.h +msgcmp.o: msgcmp.c ../config.h ../lib/getopt.h dir-list.h ../lib/error.h \ + message.h po-lex.h str-list.h ../lib/system.h po.h +msgcomm.o: msgcomm.c ../config.h ../lib/getopt.h dir-list.h \ + ../lib/error.h ../lib/getline.h ../intl/libgettext.h message.h \ + po-lex.h str-list.h po.h ../lib/system.h +msgfmt.o: msgfmt.c ../config.h ../lib/getopt.h ../lib/hash.h \ + ../lib/obstack.h dir-list.h ../lib/error.h ../lib/getline.h \ + ../lib/printf.h ../lib/system.h ../intl/gettext.h domain.h \ + ../intl/hash-string.h message.h po-lex.h str-list.h po.h +msgmerge.o: msgmerge.c ../config.h ../lib/getopt.h dir-list.h \ + ../lib/error.h message.h po-lex.h str-list.h ../lib/system.h \ + po.h +msgunfmt.o: msgunfmt.c ../config.h ../lib/getopt.h ../lib/hash.h \ + ../lib/obstack.h ../lib/error.h ../lib/getline.h \ + ../lib/printf.h ../lib/system.h ../intl/gettext.h domain.h \ + ../intl/hash-string.h message.h po-lex.h str-list.h +open-po.o: open-po.c ../config.h dir-list.h ../lib/error.h \ + ../lib/system.h +po-gram.gen.o: po-gram.gen.c ../config.h po-lex.h ../lib/error.h \ + po-gram.h ../lib/system.h po.h +po-hash.gen.o: po-hash.gen.c ../config.h ../lib/system.h po-hash.h po.h \ + po-lex.h ../lib/error.h +po-lex.o: po-lex.c ../config.h po-lex.h ../lib/error.h po-gram.h \ + ../lib/system.h po-gram.gen.h +po.o: po.c ../config.h po.h po-lex.h ../lib/error.h po-hash.h \ + ../lib/system.h +str-list.o: str-list.c ../config.h ../lib/system.h str-list.h +xget-lex.o: xget-lex.c ../config.h dir-list.h ../lib/error.h \ + ../lib/system.h ../intl/libgettext.h str-list.h xget-lex.h +xgettext.o: xgettext.c ../config.h ../lib/getopt.h dir-list.h \ + ../lib/error.h ../lib/hash.h ../lib/obstack.h ../lib/getline.h \ + ../lib/system.h po.h po-lex.h message.h str-list.h xget-lex.h \ + ../lib/printf-parse.h ../lib/printf.h ../intl/gettext.h \ + domain.h + +info: +dvi: +check: all + $(MAKE) +installcheck: +install-exec: install-binPROGRAMS + @$(NORMAL_INSTALL) + +install-data: + @$(NORMAL_INSTALL) + +install: install-exec install-data all + @: + +uninstall: uninstall-binPROGRAMS + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: + $(mkinstalldirs) $(DATADIR)$(bindir) + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean: mostlyclean-binPROGRAMS mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags \ + mostlyclean-generic + +clean: clean-binPROGRAMS clean-compile clean-libtool clean-tags \ + clean-generic mostlyclean + +distclean: distclean-binPROGRAMS distclean-compile distclean-libtool \ + distclean-tags distclean-generic clean + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-binPROGRAMS maintainer-clean-compile \ + maintainer-clean-libtool maintainer-clean-tags \ + maintainer-clean-generic distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ +maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile mostlyclean-libtool distclean-libtool \ +clean-libtool maintainer-clean-libtool tags mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info dvi \ +installcheck install-exec install-data install uninstall all \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Some rules for yacc handling. +po-gram.gen.c po-gram.gen.h: po-gram.y + $(YACC) $(YFLAGS) $(srcdir)/po-gram.y + if test -s y.tab.c && test -s y.tab.h; then \ + rm -f $(srcdir)/po-gram.gen.c $(srcdir)/po-gram.gen.h; \ + $(SED) 's/[yY][yY]/po_gram_/g' < y.tab.c > $(srcdir)/po-gram.gen.c; \ + $(SED) 's/[yY][yY]/po_gram_/g' < y.tab.h > $(srcdir)/po-gram.gen.h; \ + fi + rm -f y.tab.c y.tab.h + +po-hash.gen.c po-hash.gen.h: po-hash.y + $(YACC) $(YFLAGS) $(srcdir)/po-hash.y + if test -s y.tab.c && test -s y.tab.h; then \ + rm -f $(srcdir)/po-hash.gen.c $(srcdir)/po-hash.gen.h; \ + $(SED) 's/[yY][yY]/po_hash_/g' < y.tab.c > $(srcdir)/po-hash.gen.c; \ + $(SED) 's/[yY][yY]/po_hash_/g' < y.tab.h > $(srcdir)/po-hash.gen.h; \ + fi + rm -f y.tab.c y.tab.h + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/dir-list.c b/debian/gettext-kde/gettext-kde-0.10.35/src/dir-list.c new file mode 100644 index 00000000..e02d7089 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/dir-list.c @@ -0,0 +1,55 @@ +/* GNU gettext - internationalization aids + Copyright (C) 1996, 1998 Free Software Foundation, Inc. + + This file was written by Peter Miller <[email protected]> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef STDC_HEADERS +# include <stdlib.h> +#endif + +#include "system.h" +#include "dir-list.h" +#include "str-list.h" + +static string_list_ty *directory; + + +void +dir_list_append (s) + const char *s; +{ + if (directory == NULL) + directory = string_list_alloc (); + string_list_append_unique (directory, s); +} + + +const char * +dir_list_nth (n) + int n; +{ + if (directory == NULL) + dir_list_append ("."); + if (n < 0 || n >= directory->nitems) + return NULL; + return directory->item[n]; +} diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/dir-list.h b/debian/gettext-kde/gettext-kde-0.10.35/src/dir-list.h new file mode 100644 index 00000000..fd6bae7a --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/dir-list.h @@ -0,0 +1,26 @@ +/* GNU gettext - internationalization aids + Copyright (C) 1996, 1998 Free Software Foundation, Inc. + + This file was written by Peter Miller <[email protected]> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef SRC_DIR_LIST_H +#define SRC_DIR_LIST_H + +void dir_list_append PARAMS ((const char *__directory)); +const char *dir_list_nth PARAMS ((int __n)); + +#endif /* SRC_DIR_LIST_H */ diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/domain.h b/debian/gettext-kde/gettext-kde-0.10.35/src/domain.h new file mode 100644 index 00000000..c3d4284f --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/domain.h @@ -0,0 +1,35 @@ + +/* Copyright (C) 1995 Free Software Foundation, Inc. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#ifndef _DOMAIN_H +#define _DOMAIN_H 1 + +#include <stdio.h> +#include "hash.h" + +struct msg_domain +{ + /* Table for mapping message IDs to message strings. */ + hash_table symbol_tab; + /* Name domain these ID/String pairs are part of. */ + const char *domain_name; + /* Link to the next domain. */ + struct msg_domain *next; +}; + +#endif /* domain.h */ diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/gettextp.c b/debian/gettext-kde/gettext-kde-0.10.35/src/gettextp.c new file mode 100644 index 00000000..911577e6 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/gettextp.c @@ -0,0 +1,351 @@ +/* gettext - retrieve text string from message catalog and print it. + Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. + Written by Ulrich Drepper <[email protected]>, May 1995. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <getopt.h> +#include <stdio.h> + +#ifdef STDC_HEADERS +# include <stdlib.h> +#else +char *getenv (); +#endif + +#ifdef HAVE_LOCALE_H +# include <locale.h> +#endif + +#include "error.h" +#include "system.h" + +#include "libgettext.h" + +#define _(str) gettext (str) + +/* If nonzero add newline after last string. This makes only sense in + the `echo' emulation mode. */ +int add_newline; +/* If nonzero expand escape sequences in strings before looking in the + message catalog. */ +int do_expand; + +/* Name the program is called with. */ +char *program_name; + +/* Long options. */ +static const struct option long_options[] = +{ + { "domain", required_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "shell-script", no_argument, NULL, 's' }, + { "version", no_argument, NULL, 'V' }, + { NULL, 0, NULL, 0 } +}; + +/* Prototypes for local functions. */ +static void usage PARAMS ((int __status)) +#if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2) + __attribute__ ((noreturn)) +#endif +; +static const char *expand_escape PARAMS((const char *__str)); + +int +main (argc, argv) + int argc; + char *argv[]; +{ + int optchar; + int do_help = 0; + int do_shell = 0; + int do_version = 0; + const char *msgid; + const char *domain = getenv ("TEXTDOMAIN"); + const char *domaindir = getenv ("TEXTDOMAINDIR"); + + /* Set program name for message texts. */ + program_name = argv[0]; + add_newline = 1; + do_expand = 0; + +#ifdef HAVE_SETLOCALE + /* Set locale via LC_ALL. */ + setlocale (LC_ALL, ""); +#endif + + /* Set the text message domain. */ + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + while ((optchar = getopt_long (argc, argv, "+d:eEhnsV", long_options, NULL)) + != EOF) + switch (optchar) + { + case '\0': /* Long option. */ + break; + case 'd': + domain = optarg; + break; + case 'e': + do_expand = 1; + break; + case 'E': + /* Ignore. Just for compatibility. */ + break; + case 'h': + do_help = 1; + break; + case 'n': + add_newline = 0; + break; + case 's': + do_shell = 1; + break; + case 'V': + do_version = 1; + break; + default: + usage (EXIT_FAILURE); + } + + /* Version information is requested. */ + if (do_version) + { + printf ("%s (GNU %s) %s\n", basename (program_name), PACKAGE, VERSION); + /* xgettext: no-wrap */ + printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\ +This is free software; see the source for copying conditions. There is NO\n\ +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ +"), + "1995, 1996, 1997"); + printf (_("Written by %s.\n"), "Ulrich Drepper"); + exit (EXIT_SUCCESS); + } + + /* Help is requested. */ + if (do_help) + usage (EXIT_SUCCESS); + + /* We have two major modes: use following Uniforum spec and as + internationalized `echo' program. */ + if (do_shell == 0) + { + /* We have to write a single strings translation to stdout. */ + + if (optind >= argc) + error (EXIT_FAILURE, 0, _("missing arguments")); + + /* Get arguments. */ + msgid = argv[optind++]; + if (optind < argc) + { + domain = msgid; + msgid = argv[optind++]; + + if (optind < argc) + error (EXIT_FAILURE, 0, _("too many arguments")); + } + + /* If no domain name is given we print the original string. */ + if (domain == NULL || domain[0] == '\0') + { + fputs (msgid, stdout); + exit (EXIT_SUCCESS); + } + + /* Bind domain to appropriate directory. */ + if (domaindir != NULL && domaindir[0] != '\0') + bindtextdomain__ (domain, domaindir); + + /* Expand escape sequences is enabled. */ + if (do_expand) + msgid = expand_escape (msgid); + + /* Write out the result. */ + fputs (dgettext__ (domain, msgid), stdout); + } + else + { + /* If no domain name is given we print the original string. + We mark this assigning NULL to domain. */ + if (domain == NULL || domain[0] == '\0') + domain = NULL; + else + /* Bind domain to appropriate directory. */ + if (domaindir != NULL && domaindir[0] != '\0') + bindtextdomain__ (domain, domaindir); + + /* We have to simulate `echo'. All arguments are strings. */ + while (optind < argc) + { + msgid = argv[optind++]; + + /* Expand escape sequences is enabled. */ + if (do_expand) + msgid = expand_escape (msgid); + + /* Write out the result. */ + fputs (domain == NULL ? msgid : dgettext__ (domain, msgid), stdout); + + /* We separate the arguments by a single ' '. */ + if (optind < argc) + fputc (' ', stdout); + } + + /* If not otherwise told add trailing newline. */ + if (add_newline) + fputc ('\n', stdout); + } + + exit (EXIT_SUCCESS); +} + + +/* Display usage information and exit. */ +static void +usage (status) + int status; +{ + if (status != EXIT_SUCCESS) + fprintf (stderr, _("Try `%s --help' for more information.\n"), + program_name); + else + { + /* xgettext: no-wrap */ + printf (_("\ +Usage: %s [OPTION] [[[TEXTDOMAIN] MSGID] | [-s [MSGID]...]]\n\ + -d, --domain=TEXTDOMAIN retrieve translated messages from TEXTDOMAIN\n\ + -e enable expansion of some escape sequences\n\ + -E (ignored for compatibility)\n\ + -h, --help display this help and exit\n\ + -n suppress trailing newline\n\ + -V, --version display version information and exit\n\ + [TEXTDOMAIN] MSGID retrieve translated message corresponding\n\ + to MSGID from TEXTDOMAIN\n"), + program_name); + /* xgettext: no-wrap */ + printf (_("\ +\n\ +If the TEXTDOMAIN parameter is not given, the domain is determined from the\n\ +environment variable TEXTDOMAIN. If the message catalog is not found in the\n\ +regular directory, another location can be specified with the environment\n\ +variable TEXTDOMAINDIR.\n\ +When used with the -s option the program behaves like the `echo' command.\n\ +But it does not simply copy its arguments to stdout. Instead those messages\n\ +found in the selected catalog are translated.\n\ +Standard search directory: %s\n"), LOCALEDIR); + fputs (_("Report bugs to <[email protected]>.\n"), stdout); + } + + exit (status); +} + + +/* Expand some escape sequences found in the argument string. */ +static const char * +expand_escape (str) + const char *str; +{ + char *retval, *rp; + const char *cp = str; + + do + { + while (cp[0] != '\0' && cp[0] != '\\') + ++cp; + } + while (cp[0] != '\0' && cp[1] != '\0' + && strchr ("bcfnrt\\01234567", cp[1]) == NULL); + + if (cp[0] == '\0') + return str; + + retval = (char *) xmalloc (strlen (str)); + + rp = retval + (cp - str); + memcpy (retval, str, cp - str); + + do + { + switch (*++cp) + { + case 'b': /* backspace */ + *rp++ = '\b'; + ++cp; + break; + case 'c': /* suppress trailing newline */ + add_newline = 0; + ++cp; + break; + case 'f': /* form feed */ + *rp++ = '\f'; + ++cp; + break; + case 'n': /* new line */ + *rp++ = '\n'; + ++cp; + break; + case 'r': /* carriage return */ + *rp++ = '\r'; + ++cp; + break; + case 't': /* horizontal tab */ + *rp++ = '\t'; + ++cp; + break; + case '\\': + *rp = '\\'; + ++cp; + break; + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + { + int ch = *cp++ - '0'; + + if (*cp >= '0' && *cp <= '7') + { + ch *= 8; + ch += *cp++ - '0'; + + if (*cp >= '0' && *cp <= '7') + { + ch *= 8; + ch += *cp++ - '0'; + } + } + *rp = ch; + } + break; + default: + *rp = '\\'; + break; + } + + while (cp[0] != '\0' && cp[0] != '\\') + *rp++ = *cp++; + } + while (cp[0] != '\0'); + + /* Terminate string. */ + *rp = '\0'; + + return (const char *) retval; +} diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/message.c b/debian/gettext-kde/gettext-kde-0.10.35/src/message.c new file mode 100644 index 00000000..e381a291 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/message.c @@ -0,0 +1,1404 @@ +/* GNU gettext - internationalization aids + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + + This file was written by Peter Miller <[email protected]> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <errno.h> +#include <ctype.h> +#include <stdio.h> + +#ifdef HAVE_LIMITS_H +# include <limits.h> +#endif + +#ifdef HAVE_LOCALE_H +# include <locale.h> +#endif + +#ifdef STDC_HEADERS +# include <stdlib.h> +#endif + +#include "fstrcmp.h" +#include "message.h" +#include "system.h" +#include "error.h" +#include "libgettext.h" + + +/* Our regular abbreviation. */ +#define _(str) gettext (str) + + +/* These two variables control the output style of the message_print + function. Interface functions for them are to be used. */ +static int indent; +static int uniforum; +static int escape; + +/* This variable controls the page width when printing messages. + Defaults to PAGE_WIDTH if not set. Zero (0) given to message_page_- + width_set will result in no wrapping being performed. */ +static size_t page_width = PAGE_WIDTH; + + +/* Prototypes for local functions. */ +static void wrap PARAMS ((FILE *__fp, const char *__line_prefix, + const char *__name, const char *__value, + int do_wrap)); +static void print_blank_line PARAMS ((FILE *__fp)); +static void message_print PARAMS ((const message_ty *__mp, FILE *__fp, + const char *__domain, int blank_line, + int __debug)); +static void message_print_obsolete PARAMS ((const message_ty *__mp, FILE *__fp, + const char *__domain, + int blank_line)); +static int msgid_cmp PARAMS ((const void *__va, const void *__vb)); +static int filepos_cmp PARAMS ((const void *__va, const void *__vb)); +static const char *make_c_format_description_string PARAMS ((enum is_c_format, + int debug)); +static const char *make_c_width_description_string PARAMS ((enum is_c_format)); +static int significant_c_format_p PARAMS ((enum is_c_format __is_c_format)); + + + +message_ty * +message_alloc (msgid) + char *msgid; +{ + message_ty *mp; + + mp = xmalloc (sizeof (message_ty)); + mp->msgid = msgid; + mp->comment = NULL; + mp->comment_dot = NULL; + mp->filepos_count = 0; + mp->filepos = NULL; + mp->variant_count = 0; + mp->variant = NULL; + mp->used = 0; + mp->obsolete = 0; + mp->is_fuzzy = 0; + mp->is_c_format = undecided; + mp->do_wrap = undecided; + return mp; +} + + +void +message_free (mp) + message_ty *mp; +{ + size_t j; + + if (mp->comment != NULL) + string_list_free (mp->comment); + if (mp->comment_dot != NULL) + string_list_free (mp->comment_dot); + free ((char *) mp->msgid); + for (j = 0; j < mp->variant_count; ++j) + free ((char *) mp->variant[j].msgstr); + if (mp->variant != NULL) + free (mp->variant); + for (j = 0; j < mp->filepos_count; ++j) + free ((char *) mp->filepos[j].file_name); + if (mp->filepos != NULL) + free (mp->filepos); + free (mp); +} + + +message_variant_ty * +message_variant_search (mp, domain) + message_ty *mp; + const char *domain; +{ + size_t j; + message_variant_ty *mvp; + + for (j = 0; j < mp->variant_count; ++j) + { + mvp = &mp->variant[j]; + if (0 == strcmp (domain, mvp->domain)) + return mvp; + } + return 0; +} + + +void +message_variant_append (mp, domain, msgstr, pp) + message_ty *mp; + const char *domain; + const char *msgstr; + const lex_pos_ty *pp; +{ + size_t nbytes; + message_variant_ty *mvp; + + nbytes = (mp->variant_count + 1) * sizeof (mp->variant[0]); + mp->variant = xrealloc (mp->variant, nbytes); + mvp = &mp->variant[mp->variant_count++]; + mvp->domain = domain; + mvp->msgstr = msgstr; + mvp->pos = *pp; +} + + +void +message_comment_append (mp, s) + message_ty *mp; + const char *s; +{ + if (mp->comment == NULL) + mp->comment = string_list_alloc (); + string_list_append (mp->comment, s); +} + + +void +message_comment_dot_append (mp, s) + message_ty *mp; + const char *s; +{ + if (mp->comment_dot == NULL) + mp->comment_dot = string_list_alloc (); + string_list_append (mp->comment_dot, s); +} + + +message_ty * +message_copy (mp) + message_ty *mp; +{ + message_ty *result; + size_t j; + + result = message_alloc (xstrdup (mp->msgid)); + + for (j = 0; j < mp->variant_count; ++j) + { + message_variant_ty *mvp = &mp->variant[j]; + message_variant_append (result, mvp->domain, mvp->msgstr, &mvp->pos); + } + if (mp->comment) + { + for (j = 0; j < mp->comment->nitems; ++j) + message_comment_append (result, mp->comment->item[j]); + } + if (mp->comment_dot) + { + for (j = 0; j < mp->comment_dot->nitems; ++j) + message_comment_dot_append (result, mp->comment_dot->item[j]); + } + result->is_fuzzy = mp->is_fuzzy; + result->is_c_format = mp->is_c_format; + result->do_wrap = mp->do_wrap; + for (j = 0; j < mp->filepos_count; ++j) + { + lex_pos_ty *pp = &mp->filepos[j]; + message_comment_filepos (result, pp->file_name, pp->line_number); + } + return result; +} + + +message_ty * +message_merge (def, ref) + message_ty *def; + message_ty *ref; +{ + message_ty *result; + const char *pot_date_ptr = NULL; + size_t pot_date_len = 0; + size_t j; + + /* Take the msgid from the reference. When fuzzy matches are made, + the definition will not be unique, but the reference will be - + usually because it has a typo. */ + result = message_alloc (xstrdup (ref->msgid)); + + /* If msgid is the header entry (i.e., "") we find the + POT-Creation-Date line in the reference. */ + if (ref->msgid[0] == '\0') + { + pot_date_ptr = strstr (ref->variant[0].msgstr, "POT-Creation-Date:"); + if (pot_date_ptr != NULL) + { + const char *endp; + + pot_date_ptr += sizeof ("POT-Creation-Date:") - 1; + + endp = strchr (pot_date_ptr, '\n'); + if (endp == NULL) + { + char *extended; + endp = strchr (pot_date_ptr, '\0'); + pot_date_len = (endp - pot_date_ptr) + 1; + extended = (char *) alloca (pot_date_len + 1); + stpcpy (stpcpy (extended, pot_date_ptr), "\n"); + pot_date_ptr = extended; + } + else + pot_date_len = (endp - pot_date_ptr) + 1; + + if (pot_date_len == 0) + pot_date_ptr = NULL; + } + } + + /* Take the variant list from the definition. The msgstr of the + refences will be empty, as they were generated by xgettext. If + we currently process the header entry we have to merge the msgstr + by using the POT-Creation-Date field from the .pot file. */ + for (j = 0; j < def->variant_count; ++j) + { + message_variant_ty *mvp = &def->variant[j]; + + if (ref->msgid[0] == '\0') + { + /* Oh, oh. The header entry and we have something to fill in. */ + static const struct + { + const char *name; + size_t len; + } known_fields[] = + { + { "Project-Id-Version:", sizeof ("Project-Id-Version:") - 1 }, +#define PROJECT_ID 0 + { "POT-Creation-Date:", sizeof ("POT-Creation-Date:") - 1 }, +#define POT_CREATION 1 + { "PO-Revision-Date:", sizeof ("PO-Revision-Date:") - 1 }, +#define PO_REVISION 2 + { "Last-Translator:", sizeof ("Last-Translator:") - 1 }, +#define LAST_TRANSLATOR 3 + { "Language-Team:", sizeof ("Language-Team:") - 1 }, +#define LANGUAGE_TEAM 4 + { "MIME-Version:", sizeof ("MIME-Version:") - 1 }, +#define MIME_VERSION 5 + { "Content-Type:", sizeof ("Content-Type:") - 1 }, +#define CONTENT_TYPE 6 + { "Content-Transfer-Encoding:", + sizeof ("Content-Transfer-Encoding:") - 1 } +#define CONTENT_TRANSFER 7 + }; +#define UNKNOWN 8 + struct + { + const char *string; + size_t len; + } header_fields[UNKNOWN + 1]; + const char *cp; + char *newp; + size_t len, cnt; + + /* Clear all fields. */ + memset (header_fields, '\0', sizeof (header_fields)); + + cp = mvp->msgstr; + while (*cp != '\0') + { + const char *endp = strchr (cp, '\n'); + int terminated = endp != NULL; + + if (!terminated) + { + char *copy; + endp = strchr (cp, '\0'); + + len = endp - cp + 1; + + copy = (char *) alloca (len + 1); + stpcpy (stpcpy (copy, cp), "\n"); + cp = copy; + } + else + { + len = (endp - cp) + 1; + ++endp; + } + + /* Compare with any of the known fields. */ + for (cnt = 0; + cnt < sizeof (known_fields) / sizeof (known_fields[0]); + ++cnt) + if (strncasecmp (cp, known_fields[cnt].name, + known_fields[cnt].len) == 0) + break; + + if (cnt < sizeof (known_fields) / sizeof (known_fields[0])) + { + header_fields[cnt].string = &cp[known_fields[cnt].len]; + header_fields[cnt].len = len - known_fields[cnt].len; + } + else + { + /* It's an unknown field. Append content to what is + already known. */ + char *extended = (char *) alloca (header_fields[UNKNOWN].len + + len + 1); + memcpy (extended, header_fields[UNKNOWN].string, + header_fields[UNKNOWN].len); + memcpy (&extended[header_fields[UNKNOWN].len], cp, len); + extended[header_fields[UNKNOWN].len + len] = '\0'; + header_fields[UNKNOWN].string = extended; + header_fields[UNKNOWN].len += len; + } + + cp = endp; + } + + if (pot_date_ptr != NULL) + { + header_fields[POT_CREATION].string = pot_date_ptr; + header_fields[POT_CREATION].len = pot_date_len; + } + + /* Concatenate all the various fields. */ + len = 0; + for (cnt = 0; cnt < UNKNOWN; ++cnt) + if (header_fields[cnt].string != NULL) + len += known_fields[cnt].len + header_fields[cnt].len; + len += header_fields[UNKNOWN].len; + + cp = newp = (char *) xmalloc (len + 1); + newp[len] = '\0'; + +#define IF_FILLED(idx) \ + if (header_fields[idx].string) \ + newp = stpncpy (stpcpy (newp, known_fields[idx].name), \ + header_fields[idx].string, header_fields[idx].len) + + IF_FILLED (PROJECT_ID); + IF_FILLED (POT_CREATION); + IF_FILLED (PO_REVISION); + IF_FILLED (LAST_TRANSLATOR); + IF_FILLED (LANGUAGE_TEAM); + IF_FILLED (MIME_VERSION); + IF_FILLED (CONTENT_TYPE); + IF_FILLED (CONTENT_TRANSFER); + if (header_fields[UNKNOWN].string != NULL) + stpcpy (newp, header_fields[UNKNOWN].string); + + message_variant_append (result, mvp->domain, cp, &mvp->pos); + } + else + message_variant_append (result, mvp->domain, mvp->msgstr, &mvp->pos); + } + + /* Take the comments from the definition file. There will be none at + all in the reference file, as it was generated by xgettext. */ + if (def->comment) + for (j = 0; j < def->comment->nitems; ++j) + message_comment_append (result, def->comment->item[j]); + + /* Take the dot comments from the reference file, as they are + generated by xgettext. Any in the definition file are old ones + collected by previous runs of xgettext and msgmerge. */ + if (ref->comment_dot) + for (j = 0; j < ref->comment_dot->nitems; ++j) + message_comment_dot_append (result, ref->comment_dot->item[j]); + + /* The flags are mixed in a special way. Some informations come + from the reference message (such as format/no-format), others + come from the definition file (fuzzy or not). */ + result->is_fuzzy = def->is_fuzzy; + result->is_c_format = ref->is_c_format; + result->do_wrap = ref->do_wrap; + + /* Take the file position comments from the reference file, as they + are generated by xgettext. Any in the definition file are old ones + collected by previous runs of xgettext and msgmerge. */ + for (j = 0; j < ref->filepos_count; ++j) + { + lex_pos_ty *pp = &ref->filepos[j]; + message_comment_filepos (result, pp->file_name, pp->line_number); + } + + /* All done, return the merged message to the caller. */ + return result; +} + + +void +message_comment_filepos (mp, name, line) + message_ty *mp; + const char *name; + size_t line; +{ + size_t nbytes; + lex_pos_ty *pp; + int min, max; + int j; + + /* See if we have this position already. They are kept in sorted + order, so use a binary chop. */ + /* FIXME: use bsearch */ + min = 0; + max = (int) mp->filepos_count - 1; + while (min <= max) + { + int mid; + int cmp; + + mid = (min + max) / 2; + pp = &mp->filepos[mid]; + cmp = strcmp (pp->file_name, name); + if (cmp == 0) + cmp = (int) pp->line_number - line; + if (cmp == 0) + return; + if (cmp < 0) + min = mid + 1; + else + max = mid - 1; + } + + /* Extend the list so that we can add an position to it. */ + nbytes = (mp->filepos_count + 1) * sizeof (mp->filepos[0]); + mp->filepos = xrealloc (mp->filepos, nbytes); + + /* Shuffle the rest of the list up one, so that we can insert the + position at ``min''. */ + /* FIXME: use memmove */ + for (j = mp->filepos_count; j > min; --j) + mp->filepos[j] = mp->filepos[j - 1]; + mp->filepos_count++; + + /* Insert the postion into the empty slot. */ + pp = &mp->filepos[min]; + pp->file_name = xstrdup (name); + pp->line_number = line; +} + + +void +message_print_style_indent () +{ + indent = 1; +} + + +void +message_print_style_uniforum () +{ + uniforum = 1; +} + + +void +message_print_style_escape (flag) + int flag; +{ + escape = (flag != 0); +} + + +message_list_ty * +message_list_alloc () +{ + message_list_ty *mlp; + + mlp = xmalloc (sizeof (message_list_ty)); + mlp->nitems = 0; + mlp->nitems_max = 0; + mlp->item = 0; + return mlp; +} + + +void +message_list_append (mlp, mp) + message_list_ty *mlp; + message_ty *mp; +{ + if (mlp->nitems >= mlp->nitems_max) + { + size_t nbytes; + + mlp->nitems_max = mlp->nitems_max * 2 + 4; + nbytes = mlp->nitems_max * sizeof (message_ty *); + mlp->item = xrealloc (mlp->item, nbytes); + } + mlp->item[mlp->nitems++] = mp; +} + + +void +message_list_delete_nth (mlp, n) + message_list_ty *mlp; + size_t n; +{ + size_t j; + + if (n >= mlp->nitems) + return; + message_free (mlp->item[n]); + for (j = n + 1; j < mlp->nitems; ++j) + mlp->item[j - 1] = mlp->item[j]; + mlp->nitems--; +} + + +message_ty * +message_list_search (mlp, msgid) + message_list_ty *mlp; + const char *msgid; +{ + size_t j; + + for (j = 0; j < mlp->nitems; ++j) + { + message_ty *mp; + + mp = mlp->item[j]; + if (0 == strcmp (msgid, mp->msgid)) + return mp; + } + return 0; +} + + +message_ty * +message_list_search_fuzzy (mlp, msgid) + message_list_ty *mlp; + const char *msgid; +{ + size_t j; + double best_weight; + message_ty *best_mp; + + best_weight = 0.6; + best_mp = NULL; + for (j = 0; j < mlp->nitems; ++j) + { + size_t k; + double weight; + message_ty *mp; + + mp = mlp->item[j]; + + for (k = 0; k < mp->variant_count; ++k) + if (mp->variant[k].msgstr != NULL && mp->variant[k].msgstr[0] != '\0') + break; + if (k >= mp->variant_count) + continue; + + weight = fstrcmp (msgid, mp->msgid); + if (weight > best_weight) + { + best_weight = weight; + best_mp = mp; + } + } + return best_mp; +} + + +void +message_list_free (mlp) + message_list_ty *mlp; +{ + size_t j; + + for (j = 0; j < mlp->nitems; ++j) + message_free (mlp->item[j]); + if (mlp->item) + free (mlp->item); + free (mlp); +} + + +/* Local functions. */ + +static void +wrap (fp, line_prefix, name, value, do_wrap) + FILE *fp; + const char *line_prefix; + const char *name; + const char *value; + int do_wrap; +{ + const char *s; + int first_line; + /* The \a and \v escapes were added by the ANSI C Standard. Prior + to the Standard, most compilers did not have them. Because we + need the same program on all platforms we don't provide support + for them here. */ + static const char escapes[] = "\b\f\n\r\t"; + static const char escape_names[] = "bfnrt"; + + /* The empty string is a special case. */ + if (*value == '\0') + { + if (line_prefix != NULL) + fputs (line_prefix, fp); + fputs (name, fp); + putc (indent ? '\t' : ' ', fp); + fputs ("\"\"\n", fp); + return; + } + + s = value; + first_line = 1; + while (*s) + { + const char *ep; + int ocol; + + /* The line starts with different things depending on whether it + is the first line, and if we are using the indented style. */ + if (first_line) + { + ocol = strlen (name) + (line_prefix ? strlen (line_prefix) : 0); + if (indent && ocol < 8) + ocol = 8; + else + ++ocol; + } + else + ocol = (indent ? 8 : 0); + + /* Allow room for the opening quote character. */ + ++ocol; + + /* Work out how many characters from the string will fit on a + line. Natural breaks occur at embedded newline characters. */ + for (ep = s; *ep; ++ep) + { + const char *esc; + int cw; + int c; + + c = (unsigned char) *ep; + /* FIXME This is the wrong locale. While message_list_print + set the "C" locale for LC_CTYPE, the need is to use the + correct locale for the file's contents. */ + esc = strchr (escapes, c); + if (esc == NULL && (!escape || isprint (c))) + cw = 1 + (c == '\\' || c == '"'); + else + cw = esc != NULL ? 2 : 4; + /* Allow 1 character for the closing quote. */ + if (ocol + cw >= (do_wrap == no ? INT_MAX : page_width)) + break; + ocol += cw; + if (c == '\n') + { + ++ep; + break; + } + } + + /* The above loop detects if a line is too long. If it is too + long, see if there is a better place to break the line. */ + if (*ep) + { + const char *bp; + + for (bp = ep; bp > s; --bp) + if (bp[-1] == ' ' || bp[-1] == '\n') + { + ep = bp; + break; + } + } + + /* If this is the first line, and we are not using the indented + style, and the line would wrap, then use an empty first line + and restart. */ + if (first_line && !indent && *ep != '\0') + { + fprintf (fp, "%s%s \"\"\n", line_prefix ? line_prefix : "", name); + s = value; + first_line = 0; + continue; + } + + /* Print the beginning of the line. This will depend on whether + this is the first line, and if the indented style is being + used. */ + if (first_line) + { + first_line = 0; + if (line_prefix != NULL) + fputs (line_prefix, fp); + fputs (name, fp); + putc (indent ? '\t' : ' ', fp); + } + else + { + if (line_prefix != NULL) + fputs (line_prefix, fp); + if (indent) + putc ('\t', fp); + } + + /* Print the body of the line. C escapes are used for + unprintable characters. */ + putc ('"', fp); + while (s < ep) + { + const char *esc; + int c; + + c = (unsigned char) *s++; + /* FIXME This is the wrong locale. While message_list_print + set the "C" locale for LC_CTYPE, the need is to use the + correct locale for the file's contents. */ + esc = strchr (escapes, c); + if (esc == NULL && (!escape || isprint (c))) + { + if (c == '\\' || c == '"') + putc ('\\', fp); + putc (c, fp); + } + else if (esc != NULL) + { + c = escape_names[esc - escapes]; + + putc ('\\', fp); + putc (c, fp); + + /* We warn about any use of escape sequences beside + '\n' and '\t'. */ + if (c != 'n' && c != 't') + error (0, 0, _("\ +internationalized messages should not contain the `\\%c' escape sequence"), + c); + } + else + fprintf (fp, "\\%3.3o", c); + } + fputs ("\"\n", fp); + } +} + + +static void +print_blank_line (fp) + FILE *fp; +{ + if (uniforum) + fputs ("#\n", fp); + else + putc ('\n', fp); +} + + +static void +message_print (mp, fp, domain, blank_line, debug) + const message_ty *mp; + FILE *fp; + const char *domain; + int blank_line; + int debug; +{ + message_variant_ty *mvp; + int first; + size_t j; + + /* Find the relevant message variant. If there isn't one, remember + this using a NULL pointer. */ + mvp = NULL; + first = 0; + + for (j = 0; j < mp->variant_count; ++j) + { + if (strcmp (domain, mp->variant[j].domain) == 0) + { + mvp = &mp->variant[j]; + first = (j == 0); + break; + } + } + + /* Separate messages with a blank line. Uniforum doesn't like blank + lines, so use an empty comment (unless there already is one). */ + if (blank_line && (!uniforum + || mp->comment == NULL + || mp->comment->nitems == 0 + || mp->comment->item[0][0] != '\0')) + print_blank_line (fp); + + /* The first variant of a message will have the comments attached to + it. We can't attach them to all variants in case we are read in + again, multiplying the number of comment lines. Usually there is + only one variant. */ + if (first) + { + if (mp->comment != NULL) + for (j = 0; j < mp->comment->nitems; ++j) + { + const unsigned char *s = mp->comment->item[j]; + do + { + const unsigned char *e; + putc ('#', fp); + /* FIXME This is the wrong locale. While + message_list_print set the "C" locale for LC_CTYPE, + the need to use the correct locale for the file's + contents. */ + if (*s != '\0' && !isspace (*s)) + putc (' ', fp); + e = strchr (s, '\n'); + if (e == NULL) + { + fputs (s, fp); + s = NULL; + } + else + { + fwrite (s, 1, e - s, fp); + s = e + 1; + } + putc ('\n', fp); + } + while (s != NULL); + } + + if (mp->comment_dot != NULL) + for (j = 0; j < mp->comment_dot->nitems; ++j) + { + const unsigned char *s = mp->comment_dot->item[j]; + putc ('#', fp); + putc ('.', fp); + /* FIXME This is the wrong locale. While + message_list_print set the "C" locale for LC_CTYPE, the + need to use the correct locale for the file's contents. */ + if (*s && !isspace (*s)) + putc (' ', fp); + fputs (s, fp); + putc ('\n', fp); + } + } + + /* Print the file position comments for every domain. This will + help a human who is trying to navigate the sources. There is no + problem of getting repeat positions, because duplicates are + checked for. */ + if (mp->filepos_count != 0) + { + if (uniforum) + for (j = 0; j < mp->filepos_count; ++j) + { + lex_pos_ty *pp = &mp->filepos[j]; + char *cp = pp->file_name; + while (cp[0] == '.' && cp[1] == '/') + cp += 2; + /* There are two Sun formats to choose from: SunOS and + Solaris. Use the Solaris form here. */ + fprintf (fp, "# File: %s, line: %ld\n", + cp, (long) pp->line_number); + } + else + { + size_t column; + + fputs ("#:", fp); + column = 2; + for (j = 0; j < mp->filepos_count; ++j) + { + lex_pos_ty *pp; + char buffer[20]; + char *cp; + size_t len; + + pp = &mp->filepos[j]; + cp = pp->file_name; + while (cp[0] == '.' && cp[1] == '/') + cp += 2; + sprintf (buffer, "%ld", (long) pp->line_number); + len = strlen (cp) + strlen (buffer) + 2; + if (column > 2 && column + len >= page_width) + { + fputs ("\n#:", fp); + column = 2; + } + fprintf (fp, " %s:%s", cp, buffer); + column += len; + } + putc ('\n', fp); + } + } + + /* Print flag information in special comment. */ + if (first && ((mp->is_fuzzy && mvp != NULL && mvp->msgstr[0] != '\0') + || significant_c_format_p (mp->is_c_format) + || mp->do_wrap == no)) + { + int first_flag = 1; + + putc ('#', fp); + putc (',', fp); + + /* We don't print the fuzzy flag if the msgstr is empty. This + might be introduced by the user but we want to normalize the + output. */ + if (mp->is_fuzzy && mvp != NULL && mvp->msgstr[0] != '\0') + { + fputs (" fuzzy", fp); + first_flag = 0; + } + + if (significant_c_format_p (mp->is_c_format)) + { + if (!first_flag) + putc (',', fp); + + fputs (make_c_format_description_string (mp->is_c_format, debug), + fp); + first_flag = 0; + } + + if (mp->do_wrap == no) + { + if (!first_flag) + putc (',', fp); + + fputs (make_c_width_description_string (mp->do_wrap), fp); + first_flag = 0; + } + + putc ('\n', fp); + } + + /* Print each of the message components. Wrap them nicely so they + are as readable as possible. If there is no recorded msgstr for + this domain, emit an empty string. */ + wrap (fp, NULL, "msgid", mp->msgid, mp->do_wrap); + wrap (fp, NULL, "msgstr", mvp ? mvp->msgstr : "", mp->do_wrap); +} + + +static void +message_print_obsolete (mp, fp, domain, blank_line) + const message_ty *mp; + FILE *fp; + const char *domain; + int blank_line; +{ + message_variant_ty *mvp; + size_t j; + + /* Find the relevant message variant. If there isn't one, remember + this using a NULL pointer. */ + mvp = NULL; + + for (j = 0; j < mp->variant_count; ++j) + { + if (strcmp (domain, mp->variant[j].domain) == 0) + { + mvp = &mp->variant[j]; + break; + } + } + + /* If no msgstr is found or it is the empty string we print nothing. */ + if (mvp == NULL || mvp->msgstr[0] == '\0') + return; + + /* Separate messages with a blank line. Uniforum doesn't like blank + lines, so use an empty comment (unless there already is one). */ + if (blank_line) + print_blank_line (fp); + + /* Print translator comment if available. */ + if (mp->comment) + for (j = 0; j < mp->comment->nitems; ++j) + { + const unsigned char *s = mp->comment->item[j]; + do + { + const unsigned char *e; + putc ('#', fp); + /* FIXME This is the wrong locale. While + message_list_print set the "C" locale for LC_CTYPE, the + need to use the correct locale for the file's contents. */ + if (*s != '\0' && !isspace (*s)) + putc (' ', fp); + e = strchr (s, '\n'); + if (e == NULL) + { + fputs (s, fp); + s = NULL; + } + else + { + fwrite (s, 1, e - s, fp); + s = e + 1; + } + putc ('\n', fp); + } + while (s != NULL); + } + + /* Print flag information in special comment. */ + if (mp->is_fuzzy) + { + int first = 1; + + putc ('#', fp); + putc (',', fp); + + if (mp->is_fuzzy) + { + fputs (" fuzzy", fp); + first = 0; + } + + putc ('\n', fp); + } + + /* Print each of the message components. Wrap them nicely so they + are as readable as possible. */ + wrap (fp, "#~ ", "msgid", mp->msgid, mp->do_wrap); + wrap (fp, "#~ ", "msgstr", mvp->msgstr, mp->do_wrap); +} + + +void +message_list_print (mlp, filename, force, debug) + message_list_ty *mlp; + const char *filename; + int force; + int debug; +{ + FILE *fp; + size_t j, k; + string_list_ty *dl; + int blank_line; +#ifdef HAVE_SETLOCALE + char *old_locale; +#endif + + /* We will not write anything if we have no message or only the + header entry. */ + if (force == 0 + && (mlp->nitems == 0 + || (mlp->nitems == 1 && *mlp->item[0]->msgid == '\0'))) + return; + + /* Build the list of domains. */ + dl = string_list_alloc (); + for (j = 0; j < mlp->nitems; ++j) + { + message_ty *mp = mlp->item[j]; + for (k = 0; k < mp->variant_count; ++k) + string_list_append_unique (dl, mp->variant[k].domain); + } + + /* Open the output file. */ + if (filename != NULL && strcmp (filename, "-") != 0 + && strcmp (filename, "/dev/stdout") != 0) + { + fp = fopen (filename, "w"); + if (fp == NULL) + error (EXIT_FAILURE, errno, _("cannot create output file \"%s\""), + filename); + } + else + { + fp = stdout; + /* xgettext:no-c-format */ + filename = _("standard output"); + } + +#ifdef HAVE_SETLOCALE + /* FIXME This is the wrong locale. The program is currently set for + the user's native language locale, for the error messages. This + code sets it to the "C" locale, but that isn't right either. The + need is to use the correct locale for the file's contents. */ + old_locale = setlocale (LC_CTYPE, "C"); + if (old_locale) + old_locale = xstrdup (old_locale); +#endif + + /* Write out the messages for each domain. */ + blank_line = 0; + for (k = 0; k < dl->nitems; ++k) + { + /* If there is only one domain, and that domain is the default, + don't bother emitting the domain name, because it is the + default. */ + if (dl->nitems != 1 || strcmp (dl->item[0], MESSAGE_DOMAIN_DEFAULT) != 0) + { + if (blank_line) + print_blank_line (fp); + fprintf (fp, "domain \"%s\"\n", dl->item[k]); + blank_line = 1; + } + + /* Write out each of the messages for this domain. */ + for (j = 0; j < mlp->nitems; ++j) + if (mlp->item[j]->obsolete == 0) + { + message_print (mlp->item[j], fp, dl->item[k], blank_line, debug); + blank_line = 1; + } + + /* Write out each of the obsolete messages for this domain. */ + for (j = 0; j < mlp->nitems; ++j) + if (mlp->item[j]->obsolete != 0) + { + message_print_obsolete (mlp->item[j], fp, dl->item[k], blank_line); + blank_line = 1; + } + } + string_list_free (dl); + + /* Restore the old locale. Do this before emitting error messages, + so that the correct locale is used for the error. (Ideally, + error should ensure this before calling gettext for the format + string.) */ +#ifdef HAVE_SETLOCALE + if (old_locale) + { + setlocale (LC_CTYPE, old_locale); + free (old_locale); + } +#endif + + /* Make sure nothing went wrong. */ + if (fflush (fp)) + error (EXIT_FAILURE, errno, _("error while writing \"%s\" file"), + filename); + fclose (fp); +} + + +static int +msgid_cmp (va, vb) + const void *va; + const void *vb; +{ + const message_ty *a = *(const message_ty **) va; + const message_ty *b = *(const message_ty **) vb; +#ifdef HAVE_STRCOLL + return strcoll (a->msgid, b->msgid); +#else + return strcmp (a->msgid, b->msgid); +#endif +} + + +void +message_list_sort_by_msgid (mlp) + message_list_ty *mlp; +{ + /* FIXME This is the wrong locale. The program is currently set for + the user's native language locale, for the error messages. This + code sets it to the "C" locale, but that isn't right either. The + need is to use the correct locale for the file's contents. */ +#ifdef HAVE_SETLOCALE + char *tmp = setlocale (LC_COLLATE, "C"); + if (tmp) + tmp = xstrdup (tmp); +#endif + qsort (mlp->item, mlp->nitems, sizeof (mlp->item[0]), msgid_cmp); +#ifdef HAVE_SETLOCALE + if (tmp) + { + setlocale (LC_COLLATE, tmp); + free (tmp); + } +#endif +} + + +static int +filepos_cmp (va, vb) + const void *va; + const void *vb; +{ + const message_ty *a = *(const message_ty **) va; + const message_ty *b = *(const message_ty **) vb; + int cmp; + + /* No filepos is smaller than any other filepos. */ + if (a->filepos_count == 0) + { + if (b->filepos_count != 0) + return -1; + } + if (b->filepos_count == 0) + return 1; + + /* Compare on the file names... */ + cmp = strcmp (a->filepos[0].file_name, b->filepos[0].file_name); + if (cmp != 0) + return cmp; + + /* If they are equal, compare on the line numbers... */ + cmp = a->filepos[0].line_number - b->filepos[0].line_number; + if (cmp != 0) + return cmp; + + /* If they are equal, compare on the msgid strings. */ +#ifdef HAVE_STRCOLL + return strcoll (a->msgid, b->msgid); +#else + return strcmp (a->msgid, b->msgid); +#endif +} + + +void +message_list_sort_by_filepos (mlp) + message_list_ty *mlp; +{ + /* FIXME This is the wrong locale. The program is currently set for + the user's native language locale, for the error messages. This + code sets it to the "C" locale, but that isn't right either. The + need is to use the correct locale for the file's contents. */ +#ifdef HAVE_SETLOCALE + char *tmp = setlocale (LC_COLLATE, "C"); + if (tmp) + tmp = xstrdup (tmp); +#endif + qsort (mlp->item, mlp->nitems, sizeof (mlp->item[0]), filepos_cmp); +#ifdef HAVE_SETLOCALE + if (tmp) + { + setlocale (LC_COLLATE, tmp); + free (tmp); + } +#endif +} + + +enum is_c_format +parse_c_format_description_string (s) + const char *s; +{ + if (strstr (s, "no-c-format") != NULL) + return no; + else if (strstr (s, "impossible-c-format") != NULL) + return impossible; + else if (strstr (s, "possible-c-format") != NULL) + return possible; + else if (strstr (s, "c-format") != NULL) + return yes; + return undecided; +} + + +enum is_c_format +parse_c_width_description_string (s) + const char *s; +{ + if (strstr (s, "no-wrap") != NULL) + return no; + else if (strstr (s, "wrap") != NULL) + return yes; + return undecided; +} + + +static const char * +make_c_format_description_string (is_c_format, debug) + enum is_c_format is_c_format; + int debug; +{ + const char *result = NULL; + + switch (is_c_format) + { + case possible: + if (debug) + { + result = " possible-c-format"; + break; + } + /* FALLTHROUGH */ + case yes: + result = " c-format"; + break; + case impossible: + result = " impossible-c-format"; + break; + case no: + result = " no-c-format"; + break; + case undecided: + result = " undecided"; + break; + default: + abort (); + } + + return result; +} + + +static const char * +make_c_width_description_string (do_wrap) + enum is_c_format do_wrap; +{ + const char *result = NULL; + + switch (do_wrap) + { + case yes: + result = " wrap"; + break; + case no: + result = " no-wrap"; + break; + default: + abort (); + } + + return result; +} + + +int +possible_c_format_p (is_c_format) + enum is_c_format is_c_format; +{ + return is_c_format == possible || is_c_format == yes; +} + + +static int +significant_c_format_p (is_c_format) + enum is_c_format is_c_format; +{ + return is_c_format != undecided && is_c_format != impossible; +} + + +void +message_page_width_set (n) + size_t n; +{ + if (n == 0) + { + page_width = INT_MAX; + return; + } + + if (n < 20) + n = 20; + + page_width = n; +} diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/message.h b/debian/gettext-kde/gettext-kde-0.10.35/src/message.h new file mode 100644 index 00000000..149b8b38 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/message.h @@ -0,0 +1,129 @@ +/* GNU gettext - internationalization aids + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + + This file was written by Peter Miller <[email protected]> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free SoftwareFoundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef _MESSAGE_H +#define _MESSAGE_H + +#include "po-lex.h" +#include "str-list.h" + +/* According to Sun's Uniforum proposal the default message domain is + named `messages'. */ +#define MESSAGE_DOMAIN_DEFAULT "messages" + + +/* Is current msgid a format string? */ +enum is_c_format +{ + undecided, + yes, + no, + possible, + impossible +}; + +typedef struct message_variant_ty message_variant_ty; +struct message_variant_ty +{ + const char *domain; + lex_pos_ty pos; + const char *msgstr; +}; + +typedef struct message_ty message_ty; +struct message_ty +{ + /* Plain comments (#) appearing before the message. */ + string_list_ty *comment; + + /* Extracted comments (#.) appearing before the message. */ + string_list_ty *comment_dot; + + /* File position comments (#:) appearing before the message, one for + each unique file position instance, sorted by file name and then + by line. */ + size_t filepos_count; + lex_pos_ty *filepos; + + /* Informations from special comments (e.g. generated by msgmerge). */ + int is_fuzzy; + enum is_c_format is_c_format; + + /* Do we want the string to be wrapped in the emitted PO file? */ + enum is_c_format do_wrap; + + /* The msgid string. */ + const char *msgid; + + /* The msgstr strings, one for each observed domain in the file. */ + size_t variant_count; + message_variant_ty *variant; + + /* Used for checking that messages have been used, in the msgcmp and + msgmerge programs. */ + int used; + + /* If set the message is obsolete and while writing out it should be + commented out. */ + int obsolete; +}; + +message_ty *message_alloc PARAMS ((char *msgid)); +void message_free PARAMS ((message_ty *)); + +message_variant_ty *message_variant_search PARAMS ((message_ty *mp, + const char *domain)); +void message_variant_append PARAMS ((message_ty *mp, const char *domain, + const char *msgstr, + const lex_pos_ty *pp)); +void message_comment_append PARAMS ((message_ty *, const char *)); +void message_comment_dot_append PARAMS ((message_ty *, const char *)); +message_ty *message_copy PARAMS ((message_ty *)); +message_ty *message_merge PARAMS ((message_ty *def, message_ty *ref)); +void message_comment_filepos PARAMS ((message_ty *, const char *, size_t)); +void message_print_style_indent PARAMS ((void)); +void message_print_style_uniforum PARAMS ((void)); +void message_print_style_escape PARAMS ((int)); + + +typedef struct message_list_ty message_list_ty; +struct message_list_ty +{ + message_ty **item; + size_t nitems; + size_t nitems_max; +}; + +message_list_ty *message_list_alloc PARAMS ((void)); +void message_list_free PARAMS ((message_list_ty *)); +void message_list_append PARAMS ((message_list_ty *, message_ty *)); +void message_list_delete_nth PARAMS ((message_list_ty *, size_t)); +message_ty *message_list_search PARAMS ((message_list_ty *, const char *)); +message_ty *message_list_search_fuzzy PARAMS ((message_list_ty *, + const char *)); +void message_list_print PARAMS ((message_list_ty *, const char *, int, int)); +void message_list_sort_by_msgid PARAMS ((message_list_ty *)); +void message_list_sort_by_filepos PARAMS ((message_list_ty *)); + +enum is_c_format parse_c_format_description_string PARAMS ((const char *s)); +enum is_c_format parse_c_width_description_string PARAMS ((const char *s)); +int possible_c_format_p PARAMS ((enum is_c_format)); +void message_page_width_set PARAMS ((size_t width)); + +#endif /* message.h */ diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/msgcmp.c b/debian/gettext-kde/gettext-kde-0.10.35/src/msgcmp.c new file mode 100644 index 00000000..af689a29 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/msgcmp.c @@ -0,0 +1,437 @@ +/* GNU gettext - internationalization aids + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + This file was written by Peter Miller <[email protected]> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <getopt.h> +#include <stdio.h> + +#ifdef STDC_HEADERS +# include <stdlib.h> +#endif + +#ifdef HAVE_LOCALE_H +# include <locale.h> +#endif + +#include "dir-list.h" +#include "error.h" +#include "message.h" +#include <system.h> +#include <libintl.h> +#include "po.h" +#include "str-list.h" + +#define _(str) gettext (str) + + +/* This structure defines a derived class of the po_ty class. (See + po.h for an explanation.) */ +typedef struct compare_class_ty compare_class_ty; +struct compare_class_ty +{ + /* inherited instance variables, etc */ + PO_BASE_TY + + /* Name of domain we are currently examining. */ + char *domain; + + /* List of domains already appeared in the current file. */ + string_list_ty *domain_list; + + /* List of messages already appeared in the current file. */ + message_list_ty *mlp; +}; + +/* String containing name the program is called with. */ +const char *program_name; + +/* Long options. */ +static const struct option long_options[] = +{ + { "directory", required_argument, NULL, 'D' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'V' }, + { NULL, 0, NULL, 0 } +}; + + +/* Prototypes for local functions. */ +static void usage PARAMS ((int __status)); +static void error_print PARAMS ((void)); +static void compare PARAMS ((char *, char *)); +static message_list_ty *grammar PARAMS ((char *__filename)); +static void compare_constructor PARAMS ((po_ty *__that)); +static void compare_destructor PARAMS ((po_ty *__that)); +static void compare_directive_domain PARAMS ((po_ty *__that, char *__name)); +static void compare_directive_message PARAMS ((po_ty *__that, char *__msgid, + lex_pos_ty *msgid_pos, + char *__msgstr, + lex_pos_ty *__msgstr_pos)); +static void compare_parse_debrief PARAMS ((po_ty *__that)); + + +int +main (argc, argv) + int argc; + char *argv[]; +{ + int optchar; + int do_help; + int do_version; + + /* Set program name for messages. */ + program_name = argv[0]; + error_print_progname = error_print; + +#ifdef HAVE_SETLOCALE + /* Set locale via LC_ALL. */ + setlocale (LC_ALL, ""); +#endif + + /* Set the text message domain. */ + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + do_help = 0; + do_version = 0; + while ((optchar = getopt_long (argc, argv, "D:hV", long_options, NULL)) + != EOF) + switch (optchar) + { + case '\0': /* long option */ + break; + + case 'D': + dir_list_append (optarg); + break; + + case 'h': + do_help = 1; + break; + + case 'V': + do_version = 1; + break; + + default: + usage (EXIT_FAILURE); + break; + } + + /* Version information is requested. */ + if (do_version) + { + printf ("%s (GNU %s) %s\n", basename (program_name), PACKAGE, VERSION); + /* xgettext: no-wrap */ + printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\ +This is free software; see the source for copying conditions. There is NO\n\ +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ +"), + "1995, 1996, 1997, 1998"); + printf (_("Written by %s.\n"), "Peter Miller"); + exit (EXIT_SUCCESS); + } + + /* Help is requested. */ + if (do_help) + usage (EXIT_SUCCESS); + + /* Test whether we have an .po file name as argument. */ + if (optind >= argc) + { + error (EXIT_SUCCESS, 0, _("no input files given")); + usage (EXIT_FAILURE); + } + if (optind + 2 != argc) + { + error (EXIT_SUCCESS, 0, _("exactly 2 input files required")); + usage (EXIT_FAILURE); + } + + /* compare the two files */ + compare (argv[optind], argv[optind + 1]); + exit (EXIT_SUCCESS); +} + + +/* Display usage information and exit. */ +static void +usage (status) + int status; +{ + if (status != EXIT_SUCCESS) + fprintf (stderr, _("Try `%s --help' for more information.\n"), + program_name); + else + { + /* xgettext: no-wrap */ + printf (_("\ +Usage: %s [OPTION] def.po ref.po\n\ +Mandatory arguments to long options are mandatory for short options too.\n\ + -D, --directory=DIRECTORY add DIRECTORY to list for input files search\n\ + -h, --help display this help and exit\n\ + -V, --version output version information and exit\n\ +\n\ +Compare two Uniforum style .po files to check that both contain the same\n\ +set of msgid strings. The def.po file is an existing PO file with the\n\ +old translations. The ref.po file is the last created PO file\n\ +(generally by xgettext). This is useful for checking that you have\n\ +translated each and every message in your program. Where an exact match\n\ +cannot be found, fuzzy matching is used to produce better diagnostics.\n"), + program_name); + fputs (_("Report bugs to <[email protected]>.\n"), stdout); + } + + exit (status); +} + + +/* The address of this function will be assigned to the hook in the error + functions. */ +static void +error_print () +{ + /* We don't want the program name to be printed in messages. Emacs' + compile.el does not like this. */ +} + + +static void +compare (fn1, fn2) + char *fn1; + char *fn2; +{ + message_list_ty *list1; + message_list_ty *list2; + int nerrors; + message_ty *mp1; + size_t j, k; + + /* This is the master file, created by a human. */ + list1 = grammar (fn1); + + /* This is the generated file, created by groping the sources with + the xgettext program. */ + list2 = grammar (fn2); + + /* Every entry in the xgettext generated file must be matched by a + (single) entry in the human created file. */ + nerrors = 0; + for (j = 0; j < list2->nitems; ++j) + { + message_ty *mp2; + + mp2 = list2->item[j]; + + /* See if it is in the other file. */ + mp1 = message_list_search (list1, mp2->msgid); + if (mp1) + { + mp1->used = 1; + continue; + } + + /* If the message was not defined at all, try to find a very + similar message, it could be a typo, or the suggestion may + help. */ + ++nerrors; + mp1 = message_list_search_fuzzy (list1, mp2->msgid); + if (mp1) + { + gram_error_at_line (&mp2->variant[0].pos, _("\ +this message is used but not defined...")); + gram_error_at_line (&mp1->variant[0].pos, _("\ +...but this definition is similar")); + mp1->used = 1; + } + else + { + gram_error_at_line (&mp2->variant[0].pos, _("\ +this message is used but not defined in %s"), fn1); + } + } + + /* Look for messages in the human generated file, which are not + present in the xgettext generated file, indicating messages which + are not used in the program. */ + for (k = 0; k < list1->nitems; ++k) + { + mp1 = list1->item[k]; + if (mp1->used) + continue; + gram_error_at_line (&mp1->variant[0].pos, + _("warning: this message is not used")); + } + + /* Exit with status 1 on any error. */ + if (nerrors > 0) + error (EXIT_FAILURE, 0, "found %d fatal errors", nerrors); +} + + +/* Local functions. */ + +static void +compare_constructor (that) + po_ty *that; +{ + compare_class_ty *this = (compare_class_ty *) that; + + this->mlp = message_list_alloc (); + this->domain = MESSAGE_DOMAIN_DEFAULT; + this->domain_list = string_list_alloc (); +} + + +static void +compare_destructor (that) + po_ty *that; +{ + compare_class_ty *this = (compare_class_ty *) that; + + string_list_free (this->domain_list); + /* Do not free this->mlp! */ +} + + +static void +compare_directive_domain (that, name) + po_ty *that; + char *name; +{ + compare_class_ty *this = (compare_class_ty *)that; + /* Override current domain name. Don't free memory. */ + this->domain = name; +} + + +static void +compare_directive_message (that, msgid, msgid_pos, msgstr, msgstr_pos) + po_ty *that; + char *msgid; + lex_pos_ty *msgid_pos; + char *msgstr; + lex_pos_ty *msgstr_pos; +{ + compare_class_ty *this = (compare_class_ty *) that; + message_ty *mp; + message_variant_ty *mvp; + + /* Remember the domain names for later. */ + string_list_append_unique (this->domain_list, this->domain); + + /* See if this message ID has been seen before. */ + mp = message_list_search (this->mlp, msgid); + if (mp) + free (msgid); + else + { + mp = message_alloc (msgid); + message_list_append (this->mlp, mp); + } + + /* See if this domain has been seen for this message ID. */ + mvp = message_variant_search (mp, this->domain); + if (mvp) + { + gram_error_at_line (msgid_pos, _("duplicate message definition")); + gram_error_at_line (&mvp->pos, _("\ +...this is the location of the first definition")); + free (msgstr); + } + else + message_variant_append (mp, this->domain, msgstr, msgstr_pos); +} + + +static void +compare_parse_debrief (that) + po_ty *that; +{ + compare_class_ty *this = (compare_class_ty *) that; + message_list_ty *mlp = this->mlp; + size_t j; + + /* For each domain in the used-domain-list, make sure each message + defines a msgstr in that domain. */ + for (j = 0; j < this->domain_list->nitems; ++j) + { + const char *domain_name; + size_t k; + + domain_name = this->domain_list->item[j]; + for (k = 0; k < mlp->nitems; ++k) + { + const message_ty *mp; + size_t m; + + mp = mlp->item[k]; + for (m = 0; m < mp->variant_count; ++m) + { + message_variant_ty *mvp; + + mvp = &mp->variant[m]; + if (strcmp (domain_name, mvp->domain) == 0) + break; + } + if (m >= mp->variant_count) + gram_error_at_line (&mp->variant[0].pos, _("\ +this message has no definition in the \"%s\" domain"), domain_name); + } + } +} + + +/* So that the one parser can be used for multiple programs, and also + use good data hiding and encapsulation practices, an object + oriented approach has been taken. An object instance is allocated, + and all actions resulting from the parse will be through + invokations of method functions of that object. */ + +static po_method_ty compare_methods = +{ + sizeof (compare_class_ty), + compare_constructor, + compare_destructor, + compare_directive_domain, + compare_directive_message, + NULL, /* parse_brief */ + compare_parse_debrief, + NULL, /* comment */ + NULL, /* comment_dot */ + NULL, /* comment_filepos */ + NULL, /* comment_special */ +}; + + +static message_list_ty * +grammar (filename) + char *filename; +{ + po_ty *pop; + message_list_ty *mlp; + + pop = po_alloc(&compare_methods); + po_scan(pop, filename); + mlp = ((compare_class_ty *)pop)->mlp; + po_free(pop); + return mlp; +} diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/msgcomm.c b/debian/gettext-kde/gettext-kde-0.10.35/src/msgcomm.c new file mode 100644 index 00000000..082639ac --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/msgcomm.c @@ -0,0 +1,781 @@ +/* GNU gettext - internationalization aids + Copyright (C) 1997, 1998 Free Software Foundation, Inc. + + This file was written by Peter Miller <[email protected]> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <errno.h> +#include <getopt.h> +#include <stdio.h> +#include <sys/types.h> + +#ifdef STDC_HEADERS +# include <stdlib.h> +#endif + +#ifdef HAVE_LIMITS_H +# include <limits.h> +#endif + +#ifdef HAVE_LOCALE_H +# include <locale.h> +#endif + +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif + +#include "dir-list.h" +#include "error.h" +#include "getline.h" +#include "libgettext.h" +#include "message.h" +#include "po.h" +#include "system.h" + + +/* A convenience macro. I don't like writing gettext() every time. */ +#define _(str) gettext (str) + + +/* If nonzero add comments for file name and line number for each msgid. */ +static int line_comment = 1; + +/* Name of default domain file. If not set defaults to messages.po. */ +static char *default_domain; + +/* Force output of PO file even if empty. */ +static int force_po; + +/* Directory in which output files are created. */ +static char *output_dir; + +/* If nonzero omit header with information about this run. */ +static int omit_header; + +/* String containing name the program is called with. */ +const char *program_name; + +/* These variables control which messages are selected. */ +static int more_than = -1; +static int less_than = -1; + +/* Long options. */ +static const struct option long_options[] = +{ + { "add-comments", optional_argument, NULL, 'c' }, + { "add-location", no_argument, &line_comment, 1 }, + { "default-domain", required_argument, NULL, 'd' }, + { "directory", required_argument, NULL, 'D' }, + { "escape", no_argument, NULL, 'E' }, + { "files-from", required_argument, NULL, 'f' }, + { "force-po", no_argument, &force_po, 1 }, + { "help", no_argument, NULL, 'h' }, + { "indent", no_argument, NULL, 'i' }, + { "join-existing", no_argument, NULL, 'j' }, + { "no-escape", no_argument, NULL, 'e' }, + { "no-location", no_argument, &line_comment, 0 }, + { "omit-header", no_argument, &omit_header, 1 }, + { "output", required_argument, NULL, 'o' }, + { "output-dir", required_argument, NULL, 'p' }, + { "sort-by-file", no_argument, NULL, 'F' }, + { "sort-output", no_argument, NULL, 's' }, + { "strict", no_argument, NULL, 'S' }, + { "version", no_argument, NULL, 'V' }, + { "width", required_argument, NULL, 'w', }, + { "more-than", required_argument, NULL, '>', }, + { "less-than", required_argument, NULL, '<', }, + { NULL, 0, NULL, 0 } +}; + + +/* Prototypes for local functions. */ +static void usage PARAMS ((int status)) +#if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ > 4) || __GNUC__ > 2) + __attribute__ ((noreturn)) +#endif +; +static void error_print PARAMS ((void)); +static string_list_ty *read_name_from_file PARAMS ((const char *__file_name)); +static void extract_constructor PARAMS ((po_ty *__that)); +static void extract_directive_domain PARAMS ((po_ty *__that, char *__name)); +static void extract_directive_message PARAMS ((po_ty *__that, char *__msgid, + lex_pos_ty *__msgid_pos, + char *__msgstr, + lex_pos_ty *__msgstr_pos)); +static void extract_parse_brief PARAMS ((po_ty *__that)); +static void extract_comment PARAMS ((po_ty *__that, const char *__s)); +static void extract_comment_dot PARAMS ((po_ty *__that, const char *__s)); +static void extract_comment_filepos PARAMS ((po_ty *__that, const char *__name, + int __line)); +static void extract_comment_special PARAMS ((po_ty *that, const char *s)); +static void read_po_file PARAMS ((const char *__file_name, + message_list_ty *__mlp)); + + +int +main (argc, argv) + int argc; + char *argv[]; +{ + int cnt; + int optchar; + int do_help = 0; + int do_version = 0; + message_list_ty *mlp; + int sort_output = 0; + int sort_by_file = 0; + char *file_name; + const char *files_from = NULL; + string_list_ty *file_list; + char *output_file = NULL; + size_t j; + + /* Set program name for messages. */ + program_name = argv[0]; + error_print_progname = error_print; + +#ifdef HAVE_SETLOCALE + /* Set locale via LC_ALL. */ + setlocale (LC_ALL, ""); +#endif + + /* Set the text message domain. */ + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + /* Set initial value of variables. */ + line_comment = -1; + default_domain = MESSAGE_DOMAIN_DEFAULT; + + while ((optchar = getopt_long (argc, argv, + "<>ac::Cd:D:eEf:Fhijk::l:L:m::M::no:p:sTuVw:x:", + long_options, NULL)) != EOF) + switch (optchar) + { + case '\0': /* Long option. */ + break; + case '>': + { + int value; + char *endp; + value = strtol (optarg, &endp, 10); + if (endp != optarg) + more_than = value; + } + break; + case '<': + { + int value; + char *endp; + value = strtol (optarg, &endp, 10); + if (endp != optarg) + less_than = value; + } + break; + case 'd': + default_domain = optarg; + break; + case 'D': + dir_list_append (optarg); + break; + case 'e': + message_print_style_escape (0); + break; + case 'E': + message_print_style_escape (1); + break; + case 'f': + files_from = optarg; + break; + case 'F': + sort_by_file = 1; + break; + case 'h': + do_help = 1; + break; + case 'i': + message_print_style_indent (); + break; + case 'n': + line_comment = 1; + break; + case 'o': + output_file = optarg; + break; + case 'p': + { + size_t len = strlen (optarg); + + if (output_dir != NULL) + free (output_dir); + + if (optarg[len - 1] == '/') + output_dir = xstrdup (optarg); + else + { + asprintf (&output_dir, "%s/", optarg); + if (output_dir == NULL) + /* We are about to construct the absolute path to the + directory for the output files but asprintf failed. */ + error (EXIT_FAILURE, errno, _("while preparing output")); + } + } + break; + case 's': + sort_output = 1; + break; + case 'S': + message_print_style_uniforum (); + break; + case 'u': + less_than = 2; + break; + case 'V': + do_version = 1; + break; + case 'w': + { + int value; + char *endp; + value = strtol (optarg, &endp, 10); + if (endp != optarg) + message_page_width_set (value); + } + break; + default: + usage (EXIT_FAILURE); + /* NOTREACHED */ + } + + /* Normalize selected options. */ + if (omit_header != 0 && line_comment < 0) + line_comment = 0; + + if (!line_comment && sort_by_file) + error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"), + "--no-location", "--sort-by-file"); + + if (sort_output && sort_by_file) + error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"), + "--sort-output", "--sort-by-file"); + + /* Version information requested. */ + if (do_version) + { + printf ("%s (GNU %s) %s\n", basename (program_name), PACKAGE, VERSION); + /* xgettext: no-wrap */ + printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\ +This is free software; see the source for copying conditions. There is NO\n\ +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ +"), + "1995, 1996, 1997, 1998"); + printf (_("Written by %s.\n"), "Peter Miller"); + exit (EXIT_SUCCESS); + } + + /* Help is requested. */ + if (do_help) + usage (EXIT_SUCCESS); + + /* Default output directory is the current directory. */ + if (output_dir == NULL) + output_dir = "."; + + /* Construct the name of the ouput file. If the default domain has + the special name "-" we write to stdout. */ + if (output_file) + { + if (output_file[0] == '/' || + strcmp(output_dir, ".") == 0 || + strcmp(output_file, "-") == 0 + ) + file_name = xstrdup (output_file); + else + { + /* Please do NOT add a .po suffix! */ + file_name = xmalloc (strlen (output_dir) + strlen (default_domain) + 2); + strcat (strcat (strcpy(file_name, output_dir), "/"), output_file); + } + } + else if (strcmp (default_domain, "-") == 0) + file_name = "-"; + else + { + file_name = (char *) xmalloc (strlen (output_dir) + + strlen (default_domain) + + sizeof (".po") + 2); + stpcpy (stpcpy (stpcpy (stpcpy (file_name, output_dir), "/"), + default_domain), ".po"); + } + + /* Determine list of files we have to process. */ + if (files_from != NULL) + file_list = read_name_from_file (files_from); + else + file_list = string_list_alloc (); + /* Append names from command line. */ + for (cnt = optind; cnt < argc; ++cnt) + string_list_append_unique (file_list, argv[cnt]); + + /* Test whether sufficient input files weregiven. */ + if (file_list->nitems < 2) + { + error (EXIT_SUCCESS, 0, _("at least two files must be specified")); + usage (EXIT_FAILURE); + } + + /* Allocate a message list to remember all the messages. */ + mlp = message_list_alloc (); + + /* Process all input files. */ + for (cnt = 0; cnt < file_list->nitems; ++cnt) + read_po_file (file_list->item[cnt], mlp); + string_list_free (file_list); + + /* Default the message selection criteria, and check them for sanity. */ + if (more_than < 0) + more_than = (less_than < 0 ? 1 : 0); + if (less_than < 0) + less_than = INT_MAX; + if (more_than >= less_than || less_than < 2 || more_than >= mlp->nitems) + error (EXIT_FAILURE, 0, + _("impossible selection criteria specified (%d < n < %d)"), + more_than, less_than); + + /* Remove messages which do not fit the criteria. */ + j = 0; + while (j < mlp->nitems) + { + message_ty *mp; + + mp = mlp->item[j]; + if (mp->used > more_than && mp->used < less_than) + ++j; + else + message_list_delete_nth(mlp, j); + } + + /* Sorting the list of messages. */ + if (sort_by_file) + message_list_sort_by_filepos (mlp); + else if (sort_output) + message_list_sort_by_msgid (mlp); + + /* Write the PO file. */ + message_list_print (mlp, file_name, force_po, 0); + + exit (EXIT_SUCCESS); +} + + +/* Display usage information and exit. */ +static void +usage (status) + int status; +{ + if (status != EXIT_SUCCESS) + fprintf (stderr, _("Try `%s --help' for more information.\n"), + program_name); + else + { + /* xgettext: no-wrap */ + printf (_("\ +Usage: %s [OPTION] INPUTFILE ...\n\ +Mandatory arguments to long options are mandatory for short options too.\n\ + -d, --default-domain=NAME use NAME.po for output (instead of messages.po)\n\ + -D, --directory=DIRECTORY add DIRECTORY to list for input files search\n\ + -e, --no-escape do not use C escapes in output (default)\n\ + -E, --escape use C escapes in output, no extended chars\n\ + -f, --files-from=FILE get list of input files from FILE\n\ + --force-po write PO file even if empty\n\ + -F, --sort-by-file sort output by file location\n\ + -h, --help display this help and exit\n"), + program_name); + fputs (_("\ + -i, --indent write the .po file using indented style\n\ + --no-location do not write '#: filename:line' lines\n\ + -n, --add-location generate '#: filename:line' lines (default)\n\ + --omit-header don't write header with `msgid \"\"' entry\n\ + -o, --output=FILE write output to specified file\n\ + -p, --output-dir=DIR output files will be placed in directory DIR\n\ + -s, --sort-output generate sorted output and remove duplicates\n\ + --strict write out strict Uniforum conforming .po file\n\ + -T, --trigraphs understand ANSI C trigraphs for input\n\ + -u, --unique shorthand for --less-than=2, requests\n\ + that only unique messages be printed\n"), + stdout); + fputs (_("\ + -V, --version output version information and exit\n\ + -w, --width=NUMBER set output page width\n\ + -<, --less-than=NUMBER print messages with less than this many\n\ + definitions, defaults to infinite if not\n\ + set\n\ + ->, --more-than=NUMBER print messages with more than this many\n\ + definitions, defaults to 1 if not set\n\ +\n\ +Find messages which are common to two or more of the specified PO files.\n\ +By using the --more-than option, greater commonality may be requested\n\ +before messages are printed. Conversely, the --less-than option may be\n\ +used to specify less commonality before messages are printed (i.e.\n\ +--less-than=2 will only print the unique messages). Translations,\n\ +comments and extract comments will be preserved, but only from the first\n\ +PO file to define them. File positions from all PO files will be\n\ +preserved.\n"), stdout); + fputs (_("Report bugs to <[email protected]>.\n"), + stdout); + } + + exit (status); +} + + +/* The address of this function will be assigned to the hook in the error + functions. */ +static void +error_print () +{ + /* We don't want the program name to be printed in messages. */ +} + + +/* Read list of files to process from file. */ +static string_list_ty * +read_name_from_file (file_name) + const char *file_name; +{ + size_t line_len = 0; + char *line_buf = NULL; + FILE *fp; + string_list_ty *result; + + if (strcmp (file_name, "-") == 0) + fp = stdin; + else + { + fp = fopen (file_name, "r"); + if (fp == NULL) + error (EXIT_FAILURE, errno, + _("error while opening \"%s\" for reading"), file_name); + } + + result = string_list_alloc (); + + while (!feof (fp)) + { + /* Read next line from file. */ + int len = getline (&line_buf, &line_len, fp); + + /* In case of an error leave loop. */ + if (len < 0) + break; + + /* Remove trailing '\n'. */ + if (len > 0 && line_buf[len - 1] == '\n') + line_buf[--len] = '\0'; + + /* Test if we have to ignore the line. */ + if (*line_buf == '\0' || *line_buf == '#') + continue; + + string_list_append_unique (result, line_buf); + } + + /* Free buffer allocated through getline. */ + if (line_buf != NULL) + free (line_buf); + + /* Close input stream. */ + if (fp != stdin) + fclose (fp); + + return result; +} + + +typedef struct extract_class_ty extract_class_ty; +struct extract_class_ty +{ + /* Inherited instance variables and methods. */ + PO_BASE_TY + + /* Cumulative list of messages. */ + message_list_ty *mlp; + + /* Cumulative comments for next message. */ + string_list_ty *comment; + string_list_ty *comment_dot; + + int is_fuzzy; + int is_c_format; + int do_wrap; + + int filepos_count; + lex_pos_ty *filepos; +}; + + +static void +extract_constructor (that) + po_ty *that; +{ + extract_class_ty *this = (extract_class_ty *) that; + + this->mlp = NULL; /* actually set in read_po_file, below */ + this->comment = NULL; + this->comment_dot = NULL; + this->is_fuzzy = 0; + this->is_c_format = undecided; + this->do_wrap = undecided; + this->filepos_count = 0; + this->filepos = NULL; +} + + +static void +extract_directive_domain (that, name) + po_ty *that; + char *name; +{ + po_gram_error (_("this file may not contain domain directives")); +} + + +static void +extract_directive_message (that, msgid, msgid_pos, msgstr, msgstr_pos) + po_ty *that; + char *msgid; + lex_pos_ty *msgid_pos; + char *msgstr; + lex_pos_ty *msgstr_pos; +{ + extract_class_ty *this = (extract_class_ty *)that; + message_ty *mp; + message_variant_ty *mvp; + size_t j; + + /* If the msgid is the empty string, and we are omiting headers, throw + it away. */ + if (omit_header && *msgid == '\0') + { + free (msgid); + free (msgstr); + if (this->comment != NULL) + string_list_free (this->comment); + if (this->comment_dot != NULL) + string_list_free (this->comment_dot); + if (this->filepos != NULL) + free (this->filepos); + this->comment = NULL; + this->comment_dot = NULL; + this->filepos_count = 0; + this->filepos = NULL; + this->is_fuzzy = 0; + this->is_c_format = undecided; + this->do_wrap = undecided; + return; + } + + /* See if this message ID has been seen before. */ + mp = message_list_search (this->mlp, msgid); + if (mp) + free (msgid); + else + { + mp = message_alloc (msgid); + message_list_append (this->mlp, mp); + } + + /* The ``obsolete'' flag is cleared before reading each PO file. + If thisflag is clear, set it, and increment the ``used'' counter. + This allows us to count how many of the PO files use the message. */ + if (mp->obsolete == 0) + { + mp->obsolete = 1; + mp->used++; + } + + /* Add the accumulated comments to the message. Clear the + accumulation in preparation for the next message. */ + if (this->comment != NULL) + { + if (mp->comment == NULL) + for (j = 0; j < this->comment->nitems; ++j) + message_comment_append (mp, this->comment->item[j]); + string_list_free (this->comment); + this->comment = NULL; + } + if (this->comment_dot != NULL) + { + if (mp->comment_dot == NULL) + for (j = 0; j < this->comment_dot->nitems; ++j) + message_comment_dot_append (mp, this->comment_dot->item[j]); + string_list_free (this->comment_dot); + this->comment_dot = NULL; + } + mp->is_fuzzy |= this->is_fuzzy; + if (mp->is_c_format == undecided) + mp->is_c_format = this->is_c_format; + if (mp->do_wrap == undecided) + mp->do_wrap = this->do_wrap; + for (j = 0; j < this->filepos_count; ++j) + { + lex_pos_ty *pp; + + pp = &this->filepos[j]; + message_comment_filepos (mp, pp->file_name, pp->line_number); + free (pp->file_name); + } + if (this->filepos != NULL) + free (this->filepos); + this->filepos_count = 0; + this->filepos = NULL; + this->is_fuzzy = 0; + this->is_c_format = undecided; + this->do_wrap = undecided; + + /* See if this domain has been seen for this message ID. */ + mvp = message_variant_search (mp, MESSAGE_DOMAIN_DEFAULT); + if (mvp != NULL) + free (msgstr); + else + message_variant_append (mp, MESSAGE_DOMAIN_DEFAULT, msgstr, msgstr_pos); +} + + +static void +extract_parse_brief (that) + po_ty *that; +{ + po_lex_pass_comments (1); +} + + +static void +extract_comment (that, s) + po_ty *that; + const char *s; +{ + extract_class_ty *this = (extract_class_ty *) that; + + if (this->comment == NULL) + this->comment = string_list_alloc (); + string_list_append (this->comment, s); +} + + +static void +extract_comment_dot (that, s) + po_ty *that; + const char *s; +{ + extract_class_ty *this = (extract_class_ty *) that; + + if (this->comment_dot == NULL) + this->comment_dot = string_list_alloc (); + string_list_append (this->comment_dot, s); +} + + +static void +extract_comment_filepos (that, name, line) + po_ty *that; + const char *name; + int line; +{ + extract_class_ty *this = (extract_class_ty *) that; + size_t nbytes; + lex_pos_ty *pp; + + /* Write line numbers only if -n option is given. */ + if (line_comment != 0) + { + nbytes = (this->filepos_count + 1) * sizeof (this->filepos[0]); + this->filepos = xrealloc (this->filepos, nbytes); + pp = &this->filepos[this->filepos_count++]; + pp->file_name = xstrdup (name); + pp->line_number = line; + } +} + + +static void +extract_comment_special (that, s) + po_ty *that; + const char *s; +{ + extract_class_ty *this = (extract_class_ty *) that; + + if (strstr (s, "fuzzy") != NULL) + this->is_fuzzy = 1; + if (strstr (s, "c-format") != NULL) + this->is_c_format = yes; + if (strstr (s, "no-c-format") != NULL) + this->is_c_format = no; + if (strstr (s, "wrap") != NULL) + this->do_wrap = yes; + if (strstr (s, "no-wrap") != NULL) + this->do_wrap = no; +} + + +/* So that the one parser can be used for multiple programs, and also + use good data hiding and encapsulation practices, an object + oriented approach has been taken. An object instance is allocated, + and all actions resulting from the parse will be through + invocations of method functions of that object. */ + +static po_method_ty extract_methods = +{ + sizeof (extract_class_ty), + extract_constructor, + NULL, /* destructor */ + extract_directive_domain, + extract_directive_message, + extract_parse_brief, + NULL, /* parse_debrief */ + extract_comment, + extract_comment_dot, + extract_comment_filepos, + extract_comment_special +}; + + +/* Read the contents of the specified .po file into a message list. */ + +static void +read_po_file (file_name, mlp) + const char *file_name; + message_list_ty *mlp; +{ + size_t j; + + po_ty *pop = po_alloc (&extract_methods); + ((extract_class_ty *) pop)->mlp = mlp; + po_scan (pop, file_name); + po_free (pop); + + /* The ``obsolete'' flag of each message is cleared before reading + each PO file. As each message is read from a PO file, if this flag + is clear, it is set, and increment the ``used'' counter. This + allows us to count how many of the PO files use each message. */ + for (j = 0; j < mlp->nitems; ++j) + mlp->item[j]->obsolete = 0; +} diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/msgfmt.c b/debian/gettext-kde/gettext-kde-0.10.35/src/msgfmt.c new file mode 100644 index 00000000..35f3d980 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/msgfmt.c @@ -0,0 +1,972 @@ +/* Converts Uniforum style .po files to binary .mo files + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + Written by Ulrich Drepper <[email protected]>, April 1995. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <ctype.h> +#include <errno.h> +#include <getopt.h> +#include <stdio.h> +#include <sys/param.h> +#include <sys/types.h> + +#ifdef STDC_HEADERS +# include <stdlib.h> +#endif + +#ifdef HAVE_LOCALE_H +# include <locale.h> +#endif + +#include "hash.h" + +#include "dir-list.h" +#include "error.h" +#include "getline.h" +#include "printf.h" +#include <system.h> + +#include "gettext.h" +#include "domain.h" +#include "hash-string.h" +#include <libintl.h> +#include "message.h" +#include "po.h" + +#define _(str) gettext (str) + +#ifndef errno +extern int errno; +#endif + +/* Define the data structure which we need to represent the data to + be written out. */ +struct id_str_pair +{ + char *id; + char *str; +}; + +/* Contains information about the definition of one translation. */ +struct msgstr_def +{ + char *msgstr; + lex_pos_ty pos; +}; + +/* This structure defines a derived class of the po_ty class. (See + po.h for an explanation.) */ +typedef struct msgfmt_class_ty msgfmt_class_ty; +struct msgfmt_class_ty +{ + /* inherited instance variables, etc */ + PO_BASE_TY + + int is_fuzzy; + enum is_c_format is_c_format; + enum is_c_format do_wrap; + + int has_header_entry; +}; + +/* Alignment of strings in resulting .mo file. */ +static size_t alignment; + +/* Contains exit status for case in which no premature exit occurs. */ +static int exit_status; + +/* If nonzero include even fuzzy translations in output file. */ +static int include_all; + +/* Nonzero if no hash table in .mo is wanted. */ +static int no_hash_table; + +/* Specifies name of the output file. */ +static const char *output_file_name; + +/* String containing name the program is called with. */ +const char *program_name; + +/* We may have more than one input file. Domains with same names in + different files have to merged. So we need a list of tables for + each output file. */ +static struct msg_domain *domain; +static struct msg_domain *current_domain; + +/* If not zero list duplicate message identifiers. */ +static int verbose_level; + +/* If not zero check strings according to format string rules for the + language. */ +static int do_check; + +/* Counters for statistics on translations for the processed files. */ +static int msgs_translated; +static int msgs_untranslated; +static int msgs_fuzzy; + +/* If not zero print statistics about translation at the end. */ +static int do_statistics; + +/* Long options. */ +static const struct option long_options[] = +{ + { "alignment", required_argument, NULL, 'a' }, + { "check", no_argument, &do_check, 1 }, + { "directory", required_argument, NULL, 'D' }, + { "help", no_argument, NULL, 'h' }, + { "no-hash", no_argument, &no_hash_table, 1 }, + { "output-file", required_argument, NULL, 'o' }, + { "statistics", no_argument, &do_statistics, 1 }, + { "strict", no_argument, NULL, 'S' }, + { "use-fuzzy", no_argument, NULL, 'f' }, + { "verbose", no_argument, NULL, 'v' }, + { "version", no_argument, NULL, 'V' }, + { NULL, 0, NULL, 0 } +}; + + +#ifndef roundup +# if defined __GNUC__ && __GNUC__ >= 2 +# define roundup(x, y) ({typeof(x) _x = (x); typeof(y) _y = (y); \ + ((_x + _y - 1) / _y) * _y; }) +# else +# define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) +# endif /* GNU CC2 */ +#endif /* roundup */ + +/* Prototypes for local functions. */ +static void usage PARAMS ((int status)) +#if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2) + __attribute__ ((noreturn)) +#endif +; +static void error_print PARAMS ((void)); +static void grammar PARAMS ((char *__filename)); +static void format_constructor PARAMS ((po_ty *__that)); +static void format_directive_domain PARAMS ((po_ty *__pop, char *__name)); +static void format_directive_message PARAMS ((po_ty *__pop, char *__msgid, + lex_pos_ty *__msgid_pos, + char *__msgstr, + lex_pos_ty *__msgstr_pos)); +static void format_comment_special PARAMS ((po_ty *pop, const char *s)); +static void format_debrief PARAMS((po_ty *)); +static struct msg_domain *new_domain PARAMS ((const char *name)); +static int compare_id PARAMS ((const void *pval1, const void *pval2)); +static void write_table PARAMS ((FILE *output_file, hash_table *tab)); +static void check_pair PARAMS ((const char *msgid, const lex_pos_ty *msgid_pos, + const char *msgstr, + const lex_pos_ty *msgstr_pos, int is_format)); +static const char *add_mo_suffix PARAMS ((const char *)); + + +int +main(argc, argv) + int argc; + char *argv[]; +{ + int opt; + int do_help = 0; + int do_version = 0; + int strict_uniforum = 0; + + /* Set default value for global variables. */ + alignment = DEFAULT_OUTPUT_ALIGNMENT; + + /* Set program name for messages. */ + program_name = argv[0]; + error_print_progname = error_print; + error_one_per_line = 1; + exit_status = EXIT_SUCCESS; + +#ifdef HAVE_SETLOCALE + /* Set locale via LC_ALL. */ + setlocale (LC_ALL, ""); +#endif + + /* Set the text message domain. */ + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + while ((opt = getopt_long (argc, argv, "a:cD:fho:vV", long_options, NULL)) + != EOF) + switch (opt) + { + case '\0': /* Long option. */ + break; + case 'a': + { + char *endp; + size_t new_align = strtoul (optarg, &endp, 0); + + if (endp != optarg) + alignment = new_align; + } + break; + case 'c': + do_check = 1; + break; + case 'D': + dir_list_append (optarg); + break; + case 'f': + include_all = 1; + break; + case 'h': + do_help = 1; + break; + case 'o': + output_file_name = optarg; + break; + case 'S': + strict_uniforum = 1; + break; + case 'v': + ++verbose_level; + break; + case 'V': + do_version = 1; + break; + default: + usage (EXIT_FAILURE); + break; + } + + /* Version information is requested. */ + if (do_version) + { + printf ("%s (GNU %s) %s\n", basename (program_name), PACKAGE, VERSION); + /* xgettext: no-wrap */ + printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\ +This is free software; see the source for copying conditions. There is NO\n\ +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ +"), + "1995, 1996, 1997, 1998"); + printf (_("Written by %s.\n"), "Ulrich Drepper"); + exit (EXIT_SUCCESS); + } + + /* Help is requested. */ + if (do_help) + usage (EXIT_SUCCESS); + + /* Test whether we have a .po file name as argument. */ + if (optind >= argc) + { + error (EXIT_SUCCESS, 0, _("no input file given")); + usage (EXIT_FAILURE); + } + + /* The -o option determines the name of the domain and therefor + the output file. */ + if (output_file_name != NULL) + current_domain = new_domain (output_file_name); + + /* Prepare PO file reader. We need to see the comments because inexact + translations must be reported. */ + po_lex_pass_comments (1); + + /* Now write out all domains. */ + /* Process all given .po files. */ + while (argc > optind) + { + /* Remember that we currently have not specified any domain. This + is of course not true when we saw the -o option. */ + if (output_file_name == NULL) + current_domain = NULL; + + /* And process the input file. */ + grammar (argv[optind]); + + ++optind; + } + + while (domain != NULL) + { + FILE *output_file; + + /* If no entry for this domain don't even create the file. */ + if (domain->symbol_tab.filled != 0) + { + if (strcmp (domain->domain_name, "-") == 0) + output_file = stdout; + else + { + const char *fname; + + fname = strict_uniforum ? add_mo_suffix (domain->domain_name) + : domain->domain_name; + + output_file = fopen (fname, "w"); + if (output_file == NULL) + { + error (0, errno, + _("error while opening \"%s\" for writing"), fname); + exit_status = EXIT_FAILURE; + } + + if (strict_uniforum) + free ((void *) fname); + } + + if (output_file != NULL) + { + write_table (output_file, &domain->symbol_tab); + if (output_file != stdout) + fclose (output_file); + } + } + + domain = domain->next; + } + + /* Print statistics if requested. */ + if (verbose_level > 0 || do_statistics) + { + fprintf (stderr, _("%d translated messages"), msgs_translated); + if (msgs_fuzzy > 0) + fprintf (stderr, _(", %d fuzzy translations"), msgs_fuzzy); + if (msgs_untranslated > 0) + fprintf (stderr, _(", %d untranslated messages"), msgs_untranslated); + fputs (".\n", stderr); + } + + exit (exit_status); +} + + +/* Display usage information and exit. */ +static void +usage (status) + int status; +{ + if (status != EXIT_SUCCESS) + fprintf (stderr, _("Try `%s --help' for more information.\n"), + program_name); + else + { + /* xgettext: no-wrap */ + printf (_("\ +Usage: %s [OPTION] filename.po ...\n\ +Generate binary message catalog from textual translation description.\n\ +\n\ +Mandatory arguments to long options are mandatory for short options too.\n\ + -a, --alignment=NUMBER align strings to NUMBER bytes (default: %d)\n\ + -c, --check perform language dependent checks on strings\n\ + -D, --directory=DIRECTORY add DIRECTORY to list for input files search\n\ + -f, --use-fuzzy use fuzzy entries in output\n\ + -h, --help display this help and exit\n\ + --no-hash binary file will not include the hash table\n\ + -o, --output-file=FILE specify output file name as FILE\n\ + --statistics print statistics about translations\n\ + --strict enable strict Uniforum mode\n\ + -v, --verbose list input file anomalies\n\ + -V, --version output version information and exit\n\ +\n\ +Giving the -v option more than once increases the verbosity level.\n\ +\n\ +If input file is -, standard input is read. If output file is -,\n\ +output is written to standard output.\n"), + program_name, DEFAULT_OUTPUT_ALIGNMENT); + fputs (_("Report bugs to <[email protected]>.\n"), stdout); + } + + exit (status); +} + + +static struct msg_domain * +new_domain (name) + const char *name; +{ + struct msg_domain **p_dom = &domain; + + while (*p_dom != NULL && strcmp (name, (*p_dom)->domain_name) != 0) + p_dom = &(*p_dom)->next; + + if (*p_dom == NULL) + { + *p_dom = (struct msg_domain *) xmalloc (sizeof (**p_dom)); + + if (init_hash (&(*p_dom)->symbol_tab, 100) != 0) + error (EXIT_FAILURE, errno, _("while creating hash table")); + (*p_dom)->domain_name = name; + (*p_dom)->next = NULL; + } + + return *p_dom; +} + + +/* The address of this function will be assigned to the hook in the error + functions. */ +static void +error_print () +{ + /* We don't want the program name to be printed in messages. Emacs' + compile.el does not like this. */ +} + + +/* Prepare for first message. */ +static void +format_constructor (that) + po_ty *that; +{ + msgfmt_class_ty *this = (msgfmt_class_ty *) that; + + this->is_fuzzy = 0; + this->is_c_format = undecided; + this->do_wrap = undecided; + this->has_header_entry = 0; +} + + +/* Some checks after whole file is read. */ +static void +format_debrief (that) + po_ty *that; +{ + msgfmt_class_ty *this = (msgfmt_class_ty *) that; + + /* If in verbose mode, test whether header entry was found. */ + if (verbose_level > 0 && this->has_header_entry == 0) + error (0, 0, _("%s: warning: no header entry found"), gram_pos.file_name); +} + + +/* Process `domain' directive from .po file. */ +static void +format_directive_domain (pop, name) + po_ty *pop; + char *name; +{ + /* If no output file was given, we change it with each `domain' + directive. */ + if (output_file_name == NULL) + { + size_t correct; + + correct = strcspn (name, INVALID_PATH_CHAR); + if (name[correct] != '\0') + { + exit_status = EXIT_FAILURE; + if (correct == 0) + { + error (0, 0, _("\ +domain name \"%s\" not suitable as file name"), name); + return; + } + else + error (0, 0, _("\ +domain name \"%s\" not suitable as file name: will use prefix"), name); + name[correct] = '\0'; + } + + /* Set new domain. */ + current_domain = new_domain (name); + } + else + { + if (verbose_level > 0) + /* We don't change the exit status here because this is really + only an information. */ + error (0, 0, _("`domain %s' directive ignored"), name); + + /* NAME was allocated in po-gram.y but is not used anywhere. */ + free (name); + } +} + + +/* Process `msgid'/`msgstr' pair from .po file. */ +static void +format_directive_message (that, msgid_string, msgid_pos, msgstr_string, + msgstr_pos) + po_ty *that; + char *msgid_string; + lex_pos_ty *msgid_pos; + char *msgstr_string; + lex_pos_ty *msgstr_pos; +{ + msgfmt_class_ty *this = (msgfmt_class_ty *) that; + struct msgstr_def *entry; + + if (msgstr_string[0] == '\0' || (!include_all && this->is_fuzzy)) + { + if (verbose_level > 1) + /* We don't change the exit status here because this is really + only an information. */ + error_at_line (0, 0, msgstr_pos->file_name, msgstr_pos->line_number, + (msgstr_string[0] == '\0' + ? _("empty `msgstr' entry ignored") + : _("fuzzy `msgstr' entry ignored"))); + + /* Free strings allocated in po-gram.y. */ + free (msgstr_string); + + /* Increment counter for fuzzy/untranslated messages. */ + if (this->is_fuzzy) + ++msgs_fuzzy; + else + ++msgs_untranslated; + + goto prepare_next; + } + + /* Test for header entry. */ + if (msgid_string[0] == '\0') + { + this->has_header_entry = 1; + + /* Do some more tests on test contents of the header entry. */ + if (verbose_level > 0) + { + static const char *required_fields[] = + { + "Project-Id-Version", "PO-Revision-Date", + "Last-Translator", "Language-Team", "MIME-Version", + "Content-Type", "Content-Transfer-Encoding" + }; + static const char *default_values[] = + { + "PACKAGE VERSION", "YEAR-MO-DA", "FULL NAME", "LANGUAGE", + NULL, "text/plain; charset=CHARSET", "ENCODING" + }; + const size_t nfields = (sizeof (required_fields) + / sizeof (required_fields[0])); + int initial = -1; + int cnt; + + for (cnt = 0; cnt < nfields; ++cnt) + { + char *endp = strstr (msgstr_string, required_fields[cnt]); + + if (endp == NULL) + error (0, 0, _("headerfield `%s' missing in header"), + required_fields[cnt]); + else if (endp != msgstr_string && endp[-1] != '\n') + error (0, 0, _("\ +header field `%s' should start at beginning of line"), + required_fields[cnt]); + else if (default_values[cnt] != NULL + && strncmp (default_values[cnt], + endp + strlen (required_fields[cnt]) + 2, + strlen (default_values[cnt])) == 0) + { + if (initial != -1) + { + error (0, 0, _("\ +some header fields still have the initial default value")); + initial = -1; + break; + } + else + initial = cnt; + } + } + + if (initial != -1) + error (0, 0, _("field `%s' still has initial default value"), + required_fields[initial]); + } + } + else + /* We don't count the header entry in the statistic so place the + counter incrementation here. */ + if (this->is_fuzzy) + ++msgs_fuzzy; + else + ++msgs_translated; + + /* We found a valid pair of msgid/msgstr. + Construct struct to describe msgstr definition. */ + entry = (struct msgstr_def *) xmalloc (sizeof (*entry)); + + entry->msgstr = msgstr_string; + entry->pos = *msgstr_pos; + + /* Do some more checks on both strings. */ + check_pair (msgid_string, msgid_pos, msgstr_string, msgstr_pos, + do_check && possible_c_format_p (this->is_c_format)); + + /* Check whether already a domain is specified. If not use default + domain. */ + if (current_domain == NULL) + current_domain = new_domain ("messages"); + + /* We insert the ID/string pair into the hashing table. But we have + to take care for dublicates. */ + if (insert_entry (¤t_domain->symbol_tab, msgid_string, + strlen (msgid_string), entry)) + { + /* We don't need the just constructed entry. */ + free (entry); + + if (verbose_level > 0) + { + /* We give a fatal error about this, but only if the + translations are different. Tell the user the old + definition for reference. */ + find_entry (¤t_domain->symbol_tab, msgid_string, + strlen (msgid_string), (void **) &entry); + if (0 != strcmp(msgstr_string, entry->msgstr)) + { + gram_error_at_line (msgid_pos, _("duplicate message definition")); + gram_error_at_line (&entry->pos, _("\ +...this is the location of the first definition")); + + /* FIXME Should this be always a reason for an exit status != 0? */ + exit_status = EXIT_FAILURE; + } + } + + /* We don't need the just constructed entries' + parameter string (allocated in po-gram.y). */ + free (msgstr_string); + } + +prepare_next: + /* We do not need the msgid string in any case. */ + free (msgid_string); + + /* Prepare for next message. */ + this->is_fuzzy = 0; + this->is_c_format = undecided; + this->do_wrap = undecided; +} + + +/* Test for `#, fuzzy' comments and warn. */ +static void +format_comment_special (that, s) + po_ty *that; + const char *s; +{ + msgfmt_class_ty *this = (msgfmt_class_ty *) that; + + if (strstr (s, "fuzzy") != NULL) + { + static int warned = 0; + + if (!include_all && verbose_level > 1 && warned == 0) + { + warned = 1; + error (0, 0, _("\ +%s: warning: source file contains fuzzy translation"), + gram_pos.file_name); + } + + this->is_fuzzy = 1; + } + this->is_c_format = parse_c_format_description_string (s); + this->do_wrap = parse_c_width_description_string (s); +} + + +static int +compare_id (pval1, pval2) + const void *pval1; + const void *pval2; +{ + return strcmp (((struct id_str_pair *) pval1)->id, + ((struct id_str_pair *) pval2)->id); +} + + +static void +write_table (output_file, tab) + FILE *output_file; + hash_table *tab; +{ + static char null = '\0'; + /* This should be explained: + Each string has an associate hashing value V, computed by a fixed + function. To locate the string we use open addressing with double + hashing. The first index will be V % M, where M is the size of the + hashing table. If no entry is found, iterating with a second, + independent hashing function takes place. This second value will + be 1 + V % (M - 2). + The approximate number of probes will be + + for unsuccessful search: (1 - N / M) ^ -1 + for successful search: - (N / M) ^ -1 * ln (1 - N / M) + + where N is the number of keys. + + If we now choose M to be the next prime bigger than 4 / 3 * N, + we get the values + 4 and 1.85 resp. + Because unsuccesful searches are unlikely this is a good value. + Formulas: [Knuth, The Art of Computer Programming, Volume 3, + Sorting and Searching, 1973, Addison Wesley] */ + nls_uint32 hash_tab_size = no_hash_table ? 0 + : next_prime ((tab->filled * 4) + / 3); + nls_uint32 *hash_tab; + + /* Header of the .mo file to be written. */ + struct mo_file_header header; + struct id_str_pair *msg_arr; + void *ptr; + size_t cnt; + char *id; + struct msgstr_def *entry; + struct string_desc sd; + + /* Fill the structure describing the header. */ + header.magic = _MAGIC; /* Magic number. */ + header.revision = MO_REVISION_NUMBER; /* Revision number of file format. */ + header.nstrings = tab->filled; /* Number of strings. */ + header.orig_tab_offset = sizeof (header); + /* Offset of table for original string offsets. */ + header.trans_tab_offset = sizeof (header) + + tab->filled * sizeof (struct string_desc); + /* Offset of table for translation string offsets. */ + header.hash_tab_size = hash_tab_size; /* Size of used hashing table. */ + header.hash_tab_offset = + no_hash_table ? 0 : sizeof (header) + + 2 * (tab->filled * sizeof (struct string_desc)); + /* Offset of hashing table. */ + + /* Write the header out. */ + fwrite (&header, sizeof (header), 1, output_file); + + /* Allocate table for the all elements of the hashing table. */ + msg_arr = (struct id_str_pair *) alloca (tab->filled * sizeof (msg_arr[0])); + + /* Read values from hashing table into array. */ + for (cnt = 0, ptr = NULL; + iterate_table (tab, &ptr, (const void **) &id, (void **) &entry) >= 0; + ++cnt) + { + msg_arr[cnt].id = id; + msg_arr[cnt].str = entry->msgstr; + } + + /* Sort the table according to original string. */ + qsort (msg_arr, tab->filled, sizeof (msg_arr[0]), compare_id); + + /* Set offset to first byte after all the tables. */ + sd.offset = roundup (sizeof (header) + + tab->filled * sizeof (sd) + + tab->filled * sizeof (sd) + + hash_tab_size * sizeof (nls_uint32), + alignment); + + /* Write out length and starting offset for all original strings. */ + for (cnt = 0; cnt < tab->filled; ++cnt) + { + sd.length = strlen (msg_arr[cnt].id); + fwrite (&sd, sizeof (sd), 1, output_file); + sd.offset += roundup (sd.length + 1, alignment); + } + + /* Write out length and starting offset for all translation strings. */ + for (cnt = 0; cnt < tab->filled; ++cnt) + { + sd.length = strlen (msg_arr[cnt].str); + fwrite (&sd, sizeof (sd), 1, output_file); + sd.offset += roundup (sd.length + 1, alignment); + } + + /* Skip this part when no hash table is needed. */ + if (!no_hash_table) + { + /* Allocate room for the hashing table to be written out. */ + hash_tab = (nls_uint32 *) alloca (hash_tab_size * sizeof (nls_uint32)); + memset (hash_tab, '\0', hash_tab_size * sizeof (nls_uint32)); + + /* Insert all value in the hash table, following the algorithm described + above. */ + for (cnt = 0; cnt < tab->filled; ++cnt) + { + nls_uint32 hash_val = hash_string (msg_arr[cnt].id); + nls_uint32 idx = hash_val % hash_tab_size; + + if (hash_tab[idx] != 0) + { + /* We need the second hashing function. */ + nls_uint32 c = 1 + (hash_val % (hash_tab_size - 2)); + + do + if (idx >= hash_tab_size - c) + idx -= hash_tab_size - c; + else + idx += c; + while (hash_tab[idx] != 0); + } + + hash_tab[idx] = cnt + 1; + } + + /* Write the hash table out. */ + fwrite (hash_tab, sizeof (nls_uint32), hash_tab_size, output_file); + } + + /* Write bytes to make first string to be aligned. */ + cnt = sizeof (header) + 2 * tab->filled * sizeof (sd) + + hash_tab_size * sizeof (nls_uint32); + fwrite (&null, 1, roundup (cnt, alignment) - cnt, output_file); + + /* Now write the original strings. */ + for (cnt = 0; cnt < tab->filled; ++cnt) + { + size_t len = strlen (msg_arr[cnt].id); + + fwrite (msg_arr[cnt].id, len + 1, 1, output_file); + fwrite (&null, 1, roundup (len + 1, alignment) - (len + 1), output_file); + } + + /* Now write the translation strings. */ + for (cnt = 0; cnt < tab->filled; ++cnt) + { + size_t len = strlen (msg_arr[cnt].str); + + fwrite (msg_arr[cnt].str, len + 1, 1, output_file); + fwrite (&null, 1, roundup (len + 1, alignment) - (len + 1), output_file); + + free (msg_arr[cnt].str); + } + + /* Hashing table is not used anmore. */ + delete_hash (tab); +} + + +static void +check_pair (msgid, msgid_pos, msgstr, msgstr_pos, is_format) + const char *msgid; + const lex_pos_ty *msgid_pos; + const char *msgstr; + const lex_pos_ty *msgstr_pos; + int is_format; +{ + size_t msgid_len = strlen (msgid); + size_t msgstr_len = strlen (msgstr); + size_t nidfmts, nstrfmts; + + /* If the msgid string is empty we have the special entry reserved for + information about the translation. */ + if (msgid_len == 0) + return; + + /* Test 1: check whether both or none of the strings begin with a '\n'. */ + if (((msgid[0] == '\n') ^ (msgstr[0] == '\n')) != 0) + { + error_at_line (0, 0, msgid_pos->file_name, msgid_pos->line_number, _("\ +`msgid' and `msgstr' entries do not both begin with '\\n'")); + exit_status = EXIT_FAILURE; + } + + /* Test 2: check whether both or none of the strings end with a '\n'. */ + if (((msgid[msgid_len - 1] == '\n') ^ (msgstr[msgstr_len - 1] == '\n')) != 0) + { + error_at_line (0, 0, msgid_pos->file_name, msgid_pos->line_number, _("\ +`msgid' and `msgstr' entries do not both end with '\\n'")); + exit_status = EXIT_FAILURE; + } + + if (is_format != 0) + { + /* Test 3: check whether both formats strings contain the same + number of format specifications. */ + nidfmts = parse_printf_format (msgid, 0, NULL); + nstrfmts = parse_printf_format (msgstr, 0, NULL); + if (nidfmts != nstrfmts) + { + error_at_line (0, 0, msgid_pos->file_name, msgid_pos->line_number, + _("\ +number of format specifications in `msgid' and `msgstr' does not match")); + exit_status = EXIT_FAILURE; + } + else + { + int *id_args = (int *) alloca (nidfmts * sizeof (int)); + int *str_args = (int *) alloca (nstrfmts * sizeof (int)); + size_t cnt; + + (void) parse_printf_format (msgid, nidfmts, id_args); + (void) parse_printf_format (msgstr, nstrfmts, str_args); + + for (cnt = 0; cnt < nidfmts; ++cnt) + if (id_args[cnt] != str_args[cnt]) + { + error_at_line (0, 0, msgid_pos->file_name, + msgid_pos->line_number, _("\ +format specifications for argument %u are not the same"), cnt); + exit_status = EXIT_FAILURE; + } + } + } +} + + +/* So that the one parser can be used for multiple programs, and also + use good data hiding and encapsulation practices, an object + oriented approach has been taken. An object instance is allocated, + and all actions resulting from the parse will be through + invokations of method functions of that object. */ + +static po_method_ty format_methods = +{ + sizeof (msgfmt_class_ty), + format_constructor, /* constructor */ + NULL, /* destructor */ + format_directive_domain, + format_directive_message, + NULL, /* parse_brief */ + format_debrief, /* parse_debrief */ + NULL, /* comment */ + NULL, /* comment_dot */ + NULL, /* comment_filepos */ + format_comment_special /* comment */ +}; + + +/* Read .po file FILENAME and store translation pairs. */ +static void +grammar (filename) + char *filename; +{ + po_ty *pop; + + pop = po_alloc (&format_methods); + po_scan (pop, filename); + po_free (pop); +} + + +static const char * +add_mo_suffix (fname) + const char *fname; +{ + size_t len; + char *result; + + len = strlen (fname); + if (len > 3 && memcmp (fname + len - 3, ".mo", 3) == 0) + return xstrdup (fname); + if (len > 4 && memcmp (fname + len - 4, ".gmo", 4) == 0) + return xstrdup (fname); + result = (char *) xmalloc (len + 4); + stpcpy (stpcpy (result, fname), ".mo"); + return result; +} diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/msgmerge.c b/debian/gettext-kde/gettext-kde-0.10.35/src/msgmerge.c new file mode 100644 index 00000000..8ec02fc0 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/msgmerge.c @@ -0,0 +1,781 @@ +/* GNU gettext - internationalization aids + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + This file was written by Peter Miller <[email protected]> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <getopt.h> +#include <limits.h> +#include <stdio.h> + +#ifdef STDC_HEADERS +# include <stdlib.h> +#endif + +#if HAVE_STRING_H +# include <string.h> +#else +# include <strings.h> +#endif + +#if HAVE_LOCALE_H +# include <locale.h> +#endif + +#include "dir-list.h" +#include "error.h" +#include "message.h" +#include <system.h> +#include <libintl.h> +#include "po.h" + +#define _(str) gettext (str) + + +/* This structure defines a derived class of the po_ty class. (See + po.h for an explanation.) */ +typedef struct merge_class_ty merge_class_ty; +struct merge_class_ty +{ + /* inherited instance variables, etc */ + PO_BASE_TY + + /* Name of domain we are currently examining. */ + char *domain; + + /* List of domains already appeared in the current file. */ + string_list_ty *domain_list; + + /* List of messages already appeared in the current file. */ + message_list_ty *mlp; + + /* Accumulate comments for next message directive */ + string_list_ty *comment; + string_list_ty *comment_dot; + + /* Flags transported in special comments. */ + int is_fuzzy; + enum is_c_format is_c_format; + enum is_c_format do_wrap; + + /* Accumulate filepos comments for the next message directive. */ + size_t filepos_count; + lex_pos_ty *filepos; +}; + + +/* String containing name the program is called with. */ +const char *program_name; + +/* If non-zero do not print unneeded messages. */ +static int quiet; + +/* Verbosity level. */ +static int verbosity_level; + +/* If nonzero, remember comments for file name and line number for each + msgid, if present in the reference input. Defaults to true. */ +static int line_comment = 1; + +/* Force output of PO file even if empty. */ +static int force_po; + +/* Long options. */ +static const struct option long_options[] = +{ + { "add-location", no_argument, &line_comment, 1 }, + { "directory", required_argument, NULL, 'D' }, + { "escape", no_argument, NULL, 'E' }, + { "force-po", no_argument, &force_po, 1 }, + { "help", no_argument, NULL, 'h' }, + { "indent", no_argument, NULL, 'i' }, + { "no-escape", no_argument, NULL, 'e' }, + { "no-location", no_argument, &line_comment, 0 }, + { "output-file", required_argument, NULL, 'o' }, + { "quiet", no_argument, NULL, 'q' }, + { "sort-by-file", no_argument, NULL, 'F' }, + { "sort-output", no_argument, NULL, 's' }, + { "silent", no_argument, NULL, 'q' }, + { "strict", no_argument, NULL, 'S' }, + { "verbose", no_argument, NULL, 'v' }, + { "version", no_argument, NULL, 'V' }, + { "width", required_argument, NULL, 'w', }, + { NULL, 0, NULL, 0 } +}; + + +/* Prototypes for local functions. */ +static void usage PARAMS ((int __status)); +static void error_print PARAMS ((void)); +static void merge_constructor PARAMS ((po_ty *__that)); +static void merge_destructor PARAMS ((po_ty *__that)); +static void merge_directive_domain PARAMS ((po_ty *__that, char *__name)); +static void merge_directive_message PARAMS ((po_ty *__that, char *__msgid, + lex_pos_ty *__msgid_pos, + char *__msgstr, + lex_pos_ty *__msgstr_pos)); +static void merge_parse_brief PARAMS ((po_ty *__that)); +static void merge_parse_debrief PARAMS ((po_ty *__that)); +static void merge_comment PARAMS ((po_ty *__that, const char *__s)); +static void merge_comment_dot PARAMS ((po_ty *__that, const char *__s)); +static void merge_comment_special PARAMS ((po_ty *__that, const char *__s)); +static void merge_comment_filepos PARAMS ((po_ty *__that, const char *__name, + int __line)); +static message_list_ty *grammar PARAMS ((const char *__filename)); +static message_list_ty *merge PARAMS ((const char *__fn1, const char *__fn2)); + + +int +main (argc, argv) + int argc; + char **argv; +{ + int opt; + int do_help; + int do_version; + char *output_file; + message_list_ty *result; + int sort_by_filepos = 0; + int sort_by_msgid = 0; + + /* Set program name for messages. */ + program_name = argv[0]; + verbosity_level = 0; + quiet = 0; + error_print_progname = error_print; + gram_max_allowed_errors = INT_MAX; + +#ifdef HAVE_SETLOCALE + /* Set locale via LC_ALL. */ + setlocale (LC_ALL, ""); +#endif + + /* Set the text message domain. */ + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + /* Set default values for variables. */ + do_help = 0; + do_version = 0; + output_file = NULL; + + while ((opt + = getopt_long (argc, argv, "D:eEFhio:qsvVw:", long_options, NULL)) + != EOF) + switch (opt) + { + case '\0': /* Long option. */ + break; + + case 'D': + dir_list_append (optarg); + break; + + case 'e': + message_print_style_escape (0); + break; + + case 'E': + message_print_style_escape (1); + break; + + case 'F': + sort_by_filepos = 1; + break; + + case 'h': + do_help = 1; + break; + + case 'i': + message_print_style_indent (); + break; + + case 'o': + output_file = optarg; + break; + + case 'q': + quiet = 1; + break; + + case 's': + sort_by_msgid = 1; + break; + + case 'S': + message_print_style_uniforum (); + break; + + case 'v': + ++verbosity_level; + break; + + case 'V': + do_version = 1; + break; + + case 'w': + { + int value; + char *endp; + value = strtol (optarg, &endp, 10); + if (endp != optarg) + message_page_width_set (value); + } + break; + + default: + usage (EXIT_FAILURE); + break; + } + + /* Version information is requested. */ + if (do_version) + { + printf ("%s (GNU %s) %s\n", basename (program_name), PACKAGE, VERSION); + /* xgettext: no-wrap */ + printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\ +This is free software; see the source for copying conditions. There is NO\n\ +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ +"), + "1995, 1996, 1997, 1998"); + printf (_("Written by %s.\n"), "Peter Miller"); + exit (EXIT_SUCCESS); + } + + /* Help is requested. */ + if (do_help) + usage (EXIT_SUCCESS); + + /* Test whether we have an .po file name as argument. */ + if (optind >= argc) + { + error (EXIT_SUCCESS, 0, _("no input files given")); + usage (EXIT_FAILURE); + } + if (optind + 2 != argc) + { + error (EXIT_SUCCESS, 0, _("exactly 2 input files required")); + usage (EXIT_FAILURE); + } + + /* merge the two files */ + result = merge (argv[optind], argv[optind + 1]); + + /* Sort the results. */ + if (sort_by_filepos) + message_list_sort_by_filepos (result); + else if (sort_by_msgid) + message_list_sort_by_msgid (result); + + /* Write the merged message list out. */ + message_list_print (result, output_file, force_po, 0); + + exit (EXIT_SUCCESS); +} + + +/* Display usage information and exit. */ +static void +usage (status) + int status; +{ + if (status != EXIT_SUCCESS) + fprintf (stderr, _("Try `%s --help' for more information.\n"), + program_name); + else + { + /* xgettext: no-wrap */ + printf (_("\ +Usage: %s [OPTION] def.po ref.po\n\ +Mandatory arguments to long options are mandatory for short options too.\n\ + -D, --directory=DIRECTORY add DIRECTORY to list for input files search\n\ + -e, --no-escape do not use C escapes in output (default)\n\ + -E, --escape use C escapes in output, no extended chars\n\ + --force-po write PO file even if empty\n\ + -h, --help display this help and exit\n\ + -i, --indent indented output style\n\ + -o, --output-file=FILE result will be written to FILE\n\ + --no-location suppress '#: filename:line' lines\n\ + --add-location preserve '#: filename:line' lines (default)\n\ + --strict strict Uniforum output style\n\ + -v, --verbose increase verbosity level\n\ + -V, --version output version information and exit\n\ + -w, --width=NUMBER set output page width\n"), + program_name); + /* xgettext: no-wrap */ + fputs (_("\n\ +Merges two Uniforum style .po files together. The def.po file is an\n\ +existing PO file with the old translations which will be taken over to\n\ +the newly created file as long as they still match; comments will be\n\ +preserved, but extract comments and file positions will be discarded.\n\ +The ref.po file is the last created PO file (generally by xgettext), any\n\ +translations or comments in the file will be discarded, however dot\n\ +comments and file positions will be preserved. Where an exact match\n\ +cannot be found, fuzzy matching is used to produce better results. The\n\ +results are written to stdout unless an output file is specified.\n"), stdout); + fputs (_("Report bugs to <[email protected]>.\n"), + stdout); + } + + exit (status); +} + + +/* The address of this function will be assigned to the hook in the + error functions. */ +static void +error_print () +{ + /* We don't want the program name to be printed in messages. Emacs' + compile.el does not like this. */ + + /* FIXME Why must this program toady to Emacs? Why can't compile.el + be enhanced to cope with a leading program name? --PMiller */ +} + + +static void +merge_constructor (that) + po_ty *that; +{ + merge_class_ty *this = (merge_class_ty *) that; + + this->mlp = message_list_alloc (); + this->domain = MESSAGE_DOMAIN_DEFAULT; + this->domain_list = string_list_alloc (); + this->comment = NULL; + this->comment_dot = NULL; + this->filepos_count = 0; + this->filepos = NULL; + this->is_fuzzy = 0; + this->is_c_format = undecided; + this->do_wrap = undecided; +} + + +static void +merge_destructor (that) + po_ty *that; +{ + merge_class_ty *this = (merge_class_ty *) that; + size_t j; + + string_list_free (this->domain_list); + /* Do not free this->mlp. */ + if (this->comment != NULL) + string_list_free (this->comment); + if (this->comment_dot != NULL) + string_list_free (this->comment_dot); + for (j = 0; j < this->filepos_count; ++j) + free (this->filepos[j].file_name); + if (this->filepos != NULL) + free (this->filepos); +} + + +static void +merge_directive_domain (that, name) + po_ty *that; + char *name; +{ + size_t j; + + merge_class_ty *this = (merge_class_ty *) that; + /* Override current domain name. Don't free memory. */ + this->domain = name; + + /* If there are accumulated comments, throw them away, they are + probably part of the file header, or about the domain directive, + and will be unrelated to the next message. */ + if (this->comment != NULL) + { + string_list_free (this->comment); + this->comment = NULL; + } + if (this->comment_dot != NULL) + { + string_list_free (this->comment_dot); + this->comment_dot = NULL; + } + for (j = 0; j < this->filepos_count; ++j) + free (this->filepos[j].file_name); + if (this->filepos != NULL) + free (this->filepos); + this->filepos_count = 0; + this->filepos = NULL; +} + + +static void +merge_directive_message (that, msgid, msgid_pos, msgstr, msgstr_pos) + po_ty *that; + char *msgid; + lex_pos_ty *msgid_pos; + char *msgstr; + lex_pos_ty *msgstr_pos; +{ + merge_class_ty *this = (merge_class_ty *) that; + message_ty *mp; + message_variant_ty *mvp; + size_t j; + + /* Remember the domain names for later. */ + string_list_append_unique (this->domain_list, this->domain); + + /* See if this message ID has been seen before. */ + mp = message_list_search (this->mlp, msgid); + if (mp) + free (msgid); + else + { + mp = message_alloc (msgid); + message_list_append (this->mlp, mp); + } + + /* Add the accumulated comments to the message. Clear the + accumulation in preparation for the next message. */ + if (this->comment != NULL) + { + for (j = 0; j < this->comment->nitems; ++j) + message_comment_append (mp, this->comment->item[j]); + string_list_free (this->comment); + this->comment = NULL; + } + if (this->comment_dot != NULL) + { + for (j = 0; j < this->comment_dot->nitems; ++j) + message_comment_dot_append (mp, this->comment_dot->item[j]); + string_list_free (this->comment_dot); + this->comment_dot = NULL; + } + for (j = 0; j < this->filepos_count; ++j) + { + lex_pos_ty *pp; + + pp = &this->filepos[j]; + message_comment_filepos (mp, pp->file_name, pp->line_number); + free (pp->file_name); + } + mp->is_fuzzy = this->is_fuzzy; + mp->is_c_format = this->is_c_format; + mp->do_wrap = this->do_wrap; + + if (this->filepos != NULL) + free (this->filepos); + this->filepos_count = 0; + this->filepos = NULL; + this->is_fuzzy = 0; + this->is_c_format = undecided; + this->do_wrap = undecided; + + /* See if this domain has been seen for this message ID. */ + mvp = message_variant_search (mp, this->domain); + if (mvp) + { + gram_error_at_line (msgid_pos, _("duplicate message definition")); + gram_error_at_line (&mvp->pos, _("\ +...this is the location of the first definition")); + free (msgstr); + } + else + message_variant_append (mp, this->domain, msgstr, msgstr_pos); +} + + +static void +merge_parse_brief (that) + po_ty *that; +{ + po_lex_pass_comments (1); +} + + +static void +merge_parse_debrief (that) + po_ty *that; +{ + merge_class_ty *this = (merge_class_ty *) that; + message_list_ty *mlp = this->mlp; + size_t j; + + /* For each domain in the used-domain-list, make sure each message + defines a msgstr in that domain. */ + for (j = 0; j < this->domain_list->nitems; ++j) + { + const char *domain_name; + size_t k; + + domain_name = this->domain_list->item[j]; + for (k = 0; k < mlp->nitems; ++k) + { + const message_ty *mp; + size_t m; + + mp = mlp->item[k]; + for (m = 0; m < mp->variant_count; ++m) + { + message_variant_ty *mvp; + + mvp = &mp->variant[m]; + if (strcmp (domain_name, mvp->domain) == 0) + break; + } + if (m >= mp->variant_count) + gram_error_at_line (&mp->variant[0].pos, _("\ +this message has no definition in the \"%s\" domain"), domain_name); + } + } +} + + +static void +merge_comment (that, s) + po_ty *that; + const char *s; +{ + merge_class_ty *this = (merge_class_ty *) that; + + if (this->comment == NULL) + this->comment = string_list_alloc (); + string_list_append (this->comment, s); +} + + +static void +merge_comment_dot (that, s) + po_ty *that; + const char *s; +{ + merge_class_ty *this = (merge_class_ty *) that; + + if (this->comment_dot == NULL) + this->comment_dot = string_list_alloc (); + string_list_append (this->comment_dot, s); +} + + +static void +merge_comment_special (that, s) + po_ty *that; + const char *s; +{ + merge_class_ty *this = (merge_class_ty *) that; + + if (strstr (s, "fuzzy") != NULL) + this->is_fuzzy = 1; + + this->is_c_format = parse_c_format_description_string (s); + this->do_wrap = parse_c_width_description_string (s); +} + + +static void +merge_comment_filepos (that, name, line) + po_ty *that; + const char *name; + int line; +{ + merge_class_ty *this = (merge_class_ty *) that; + size_t nbytes; + lex_pos_ty *pp; + + if (!line_comment) + return; + nbytes = (this->filepos_count + 1) * sizeof (this->filepos[0]); + this->filepos = xrealloc (this->filepos, nbytes); + pp = &this->filepos[this->filepos_count++]; + pp->file_name = xstrdup (name); + pp->line_number = line; +} + + +/* So that the one parser can be used for multiple programs, and also + use good data hiding and encapsulation practices, an object + oriented approach has been taken. An object instance is allocated, + and all actions resulting from the parse will be through + invokations of method functions of that object. */ + +static po_method_ty merge_methods = +{ + sizeof (merge_class_ty), + merge_constructor, + merge_destructor, + merge_directive_domain, + merge_directive_message, + merge_parse_brief, + merge_parse_debrief, + merge_comment, + merge_comment_dot, + merge_comment_filepos, + merge_comment_special +}; + + +static message_list_ty * +grammar (filename) + const char *filename; +{ + po_ty *pop; + message_list_ty *mlp; + + pop = po_alloc (&merge_methods); + po_lex_pass_obsolete_entries (1); + po_scan (pop, filename); + mlp = ((merge_class_ty *) pop)->mlp; + po_free (pop); + return mlp; +} + + +#define DOT_FREQUENCE 10 + +static message_list_ty * +merge (fn1, fn2) + const char *fn1; /* definitions */ + const char *fn2; /* references */ +{ + message_list_ty *def; + message_list_ty *ref; + message_ty *defmsg; + size_t j, k; + size_t merged, fuzzied, missing, obsolete; + message_list_ty *result; + + merged = fuzzied = missing = obsolete = 0; + + /* This is the definitions file, created by a human. */ + def = grammar (fn1); + + /* This is the references file, created by groping the sources with + the xgettext program. */ + ref = grammar (fn2); + + result = message_list_alloc (); + + /* Every reference must be matched with its definition. */ + for (j = 0; j < ref->nitems; ++j) + { + message_ty *refmsg; + + /* Because merging can take a while we print something to signal + we are not dead. */ + if (!quiet && verbosity_level <= 1 && j % DOT_FREQUENCE == 0) + fputc ('.', stderr); + + refmsg = ref->item[j]; + + /* See if it is in the other file. */ + defmsg = message_list_search (def, refmsg->msgid); + if (defmsg) + { + /* Merge the reference with the definition: take the #. and + #: comments from the reference, take the # comments from + the definition, take the msgstr from the definition. Add + this merged entry to the output message list. */ + message_ty *mp = message_merge (defmsg, refmsg); + + message_list_append (result, mp); + + /* Remember that this message has been used, when we scan + later to see if anything was omitted. */ + defmsg->used = 1; + ++merged; + continue; + } + + /* If the message was not defined at all, try to find a very + similar message, it could be a typo, or the suggestion may + help. */ + defmsg = message_list_search_fuzzy (def, refmsg->msgid); + if (defmsg) + { + message_ty *mp; + + if (verbosity_level > 1) + { + gram_error_at_line (&refmsg->variant[0].pos, _("\ +this message is used but not defined...")); + gram_error_at_line (&defmsg->variant[0].pos, _("\ +...but this definition is similar")); + } + + /* Merge the reference with the definition: take the #. and + #: comments from the reference, take the # comments from + the definition, take the msgstr from the definition. Add + this merged entry to the output message list. */ + mp = message_merge (defmsg, refmsg); + + mp->is_fuzzy = 1; + + message_list_append (result, mp); + + /* Remember that this message has been used, when we scan + later to see if anything was omitted. */ + defmsg->used = 1; + ++fuzzied; + if (!quiet && verbosity_level <= 1) + /* Always print a dot if we handled a fuzzy match. */ + fputc ('.', stderr); + } + else + { + message_ty *mp; + + if (verbosity_level > 1) + gram_error_at_line (&refmsg->variant[0].pos, _("\ +this message is used but not defined in %s"), fn1); + + mp = message_copy (refmsg); + + message_list_append (result, mp); + ++missing; + } + } + + /* Look for messages in the definition file, which are not present + in the reference file, indicating messages which defined but not + used in the program. */ + for (k = 0; k < def->nitems; ++k) + { + defmsg = def->item[k]; + if (defmsg->used) + continue; + + /* Remember the old translation although it is not used anymore. + But we mark it as obsolete. */ + defmsg->obsolete = 1; + + message_list_append (result, defmsg); + ++obsolete; + } + + /* Report some statistics. */ + if (verbosity_level > 0) + fprintf (stderr, _("%s\ +Read %d old + %d reference, \ +merged %d, fuzzied %d, missing %d, obsolete %d.\n"), + !quiet && verbosity_level <= 1 ? "\n" : "", + def->nitems, ref->nitems, merged, fuzzied, missing, obsolete); + else if (!quiet) + fputs (_(" done.\n"), stderr); + + return result; +} diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/msgunfmt.c b/debian/gettext-kde/gettext-kde-0.10.35/src/msgunfmt.c new file mode 100644 index 00000000..920d82fe --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/msgunfmt.c @@ -0,0 +1,411 @@ +/* msgunfmt - converts binary .mo files to Uniforum style .po files + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + Written by Ulrich Drepper <[email protected]>, April 1995. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <ctype.h> +#include <errno.h> +#include <getopt.h> +#include <stdio.h> +#include <sys/param.h> +#include <sys/types.h> + +#ifdef STDC_HEADERS +# include <stdlib.h> +#endif + +#ifdef HAVE_LOCALE_H +# include <locale.h> +#endif + +#include "hash.h" + +#include "error.h" +#include "getline.h" +#include "printf.h" +#include <system.h> + +#include "gettext.h" +#include "domain.h" +#include "hash-string.h" +#include <libintl.h> +#include "message.h" + +#define _(str) gettext (str) + +#ifndef errno +extern int errno; +#endif + + +/* String containing name the program is called with. */ +const char *program_name; + +/* Force output of PO file even if empty. */ +static int force_po; + +/* Long options. */ +static const struct option long_options[] = +{ + { "escape", no_argument, NULL, 'E' }, + { "force-po", no_argument, &force_po, 1 }, + { "help", no_argument, NULL, 'h' }, + { "indent", no_argument, NULL, 'i' }, + { "no-escape", no_argument, NULL, 'e' }, + { "output-file", required_argument, NULL, 'o' }, + { "strict", no_argument, NULL, 'S' }, + { "version", no_argument, NULL, 'V' }, + { "width", required_argument, NULL, 'w', }, + { NULL, 0, NULL, 0 } +}; + + +/* This defines the byte order within the file. It needs to be set + appropriately once we have the file open. */ +static enum { MO_LITTLE_ENDIAN, MO_BIG_ENDIAN } endian; + + +/* Prototypes for local functions. */ +static void usage PARAMS ((int __status)); +static void error_print PARAMS ((void)); +static nls_uint32 read32 PARAMS ((FILE *__fp, const char *__fn)); +static void seek32 PARAMS ((FILE *__fp, const char *__fn, long __offset)); +static char *string32 PARAMS ((FILE *__fp, const char *__fn, long __offset)); +static message_list_ty *read_mo_file PARAMS ((message_list_ty *__mlp, + const char *__fn)); + + +int +main (argc, argv) + int argc; + char **argv; +{ + int optchar; + int do_help = 0; + int do_version = 0; + const char *output_file = "-"; + message_list_ty *mlp = NULL; + + /* Set program name for messages. */ + program_name = argv[0]; + error_print_progname = error_print; + +#ifdef HAVE_SETLOCALE + /* Set locale via LC_ALL. */ + setlocale (LC_ALL, ""); +#endif + + /* Set the text message domain. */ + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + while ((optchar = getopt_long (argc, argv, "hio:Vw:", long_options, NULL)) + != EOF) + switch (optchar) + { + case '\0': + /* long option */ + break; + + case 'e': + message_print_style_escape (0); + break; + + case 'E': + message_print_style_escape (1); + break; + + case 'h': + do_help = 1; + break; + + case 'i': + message_print_style_indent (); + break; + + case 'o': + output_file = optarg; + break; + + case 'S': + message_print_style_uniforum (); + break; + + case 'V': + do_version = 1; + break; + + case 'w': + { + int value; + char *endp; + value = strtol (optarg, &endp, 10); + if (endp != optarg) + message_page_width_set (value); + } + break; + + default: + usage (EXIT_FAILURE); + break; + } + + /* Version information is requested. */ + if (do_version) + { + printf ("%s (GNU %s) %s\n", basename (program_name), PACKAGE, VERSION); + /* xgettext: no-wrap */ + printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\ +This is free software; see the source for copying conditions. There is NO\n\ +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ +"), + "1995, 1996, 1997, 1998"); + printf (_("Written by %s.\n"), "Ulrich Drepper"); + exit (EXIT_SUCCESS); + } + + /* Help is requested. */ + if (do_help) + usage (EXIT_SUCCESS); + + /* Read the given .mo file. */ + if (optind < argc) + do + mlp = read_mo_file (mlp, argv[optind]); + while (++optind < argc); + else + mlp = read_mo_file (NULL, "-"); + + /* Write the resulting message list to the given .po file. */ + message_list_print (mlp, output_file, force_po, 0); + + /* No problems. */ + exit (EXIT_SUCCESS); +} + + +/* Display usage information and exit. */ +static void +usage (status) + int status; +{ + if (status != EXIT_SUCCESS) + fprintf (stderr, _("Try `%s --help' for more information.\n"), + program_name); + else + { + /* xgettext: no-wrap */ + printf (_("\ +Usage: %s [OPTION] [FILE]...\n\ +Mandatory arguments to long options are mandatory for short options too.\n\ + -e, --no-escape do not use C escapes in output (default)\n\ + -E, --escape use C escapes in output, no extended chars\n\ + --force-po write PO file even if empty\n\ + -h, --help display this help and exit\n\ + -i, --indent write indented output style\n\ + -o, --output-file=FILE write output into FILE instead of standard output\n\ + --strict write strict uniforum style\n\ + -V, --version output version information and exit\n\ + -w, --width=NUMBER set output page width\n"), + program_name); + /* xgettext: no-wrap */ + fputs (_("\n\ +Convert binary .mo files to Uniforum style .po files.\n\ +Both little-endian and big-endian .mo files are handled.\n\ +If no input file is given or it is -, standard input is read.\n\ +By default the output is written to standard output.\n"), stdout); + fputs (_("Report bugs to <[email protected]>.\n"), + stdout); + } + + exit (status); +} + + +/* The address of this function will be assigned to the hook in the error + functions. */ +static void +error_print () +{ + /* We don't want the program name to be printed in messages. Emacs' + compile.el does not like this. */ +} + + +/* This function reads a 32-bit number from the file, and assembles it + according to the current ``endian'' setting. */ +static nls_uint32 +read32 (fp, fn) + FILE *fp; + const char *fn; +{ + int c1, c2, c3, c4; + + c1 = getc (fp); + if (c1 == EOF) + { + bomb: + if (ferror (fp)) + error (EXIT_FAILURE, errno, _("error while reading \"%s\""), fn); + error (EXIT_FAILURE, 0, _("file \"%s\" truncated"), fn); + } + c2 = getc (fp); + if (c2 == EOF) + goto bomb; + c3 = getc (fp); + if (c3 == EOF) + goto bomb; + c4 = getc (fp); + if (c4 == EOF) + goto bomb; + if (endian == MO_LITTLE_ENDIAN) + return (((nls_uint32) c1) + | ((nls_uint32) c2 << 8) + | ((nls_uint32) c3 << 16) + | ((nls_uint32) c4 << 24)); + + return (((nls_uint32) c1 << 24) + | ((nls_uint32) c2 << 16) + | ((nls_uint32) c3 << 8) + | ((nls_uint32) c4)); +} + + +static void +seek32 (fp, fn, offset) + FILE *fp; + const char *fn; + long offset; +{ + if (fseek (fp, offset, 0) < 0) + error (EXIT_FAILURE, errno, _("seek \"%s\" offset %ld failed"), + fn, offset); +} + + +static char * +string32 (fp, fn, offset) + FILE *fp; + const char *fn; + long offset; +{ + long length; + char *buffer; + long n; + + /* Read the string_desc structure, describing where in the file to + find the string. */ + seek32 (fp, fn, offset); + length = read32 (fp, fn); + offset = read32 (fp, fn); + + /* Allocate memory for the string to be read into. Leave space for + the NUL on the end. */ + buffer = xmalloc (length + 1); + + /* Read in the string. Complain if there is an error or it comes up + short. Add the NUL ourselves. */ + seek32 (fp, fn, offset); + n = fread (buffer, 1, length, fp); + if (n != length) + { + if (ferror (fp)) + error (EXIT_FAILURE, errno, _("error while reading \"%s\""), fn); + error (EXIT_FAILURE, 0, _("file \"%s\" truncated"), fn); + } + buffer[length] = 0; + + /* Return the string to the caller. */ + return buffer; +} + + +/* This function reads and existing .mo file. Return a message list. */ +static message_list_ty * +read_mo_file (mlp, fn) + message_list_ty *mlp; + const char *fn; +{ + FILE *fp; + struct mo_file_header header; + int j; + + if (strcmp (fn, "-") == 0 || strcmp (fn, "/dev/stdout") == 0) + fp = stdin; + else + { + fp = fopen (fn, "rb"); + if (fp == NULL) + error (EXIT_FAILURE, errno, + _("error while opening \"%s\" for reading"), fn); + } + + /* We must grope the file to determine which endian it is. + Perversity of the universe tends towards maximum, so it will + probably not match the currently executing architecture. */ + endian = MO_BIG_ENDIAN; + header.magic = read32 (fp, fn); + if (header.magic != _MAGIC) + { + endian = MO_LITTLE_ENDIAN; + seek32 (fp, fn, 0L); + header.magic = read32 (fp, fn); + if (header.magic != _MAGIC) + { + unrecognised: + error (EXIT_FAILURE, 0, _("file \"%s\" is not in GNU .mo format"), + fn); + } + } + + /* Fill the structure describing the header. */ + header.revision = read32 (fp, fn); + if (header.revision != MO_REVISION_NUMBER) + goto unrecognised; + header.nstrings = read32 (fp, fn); + header.orig_tab_offset = read32 (fp, fn); + header.trans_tab_offset = read32 (fp, fn); + header.hash_tab_size = read32 (fp, fn); + header.hash_tab_offset = read32 (fp, fn); + + if (mlp == NULL) + mlp = message_list_alloc (); + for (j = 0; j < header.nstrings; ++j) + { + static lex_pos_ty pos = { __FILE__, __LINE__ }; + message_ty *mp; + char *msgid; + char *msgstr; + + /* Read the msgid. */ + msgid = string32 (fp, fn, header.orig_tab_offset + j * 8); + + /* Read the msgstr. */ + msgstr = string32 (fp, fn, header.trans_tab_offset + j * 8); + + mp = message_alloc (msgid); + message_variant_append (mp, MESSAGE_DOMAIN_DEFAULT, msgstr, &pos); + message_list_append (mlp, mp); + } + + if (fp != stdin) + fclose (fp); + return mlp; +} diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/open-po.c b/debian/gettext-kde/gettext-kde-0.10.35/src/open-po.c new file mode 100644 index 00000000..aad7e619 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/open-po.c @@ -0,0 +1,131 @@ +/* open-po - search for .po file along search path list and open for reading + Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Written by Ulrich Drepper <[email protected]>, April 1995. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <errno.h> +#include <stdio.h> +#include <sys/types.h> + +#ifdef STDC_HEADERS +# include <stdlib.h> +#endif + +#if defined STDC_HEADERS || HAVE_STRING_H +# include <string.h> +#else +# include <strings.h> +#endif + +#include "dir-list.h" +#include "error.h" +#include "system.h" + +#include <libintl.h> + +#define _(str) gettext (str) + +#ifndef errno +extern int errno; +#endif + +/* Prototypes for helper functions. */ +extern char *xstrdup PARAMS ((const char *string)); + +/* This macro is used to determine the number of elements in an erray. */ +#define SIZEOF(a) (sizeof(a)/sizeof(a[0])) + +/* Open the input file with the name INPUT_NAME. The ending .po is added + if necessary. If INPUT_NAME is not an absolute file name and the file is + not found, the list of directories in INPUT_PATH_LIST is searched. */ +FILE * +open_po_file (input_name, file_name) + const char *input_name; + char **file_name; +{ + static const char *extension[] = { "", ".po", ".pot", }; + FILE *ret_val; + int j, k; + const char *dir; + const char *ext; + + if (strcmp (input_name, "-") == 0 || strcmp (input_name, "/dev/stdin") == 0) + { + *file_name = xstrdup (_("<stdin>")); + return stdin; + } + + /* We have a real name for the input file. If the name is absolute, + try the various extensions, but ignore the directory search list. */ + if (*input_name == '/') + { + for (k = 0; k < SIZEOF (extension); ++k) + { + ext = extension[k]; + *file_name = xmalloc (strlen (input_name) + strlen (ext) + 1); + stpcpy (stpcpy (*file_name, input_name), ext); + + ret_val = fopen (*file_name, "r"); + if (ret_val != NULL || errno != ENOENT) + /* We found the file. */ + return ret_val; + + free (*file_name); + } + + /* File does not exist. */ + *file_name = xstrdup (input_name); + errno = ENOENT; + return NULL; + } + + /* For relative file names, look through the directory search list, + trying the various extensions. If no directory search list is + specified, the current directory is used. */ + for (j = 0; (dir = dir_list_nth (j)) != NULL; ++j) + for (k = 0; k < SIZEOF (extension); ++k) + { + ext = extension[k]; + if (dir[0] == '.' && dir[1] == '\0') + { + *file_name = xmalloc (strlen(input_name) + strlen(ext) + 1); + stpcpy (stpcpy (*file_name, input_name), ext); + } + else + { + *file_name = xmalloc (strlen (dir) + strlen (input_name) + + strlen (ext) + 2); + stpcpy (stpcpy (stpcpy (stpcpy (*file_name, dir), "/"), + input_name), + ext); + } + + ret_val = fopen (*file_name, "r"); + if (ret_val != NULL || errno != ENOENT) + return ret_val; + + free (*file_name); + } + + /* File does not exist. */ + *file_name = xstrdup (input_name); + errno = ENOENT; + return NULL; +} diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/po-gram.gen.c b/debian/gettext-kde/gettext-kde-0.10.35/src/po-gram.gen.c new file mode 100644 index 00000000..7ac7fa62 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/po-gram.gen.c @@ -0,0 +1,912 @@ + +/* A Bison parser, made from ../../src/po-gram.y + by GNU Bison version 1.25 + */ + +#define po_gram_BISON 1 /* Identify Bison output. */ + +#define COMMENT 258 +#define DOMAIN 259 +#define JUNK 260 +#define MSGID 261 +#define MSGSTR 262 +#define NAME 263 +#define NUMBER 264 +#define STRING 265 + +#line 20 "../../src/po-gram.y" + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdio.h> + +#include "po-lex.h" +#include "po-gram.h" +#include "error.h" +#include "system.h" +#include <libintl.h> +#include "po.h" + +#define _(str) gettext (str) + +#line 46 "../../src/po-gram.y" +typedef union +{ + char *string; + long number; + lex_pos_ty pos; +} po_gram_STYPE; +#include <stdio.h> + +#ifndef __cplusplus +#ifndef __STDC__ +#define const +#endif +#endif + + + +#define po_gram_FINAL 18 +#define po_gram_FLAG -32768 +#define po_gram_NTBASE 11 + +#define po_gram_TRANSLATE(x) ((unsigned)(x) <= 265 ? po_gram_translate[x] : 18) + +static const char po_gram_translate[] = { 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10 +}; + +#if po_gram_DEBUG != 0 +static const short po_gram_prhs[] = { 0, + 0, 1, 4, 7, 10, 13, 16, 21, 24, 26, + 28, 30, 33 +}; + +static const short po_gram_rhs[] = { -1, + 11, 17, 0, 11, 12, 0, 11, 13, 0, 11, + 1, 0, 4, 10, 0, 14, 16, 15, 16, 0, + 14, 16, 0, 6, 0, 7, 0, 10, 0, 16, + 10, 0, 3, 0 +}; + +#endif + +#if po_gram_DEBUG != 0 +static const short po_gram_rline[] = { 0, + 62, 63, 64, 65, 66, 70, 77, 81, 89, 96, + 103, 107, 122 +}; +#endif + + +#if po_gram_DEBUG != 0 || defined (po_gram_ERROR_VERBOSE) + +static const char * const po_gram_tname[] = { "$","error","$undefined.","COMMENT", +"DOMAIN","JUNK","MSGID","MSGSTR","NAME","NUMBER","STRING","msgfmt","domain", +"message","msgid","msgstr","string_list","comment", NULL +}; +#endif + +static const short po_gram_r1[] = { 0, + 11, 11, 11, 11, 11, 12, 13, 13, 14, 15, + 16, 16, 17 +}; + +static const short po_gram_r2[] = { 0, + 0, 2, 2, 2, 2, 2, 4, 2, 1, 1, + 1, 2, 1 +}; + +static const short po_gram_defact[] = { 1, + 0, 5, 13, 0, 9, 3, 4, 0, 2, 6, + 11, 8, 10, 12, 0, 7, 0, 0 +}; + +static const short po_gram_defgoto[] = { 1, + 6, 7, 8, 15, 12, 9 +}; + +static const short po_gram_pact[] = {-32768, + 0,-32768,-32768, -3,-32768,-32768,-32768, -2,-32768,-32768, +-32768, -5,-32768,-32768, -2, -1, 10,-32768 +}; + +static const short po_gram_pgoto[] = {-32768, +-32768,-32768,-32768,-32768, -4,-32768 +}; + + +#define po_gram_LAST 11 + + +static const short po_gram_table[] = { 17, + 2, 13, 3, 4, 14, 5, 10, 11, 14, 18, + 16 +}; + +static const short po_gram_check[] = { 0, + 1, 7, 3, 4, 10, 6, 10, 10, 10, 0, + 15 +}; +/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +#line 3 "/usr/lib/bison.simple" + +/* Skeleton output parser for bison, + Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +#ifndef alloca +#ifdef __GNUC__ +#define alloca __builtin_alloca +#else /* not GNU C. */ +#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) +#include <alloca.h> +#else /* not sparc */ +#if defined (MSDOS) && !defined (__TURBOC__) +#include <malloc.h> +#else /* not MSDOS, or __TURBOC__ */ +#if defined(_AIX) +#include <malloc.h> + #pragma alloca +#else /* not MSDOS, __TURBOC__, or _AIX */ +#ifdef __hpux +#ifdef __cplusplus +extern "C" { +void *alloca (unsigned int); +}; +#else /* not __cplusplus */ +void *alloca (); +#endif /* not __cplusplus */ +#endif /* __hpux */ +#endif /* not _AIX */ +#endif /* not MSDOS, or __TURBOC__ */ +#endif /* not sparc. */ +#endif /* not GNU C. */ +#endif /* alloca not defined. */ + +/* This is the parser code that is written into each bison parser + when the %semantic_parser declaration is not specified in the grammar. + It was written by Richard Stallman by simplifying the hairy parser + used when %semantic_parser is specified. */ + +/* Note: there must be only one dollar sign in this file. + It is replaced by the list of actions, each action + as one case of the switch. */ + +#define po_gram_errok (po_gram_errstatus = 0) +#define po_gram_clearin (po_gram_char = po_gram_EMPTY) +#define po_gram_EMPTY -2 +#define po_gram_EOF 0 +#define po_gram_ACCEPT return(0) +#define po_gram_ABORT return(1) +#define po_gram_ERROR goto po_gram_errlab1 +/* Like po_gram_ERROR except do call po_gram_error. + This remains here temporarily to ease the + transition to the new meaning of po_gram_ERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ +#define po_gram_FAIL goto po_gram_errlab +#define po_gram_RECOVERING() (!!po_gram_errstatus) +#define po_gram_BACKUP(token, value) \ +do \ + if (po_gram_char == po_gram_EMPTY && po_gram_len == 1) \ + { po_gram_char = (token), po_gram_lval = (value); \ + po_gram_char1 = po_gram_TRANSLATE (po_gram_char); \ + po_gram_POPSTACK; \ + goto po_gram_backup; \ + } \ + else \ + { po_gram_error ("syntax error: cannot back up"); po_gram_ERROR; } \ +while (0) + +#define po_gram_TERROR 1 +#define po_gram_ERRCODE 256 + +#ifndef po_gram_PURE +#define po_gram_LEX po_gram_lex() +#endif + +#ifdef po_gram_PURE +#ifdef po_gram_LSP_NEEDED +#ifdef po_gram_LEX_PARAM +#define po_gram_LEX po_gram_lex(&po_gram_lval, &po_gram_lloc, po_gram_LEX_PARAM) +#else +#define po_gram_LEX po_gram_lex(&po_gram_lval, &po_gram_lloc) +#endif +#else /* not po_gram_LSP_NEEDED */ +#ifdef po_gram_LEX_PARAM +#define po_gram_LEX po_gram_lex(&po_gram_lval, po_gram_LEX_PARAM) +#else +#define po_gram_LEX po_gram_lex(&po_gram_lval) +#endif +#endif /* not po_gram_LSP_NEEDED */ +#endif + +/* If nonreentrant, generate the variables here */ + +#ifndef po_gram_PURE + +int po_gram_char; /* the lookahead symbol */ +po_gram_STYPE po_gram_lval; /* the semantic value of the */ + /* lookahead symbol */ + +#ifdef po_gram_LSP_NEEDED +po_gram_LTYPE po_gram_lloc; /* location data for the lookahead */ + /* symbol */ +#endif + +int po_gram_nerrs; /* number of parse errors so far */ +#endif /* not po_gram_PURE */ + +#if po_gram_DEBUG != 0 +int po_gram_debug; /* nonzero means print parse trace */ +/* Since this is uninitialized, it does not stop multiple parsers + from coexisting. */ +#endif + +/* po_gram_INITDEPTH indicates the initial size of the parser's stacks */ + +#ifndef po_gram_INITDEPTH +#define po_gram_INITDEPTH 200 +#endif + +/* po_gram_MAXDEPTH is the maximum size the stacks can grow to + (effective only if the built-in stack extension method is used). */ + +#if po_gram_MAXDEPTH == 0 +#undef po_gram_MAXDEPTH +#endif + +#ifndef po_gram_MAXDEPTH +#define po_gram_MAXDEPTH 10000 +#endif + +/* Prevent warning if -Wstrict-prototypes. */ +#ifdef __GNUC__ +int po_gram_parse (void); +#endif + +#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +#define __po_gram__memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) +#else /* not GNU C or C++ */ +#ifndef __cplusplus + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__po_gram__memcpy (to, from, count) + char *to; + char *from; + int count; +{ + register char *f = from; + register char *t = to; + register int i = count; + + while (i-- > 0) + *t++ = *f++; +} + +#else /* __cplusplus */ + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__po_gram__memcpy (char *to, char *from, int count) +{ + register char *f = from; + register char *t = to; + register int i = count; + + while (i-- > 0) + *t++ = *f++; +} + +#endif +#endif + +#line 196 "/usr/lib/bison.simple" + +/* The user can define po_gram_PARSE_PARAM as the name of an argument to be passed + into po_gram_parse. The argument should have type void *. + It should actually point to an object. + Grammar actions can access the variable by casting it + to the proper pointer type. */ + +#ifdef po_gram_PARSE_PARAM +#ifdef __cplusplus +#define po_gram_PARSE_PARAM_ARG void *po_gram_PARSE_PARAM +#define po_gram_PARSE_PARAM_DECL +#else /* not __cplusplus */ +#define po_gram_PARSE_PARAM_ARG po_gram_PARSE_PARAM +#define po_gram_PARSE_PARAM_DECL void *po_gram_PARSE_PARAM; +#endif /* not __cplusplus */ +#else /* not po_gram_PARSE_PARAM */ +#define po_gram_PARSE_PARAM_ARG +#define po_gram_PARSE_PARAM_DECL +#endif /* not po_gram_PARSE_PARAM */ + +int +po_gram_parse(po_gram_PARSE_PARAM_ARG) + po_gram_PARSE_PARAM_DECL +{ + register int po_gram_state; + register int po_gram_n; + register short *po_gram_ssp; + register po_gram_STYPE *po_gram_vsp; + int po_gram_errstatus; /* number of tokens to shift before error messages enabled */ + int po_gram_char1 = 0; /* lookahead token as an internal (translated) token number */ + + short po_gram_ssa[po_gram_INITDEPTH]; /* the state stack */ + po_gram_STYPE po_gram_vsa[po_gram_INITDEPTH]; /* the semantic value stack */ + + short *po_gram_ss = po_gram_ssa; /* refer to the stacks thru separate pointers */ + po_gram_STYPE *po_gram_vs = po_gram_vsa; /* to allow po_gram_overflow to reallocate them elsewhere */ + +#ifdef po_gram_LSP_NEEDED + po_gram_LTYPE po_gram_lsa[po_gram_INITDEPTH]; /* the location stack */ + po_gram_LTYPE *po_gram_ls = po_gram_lsa; + po_gram_LTYPE *po_gram_lsp; + +#define po_gram_POPSTACK (po_gram_vsp--, po_gram_ssp--, po_gram_lsp--) +#else +#define po_gram_POPSTACK (po_gram_vsp--, po_gram_ssp--) +#endif + + int po_gram_stacksize = po_gram_INITDEPTH; + +#ifdef po_gram_PURE + int po_gram_char; + po_gram_STYPE po_gram_lval; + int po_gram_nerrs; +#ifdef po_gram_LSP_NEEDED + po_gram_LTYPE po_gram_lloc; +#endif +#endif + + po_gram_STYPE po_gram_val; /* the variable used to return */ + /* semantic values from the action */ + /* routines */ + + int po_gram_len; + +#if po_gram_DEBUG != 0 + if (po_gram_debug) + fprintf(stderr, "Starting parse\n"); +#endif + + po_gram_state = 0; + po_gram_errstatus = 0; + po_gram_nerrs = 0; + po_gram_char = po_gram_EMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + po_gram_ssp = po_gram_ss - 1; + po_gram_vsp = po_gram_vs; +#ifdef po_gram_LSP_NEEDED + po_gram_lsp = po_gram_ls; +#endif + +/* Push a new state, which is found in po_gram_state . */ +/* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. */ +po_gram_newstate: + + *++po_gram_ssp = po_gram_state; + + if (po_gram_ssp >= po_gram_ss + po_gram_stacksize - 1) + { + /* Give user a chance to reallocate the stack */ + /* Use copies of these so that the &'s don't force the real ones into memory. */ + po_gram_STYPE *po_gram_vs1 = po_gram_vs; + short *po_gram_ss1 = po_gram_ss; +#ifdef po_gram_LSP_NEEDED + po_gram_LTYPE *po_gram_ls1 = po_gram_ls; +#endif + + /* Get the current used size of the three stacks, in elements. */ + int size = po_gram_ssp - po_gram_ss + 1; + +#ifdef po_gram_overflow + /* Each stack pointer address is followed by the size of + the data in use in that stack, in bytes. */ +#ifdef po_gram_LSP_NEEDED + /* This used to be a conditional around just the two extra args, + but that might be undefined if po_gram_overflow is a macro. */ + po_gram_overflow("parser stack overflow", + &po_gram_ss1, size * sizeof (*po_gram_ssp), + &po_gram_vs1, size * sizeof (*po_gram_vsp), + &po_gram_ls1, size * sizeof (*po_gram_lsp), + &po_gram_stacksize); +#else + po_gram_overflow("parser stack overflow", + &po_gram_ss1, size * sizeof (*po_gram_ssp), + &po_gram_vs1, size * sizeof (*po_gram_vsp), + &po_gram_stacksize); +#endif + + po_gram_ss = po_gram_ss1; po_gram_vs = po_gram_vs1; +#ifdef po_gram_LSP_NEEDED + po_gram_ls = po_gram_ls1; +#endif +#else /* no po_gram_overflow */ + /* Extend the stack our own way. */ + if (po_gram_stacksize >= po_gram_MAXDEPTH) + { + po_gram_error("parser stack overflow"); + return 2; + } + po_gram_stacksize *= 2; + if (po_gram_stacksize > po_gram_MAXDEPTH) + po_gram_stacksize = po_gram_MAXDEPTH; + po_gram_ss = (short *) alloca (po_gram_stacksize * sizeof (*po_gram_ssp)); + __po_gram__memcpy ((char *)po_gram_ss, (char *)po_gram_ss1, size * sizeof (*po_gram_ssp)); + po_gram_vs = (po_gram_STYPE *) alloca (po_gram_stacksize * sizeof (*po_gram_vsp)); + __po_gram__memcpy ((char *)po_gram_vs, (char *)po_gram_vs1, size * sizeof (*po_gram_vsp)); +#ifdef po_gram_LSP_NEEDED + po_gram_ls = (po_gram_LTYPE *) alloca (po_gram_stacksize * sizeof (*po_gram_lsp)); + __po_gram__memcpy ((char *)po_gram_ls, (char *)po_gram_ls1, size * sizeof (*po_gram_lsp)); +#endif +#endif /* no po_gram_overflow */ + + po_gram_ssp = po_gram_ss + size - 1; + po_gram_vsp = po_gram_vs + size - 1; +#ifdef po_gram_LSP_NEEDED + po_gram_lsp = po_gram_ls + size - 1; +#endif + +#if po_gram_DEBUG != 0 + if (po_gram_debug) + fprintf(stderr, "Stack size increased to %d\n", po_gram_stacksize); +#endif + + if (po_gram_ssp >= po_gram_ss + po_gram_stacksize - 1) + po_gram_ABORT; + } + +#if po_gram_DEBUG != 0 + if (po_gram_debug) + fprintf(stderr, "Entering state %d\n", po_gram_state); +#endif + + goto po_gram_backup; + po_gram_backup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* po_gram_resume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + po_gram_n = po_gram_pact[po_gram_state]; + if (po_gram_n == po_gram_FLAG) + goto po_gram_default; + + /* Not known => get a lookahead token if don't already have one. */ + + /* po_gram_char is either po_gram_EMPTY or po_gram_EOF + or a valid token in external form. */ + + if (po_gram_char == po_gram_EMPTY) + { +#if po_gram_DEBUG != 0 + if (po_gram_debug) + fprintf(stderr, "Reading a token: "); +#endif + po_gram_char = po_gram_LEX; + } + + /* Convert token to internal form (in po_gram_char1) for indexing tables with */ + + if (po_gram_char <= 0) /* This means end of input. */ + { + po_gram_char1 = 0; + po_gram_char = po_gram_EOF; /* Don't call po_gram_LEX any more */ + +#if po_gram_DEBUG != 0 + if (po_gram_debug) + fprintf(stderr, "Now at end of input.\n"); +#endif + } + else + { + po_gram_char1 = po_gram_TRANSLATE(po_gram_char); + +#if po_gram_DEBUG != 0 + if (po_gram_debug) + { + fprintf (stderr, "Next token is %d (%s", po_gram_char, po_gram_tname[po_gram_char1]); + /* Give the individual parser a way to print the precise meaning + of a token, for further debugging info. */ +#ifdef po_gram_PRINT + po_gram_PRINT (stderr, po_gram_char, po_gram_lval); +#endif + fprintf (stderr, ")\n"); + } +#endif + } + + po_gram_n += po_gram_char1; + if (po_gram_n < 0 || po_gram_n > po_gram_LAST || po_gram_check[po_gram_n] != po_gram_char1) + goto po_gram_default; + + po_gram_n = po_gram_table[po_gram_n]; + + /* po_gram_n is what to do for this token type in this state. + Negative => reduce, -po_gram_n is rule number. + Positive => shift, po_gram_n is new state. + New state is final state => don't bother to shift, + just return success. + 0, or most negative number => error. */ + + if (po_gram_n < 0) + { + if (po_gram_n == po_gram_FLAG) + goto po_gram_errlab; + po_gram_n = -po_gram_n; + goto po_gram_reduce; + } + else if (po_gram_n == 0) + goto po_gram_errlab; + + if (po_gram_n == po_gram_FINAL) + po_gram_ACCEPT; + + /* Shift the lookahead token. */ + +#if po_gram_DEBUG != 0 + if (po_gram_debug) + fprintf(stderr, "Shifting token %d (%s), ", po_gram_char, po_gram_tname[po_gram_char1]); +#endif + + /* Discard the token being shifted unless it is eof. */ + if (po_gram_char != po_gram_EOF) + po_gram_char = po_gram_EMPTY; + + *++po_gram_vsp = po_gram_lval; +#ifdef po_gram_LSP_NEEDED + *++po_gram_lsp = po_gram_lloc; +#endif + + /* count tokens shifted since error; after three, turn off error status. */ + if (po_gram_errstatus) po_gram_errstatus--; + + po_gram_state = po_gram_n; + goto po_gram_newstate; + +/* Do the default action for the current state. */ +po_gram_default: + + po_gram_n = po_gram_defact[po_gram_state]; + if (po_gram_n == 0) + goto po_gram_errlab; + +/* Do a reduction. po_gram_n is the number of a rule to reduce with. */ +po_gram_reduce: + po_gram_len = po_gram_r2[po_gram_n]; + if (po_gram_len > 0) + po_gram_val = po_gram_vsp[1-po_gram_len]; /* implement default value of the action */ + +#if po_gram_DEBUG != 0 + if (po_gram_debug) + { + int i; + + fprintf (stderr, "Reducing via rule %d (line %d), ", + po_gram_n, po_gram_rline[po_gram_n]); + + /* Print the symbols being reduced, and their result. */ + for (i = po_gram_prhs[po_gram_n]; po_gram_rhs[i] > 0; i++) + fprintf (stderr, "%s ", po_gram_tname[po_gram_rhs[i]]); + fprintf (stderr, " -> %s\n", po_gram_tname[po_gram_r1[po_gram_n]]); + } +#endif + + + switch (po_gram_n) { + +case 6: +#line 71 "../../src/po-gram.y" +{ + po_callback_domain (po_gram_vsp[0].string); + ; + break;} +case 7: +#line 78 "../../src/po-gram.y" +{ + po_callback_message (po_gram_vsp[-2].string, &po_gram_vsp[-3].pos, po_gram_vsp[0].string, &po_gram_vsp[-1].pos); + ; + break;} +case 8: +#line 82 "../../src/po-gram.y" +{ + gram_error_at_line (&po_gram_vsp[-1].pos, _("missing `msgstr' section")); + free (po_gram_vsp[0].string); + ; + break;} +case 9: +#line 90 "../../src/po-gram.y" +{ + po_gram_val.pos = gram_pos; + ; + break;} +case 10: +#line 97 "../../src/po-gram.y" +{ + po_gram_val.pos = gram_pos; + ; + break;} +case 11: +#line 104 "../../src/po-gram.y" +{ + po_gram_val.string = po_gram_vsp[0].string; + ; + break;} +case 12: +#line 108 "../../src/po-gram.y" +{ + size_t len1; + size_t len2; + + len1 = strlen (po_gram_vsp[-1].string); + len2 = strlen (po_gram_vsp[0].string); + po_gram_val.string = (char *) xmalloc (len1 + len2 + 1); + stpcpy (stpcpy (po_gram_val.string, po_gram_vsp[-1].string), po_gram_vsp[0].string); + free (po_gram_vsp[-1].string); + free (po_gram_vsp[0].string); + ; + break;} +case 13: +#line 123 "../../src/po-gram.y" +{ + po_callback_comment (po_gram_vsp[0].string); + ; + break;} +} + /* the action file gets copied in in place of this dollarsign */ +#line 498 "/usr/lib/bison.simple" + + po_gram_vsp -= po_gram_len; + po_gram_ssp -= po_gram_len; +#ifdef po_gram_LSP_NEEDED + po_gram_lsp -= po_gram_len; +#endif + +#if po_gram_DEBUG != 0 + if (po_gram_debug) + { + short *ssp1 = po_gram_ss - 1; + fprintf (stderr, "state stack now"); + while (ssp1 != po_gram_ssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif + + *++po_gram_vsp = po_gram_val; + +#ifdef po_gram_LSP_NEEDED + po_gram_lsp++; + if (po_gram_len == 0) + { + po_gram_lsp->first_line = po_gram_lloc.first_line; + po_gram_lsp->first_column = po_gram_lloc.first_column; + po_gram_lsp->last_line = (po_gram_lsp-1)->last_line; + po_gram_lsp->last_column = (po_gram_lsp-1)->last_column; + po_gram_lsp->text = 0; + } + else + { + po_gram_lsp->last_line = (po_gram_lsp+po_gram_len-1)->last_line; + po_gram_lsp->last_column = (po_gram_lsp+po_gram_len-1)->last_column; + } +#endif + + /* Now "shift" the result of the reduction. + Determine what state that goes to, + based on the state we popped back to + and the rule number reduced by. */ + + po_gram_n = po_gram_r1[po_gram_n]; + + po_gram_state = po_gram_pgoto[po_gram_n - po_gram_NTBASE] + *po_gram_ssp; + if (po_gram_state >= 0 && po_gram_state <= po_gram_LAST && po_gram_check[po_gram_state] == *po_gram_ssp) + po_gram_state = po_gram_table[po_gram_state]; + else + po_gram_state = po_gram_defgoto[po_gram_n - po_gram_NTBASE]; + + goto po_gram_newstate; + +po_gram_errlab: /* here on detecting error */ + + if (! po_gram_errstatus) + /* If not already recovering from an error, report this error. */ + { + ++po_gram_nerrs; + +#ifdef po_gram_ERROR_VERBOSE + po_gram_n = po_gram_pact[po_gram_state]; + + if (po_gram_n > po_gram_FLAG && po_gram_n < po_gram_LAST) + { + int size = 0; + char *msg; + int x, count; + + count = 0; + /* Start X at -po_gram_n if nec to avoid negative indexes in po_gram_check. */ + for (x = (po_gram_n < 0 ? -po_gram_n : 0); + x < (sizeof(po_gram_tname) / sizeof(char *)); x++) + if (po_gram_check[x + po_gram_n] == x) + size += strlen(po_gram_tname[x]) + 15, count++; + msg = (char *) malloc(size + 15); + if (msg != 0) + { + strcpy(msg, "parse error"); + + if (count < 5) + { + count = 0; + for (x = (po_gram_n < 0 ? -po_gram_n : 0); + x < (sizeof(po_gram_tname) / sizeof(char *)); x++) + if (po_gram_check[x + po_gram_n] == x) + { + strcat(msg, count == 0 ? ", expecting `" : " or `"); + strcat(msg, po_gram_tname[x]); + strcat(msg, "'"); + count++; + } + } + po_gram_error(msg); + free(msg); + } + else + po_gram_error ("parse error; also virtual memory exceeded"); + } + else +#endif /* po_gram_ERROR_VERBOSE */ + po_gram_error("parse error"); + } + + goto po_gram_errlab1; +po_gram_errlab1: /* here on error raised explicitly by an action */ + + if (po_gram_errstatus == 3) + { + /* if just tried and failed to reuse lookahead token after an error, discard it. */ + + /* return failure if at end of input */ + if (po_gram_char == po_gram_EOF) + po_gram_ABORT; + +#if po_gram_DEBUG != 0 + if (po_gram_debug) + fprintf(stderr, "Discarding token %d (%s).\n", po_gram_char, po_gram_tname[po_gram_char1]); +#endif + + po_gram_char = po_gram_EMPTY; + } + + /* Else will try to reuse lookahead token + after shifting the error token. */ + + po_gram_errstatus = 3; /* Each real token shifted decrements this */ + + goto po_gram_errhandle; + +po_gram_errdefault: /* current state does not do anything special for the error token. */ + +#if 0 + /* This is wrong; only states that explicitly want error tokens + should shift them. */ + po_gram_n = po_gram_defact[po_gram_state]; /* If its default is to accept any token, ok. Otherwise pop it.*/ + if (po_gram_n) goto po_gram_default; +#endif + +po_gram_errpop: /* pop the current state because it cannot handle the error token */ + + if (po_gram_ssp == po_gram_ss) po_gram_ABORT; + po_gram_vsp--; + po_gram_state = *--po_gram_ssp; +#ifdef po_gram_LSP_NEEDED + po_gram_lsp--; +#endif + +#if po_gram_DEBUG != 0 + if (po_gram_debug) + { + short *ssp1 = po_gram_ss - 1; + fprintf (stderr, "Error: state stack now"); + while (ssp1 != po_gram_ssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif + +po_gram_errhandle: + + po_gram_n = po_gram_pact[po_gram_state]; + if (po_gram_n == po_gram_FLAG) + goto po_gram_errdefault; + + po_gram_n += po_gram_TERROR; + if (po_gram_n < 0 || po_gram_n > po_gram_LAST || po_gram_check[po_gram_n] != po_gram_TERROR) + goto po_gram_errdefault; + + po_gram_n = po_gram_table[po_gram_n]; + if (po_gram_n < 0) + { + if (po_gram_n == po_gram_FLAG) + goto po_gram_errpop; + po_gram_n = -po_gram_n; + goto po_gram_reduce; + } + else if (po_gram_n == 0) + goto po_gram_errpop; + + if (po_gram_n == po_gram_FINAL) + po_gram_ACCEPT; + +#if po_gram_DEBUG != 0 + if (po_gram_debug) + fprintf(stderr, "Shifting error token, "); +#endif + + *++po_gram_vsp = po_gram_lval; +#ifdef po_gram_LSP_NEEDED + *++po_gram_lsp = po_gram_lloc; +#endif + + po_gram_state = po_gram_n; + goto po_gram_newstate; +} +#line 127 "../../src/po-gram.y" diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/po-gram.gen.h b/debian/gettext-kde/gettext-kde-0.10.35/src/po-gram.gen.h new file mode 100644 index 00000000..690eb304 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/po-gram.gen.h @@ -0,0 +1,17 @@ +typedef union +{ + char *string; + long number; + lex_pos_ty pos; +} po_gram_STYPE; +#define COMMENT 258 +#define DOMAIN 259 +#define JUNK 260 +#define MSGID 261 +#define MSGSTR 262 +#define NAME 263 +#define NUMBER 264 +#define STRING 265 + + +extern po_gram_STYPE po_gram_lval; diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/po-gram.h b/debian/gettext-kde/gettext-kde-0.10.35/src/po-gram.h new file mode 100644 index 00000000..11c62226 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/po-gram.h @@ -0,0 +1,28 @@ +/* GNU gettext - internationalization aids + Copyright (C) 1995 Free Software Foundation, Inc. + + This file was written by Peter Miller <[email protected]> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef _PO_GRAM_H +#define _PO_GRAM_H + +/* Include some fundamental headers. */ +#include <sys/types.h> + +int po_gram_parse PARAMS ((void)); + +#endif diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/po-gram.y b/debian/gettext-kde/gettext-kde-0.10.35/src/po-gram.y new file mode 100644 index 00000000..f4436198 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/po-gram.y @@ -0,0 +1,126 @@ +/* GNU gettext - internationalization aids + Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc. + + This file was written by Peter Miller <[email protected]> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +%{ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdio.h> + +#include "po-lex.h" +#include "po-gram.h" +#include "error.h" +#include "system.h" +#include <libintl.h> +#include "po.h" + +#define _(str) gettext (str) +%} + +%token COMMENT +%token DOMAIN +%token JUNK +%token MSGID +%token MSGSTR +%token NAME +%token NUMBER +%token STRING + +%union +{ + char *string; + long number; + lex_pos_ty pos; +} + +%type <string> STRING COMMENT string_list +%type <number> NUMBER +%type <pos> msgid msgstr + +%right MSGSTR + +%% + +msgfmt + : /* empty */ + | msgfmt comment + | msgfmt domain + | msgfmt message + | msgfmt error + ; + +domain + : DOMAIN STRING + { + po_callback_domain ($2); + } + ; + +message + : msgid string_list msgstr string_list + { + po_callback_message ($2, &$1, $4, &$3); + } + | msgid string_list + { + gram_error_at_line (&$1, _("missing `msgstr' section")); + free ($2); + } + ; + +msgid + : MSGID + { + $$ = gram_pos; + } + ; + +msgstr + : MSGSTR + { + $$ = gram_pos; + } + ; + +string_list + : STRING + { + $$ = $1; + } + | string_list STRING + { + size_t len1; + size_t len2; + + len1 = strlen ($1); + len2 = strlen ($2); + $$ = (char *) xmalloc (len1 + len2 + 1); + stpcpy (stpcpy ($$, $1), $2); + free ($1); + free ($2); + } + ; + +comment + : COMMENT + { + po_callback_comment ($1); + } + ; diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/po-hash.gen.c b/debian/gettext-kde/gettext-kde-0.10.35/src/po-hash.gen.c new file mode 100644 index 00000000..b7ded1b8 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/po-hash.gen.c @@ -0,0 +1,1022 @@ + +/* A Bison parser, made from ../../src/po-hash.y + by GNU Bison version 1.25 + */ + +#define po_hash_BISON 1 /* Identify Bison output. */ + +#define STRING 258 +#define NUMBER 259 +#define COLON 260 +#define COMMA 261 +#define FILE_KEYWORD 262 +#define LINE_KEYWORD 263 +#define NUMBER_KEYWORD 264 + +#line 20 "../../src/po-hash.y" + + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdio.h> + +#include <system.h> +#include "po-hash.h" +#include "po.h" + + +#line 42 "../../src/po-hash.y" +typedef union +{ + char *string; + int number; +} po_hash_STYPE; +#line 51 "../../src/po-hash.y" + + +static const char *cur; + + +void po_hash_error PARAMS ((char *)); +int po_hash_lex PARAMS ((void)); + + +int +po_hash (s) + const char *s; +{ + extern int po_hash_parse PARAMS ((void)); + + cur = s; + return po_hash_parse (); +} + + +void +po_hash_error (s) + char *s; +{ + /* Do nothing, the grammar is used as a recogniser. */ +} +#include <stdio.h> + +#ifndef __cplusplus +#ifndef __STDC__ +#define const +#endif +#endif + + + +#define po_hash_FINAL 18 +#define po_hash_FLAG -32768 +#define po_hash_NTBASE 10 + +#define po_hash_TRANSLATE(x) ((unsigned)(x) <= 264 ? po_hash_translate[x] : 12) + +static const char po_hash_translate[] = { 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, + 6, 7, 8, 9 +}; + +#if po_hash_DEBUG != 0 +static const short po_hash_prhs[] = { 0, + 0, 1, 4, 8, 16, 25 +}; + +static const short po_hash_rhs[] = { -1, + 10, 11, 0, 3, 5, 4, 0, 7, 5, 3, + 6, 8, 5, 4, 0, 7, 5, 3, 6, 8, + 9, 5, 4, 0, 7, 5, 4, 0 +}; + +#endif + +#if po_hash_DEBUG != 0 +static const short po_hash_rline[] = { 0, + 82, 83, 87, 93, 99, 105 +}; +#endif + + +#if po_hash_DEBUG != 0 || defined (po_hash_ERROR_VERBOSE) + +static const char * const po_hash_tname[] = { "$","error","$undefined.","STRING", +"NUMBER","COLON","COMMA","FILE_KEYWORD","LINE_KEYWORD","NUMBER_KEYWORD","filepos_line", +"filepos", NULL +}; +#endif + +static const short po_hash_r1[] = { 0, + 10, 10, 11, 11, 11, 11 +}; + +static const short po_hash_r2[] = { 0, + 0, 2, 3, 7, 8, 3 +}; + +static const short po_hash_defact[] = { 1, + 0, 0, 0, 2, 0, 0, 3, 0, 6, 0, + 0, 0, 0, 4, 0, 5, 0, 0 +}; + +static const short po_hash_defgoto[] = { 1, + 4 +}; + +static const short po_hash_pact[] = {-32768, + 0, -3, -1,-32768, 2, 5,-32768, 4,-32768, 3, + -4, 8, 9,-32768, 11,-32768, 13,-32768 +}; + +static const short po_hash_pgoto[] = {-32768, +-32768 +}; + + +#define po_hash_LAST 15 + + +static const short po_hash_table[] = { 17, + 12, 5, 2, 6, 13, 7, 3, 8, 9, 10, + 11, 14, 18, 15, 16 +}; + +static const short po_hash_check[] = { 0, + 5, 5, 3, 5, 9, 4, 7, 3, 4, 6, + 8, 4, 0, 5, 4 +}; +/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +#line 3 "/usr/lib/bison.simple" + +/* Skeleton output parser for bison, + Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +#ifndef alloca +#ifdef __GNUC__ +#define alloca __builtin_alloca +#else /* not GNU C. */ +#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) +#include <alloca.h> +#else /* not sparc */ +#if defined (MSDOS) && !defined (__TURBOC__) +#include <malloc.h> +#else /* not MSDOS, or __TURBOC__ */ +#if defined(_AIX) +#include <malloc.h> + #pragma alloca +#else /* not MSDOS, __TURBOC__, or _AIX */ +#ifdef __hpux +#ifdef __cplusplus +extern "C" { +void *alloca (unsigned int); +}; +#else /* not __cplusplus */ +void *alloca (); +#endif /* not __cplusplus */ +#endif /* __hpux */ +#endif /* not _AIX */ +#endif /* not MSDOS, or __TURBOC__ */ +#endif /* not sparc. */ +#endif /* not GNU C. */ +#endif /* alloca not defined. */ + +/* This is the parser code that is written into each bison parser + when the %semantic_parser declaration is not specified in the grammar. + It was written by Richard Stallman by simplifying the hairy parser + used when %semantic_parser is specified. */ + +/* Note: there must be only one dollar sign in this file. + It is replaced by the list of actions, each action + as one case of the switch. */ + +#define po_hash_errok (po_hash_errstatus = 0) +#define po_hash_clearin (po_hash_char = po_hash_EMPTY) +#define po_hash_EMPTY -2 +#define po_hash_EOF 0 +#define po_hash_ACCEPT return(0) +#define po_hash_ABORT return(1) +#define po_hash_ERROR goto po_hash_errlab1 +/* Like po_hash_ERROR except do call po_hash_error. + This remains here temporarily to ease the + transition to the new meaning of po_hash_ERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ +#define po_hash_FAIL goto po_hash_errlab +#define po_hash_RECOVERING() (!!po_hash_errstatus) +#define po_hash_BACKUP(token, value) \ +do \ + if (po_hash_char == po_hash_EMPTY && po_hash_len == 1) \ + { po_hash_char = (token), po_hash_lval = (value); \ + po_hash_char1 = po_hash_TRANSLATE (po_hash_char); \ + po_hash_POPSTACK; \ + goto po_hash_backup; \ + } \ + else \ + { po_hash_error ("syntax error: cannot back up"); po_hash_ERROR; } \ +while (0) + +#define po_hash_TERROR 1 +#define po_hash_ERRCODE 256 + +#ifndef po_hash_PURE +#define po_hash_LEX po_hash_lex() +#endif + +#ifdef po_hash_PURE +#ifdef po_hash_LSP_NEEDED +#ifdef po_hash_LEX_PARAM +#define po_hash_LEX po_hash_lex(&po_hash_lval, &po_hash_lloc, po_hash_LEX_PARAM) +#else +#define po_hash_LEX po_hash_lex(&po_hash_lval, &po_hash_lloc) +#endif +#else /* not po_hash_LSP_NEEDED */ +#ifdef po_hash_LEX_PARAM +#define po_hash_LEX po_hash_lex(&po_hash_lval, po_hash_LEX_PARAM) +#else +#define po_hash_LEX po_hash_lex(&po_hash_lval) +#endif +#endif /* not po_hash_LSP_NEEDED */ +#endif + +/* If nonreentrant, generate the variables here */ + +#ifndef po_hash_PURE + +int po_hash_char; /* the lookahead symbol */ +po_hash_STYPE po_hash_lval; /* the semantic value of the */ + /* lookahead symbol */ + +#ifdef po_hash_LSP_NEEDED +po_hash_LTYPE po_hash_lloc; /* location data for the lookahead */ + /* symbol */ +#endif + +int po_hash_nerrs; /* number of parse errors so far */ +#endif /* not po_hash_PURE */ + +#if po_hash_DEBUG != 0 +int po_hash_debug; /* nonzero means print parse trace */ +/* Since this is uninitialized, it does not stop multiple parsers + from coexisting. */ +#endif + +/* po_hash_INITDEPTH indicates the initial size of the parser's stacks */ + +#ifndef po_hash_INITDEPTH +#define po_hash_INITDEPTH 200 +#endif + +/* po_hash_MAXDEPTH is the maximum size the stacks can grow to + (effective only if the built-in stack extension method is used). */ + +#if po_hash_MAXDEPTH == 0 +#undef po_hash_MAXDEPTH +#endif + +#ifndef po_hash_MAXDEPTH +#define po_hash_MAXDEPTH 10000 +#endif + +/* Prevent warning if -Wstrict-prototypes. */ +#ifdef __GNUC__ +int po_hash_parse (void); +#endif + +#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +#define __po_hash__memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) +#else /* not GNU C or C++ */ +#ifndef __cplusplus + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__po_hash__memcpy (to, from, count) + char *to; + char *from; + int count; +{ + register char *f = from; + register char *t = to; + register int i = count; + + while (i-- > 0) + *t++ = *f++; +} + +#else /* __cplusplus */ + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__po_hash__memcpy (char *to, char *from, int count) +{ + register char *f = from; + register char *t = to; + register int i = count; + + while (i-- > 0) + *t++ = *f++; +} + +#endif +#endif + +#line 196 "/usr/lib/bison.simple" + +/* The user can define po_hash_PARSE_PARAM as the name of an argument to be passed + into po_hash_parse. The argument should have type void *. + It should actually point to an object. + Grammar actions can access the variable by casting it + to the proper pointer type. */ + +#ifdef po_hash_PARSE_PARAM +#ifdef __cplusplus +#define po_hash_PARSE_PARAM_ARG void *po_hash_PARSE_PARAM +#define po_hash_PARSE_PARAM_DECL +#else /* not __cplusplus */ +#define po_hash_PARSE_PARAM_ARG po_hash_PARSE_PARAM +#define po_hash_PARSE_PARAM_DECL void *po_hash_PARSE_PARAM; +#endif /* not __cplusplus */ +#else /* not po_hash_PARSE_PARAM */ +#define po_hash_PARSE_PARAM_ARG +#define po_hash_PARSE_PARAM_DECL +#endif /* not po_hash_PARSE_PARAM */ + +int +po_hash_parse(po_hash_PARSE_PARAM_ARG) + po_hash_PARSE_PARAM_DECL +{ + register int po_hash_state; + register int po_hash_n; + register short *po_hash_ssp; + register po_hash_STYPE *po_hash_vsp; + int po_hash_errstatus; /* number of tokens to shift before error messages enabled */ + int po_hash_char1 = 0; /* lookahead token as an internal (translated) token number */ + + short po_hash_ssa[po_hash_INITDEPTH]; /* the state stack */ + po_hash_STYPE po_hash_vsa[po_hash_INITDEPTH]; /* the semantic value stack */ + + short *po_hash_ss = po_hash_ssa; /* refer to the stacks thru separate pointers */ + po_hash_STYPE *po_hash_vs = po_hash_vsa; /* to allow po_hash_overflow to reallocate them elsewhere */ + +#ifdef po_hash_LSP_NEEDED + po_hash_LTYPE po_hash_lsa[po_hash_INITDEPTH]; /* the location stack */ + po_hash_LTYPE *po_hash_ls = po_hash_lsa; + po_hash_LTYPE *po_hash_lsp; + +#define po_hash_POPSTACK (po_hash_vsp--, po_hash_ssp--, po_hash_lsp--) +#else +#define po_hash_POPSTACK (po_hash_vsp--, po_hash_ssp--) +#endif + + int po_hash_stacksize = po_hash_INITDEPTH; + +#ifdef po_hash_PURE + int po_hash_char; + po_hash_STYPE po_hash_lval; + int po_hash_nerrs; +#ifdef po_hash_LSP_NEEDED + po_hash_LTYPE po_hash_lloc; +#endif +#endif + + po_hash_STYPE po_hash_val; /* the variable used to return */ + /* semantic values from the action */ + /* routines */ + + int po_hash_len; + +#if po_hash_DEBUG != 0 + if (po_hash_debug) + fprintf(stderr, "Starting parse\n"); +#endif + + po_hash_state = 0; + po_hash_errstatus = 0; + po_hash_nerrs = 0; + po_hash_char = po_hash_EMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + po_hash_ssp = po_hash_ss - 1; + po_hash_vsp = po_hash_vs; +#ifdef po_hash_LSP_NEEDED + po_hash_lsp = po_hash_ls; +#endif + +/* Push a new state, which is found in po_hash_state . */ +/* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. */ +po_hash_newstate: + + *++po_hash_ssp = po_hash_state; + + if (po_hash_ssp >= po_hash_ss + po_hash_stacksize - 1) + { + /* Give user a chance to reallocate the stack */ + /* Use copies of these so that the &'s don't force the real ones into memory. */ + po_hash_STYPE *po_hash_vs1 = po_hash_vs; + short *po_hash_ss1 = po_hash_ss; +#ifdef po_hash_LSP_NEEDED + po_hash_LTYPE *po_hash_ls1 = po_hash_ls; +#endif + + /* Get the current used size of the three stacks, in elements. */ + int size = po_hash_ssp - po_hash_ss + 1; + +#ifdef po_hash_overflow + /* Each stack pointer address is followed by the size of + the data in use in that stack, in bytes. */ +#ifdef po_hash_LSP_NEEDED + /* This used to be a conditional around just the two extra args, + but that might be undefined if po_hash_overflow is a macro. */ + po_hash_overflow("parser stack overflow", + &po_hash_ss1, size * sizeof (*po_hash_ssp), + &po_hash_vs1, size * sizeof (*po_hash_vsp), + &po_hash_ls1, size * sizeof (*po_hash_lsp), + &po_hash_stacksize); +#else + po_hash_overflow("parser stack overflow", + &po_hash_ss1, size * sizeof (*po_hash_ssp), + &po_hash_vs1, size * sizeof (*po_hash_vsp), + &po_hash_stacksize); +#endif + + po_hash_ss = po_hash_ss1; po_hash_vs = po_hash_vs1; +#ifdef po_hash_LSP_NEEDED + po_hash_ls = po_hash_ls1; +#endif +#else /* no po_hash_overflow */ + /* Extend the stack our own way. */ + if (po_hash_stacksize >= po_hash_MAXDEPTH) + { + po_hash_error("parser stack overflow"); + return 2; + } + po_hash_stacksize *= 2; + if (po_hash_stacksize > po_hash_MAXDEPTH) + po_hash_stacksize = po_hash_MAXDEPTH; + po_hash_ss = (short *) alloca (po_hash_stacksize * sizeof (*po_hash_ssp)); + __po_hash__memcpy ((char *)po_hash_ss, (char *)po_hash_ss1, size * sizeof (*po_hash_ssp)); + po_hash_vs = (po_hash_STYPE *) alloca (po_hash_stacksize * sizeof (*po_hash_vsp)); + __po_hash__memcpy ((char *)po_hash_vs, (char *)po_hash_vs1, size * sizeof (*po_hash_vsp)); +#ifdef po_hash_LSP_NEEDED + po_hash_ls = (po_hash_LTYPE *) alloca (po_hash_stacksize * sizeof (*po_hash_lsp)); + __po_hash__memcpy ((char *)po_hash_ls, (char *)po_hash_ls1, size * sizeof (*po_hash_lsp)); +#endif +#endif /* no po_hash_overflow */ + + po_hash_ssp = po_hash_ss + size - 1; + po_hash_vsp = po_hash_vs + size - 1; +#ifdef po_hash_LSP_NEEDED + po_hash_lsp = po_hash_ls + size - 1; +#endif + +#if po_hash_DEBUG != 0 + if (po_hash_debug) + fprintf(stderr, "Stack size increased to %d\n", po_hash_stacksize); +#endif + + if (po_hash_ssp >= po_hash_ss + po_hash_stacksize - 1) + po_hash_ABORT; + } + +#if po_hash_DEBUG != 0 + if (po_hash_debug) + fprintf(stderr, "Entering state %d\n", po_hash_state); +#endif + + goto po_hash_backup; + po_hash_backup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* po_hash_resume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + po_hash_n = po_hash_pact[po_hash_state]; + if (po_hash_n == po_hash_FLAG) + goto po_hash_default; + + /* Not known => get a lookahead token if don't already have one. */ + + /* po_hash_char is either po_hash_EMPTY or po_hash_EOF + or a valid token in external form. */ + + if (po_hash_char == po_hash_EMPTY) + { +#if po_hash_DEBUG != 0 + if (po_hash_debug) + fprintf(stderr, "Reading a token: "); +#endif + po_hash_char = po_hash_LEX; + } + + /* Convert token to internal form (in po_hash_char1) for indexing tables with */ + + if (po_hash_char <= 0) /* This means end of input. */ + { + po_hash_char1 = 0; + po_hash_char = po_hash_EOF; /* Don't call po_hash_LEX any more */ + +#if po_hash_DEBUG != 0 + if (po_hash_debug) + fprintf(stderr, "Now at end of input.\n"); +#endif + } + else + { + po_hash_char1 = po_hash_TRANSLATE(po_hash_char); + +#if po_hash_DEBUG != 0 + if (po_hash_debug) + { + fprintf (stderr, "Next token is %d (%s", po_hash_char, po_hash_tname[po_hash_char1]); + /* Give the individual parser a way to print the precise meaning + of a token, for further debugging info. */ +#ifdef po_hash_PRINT + po_hash_PRINT (stderr, po_hash_char, po_hash_lval); +#endif + fprintf (stderr, ")\n"); + } +#endif + } + + po_hash_n += po_hash_char1; + if (po_hash_n < 0 || po_hash_n > po_hash_LAST || po_hash_check[po_hash_n] != po_hash_char1) + goto po_hash_default; + + po_hash_n = po_hash_table[po_hash_n]; + + /* po_hash_n is what to do for this token type in this state. + Negative => reduce, -po_hash_n is rule number. + Positive => shift, po_hash_n is new state. + New state is final state => don't bother to shift, + just return success. + 0, or most negative number => error. */ + + if (po_hash_n < 0) + { + if (po_hash_n == po_hash_FLAG) + goto po_hash_errlab; + po_hash_n = -po_hash_n; + goto po_hash_reduce; + } + else if (po_hash_n == 0) + goto po_hash_errlab; + + if (po_hash_n == po_hash_FINAL) + po_hash_ACCEPT; + + /* Shift the lookahead token. */ + +#if po_hash_DEBUG != 0 + if (po_hash_debug) + fprintf(stderr, "Shifting token %d (%s), ", po_hash_char, po_hash_tname[po_hash_char1]); +#endif + + /* Discard the token being shifted unless it is eof. */ + if (po_hash_char != po_hash_EOF) + po_hash_char = po_hash_EMPTY; + + *++po_hash_vsp = po_hash_lval; +#ifdef po_hash_LSP_NEEDED + *++po_hash_lsp = po_hash_lloc; +#endif + + /* count tokens shifted since error; after three, turn off error status. */ + if (po_hash_errstatus) po_hash_errstatus--; + + po_hash_state = po_hash_n; + goto po_hash_newstate; + +/* Do the default action for the current state. */ +po_hash_default: + + po_hash_n = po_hash_defact[po_hash_state]; + if (po_hash_n == 0) + goto po_hash_errlab; + +/* Do a reduction. po_hash_n is the number of a rule to reduce with. */ +po_hash_reduce: + po_hash_len = po_hash_r2[po_hash_n]; + if (po_hash_len > 0) + po_hash_val = po_hash_vsp[1-po_hash_len]; /* implement default value of the action */ + +#if po_hash_DEBUG != 0 + if (po_hash_debug) + { + int i; + + fprintf (stderr, "Reducing via rule %d (line %d), ", + po_hash_n, po_hash_rline[po_hash_n]); + + /* Print the symbols being reduced, and their result. */ + for (i = po_hash_prhs[po_hash_n]; po_hash_rhs[i] > 0; i++) + fprintf (stderr, "%s ", po_hash_tname[po_hash_rhs[i]]); + fprintf (stderr, " -> %s\n", po_hash_tname[po_hash_r1[po_hash_n]]); + } +#endif + + + switch (po_hash_n) { + +case 3: +#line 88 "../../src/po-hash.y" +{ + /* GNU style */ + po_callback_comment_filepos (po_hash_vsp[-2].string, po_hash_vsp[0].number); + free (po_hash_vsp[-2].string); + ; + break;} +case 4: +#line 94 "../../src/po-hash.y" +{ + /* SunOS style */ + po_callback_comment_filepos (po_hash_vsp[-4].string, po_hash_vsp[0].number); + free (po_hash_vsp[-4].string); + ; + break;} +case 5: +#line 100 "../../src/po-hash.y" +{ + /* Solaris style */ + po_callback_comment_filepos (po_hash_vsp[-5].string, po_hash_vsp[0].number); + free (po_hash_vsp[-5].string); + ; + break;} +case 6: +#line 106 "../../src/po-hash.y" +{ + /* GNU style, but STRING is `file'. Esoteric, but it + happened. */ + po_callback_comment_filepos ("file", po_hash_vsp[0].number); + ; + break;} +} + /* the action file gets copied in in place of this dollarsign */ +#line 498 "/usr/lib/bison.simple" + + po_hash_vsp -= po_hash_len; + po_hash_ssp -= po_hash_len; +#ifdef po_hash_LSP_NEEDED + po_hash_lsp -= po_hash_len; +#endif + +#if po_hash_DEBUG != 0 + if (po_hash_debug) + { + short *ssp1 = po_hash_ss - 1; + fprintf (stderr, "state stack now"); + while (ssp1 != po_hash_ssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif + + *++po_hash_vsp = po_hash_val; + +#ifdef po_hash_LSP_NEEDED + po_hash_lsp++; + if (po_hash_len == 0) + { + po_hash_lsp->first_line = po_hash_lloc.first_line; + po_hash_lsp->first_column = po_hash_lloc.first_column; + po_hash_lsp->last_line = (po_hash_lsp-1)->last_line; + po_hash_lsp->last_column = (po_hash_lsp-1)->last_column; + po_hash_lsp->text = 0; + } + else + { + po_hash_lsp->last_line = (po_hash_lsp+po_hash_len-1)->last_line; + po_hash_lsp->last_column = (po_hash_lsp+po_hash_len-1)->last_column; + } +#endif + + /* Now "shift" the result of the reduction. + Determine what state that goes to, + based on the state we popped back to + and the rule number reduced by. */ + + po_hash_n = po_hash_r1[po_hash_n]; + + po_hash_state = po_hash_pgoto[po_hash_n - po_hash_NTBASE] + *po_hash_ssp; + if (po_hash_state >= 0 && po_hash_state <= po_hash_LAST && po_hash_check[po_hash_state] == *po_hash_ssp) + po_hash_state = po_hash_table[po_hash_state]; + else + po_hash_state = po_hash_defgoto[po_hash_n - po_hash_NTBASE]; + + goto po_hash_newstate; + +po_hash_errlab: /* here on detecting error */ + + if (! po_hash_errstatus) + /* If not already recovering from an error, report this error. */ + { + ++po_hash_nerrs; + +#ifdef po_hash_ERROR_VERBOSE + po_hash_n = po_hash_pact[po_hash_state]; + + if (po_hash_n > po_hash_FLAG && po_hash_n < po_hash_LAST) + { + int size = 0; + char *msg; + int x, count; + + count = 0; + /* Start X at -po_hash_n if nec to avoid negative indexes in po_hash_check. */ + for (x = (po_hash_n < 0 ? -po_hash_n : 0); + x < (sizeof(po_hash_tname) / sizeof(char *)); x++) + if (po_hash_check[x + po_hash_n] == x) + size += strlen(po_hash_tname[x]) + 15, count++; + msg = (char *) malloc(size + 15); + if (msg != 0) + { + strcpy(msg, "parse error"); + + if (count < 5) + { + count = 0; + for (x = (po_hash_n < 0 ? -po_hash_n : 0); + x < (sizeof(po_hash_tname) / sizeof(char *)); x++) + if (po_hash_check[x + po_hash_n] == x) + { + strcat(msg, count == 0 ? ", expecting `" : " or `"); + strcat(msg, po_hash_tname[x]); + strcat(msg, "'"); + count++; + } + } + po_hash_error(msg); + free(msg); + } + else + po_hash_error ("parse error; also virtual memory exceeded"); + } + else +#endif /* po_hash_ERROR_VERBOSE */ + po_hash_error("parse error"); + } + + goto po_hash_errlab1; +po_hash_errlab1: /* here on error raised explicitly by an action */ + + if (po_hash_errstatus == 3) + { + /* if just tried and failed to reuse lookahead token after an error, discard it. */ + + /* return failure if at end of input */ + if (po_hash_char == po_hash_EOF) + po_hash_ABORT; + +#if po_hash_DEBUG != 0 + if (po_hash_debug) + fprintf(stderr, "Discarding token %d (%s).\n", po_hash_char, po_hash_tname[po_hash_char1]); +#endif + + po_hash_char = po_hash_EMPTY; + } + + /* Else will try to reuse lookahead token + after shifting the error token. */ + + po_hash_errstatus = 3; /* Each real token shifted decrements this */ + + goto po_hash_errhandle; + +po_hash_errdefault: /* current state does not do anything special for the error token. */ + +#if 0 + /* This is wrong; only states that explicitly want error tokens + should shift them. */ + po_hash_n = po_hash_defact[po_hash_state]; /* If its default is to accept any token, ok. Otherwise pop it.*/ + if (po_hash_n) goto po_hash_default; +#endif + +po_hash_errpop: /* pop the current state because it cannot handle the error token */ + + if (po_hash_ssp == po_hash_ss) po_hash_ABORT; + po_hash_vsp--; + po_hash_state = *--po_hash_ssp; +#ifdef po_hash_LSP_NEEDED + po_hash_lsp--; +#endif + +#if po_hash_DEBUG != 0 + if (po_hash_debug) + { + short *ssp1 = po_hash_ss - 1; + fprintf (stderr, "Error: state stack now"); + while (ssp1 != po_hash_ssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif + +po_hash_errhandle: + + po_hash_n = po_hash_pact[po_hash_state]; + if (po_hash_n == po_hash_FLAG) + goto po_hash_errdefault; + + po_hash_n += po_hash_TERROR; + if (po_hash_n < 0 || po_hash_n > po_hash_LAST || po_hash_check[po_hash_n] != po_hash_TERROR) + goto po_hash_errdefault; + + po_hash_n = po_hash_table[po_hash_n]; + if (po_hash_n < 0) + { + if (po_hash_n == po_hash_FLAG) + goto po_hash_errpop; + po_hash_n = -po_hash_n; + goto po_hash_reduce; + } + else if (po_hash_n == 0) + goto po_hash_errpop; + + if (po_hash_n == po_hash_FINAL) + po_hash_ACCEPT; + +#if po_hash_DEBUG != 0 + if (po_hash_debug) + fprintf(stderr, "Shifting error token, "); +#endif + + *++po_hash_vsp = po_hash_lval; +#ifdef po_hash_LSP_NEEDED + *++po_hash_lsp = po_hash_lloc; +#endif + + po_hash_state = po_hash_n; + goto po_hash_newstate; +} +#line 113 "../../src/po-hash.y" + + + +int +po_hash_lex () +{ + static char *buf; + static size_t bufmax; + size_t bufpos; + int n; + int c; + + for (;;) + { + c = *cur++; + switch (c) + { + case 0: + --cur; + return 0; + + case ' ': + case '\t': + case '\n': + break; + + case ':': + return COLON; + + case ',': + return COMMA; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + /* Accumulate a number. */ + n = 0; + for (;;) + { + n = n * 10 + c - '0'; + c = *cur++; + switch (c) + { + default: + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + continue; + } + break; + } + --cur; + po_hash_lval.number = n; + return NUMBER; + + default: + /* Accumulate a string. */ + bufpos = 0; + for (;;) + { + if (bufpos >= bufmax) + { + bufmax += 100; + buf = xrealloc (buf, bufmax); + } + buf[bufpos++] = c; + + c = *cur++; + switch (c) + { + default: + continue; + + case 0: + case ':': + case ',': + case ' ': + case '\t': + --cur; + break; + } + break; + } + + if (bufpos >= bufmax) + { + bufmax += 100; + buf = xrealloc (buf, bufmax); + } + buf[bufpos] = 0; + + if (strcmp (buf, "file") == 0 || strcmp (buf, "File") == 0) + return FILE_KEYWORD; + if (strcmp (buf, "line") == 0) + return LINE_KEYWORD; + if (strcmp (buf, "number") == 0) + return NUMBER_KEYWORD; + po_hash_lval.string = xstrdup (buf); + return STRING; + } + } +} diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/po-hash.gen.h b/debian/gettext-kde/gettext-kde-0.10.35/src/po-hash.gen.h new file mode 100644 index 00000000..4b25ded3 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/po-hash.gen.h @@ -0,0 +1,15 @@ +typedef union +{ + char *string; + int number; +} po_hash_STYPE; +#define STRING 258 +#define NUMBER 259 +#define COLON 260 +#define COMMA 261 +#define FILE_KEYWORD 262 +#define LINE_KEYWORD 263 +#define NUMBER_KEYWORD 264 + + +extern po_hash_STYPE po_hash_lval; diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/po-hash.h b/debian/gettext-kde/gettext-kde-0.10.35/src/po-hash.h new file mode 100644 index 00000000..051ff038 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/po-hash.h @@ -0,0 +1,25 @@ +/* GNU gettext - internationalization aids + Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc. + + This file was written by Peter Miller <[email protected]> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef SRC_PO_HASH_H +#define SRC_PO_HASH_H + +int po_hash PARAMS ((const char *__string)); + +#endif diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/po-hash.y b/debian/gettext-kde/gettext-kde-0.10.35/src/po-hash.y new file mode 100644 index 00000000..63cd0f6f --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/po-hash.y @@ -0,0 +1,230 @@ +/* GNU gettext - internationalization aids + Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc. + + This file was written by Peter Miller <[email protected]> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +%{ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdio.h> + +#include <system.h> +#include "po-hash.h" +#include "po.h" + +%} + +%token STRING +%token NUMBER +%token COLON +%token COMMA +%token FILE_KEYWORD +%token LINE_KEYWORD +%token NUMBER_KEYWORD + +%union +{ + char *string; + int number; +} + +%type <number> NUMBER +%type <string> STRING + +%{ + +static const char *cur; + + +void yyerror PARAMS ((char *)); +int yylex PARAMS ((void)); + + +int +po_hash (s) + const char *s; +{ + extern int yyparse PARAMS ((void)); + + cur = s; + return yyparse (); +} + + +void +yyerror (s) + char *s; +{ + /* Do nothing, the grammar is used as a recogniser. */ +} +%} + +%% + +filepos_line + : /* empty */ + | filepos_line filepos + ; + +filepos + : STRING COLON NUMBER + { + /* GNU style */ + po_callback_comment_filepos ($1, $3); + free ($1); + } + | FILE_KEYWORD COLON STRING COMMA LINE_KEYWORD COLON NUMBER + { + /* SunOS style */ + po_callback_comment_filepos ($3, $7); + free ($3); + } + | FILE_KEYWORD COLON STRING COMMA LINE_KEYWORD NUMBER_KEYWORD COLON NUMBER + { + /* Solaris style */ + po_callback_comment_filepos ($3, $8); + free ($3); + } + | FILE_KEYWORD COLON NUMBER + { + /* GNU style, but STRING is `file'. Esoteric, but it + happened. */ + po_callback_comment_filepos ("file", $3); + } + ; + +%% + + +int +yylex () +{ + static char *buf; + static size_t bufmax; + size_t bufpos; + int n; + int c; + + for (;;) + { + c = *cur++; + switch (c) + { + case 0: + --cur; + return 0; + + case ' ': + case '\t': + case '\n': + break; + + case ':': + return COLON; + + case ',': + return COMMA; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + /* Accumulate a number. */ + n = 0; + for (;;) + { + n = n * 10 + c - '0'; + c = *cur++; + switch (c) + { + default: + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + continue; + } + break; + } + --cur; + yylval.number = n; + return NUMBER; + + default: + /* Accumulate a string. */ + bufpos = 0; + for (;;) + { + if (bufpos >= bufmax) + { + bufmax += 100; + buf = xrealloc (buf, bufmax); + } + buf[bufpos++] = c; + + c = *cur++; + switch (c) + { + default: + continue; + + case 0: + case ':': + case ',': + case ' ': + case '\t': + --cur; + break; + } + break; + } + + if (bufpos >= bufmax) + { + bufmax += 100; + buf = xrealloc (buf, bufmax); + } + buf[bufpos] = 0; + + if (strcmp (buf, "file") == 0 || strcmp (buf, "File") == 0) + return FILE_KEYWORD; + if (strcmp (buf, "line") == 0) + return LINE_KEYWORD; + if (strcmp (buf, "number") == 0) + return NUMBER_KEYWORD; + yylval.string = xstrdup (buf); + return STRING; + } + } +} diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/po-lex.c b/debian/gettext-kde/gettext-kde-0.10.35/src/po-lex.c new file mode 100644 index 00000000..0d614308 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/po-lex.c @@ -0,0 +1,545 @@ +/* GNU gettext - internationalization aids + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + + This file was written by Peter Miller <[email protected]> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <ctype.h> +#include <errno.h> +#include <stdio.h> +#include <sys/types.h> + +#include <libintl.h> +#define _(str) gettext(str) + +#if HAVE_VPRINTF || HAVE_DOPRNT +# if __STDC__ +# include <stdarg.h> +# define VA_START(args, lastarg) va_start(args, lastarg) +# else +# include <varargs.h> +# define VA_START(args, lastarg) va_start(args) +# endif +#else +# define va_alist a1, a2, a3, a4, a5, a6, a7, a8 +# define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8; +#endif + +#include "po-lex.h" +#include "po-gram.h" +#include "system.h" +#include "error.h" +#include "po-gram.gen.h" + + +static FILE *fp; +lex_pos_ty gram_pos; +size_t gram_max_allowed_errors = 20; +static int pass_comments = 0; +static int pass_obsolete_entries = 0; + + +/* Prototypes for local functions. */ +static int lex_getc PARAMS ((void)); +static void lex_ungetc PARAMS ((int __ch)); +static int keyword_p PARAMS ((char *__s)); +static int control_sequence PARAMS ((void)); + + +void +lex_open (fname) + const char *fname; +{ + fp = open_po_file (fname, &gram_pos.file_name); + if (!fp) + error (EXIT_FAILURE, errno, + _("error while opening \"%s\" for reading"), fname); + + gram_pos.line_number = 1; +} + + +void +lex_close () +{ + if (error_message_count > 0) + error (EXIT_FAILURE, 0, _("found %d fatal errors"), error_message_count); + + if (fp != stdin) + fclose (fp); + fp = NULL; + gram_pos.file_name = 0; + gram_pos.line_number = 0; + error_message_count = 0; +} + + +/* CAUTION: If you change this function, you must also make identical + changes to the macro of the same name in src/po-lex.h */ + +#if !__STDC__ || !defined __GNUC__ || __GNUC__ == 1 +/* VARARGS1 */ +void +# if defined VA_START && __STDC__ +po_gram_error (const char *fmt, ...) +# else +po_gram_error (fmt, va_alist) + const char *fmt; + va_dcl +# endif +{ +# ifdef VA_START + va_list ap; + char *buffer; + + VA_START (ap, fmt); + + vasprintf (&buffer, fmt, ap); + va_end (ap); + error_at_line (0, 0, gram_pos.file_name, gram_pos.line_number, "%s", buffer); +# else + error_at_line (0, 0, gram_pos.file_name, gram_pos.line_number, fmt, + a1, a2, a3, a4, a5, a6, a7, a8); +# endif + + /* Some messages need more than one line. Continuation lines are + indicated by using "..." at the start of the string. We don't + increment the error counter for these continuation lines. */ + if (*fmt == '.') + --error_message_count; + else if (error_message_count >= gram_max_allowed_errors) + error (EXIT_FAILURE, 0, _("too many errors, aborting")); +} + + +/* CAUTION: If you change this function, you must also make identical + changes to the macro of the same name in src/po-lex.h */ + +/* VARARGS2 */ +void +# if defined VA_START && __STDC__ +gram_error_at_line (const lex_pos_ty *pp, const char *fmt, ...) +# else +gram_error_at_line (pp, fmt, va_alist) + const lex_pos_ty *pp; + const char *fmt; + va_dcl +# endif +{ +# ifdef VA_START + va_list ap; + char *buffer; + + VA_START (ap, fmt); + + vasprintf (&buffer, fmt, ap); + va_end (ap); + error_at_line (0, 0, pp->file_name, pp->line_number, "%s", buffer); +# else + error_at_line (0, 0, pp->file_name, pp->line_number, fmt, + a1, a2, a3, a4, a5, a6, a7, a8); +# endif + + /* Some messages need more than one line, or more than one location. + Continuation lines are indicated by using "..." at the start of the + string. We don't increment the error counter for these + continuation lines. */ + if (*fmt == '.') + --error_message_count; + else if (error_message_count >= gram_max_allowed_errors) + error (EXIT_FAILURE, 0, _("too many errors, aborting")); +} +#endif + + +static int +lex_getc () +{ + int c; + + for (;;) + { + c = getc (fp); + switch (c) + { + case EOF: + if (ferror (fp)) + error (EXIT_FAILURE, errno, _("error while reading \"%s\""), + gram_pos.file_name); + return EOF; + + case '\n': + ++gram_pos.line_number; + return '\n'; + + case '\\': + c = getc (fp); + if (c != '\n') + { + if (c != EOF) + ungetc (c, fp); + return '\\'; + } + ++gram_pos.line_number; + break; + + default: + return c; + } + } +} + + +static void +lex_ungetc (c) + int c; +{ + switch (c) + { + case EOF: + break; + + case '\n': + --gram_pos.line_number; + /* FALLTHROUGH */ + + default: + ungetc (c, fp); + break; + } +} + + +static int +keyword_p (s) + char *s; +{ + if (!strcmp (s, "domain")) + return DOMAIN; + if (!strcmp (s, "msgid")) + return MSGID; + if (!strcmp (s, "msgstr")) + return MSGSTR; + po_gram_error (_("keyword \"%s\" unknown"), s); + return NAME; +} + + +static int +control_sequence () +{ + int c; + int val; + int max; + + c = lex_getc (); + switch (c) + { + case 'n': + return '\n'; + + case 't': + return '\t'; + + case 'b': + return '\b'; + + case 'r': + return '\r'; + + case 'f': + return '\f'; + + case '\\': + case '"': + return c; + + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + val = 0; + for (max = 0; max < 3; ++max) + { + /* Warning: not portable, can't depend on '0'..'7' ordering. */ + val = val * 8 + c - '0'; + c = lex_getc (); + switch (c) + { + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + continue; + + default: + break; + } + break; + } + lex_ungetc (c); + return val; + + case 'x': case 'X': + c = lex_getc (); + if (c == EOF || !isxdigit (c)) + break; + + val = 0; + for (;;) + { + val *= 16; + if (isdigit (c)) + /* Warning: not portable, can't depend on '0'..'9' ordering */ + val += c - '0'; + else if (isupper (c)) + /* Warning: not portable, can't depend on 'A'..'F' ordering */ + val += c - 'A' + 10; + else + /* Warning: not portable, can't depend on 'a'..'f' ordering */ + val += c - 'a' + 10; + + c = lex_getc (); + switch (c) + { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + continue; + + default: + break; + } + break; + } + return val; + } + po_gram_error (_("illegal control sequence")); + return ' '; +} + + +int +po_gram_lex () +{ + static char *buf; + static size_t bufmax; + int c; + size_t bufpos; + + for (;;) + { + c = lex_getc (); + switch (c) + { + case EOF: + /* Yacc want this for end of file. */ + return 0; + + case ' ': + case '\t': + case '\n': + case '\r': + case '\f': + break; + + case '#': + /* Accumulate comments into a buffer. If we have been asked + to pass comments, generate a COMMENT token, otherwise + discard it. */ + c = lex_getc (); + if (c == '~' && pass_obsolete_entries) + /* A special comment beginning with #~ is found. This + is the format for obsolete entries and if we are + asked to return them is entries not as comments be + simply stop processing the comment here. The + following characters are expected to be well formed. */ + break; + + if (pass_comments) + { + bufpos = 0; + while (1) + { + if (bufpos >= bufmax) + { + bufmax += 100; + buf = xrealloc (buf, bufmax); + } + if (c == EOF || c == '\n') + break; + + buf[bufpos++] = c; + c = lex_getc (); + } + buf[bufpos] = 0; + + po_gram_lval.string = buf; + return COMMENT; + } + else + /* We do this in separate loop because collecting large + comments while they get not passed to the upper layers + is not very effective. */ + while (c != EOF && c != '\n') + c = lex_getc (); + break; + + case '"': + bufpos = 0; + while (1) + { + if (bufpos >= bufmax) + { + bufmax += 100; + buf = xrealloc (buf, bufmax); + } + c = lex_getc (); + if (c == '\n') + { + po_gram_error (_("end-of-line within string")); + break; + } + if (c == EOF) + { + po_gram_error (_("end-of-file within string")); + break; + } + if (c == '"') + break; + + if (c == '\\') + c = control_sequence (); + + buf[bufpos++] = c; + } + buf[bufpos] = 0; + + po_gram_lval.string = xstrdup (buf); + return STRING; + + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': + case 's': case 't': case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + case '_': case '$': + bufpos = 0; + for (;;) + { + if (bufpos + 1 >= bufmax) + { + bufmax += 100; + buf = xrealloc (buf, bufmax); + } + buf[bufpos++] = c; + c = lex_getc (); + switch (c) + { + default: + break; + case 'a': case 'b': case 'c': case 'd': + case 'e': case 'f': case 'g': case 'h': + case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': + case 'q': case 'r': case 's': case 't': + case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + case 'A': case 'B': case 'C': case 'D': + case 'E': case 'F': case 'G': case 'H': + case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': + case 'Q': case 'R': case 'S': case 'T': + case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + case '_': case '$': + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + case '8': case '9': + continue; + } + break; + } + lex_ungetc (c); + + buf[bufpos] = 0; + + c = keyword_p (buf); + if (c == NAME) + po_gram_lval.string = xstrdup (buf); + return c; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + /* I know, we don't need numbers, yet. */ + bufpos = 0; + for (;;) + { + if (bufpos + 1 >= bufmax) + { + bufmax += 100; + buf = xrealloc (buf, bufmax + 1); + } + buf[bufpos++] = c; + c = lex_getc (); + switch (c) + { + default: + break; + + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + case '8': case '9': + continue; + } + break; + } + lex_ungetc (c); + + buf[bufpos] = 0; + + po_gram_lval.number = atol (buf); + return NUMBER; + + default: + /* This will cause a syntax error. */ + return JUNK; + } + } +} + + +void +po_lex_pass_comments (flag) + int flag; +{ + pass_comments = (flag != 0); +} + + +void +po_lex_pass_obsolete_entries (flag) + int flag; +{ + pass_obsolete_entries = (flag != 0); +} diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/po-lex.h b/debian/gettext-kde/gettext-kde-0.10.35/src/po-lex.h new file mode 100644 index 00000000..fd95d974 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/po-lex.h @@ -0,0 +1,83 @@ +/* GNU gettext - internationalization aids + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + + This file was written by Peter Miller <[email protected]> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef _PO_LEX_H +#define _PO_LEX_H + +#include <sys/types.h> +#include "error.h" + +typedef struct lex_pos_ty lex_pos_ty; +struct lex_pos_ty +{ + char *file_name; + size_t line_number; +}; + + +/* Global variables from po-lex.c. */ +extern lex_pos_ty gram_pos; +extern size_t gram_max_allowed_errors; + + +void lex_open PARAMS ((const char *__fname)); +void lex_close PARAMS ((void)); +int po_gram_lex PARAMS ((void)); +void po_lex_pass_comments PARAMS ((int __flag)); +void po_lex_pass_obsolete_entries PARAMS ((int __flag)); + + +/* GCC is smart enough to allow optimizations like this. */ +#if __STDC__ && defined __GNUC__ && __GNUC__ >= 2 + + +/* CAUTION: If you change this macro, you must also make identical + changes to the function of the same name in src/po-lex.c */ + +# define po_gram_error(fmt, args...) \ + do { \ + error_at_line (0, 0, gram_pos.file_name, gram_pos.line_number, \ + fmt, ## args); \ + if (*fmt == '.') \ + --error_message_count; \ + else if (error_message_count >= gram_max_allowed_errors) \ + error (1, 0, _("too many errors, aborting")); \ + } while (0) + + +/* CAUTION: If you change this macro, you must also make identical + changes to the function of the same name in src/po-lex.c */ + +# define gram_error_at_line(pos, fmt, args...) \ + do { \ + error_at_line (0, 0, (pos)->file_name, (pos)->line_number, \ + fmt, ## args); \ + if (*fmt == '.') \ + --error_message_count; \ + else if (error_message_count >= gram_max_allowed_errors) \ + error (1, 0, _("too many errors, aborting")); \ + } while (0) +#else +void po_gram_error PARAMS ((const char *__fmt, ...)); +void gram_error_at_line PARAMS ((const lex_pos_ty *__pos, const char *__fmt, + ...)); +#endif + + +#endif diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/po.c b/debian/gettext-kde/gettext-kde-0.10.35/src/po.c new file mode 100644 index 00000000..2bdadb76 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/po.c @@ -0,0 +1,253 @@ +/* GNU gettext - internationalization aids + Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc. + + This file was written by Peter Miller <[email protected]> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <ctype.h> +#include <stdio.h> + +#ifdef HAVE_STDLIB_H +# include <stdlib.h> +#endif + +#include "po.h" +#include "po-hash.h" +#include "system.h" + +/* Prototypes for local functions. */ +static void po_parse_brief PARAMS ((po_ty *__pop)); +static void po_parse_debrief PARAMS ((po_ty *__pop)); + +/* Methods used indirectly by po_scan. */ +static void po_directive_domain PARAMS ((po_ty *__pop, char *__name)); +static void po_directive_message PARAMS ((po_ty *__pop, char *__msgid, + lex_pos_ty *__msgid_pos, + char *__msgstr, + lex_pos_ty *__msgstr_pos)); +static void po_comment PARAMS ((po_ty *__pop, const char *__s)); +static void po_comment_dot PARAMS ((po_ty *__pop, const char *__s)); +static void po_comment_filepos PARAMS ((po_ty *__pop, const char *__name, + int __line)); +static void po_comment_special PARAMS ((po_ty *pop, const char *s)); + +/* Local variables. */ +static po_ty *callback_arg; + + +po_ty * +po_alloc (pomp) + po_method_ty *pomp; +{ + po_ty *pop; + + pop = xmalloc (pomp->size); + pop->method = pomp; + if (pomp->constructor) + pomp->constructor (pop); + return pop; +} + + +void +po_free (pop) + po_ty *pop; +{ + if (pop->method->destructor) + pop->method->destructor (pop); + free (pop); +} + + +void +po_scan (pop, filename) + po_ty *pop; + const char *filename; +{ + extern int po_gram_parse PARAMS ((void)); + + /* The parse will call the po_callback_... functions (see below) + when the various directive are recognised. The callback_arg + variable is used to tell these functions which instance is to + have the relevant method invoked. */ + callback_arg = pop; + + /* Open the file and parse it. */ + lex_open (filename); + po_parse_brief (pop); + po_gram_parse (); + po_parse_debrief (pop); + lex_close (); + callback_arg = 0; +} + + +static void +po_parse_brief (pop) + po_ty *pop; +{ + if (pop->method->parse_brief) + pop->method->parse_brief (pop); +} + + +static void +po_parse_debrief (pop) + po_ty *pop; +{ + if (pop->method->parse_debrief) + pop->method->parse_debrief (pop); +} + + +static void +po_directive_domain (pop, name) + po_ty *pop; + char *name; +{ + if (pop->method->directive_domain) + pop->method->directive_domain (pop, name); +} + + +void +po_callback_domain (name) + char *name; +{ + /* assert(callback_arg); */ + po_directive_domain (callback_arg, name); +} + + +static void +po_directive_message (pop, msgid, msgid_pos, msgstr, msgstr_pos) + po_ty *pop; + char *msgid; + lex_pos_ty *msgid_pos; + char *msgstr; + lex_pos_ty *msgstr_pos; +{ + if (pop->method->directive_message) + pop->method->directive_message (pop, msgid, msgid_pos, msgstr, msgstr_pos); +} + + +void +po_callback_message (msgid, msgid_pos, msgstr, msgstr_pos) + char *msgid; + lex_pos_ty *msgid_pos; + char *msgstr; + lex_pos_ty *msgstr_pos; +{ + /* assert(callback_arg); */ + po_directive_message (callback_arg, msgid, msgid_pos, msgstr, msgstr_pos); +} + + +static void +po_comment_special (pop, s) + po_ty *pop; + const char *s; +{ + if (pop->method->comment_special != NULL) + pop->method->comment_special (pop, s); +} + + +static void +po_comment (pop, s) + po_ty *pop; + const char *s; +{ + if (pop->method->comment != NULL) + pop->method->comment (pop, s); +} + + +static void +po_comment_dot (pop, s) + po_ty *pop; + const char *s; +{ + if (pop->method->comment_dot != NULL) + pop->method->comment_dot (pop, s); +} + + +/* This function is called by po_gram_lex() whenever a comment is + seen. It analyzes the comment to see what sort it is, and then + dispatces it to the appropriate method. */ +void +po_callback_comment (s) + const char *s; +{ + /* assert(callback_arg); */ + if (*s == '.') + po_comment_dot (callback_arg, s + 1); + else if (*s == ':') + { + /* Parse the file location string. If the parse succeeds, the + appropriate callback will be invoked. If the parse fails, + the po_hash_parse function will return non-zero - so pretend + it was a normal comment. */ + if (po_hash (s + 1) == 0) + /* Do nothing, it is a GNU-style file pos line. */ ; + else + po_comment (callback_arg, s + 1); + } + else if (*s == ',' || *s == '!') + /* Get all entries in the special comment line. */ + po_comment_special (callback_arg, s + 1); + else + { + /* It looks like a plain vanilla comment, but Solaris-style file + position lines do, too. Rather than parse the lot, only look + at lines that could start with "# File..." This minimizes + memory leaks on failed parses. If the parse succeeds, the + appropriate callback will be invoked. */ + if (s[0] == ' ' && (s[1] == 'F' || s[1] == 'f') && s[2] == 'i' + && po_hash (s) == 0) + /* Do nothing, it is a Sun-style file pos line. */ ; + else + po_comment (callback_arg, s); + } +} + + +static void +po_comment_filepos (pop, name, line) + po_ty *pop; + const char *name; + int line; +{ + if (pop->method->comment_filepos) + pop->method->comment_filepos (pop, name, line); +} + + +void +po_callback_comment_filepos (name, line) + const char *name; + int line; +{ + /* assert(callback_arg); */ + po_comment_filepos (callback_arg, name, line); +} diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/po.h b/debian/gettext-kde/gettext-kde-0.10.35/src/po.h new file mode 100644 index 00000000..4800a6f5 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/po.h @@ -0,0 +1,129 @@ +/* GNU gettext - internationalization aids + Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc. + + This file was written by Peter Miller <[email protected]> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef SRC_PO_H +#define SRC_PO_H + +#include "po-lex.h" + +/* Note: the _t suffix is reserved by ANSI C, so the _ty suffix is + used to indicate a type name */ + +/* The following pair of structures cooperate to create an "Object" in + the OO sense, we are simply doing it manually, rather than with the + help of an OO compiler. This implementation allows polymorphism + and inheritance - more than enough for the immediate needs. + + This first structure contains pointers to functions. Each function + is a method for the class (base or derived). + + Use a NULL pointer where no action is required. */ + +/* Forward decaration. */ +struct po_ty; + + +typedef struct po_method_ty po_method_ty; +struct po_method_ty +{ + /* how many bytes to malloc for this class */ + size_t size; + + /* what to do immediately after the instance is malloc()ed */ + void (*constructor) PARAMS ((struct po_ty *__pop)); + + /* what to do immediately before the instance is free()ed */ + void (*destructor) PARAMS ((struct po_ty *__pop)); + + /* what to do with a domain directive */ + void (*directive_domain) PARAMS ((struct po_ty *__pop, char *__name)); + + /* what to do with a message directive */ + void (*directive_message) PARAMS ((struct po_ty *__pop, char *__msgid, + lex_pos_ty *__msgid_pos, char *__msgstr, + lex_pos_ty *__msgstr_pos)); + + /* This method is invoked before the parse, but after the file is + opened by the lexer. */ + void (*parse_brief) PARAMS ((struct po_ty *__pop)); + + /* This method is invoked after the parse, but before the file is + closed by the lexer. The intention is to make consistency checks + against the file here, and emit the errors through the lex_error* + functions. */ + void (*parse_debrief) PARAMS ((struct po_ty *__pop)); + + /* What to do with a plain-vanilla comment - the expectation is that + they will be accumulated, and added to the next message + definition seen. Or completely ignored. */ + void (*comment) PARAMS ((struct po_ty *__pop, const char *__s)); + + /* What to do with a comment that starts with a dot (i.e. extracted + by xgettext) - the expectation is that they will be accumulated, + and added to the next message definition seen. Or completely + ignored. */ + void (*comment_dot) PARAMS ((struct po_ty *__pop, const char *__s)); + + /* What to do with a file position seen in a comment (i.e. a message + location comment extracted by xgettext) - the expectation is that + they will be accumulated, and added to the next message + definition seen. Or completely ignored. */ + void (*comment_filepos) PARAMS ((struct po_ty *__pop, const char *__s, + int __line)); + + /* What to do with a comment that starts with a `!' - this is a + special comment. One of the possible uses is to indicate a + inexact translation. */ + void (*comment_special) PARAMS ((struct po_ty *__pop, const char *__s)); +}; + + +/* This next structure defines the base class passed to the methods. + Derived methods will often need to cast their first argument before + using it (this correponds to the implicit ``this'' argument of many + C++ implementations). + + When declaring derived classes, use the PO_BASE_TY define at the + start of the structure, to declare inherited instance variables, + etc. */ + +#define PO_BASE_TY \ + po_method_ty *method; + +typedef struct po_ty po_ty; +struct po_ty +{ + PO_BASE_TY +}; + + +po_ty *po_alloc PARAMS ((po_method_ty *__jtable)); +void po_scan PARAMS ((po_ty *__pop, const char *__filename)); +void po_free PARAMS ((po_ty *__pop)); + +/* Callbacks used by po-gram.y or po-hash.y or po-lex.c, indirectly + from po_scan. */ +void po_callback_domain PARAMS ((char *__name)); +void po_callback_message PARAMS ((char *__msgid, lex_pos_ty *__msgid_pos, + char *__msgstr, lex_pos_ty *__msgstr_pos)); +void po_callback_comment PARAMS ((const char *__s)); +void po_callback_comment_dot PARAMS ((const char *__s)); +void po_callback_comment_filepos PARAMS ((const char *__s, int __line)); + +#endif diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/str-list.c b/debian/gettext-kde/gettext-kde-0.10.35/src/str-list.c new file mode 100644 index 00000000..40007452 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/str-list.c @@ -0,0 +1,146 @@ +/* GNU gettext - internationalization aids + Copyright (C) 1995, 1998 Free Software Foundation, Inc. + + This file was written by Peter Miller <[email protected]> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdio.h> + +#include "system.h" +#include "str-list.h" + + +string_list_ty * +string_list_alloc () +{ + string_list_ty *slp; + + slp = (string_list_ty *) xmalloc (sizeof (*slp)); + slp->item = NULL; + slp->nitems = 0; + slp->nitems_max = 0; + + return slp; +} + + +void +string_list_append (slp, s) + string_list_ty *slp; + const char *s; +{ + /* Grow the list. */ + if (slp->nitems >= slp->nitems_max) + { + size_t nbytes; + + slp->nitems_max = slp->nitems_max * 2 + 4; + nbytes = slp->nitems_max * sizeof (slp->item[0]); + slp->item = (const char **) xrealloc (slp->item, nbytes); + } + + /* Add a copy of the string to the end of the list. */ + slp->item[slp->nitems++] = xstrdup (s); +} + + +void +string_list_append_unique (slp, s) + string_list_ty *slp; + const char *s; +{ + size_t j; + + /* Do not if the string is already in the list. */ + for (j = 0; j < slp->nitems; ++j) + if (strcmp (slp->item[j], s) == 0) + return; + + /* Grow the list. */ + if (slp->nitems >= slp->nitems_max) + { + slp->nitems_max = slp->nitems_max * 2 + 4; + slp->item = (const char **) xrealloc (slp->item, + slp->nitems_max + * sizeof (slp->item[0])); + } + + /* Add a copy of the string to the end of the list. */ + slp->item[slp->nitems++] = xstrdup (s); +} + + +void +string_list_free (slp) + string_list_ty *slp; +{ + size_t j; + + for (j = 0; j < slp->nitems; ++j) + free ((char *) slp->item[j]); + if (slp->item != NULL) + free (slp->item); + free (slp); +} + + +char * +string_list_join (slp) + const string_list_ty *slp; +{ + size_t len; + size_t j; + char *result; + size_t pos; + + len = 1; + for (j = 0; j < slp->nitems; ++j) + { + if (j) + ++len; + len += strlen (slp->item[j]); + } + result = xmalloc (len); + pos = 0; + for (j = 0; j < slp->nitems; ++j) + { + if (j) + result[pos++] = ' '; + len = strlen (slp->item[j]); + memcpy (result + pos, slp->item[j], len); + pos += len; + } + result[pos] = 0; + return result; +} + + +int +string_list_member (slp, s) + const string_list_ty *slp; + const char *s; +{ + size_t j; + + for (j = 0; j < slp->nitems; ++j) + if (strcmp (slp->item[j], s) == 0) + return 1; + return 0; +} diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/str-list.h b/debian/gettext-kde/gettext-kde-0.10.35/src/str-list.h new file mode 100644 index 00000000..9e2b9981 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/str-list.h @@ -0,0 +1,50 @@ +/* GNU gettext - internationalization aids + Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc. + + This file was written by Peter Miller <[email protected]> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef SRC_STR_LIST_H +#define SRC_STR_LIST_H 1 + +#ifdef STC_HEADERS +# define __need_size_t +# define __need_NULL +# include <stddef.h> +#else +# include <sys/types.h> +# include <stdio.h> +#endif + +/* Type describing list of strings implemented using a dynamic array. */ +typedef struct string_list_ty string_list_ty; +struct string_list_ty +{ + const char **item; + size_t nitems; + size_t nitems_max; +}; + + +string_list_ty *string_list_alloc PARAMS ((void)); +void string_list_append PARAMS ((string_list_ty *__slp, const char *__s)); +void string_list_append_unique PARAMS ((string_list_ty *__slp, + const char *__s)); +void string_list_free PARAMS ((string_list_ty *__slp)); +char *string_list_join PARAMS ((const string_list_ty *__slp)); +int string_list_member PARAMS ((const string_list_ty *__slp, const char *__s)); + +#endif diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/xget-lex.c b/debian/gettext-kde/gettext-kde-0.10.35/src/xget-lex.c new file mode 100644 index 00000000..a55850b0 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/xget-lex.c @@ -0,0 +1,1322 @@ +/* GNU gettext - internationalization aids + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + + This file was written by Peter Miller <[email protected]> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <ctype.h> +#include <errno.h> +#include <stdio.h> + +#ifdef STDC_HEADERS +# include <stdlib.h> +#endif + +#include "dir-list.h" +#include "error.h" +#include "system.h" +#include "libgettext.h" +#include "str-list.h" +#include "xget-lex.h" + +#ifndef errno +extern int errno; +#endif + +#define _(s) gettext(s) + + +/* The ANSI C standard defines several phases of translation: + + 1. Terminate line by \n, regardless of the external representation + of a text line. Stdio does this for us. + + 2. Convert trigraphs to their single character equivalents. + + 3. Concatenate each line ending in backslash (\) with the following + line. + + 4. Replace each comment with a space character. + + 5. Parse each resulting logical line as preprocessing tokens a + white space. + + 6. Recognize and carry out directives (it also expands macros on + non-directive lines, which we do not do here). + + 7. Replaces escape sequences within character strings with their + single character equivalents (we do this in step 5, because we + don't have to worry about the #include argument). + + 8. Concatenates adjacent string literals to form single string + literals (because we don't expand macros, there are a few things + we will miss). + + 9. Converts the remaining preprocessing tokens to C tokens and + discards any white space from the translation unit. + + This lexer implements the above, and presents the scanner (in + xgettext.c) with a stream of C tokens. The comments are + accumulated in a buffer, and given to xgettext when asked for. */ + +enum token_type_ty +{ + token_type_character_constant = 0, + token_type_eof = 1, + token_type_eoln = 2, + token_type_hash = 3, + token_type_lp = 4, + token_type_rp = 5, + token_type_comma = 6, + token_type_name = 7, + token_type_number = 8, + token_type_string_literal = 9, + token_type_symbol = 10, + token_type_white_space = 11 +}; +typedef enum token_type_ty token_type_ty; + +typedef struct token_ty token_ty; +struct token_ty +{ + token_type_ty type; + char *string; + long number; + int line_number; +}; + + +static const char *file_name; +static char *logical_file_name; +static int line_number; +static FILE *fp; +static int trigraphs; +static int cplusplus_comments; +static string_list_ty *comment; +static string_list_ty *keywords; +static int default_keywords = 1; + +/* These are for tracking whether comments count as immediately before + keyword. */ +static int last_comment_line = -1; +static int last_non_comment_line = -1; +static int newline_count = 0; + + +/* Prototypes for local functions. */ +static int phase1_getc PARAMS ((void)); +static void phase1_ungetc PARAMS ((int __c)); +static int phase2_getc PARAMS ((void)); +static void phase2_ungetc PARAMS ((int __c)); +static int phase3_getc PARAMS ((void)); +static void phase3_ungetc PARAMS ((int __c)); +static int phase4_getc PARAMS ((void)); +static void phase4_ungetc PARAMS ((int __c)); +static int phase7_getc PARAMS ((void)); +static void phase7_ungetc PARAMS ((int __c)); +static void phase5_get PARAMS ((token_ty *__tp)); +static void phase5_unget PARAMS ((token_ty *__tp)); +static void phaseX_get PARAMS ((token_ty *__tp)); +static void phase6_get PARAMS ((token_ty *__tp)); +static void phase6_unget PARAMS ((token_ty *__tp)); +static void phase8_get PARAMS ((token_ty *__tp)); + + + +void +xgettext_lex_open (fn) + const char *fn; +{ + char *new_name; + + if (strcmp (fn, "-") == 0) + { + new_name = xstrdup (_("standard input")); + logical_file_name = xstrdup (new_name); + fp = stdin; + } + else if (*fn == '/') + { + new_name = xstrdup (fn); + fp = fopen (fn, "r"); + if (fp == NULL) + error (EXIT_FAILURE, errno, _("\ +error while opening \"%s\" for reading"), fn); + logical_file_name = xstrdup (new_name); + } + else + { + size_t len1, len2; + int j; + const char *dir; + + len2 = strlen (fn); + for (j = 0; ; ++j) + { + dir = dir_list_nth (j); + if (dir == NULL) + error (EXIT_FAILURE, ENOENT, _("\ +error while opening \"%s\" for reading"), fn); + + if (dir[0] =='.' && dir[1] == '\0') + new_name = xstrdup (fn); + else + { + len1 = strlen (dir); + new_name = xmalloc (len1 + len2 + 2); + stpcpy (stpcpy (stpcpy (new_name, dir), "/"), fn); + } + + fp = fopen (new_name, "r"); + if (fp != NULL) + break; + + if (errno != ENOENT) + error (EXIT_FAILURE, errno, _("\ +error while opening \"%s\" for reading"), new_name); + free (new_name); + } + + /* Note that the NEW_NAME variable contains the actual file name + and the logical file name is what is reported by xgettext. In + this case NEW_NAME is set to the file which was found along the + directory search path, and LOGICAL_FILE_NAME is is set to the + file name which was searched for. */ + logical_file_name = xstrdup (fn); + } + + file_name = new_name; + line_number = 1; +} + + +void +xgettext_lex_close () +{ + if (fp != stdin) + fclose (fp); + free ((char *) file_name); + free (logical_file_name); + fp = NULL; + file_name = NULL; + logical_file_name = NULL; + line_number = 0; +} + + +/* 1. Terminate line by \n, regardless of the external representation of + a text line. Stdio does this for us, we just need to check that + there are no I/O errors, and cope with potentially 2 characters of + pushback, not just the one that ungetc can cope with. */ + +/* Maximum used guaranteed to be < 4. */ +static unsigned char phase1_pushback[4]; +static int phase1_pushback_length; + + +static int +phase1_getc () +{ + int c; + + if (phase1_pushback_length) + { + c = phase1_pushback[--phase1_pushback_length]; + if (c == '\n') + ++line_number; + return c; + } + while (1) + { + c = getc (fp); + switch (c) + { + case EOF: + if (ferror (fp)) + { + bomb: + error (EXIT_FAILURE, errno, _("\ +error while reading \"%s\""), file_name); + } + return EOF; + + case '\n': + ++line_number; + return '\n'; + + case '\\': + c = getc (fp); + if (c == EOF) + { + if (ferror (fp)) + goto bomb; + return '\\'; + } + if (c != '\n') + { + ungetc (c, fp); + return '\\'; + } + ++line_number; + break; + + default: + return c; + } + } +} + + +static void +phase1_ungetc (c) + int c; +{ + switch (c) + { + case EOF: + break; + + case '\n': + --line_number; + /* FALLTHROUGH */ + + default: + phase1_pushback[phase1_pushback_length++] = c; + break; + } +} + + +/* 2. Convert trigraphs to their single character equivalents. Most + sane human beings vomit copiously at the mention of trigraphs, which + is why they are on option. */ + +/* Maximum used guaranteed to be < 4. */ +static unsigned char phase2_pushback[4]; +static int phase2_pushback_length; + + +static int +phase2_getc () +{ + int c; + + if (phase2_pushback_length) + return phase2_pushback[--phase2_pushback_length]; + if (!trigraphs) + return phase1_getc (); + + c = phase1_getc (); + if (c != '?') + return c; + c = phase1_getc (); + if (c != '?') + { + phase1_ungetc (c); + return '?'; + } + c = phase1_getc (); + switch (c) + { + case '(': + return '['; + case '/': + return '\\'; + case ')': + return ']'; + case '\'': + return '^'; + case '<': + return '{'; + case '!': + return '|'; + case '>': + return '}'; + case '-': + return '~'; + case '#': + return '='; + } + phase1_ungetc (c); + phase1_ungetc ('?'); + return '?'; +} + + +static void +phase2_ungetc (c) + int c; +{ + if (c != EOF) + phase2_pushback[phase2_pushback_length++] = c; +} + + +/* 3. Concatenate each line ending in backslash (\) with the following + line. Basically, all you need to do is elide "\\\n" sequences from + the input. */ + +/* Maximum used guaranteed to be < 4. */ +static unsigned char phase3_pushback[4]; +static int phase3_pushback_length; + + +static int +phase3_getc () +{ + if (phase3_pushback_length) + return phase3_pushback[--phase3_pushback_length]; + for (;;) + { + int c = phase2_getc (); + if (c != '\\') + return c; + c = phase2_getc (); + if (c != '\n') + { + phase2_ungetc (c); + return '\\'; + } + } +} + + +static void +phase3_ungetc (c) + int c; +{ + if (c != EOF) + phase3_pushback[phase3_pushback_length++] = c; +} + + +/* 4. Replace each comment that is not inside a character constant or + string literal with a space character. We need to remember the + comment for later, because it may be attached to a keyword string. + We also optionally understand C++ comments. */ + +static int +phase4_getc () +{ + static char *buffer; + static size_t bufmax; + size_t buflen; + int c; + int state; + + c = phase3_getc (); + if (c != '/') + return c; + c = phase3_getc (); + switch (c) + { + default: + phase3_ungetc (c); + return '/'; + + case '*': + /* C comment. */ + buflen = 0; + state = 0; + if (comment == NULL) + comment = string_list_alloc (); + while (1) + { + c = phase3_getc (); + if (c == EOF) + break; + /* We skip all leading white space, but not EOLs. */ + if (buflen == 0 && isspace (c) && c != '\n') + continue; + if (buflen >= bufmax) + { + bufmax += 100; + buffer = xrealloc (buffer, bufmax); + } + buffer[buflen++] = c; + switch (c) + { + case '\n': + --buflen; + while (buflen >= 1 && (buffer[buflen - 1] == ' ' + || buffer[buflen - 1] == '\t')) + --buflen; + buffer[buflen] = 0; + string_list_append (comment, buffer); + buflen = 0; + state = 0; + continue; + + case '*': + state = 1; + continue; + + case '/': + if (state == 1) + { + buflen -= 2; + while (buflen >= 1 && (buffer[buflen - 1] == ' ' + || buffer[buflen - 1] == '\t')) + --buflen; + buffer[buflen] = 0; + string_list_append (comment, buffer); + break; + } + /* FALLTHROUGH */ + + default: + state = 0; + continue; + } + break; + } + last_comment_line = newline_count; + return ' '; + + case '/': + /* C++ comment. */ + if (!cplusplus_comments) + { + phase3_ungetc ('/'); + return '/'; + } + buflen = 0; + while (1) + { + c = phase3_getc (); + if (c == '\n' || c == EOF) + break; + if (buflen >= bufmax) + { + bufmax += 100; + buffer = xrealloc (buffer, bufmax); + } + buffer[buflen++] = c; + } + if (buflen >= bufmax) + { + bufmax += 100; + buffer = xrealloc (buffer, bufmax); + } + buffer[buflen] = 0; + if (comment == NULL) + comment = string_list_alloc (); + string_list_append (comment, buffer); + last_comment_line = newline_count; + return '\n'; + } +} + + +static void +phase4_ungetc (c) + int c; +{ + phase3_ungetc (c); +} + + +/* 7. Replace escape sequences within character strings with their + single character equivalents. This is called from phase 5, because + we don't have to worry about the #include argument. There are + pathological cases which could bite us (like the DOS directory + separator), but just pretend it can't happen. */ + +#define P7_QUOTES (1000 + '"') +#define P7_QUOTE (1000 + '\'') +#define P7_NEWLINE (1000 + '\n') + +static int +phase7_getc () +{ + int c, n, j; + + /* Use phase 3, because phase 4 elides comments. */ + c = phase3_getc (); + + /* Return a magic newline indicator, so that we can distinguish + between the user requesting a newline in the string (e.g. using + "\n" or "\15") from the user failing to terminate the string or + character constant. The ANSI C standard says: 3.1.3.4 Character + Constants contain ``any character except single quote, backslash or + newline; or an escape sequence'' and 3.1.4 String Literals contain + ``any character except double quote, backslash or newline; or an + escape sequence''. + + Most compilers give a fatal error in this case, however gcc is + stupidly silent, even though this is a very common typo. OK, so + gcc --pedantic will tell me, but that gripes about too much other + stuff. Could I have a ``gcc -Wnewline-in-string'' option, or + better yet a ``gcc -fno-newline-in-string'' option, please? Gcc is + also inconsistent between string literals and character constants: + you may not embed newlines in character constants; try it, you get + a useful diagnostic. --PMiller */ + if (c == '\n') + return P7_NEWLINE; + + if (c == '"') + return P7_QUOTES; + if (c == '\'') + return P7_QUOTE; + if (c != '\\') + return c; + c = phase3_getc (); + switch (c) + { + default: + /* Unknown escape sequences really should be an error, but just + ignore them, and let the real compiler complain. */ + phase3_ungetc (c); + return '\\'; + + case '"': + case '\'': + case '?': + case '\\': + return c; + + /* The \a and \v escapes were added by the ANSI C Standard. + Prior to the Standard, most compilers did not have them. + Because we need the same program on all platforms we don't + provide support for them here. + + The gcc sources comment that \a is commonly available in + pre-ANSI compilers. --PMiller */ + + case 'b': + return '\b'; + + /* The \e escape is preculiar to gcc, and assumes an ASCII + character set (or superset). We don't provide support for it + here. */ + + case 'f': + return '\f'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + + case 'x': + c = phase3_getc (); + switch (c) + { + default: + phase3_ungetc (c); + phase3_ungetc ('x'); + return '\\'; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + break; + } + n = 0; + for (;;) + { + switch (c) + { + default: + phase3_ungetc (c); + return n; + break; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + n = n * 16 + c - '0'; + break;; + + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + n = n * 16 + 10 + c - 'A'; + break; + + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + n = n * 16 + 10 + c - 'a'; + break; + } + c = phase3_getc (); + } + return n; + + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + n = 0; + for (j = 0; j < 3; ++j) + { + n = n * 8 + c - '0'; + c = phase3_getc (); + switch (c) + { + default: + break; + + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + continue; + } + break; + } + phase3_ungetc (c); + return n; + } +} + + +static void +phase7_ungetc (c) + int c; +{ + phase3_ungetc (c); +} + + +/* 5. Parse each resulting logical line as preprocessing tokens and + white space. Preprocessing tokens and C tokens don't always match. */ + +/* Maximum used guaranteed to be < 4. */ +static token_ty phase5_pushback[4]; +static int phase5_pushback_length; + + +static void +phase5_get (tp) + token_ty *tp; +{ + static char *buffer; + static int bufmax; + int bufpos; + int c; + + if (phase5_pushback_length) + { + *tp = phase5_pushback[--phase5_pushback_length]; + return; + } + tp->string = 0; + tp->number = 0; + tp->line_number = line_number; + c = phase4_getc (); + switch (c) + { + case EOF: + tp->type = token_type_eof; + return; + + case '\n': + tp->type = token_type_eoln; + return; + + case ' ': + case '\f': + case '\t': + for (;;) + { + c = phase4_getc (); + switch (c) + { + case ' ': + case '\f': + case '\t': + continue; + + default: + phase4_ungetc (c); + break; + } + break; + } + tp->type = token_type_white_space; + return; + + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': + case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': + case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': + case 'V': case 'W': case 'X': case 'Y': case 'Z': + case '_': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': + case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': + case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': + case 'v': case 'w': case 'x': case 'y': case 'z': + bufpos = 0; + for (;;) + { + if (bufpos >= bufmax) + { + bufmax += 100; + buffer = xrealloc (buffer, bufmax); + } + buffer[bufpos++] = c; + c = phase4_getc (); + switch (c) + { + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + case '_': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': + case 's': case 't': case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + continue; + + default: + phase4_ungetc (c); + break; + } + break; + } + if (bufpos >= bufmax) + { + bufmax += 100; + buffer = xrealloc (buffer, bufmax); + } + buffer[bufpos] = 0; + tp->string = xstrdup (buffer); + tp->type = token_type_name; + return; + + case '.': + c = phase4_getc (); + phase4_ungetc (c); + switch (c) + { + default: + tp->type = token_type_symbol; + return; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + c = '.'; + break; + } + /* FALLTHROUGH */ + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + /* The preprocessing number token is more "generous" than the C + number tokens. This is mostly due to token pasting (another + thing we can ignore here). */ + bufpos = 0; + while (1) + { + if (bufpos >= bufmax) + { + bufmax += 100; + buffer = xrealloc (buffer, bufmax); + } + buffer[bufpos++] = c; + c = phase4_getc (); + switch (c) + { + case 'e': + case 'E': + if (bufpos >= bufmax) + { + bufmax += 100; + buffer = xrealloc (buffer, bufmax); + } + buffer[bufpos++] = c; + c = phase4_getc (); + if (c != '+' || c != '-') + { + phase4_ungetc (c); + break; + } + continue; + + case 'A': case 'B': case 'C': case 'D': case 'F': + case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + case 'a': case 'b': case 'c': case 'd': case 'f': + case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': + case 's': case 't': case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case '.': + continue; + + default: + phase4_ungetc (c); + break; + } + break; + } + if (bufpos >= bufmax) + { + bufmax += 100; + buffer = xrealloc (buffer, bufmax); + } + buffer[bufpos] = 0; + tp->type = token_type_number; + tp->number = atol (buffer); + return; + + case '\'': + /* We could worry about the 'L' before wide character constants, + but ignoring it has no effect unless one of the keywords is + "L". Just pretend it won't happen. Also, we don't need to + remember the character constant. */ + while (1) + { + c = phase7_getc (); + if (c == P7_NEWLINE) + { + error (0, 0, _("%s:%d: warning: unterminated character constant"), + logical_file_name, line_number - 1); + phase7_ungetc ('\n'); + break; + } + if (c == EOF || c == P7_QUOTE) + break; + } + tp->type = token_type_character_constant; + return; + + case '"': + /* We could worry about the 'L' before wide string constants, + but since gettext's argument is not a wide character string, + let the compiler complain about the argument not matching the + prototype. Just pretend it won't happen. */ + bufpos = 0; + while (1) + { + c = phase7_getc (); + if (c == P7_NEWLINE) + { + error (0, 0, _("%s:%d: warning: unterminated string literal"), + logical_file_name, line_number - 1); + phase7_ungetc ('\n'); + break; + } + if (c == EOF || c == P7_QUOTES) + break; + if (c == P7_QUOTE) + c = '\''; + if (bufpos >= bufmax) + { + bufmax += 100; + buffer = xrealloc (buffer, bufmax); + } + buffer[bufpos++] = c; + } + if (bufpos >= bufmax) + { + bufmax += 100; + buffer = xrealloc (buffer, bufmax); + } + buffer[bufpos] = 0; + tp->type = token_type_string_literal; + tp->string = xstrdup (buffer); + return; + + case '(': + tp->type = token_type_lp; + return; + + case ')': + tp->type = token_type_rp; + return; + + case ',': + tp->type = token_type_comma; + return; + + case '#': + tp->type = token_type_hash; + return; + + default: + /* We could carefully recognize each of the 2 and 3 character + operators, but it is not necessary, as we only need to recognize + gettext invocations. Don't bother. */ + tp->type = token_type_symbol; + return; + } +} + + +static void +phase5_unget (tp) + token_ty *tp; +{ + if (tp->type != token_type_eof) + phase5_pushback[phase5_pushback_length++] = *tp; +} + + +/* X. Recognize a leading # symbol. Leave leading hash as a hash, but + turn hash in the middle of a line into a plain symbol token. This + makes the phase 6 easier. */ + +static void +phaseX_get (tp) + token_ty *tp; +{ + static int middle; + token_ty tmp; + + phase5_get (tp); + if (middle) + { + switch (tp->type) + { + case token_type_eoln: + case token_type_eof: + middle = 0; + break; + + case token_type_hash: + tp->type = token_type_symbol; + break; + + default: + break; + } + } + else + { + switch (tp->type) + { + case token_type_eoln: + case token_type_eof: + break; + + case token_type_white_space: + tmp = *tp; + phase5_get (tp); + if (tp->type != token_type_hash) + { + phase5_unget (tp); + *tp = tmp; + middle = 1; + return; + } + + /* Discard the leading white space token, the hash is all + phase 6 is interested in. */ + if (tp->type != token_type_eof && tp->type != token_type_eoln) + middle = 1; + break; + + default: + middle = 1; + break; + } + } +} + + +/* 6. Recognize and carry out directives (it also expands macros on + non-directive lines, which we do not do here). The only directive + we care about is the #line directive. We throw all the others + away. */ + +/* Maximum used guaranteed to be < 4. */ +static token_ty phase6_pushback[4]; +static int phase6_pushback_length; + + +static void +phase6_get (tp) + token_ty *tp; +{ + static token_ty *buf; + static int bufmax; + int bufpos; + int j; + + if (phase6_pushback_length) + { + *tp = phase6_pushback[--phase6_pushback_length]; + return; + } + while (1) + { + /* Get the next token. If it is not a '#' at the beginning of a + line, return immediately. Be careful of white space. */ + phaseX_get (tp); + if (tp->type != token_type_hash) + return; + + /* Accumulate the rest of the directive in a buffer. Work out + what it is later. */ + bufpos = 0; + while (1) + { + phaseX_get (tp); + if (tp->type == token_type_eoln || tp->type == token_type_eof) + break; + + /* White space would be important in the directive, if we + were interested in the #define directive. But we are + going to ignore the #define directive, so just throw + white space away. */ + if (tp->type == token_type_white_space) + continue; + + if (bufpos >= bufmax) + { + bufmax += 100; + buf = xrealloc (buf, bufmax * sizeof (buf[0])); + } + buf[bufpos++] = *tp; + } + + /* If it is a #line directive, with no macros to expand, act on + it. Ignore all other directives. */ + if (bufpos >= 3 && buf[0].type == token_type_name + && strcmp (buf[0].string, "line") == 0 + && buf[1].type == token_type_number + && buf[2].type == token_type_string_literal) + { + free (logical_file_name); + logical_file_name = xstrdup (buf[2].string); + line_number = buf[1].number; + } + if (bufpos >= 2 && buf[0].type == token_type_number + && buf[1].type == token_type_string_literal) + { + free (logical_file_name); + logical_file_name = xstrdup (buf[1].string); + line_number = buf[0].number; + } + + /* Release the storage held by the directive. */ + for (j = 0; j < bufpos; ++j) + { + switch (buf[j].type) + { + case token_type_name: + case token_type_string_literal: + free (buf[j].string); + break; + + default: + break; + } + } + + /* We must reset the selected comments. */ + xgettext_lex_comment_reset (); + } +} + + +static void +phase6_unget (tp) + token_ty *tp; +{ + if (tp->type != token_type_eof) + phase6_pushback[phase6_pushback_length++] = *tp; +} + + +/* 8. Concatenate adjacent string literals to form single string + literals (because we don't expand macros, there are a few things we + will miss). */ + +static void +phase8_get (tp) + token_ty *tp; +{ + phase6_get (tp); + if (tp->type != token_type_string_literal) + return; + while (1) + { + token_ty tmp; + size_t len; + + phase6_get (&tmp); + if (tmp.type == token_type_white_space) + continue; + if (tmp.type == token_type_eoln) + continue; + if (tmp.type != token_type_string_literal) + { + phase6_unget (&tmp); + return; + } + len = strlen (tp->string); + tp->string = xrealloc (tp->string, len + strlen (tmp.string) + 1); + strcpy (tp->string + len, tmp.string); + free (tmp.string); + } +} + + +/* 9. Convert the remaining preprocessing tokens to C tokens and + discards any white space from the translation unit. */ + +void +xgettext_lex (tp) + xgettext_token_ty *tp; +{ + while (1) + { + token_ty token; + + phase8_get (&token); + switch (token.type) + { + case token_type_eof: + newline_count = 0; + last_comment_line = -1; + last_non_comment_line = -1; + tp->type = xgettext_token_type_eof; + return; + + case token_type_white_space: + break; + + case token_type_eoln: + /* We have to track the last occurrence of a string. One + mode of xgettext allows to group an extracted message + with a comment for documentation. The rule which states + which comment is assumed to be grouped with the message + says it should immediately precede it. Our + interpretation: between the last line of the comment and + the line in which the keyword is found must be no line + with non-white space tokens. */ + ++newline_count; + if (last_non_comment_line > last_comment_line) + xgettext_lex_comment_reset (); + break; + + case token_type_name: + last_non_comment_line = newline_count; + + if (default_keywords) + { + xgettext_lex_keyword ("gettext"); + xgettext_lex_keyword ("dgettext"); + xgettext_lex_keyword ("dcgettext"); + xgettext_lex_keyword ("gettext_noop"); + default_keywords = 0; + } + + if (string_list_member (keywords, token.string)) + { + tp->type = (strcmp (token.string, "dgettext") == 0 + || strcmp (token.string, "dcgettext") == 0) + ? xgettext_token_type_keyword2 : xgettext_token_type_keyword1; + } + else + tp->type = xgettext_token_type_symbol; + free (token.string); + return; + + case token_type_lp: + last_non_comment_line = newline_count; + + tp->type = xgettext_token_type_lp; + return; + + case token_type_rp: + last_non_comment_line = newline_count; + tp->type = xgettext_token_type_rp; + return; + + case token_type_comma: + last_non_comment_line = newline_count; + + tp->type = xgettext_token_type_comma; + return; + + case token_type_string_literal: + last_non_comment_line = newline_count; + + tp->type = xgettext_token_type_string_literal; + tp->string = token.string; + tp->line_number = token.line_number; + tp->file_name = logical_file_name; + return; + + default: + last_non_comment_line = newline_count; + + tp->type = xgettext_token_type_symbol; + return; + } + } +} + + +void +xgettext_lex_keyword (name) + char *name; +{ + if (name == NULL) + default_keywords = 0; + else + { + if (keywords == NULL) + keywords = string_list_alloc (); + + string_list_append_unique (keywords, name); + } +} + + +const char * +xgettext_lex_comment (n) + size_t n; +{ + if (comment == NULL || n >= comment->nitems) + return NULL; + return comment->item[n]; +} + + +void +xgettext_lex_comment_reset () +{ + if (comment != NULL) + { + string_list_free (comment); + comment = NULL; + } +} + + +void +xgettext_lex_cplusplus () +{ + cplusplus_comments = 1; +} + + +void +xgettext_lex_trigraphs () +{ + trigraphs = 1; +} diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/xget-lex.h b/debian/gettext-kde/gettext-kde-0.10.35/src/xget-lex.h new file mode 100644 index 00000000..3240957f --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/xget-lex.h @@ -0,0 +1,58 @@ +/* GNU gettext - internationalization aids + Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc. + + This file was written by Peter Miller <[email protected]> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef SRC_XGET_LEX_H +#define SRC_XGET_LEX_H + +enum xgettext_token_type_ty +{ + xgettext_token_type_eof = 0, + xgettext_token_type_keyword1 = 1, + xgettext_token_type_keyword2 = 2, + xgettext_token_type_lp = 3, + xgettext_token_type_rp = 4, + xgettext_token_type_comma = 5, + xgettext_token_type_string_literal = 6, + xgettext_token_type_symbol = 7 +}; +typedef enum xgettext_token_type_ty xgettext_token_type_ty; + +typedef struct xgettext_token_ty xgettext_token_ty; +struct xgettext_token_ty +{ + xgettext_token_type_ty type; + + /* These 3 are only set for xgettext_token_type_string_literal. */ + char *string; + int line_number; + char *file_name; +}; + + +void xgettext_lex_open PARAMS ((const char *__file_name)); +void xgettext_lex_close PARAMS ((void)); +void xgettext_lex PARAMS ((xgettext_token_ty *__tp)); +const char *xgettext_lex_comment PARAMS ((size_t __n)); +void xgettext_lex_comment_reset PARAMS ((void)); +/* void xgettext_lex_filepos PARAMS ((char **, int *)); FIXME needed? */ +void xgettext_lex_keyword PARAMS ((char *__name)); +void xgettext_lex_cplusplus PARAMS ((void)); +void xgettext_lex_trigraphs PARAMS ((void)); + +#endif diff --git a/debian/gettext-kde/gettext-kde-0.10.35/src/xgettext.c b/debian/gettext-kde/gettext-kde-0.10.35/src/xgettext.c new file mode 100644 index 00000000..b44142f4 --- /dev/null +++ b/debian/gettext-kde/gettext-kde-0.10.35/src/xgettext.c @@ -0,0 +1,1433 @@ +/* Extracts strings from C source file to Uniforum style .po file. + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + Written by Ulrich Drepper <[email protected]>, April 1995. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <ctype.h> +#include <errno.h> +#include <getopt.h> +#include <sys/param.h> +#include <pwd.h> +#include <stdio.h> +#include <time.h> +#include <sys/types.h> + +#ifdef STDC_HEADERS +# include <stdlib.h> +#endif + +#ifdef HAVE_LOCALE_H +# include <locale.h> +#endif + +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif + +#ifndef errno +extern int errno; +#endif + +#include "dir-list.h" +#include "error.h" +#include "hash.h" +#include "getline.h" +#include "system.h" +#include "po.h" +#include "message.h" +#include "xget-lex.h" +#include "printf-parse.h" + +#include "gettext.h" +#include "domain.h" +#include <libintl.h> + +#ifndef _POSIX_VERSION +struct passwd *getpwuid (); +#endif + + +/* A convenience macro. I don't like writing gettext() every time. */ +#define _(str) gettext (str) + + +/* If nonzero add all comments immediately preceding one of the keywords. */ +static int add_all_comments; + +/* If nonzero add comments for file name and line number for each msgid. */ +static int line_comment; + +/* Tag used in comment of prevailing domain. */ +static unsigned char *comment_tag; + +/* Name of default domain file. If not set defaults to messages.po. */ +static char *default_domain; + +/* If called with --debug option the output reflects whether format + string recognition is done automatically or forced by the user. */ +static int do_debug; + +/* Content of .po files with symbols to be excluded. */ +static message_list_ty *exclude; + +/* If nonzero extract all strings. */ +static int extract_all; + +/* Force output of PO file even if empty. */ +static int force_po; + +/* If nonzero a non GNU related user wants to use this. Omit the FSF + copyright in the output. */ +static int foreign_user; + +/* String used as prefix for msgstr. */ +static char *msgstr_prefix; + +/* String used as suffix for msgstr. */ +static char *msgstr_suffix; + +/* Directory in which output files are created. */ +static char *output_dir; + +/* If nonzero omit header with information about this run. */ +static int omit_header; + +/* String containing name the program is called with. */ +const char *program_name; + +/* String length from with on warning are given for possible problem + while exceeding tools limits. */ +static size_t warn_id_len; + +/* Long options. */ +static const struct option long_options[] = +{ + { "add-comments", optional_argument, NULL, 'c' }, + { "add-location", no_argument, &line_comment, 1 }, + { "c++", no_argument, NULL, 'C' }, + { "debug", no_argument, &do_debug, 1 }, + { "default-domain", required_argument, NULL, 'd' }, + { "directory", required_argument, NULL, 'D' }, + { "escape", no_argument, NULL, 'E' }, + { "exclude-file", required_argument, NULL, 'x' }, + { "extract-all", no_argument, &extract_all, 1 }, + { "files-from", required_argument, NULL, 'f' }, + { "force-po", no_argument, &force_po, 1 }, + { "foreign-user", no_argument, &foreign_user, 1 }, + { "help", no_argument, NULL, 'h' }, + { "indent", no_argument, NULL, 'i' }, + { "join-existing", no_argument, NULL, 'j' }, + { "keyword", optional_argument, NULL, 'k' }, + { "language", required_argument, NULL, 'L' }, + { "msgstr-prefix", optional_argument, NULL, 'm' }, + { "msgstr-suffix", optional_argument, NULL, 'M' }, + { "no-escape", no_argument, NULL, 'e' }, + { "no-location", no_argument, &line_comment, 0 }, + { "omit-header", no_argument, &omit_header, 1 }, + { "output", required_argument, NULL, 'o' }, + { "output-dir", required_argument, NULL, 'p' }, + { "sort-by-file", no_argument, NULL, 'F' }, + { "sort-output", no_argument, NULL, 's' }, + { "strict", no_argument, NULL, 'S' }, + { "string-limit", required_argument, NULL, 'l' }, + { "trigraphs", no_argument, NULL, 'T' }, + { "version", no_argument, NULL, 'V' }, + { "width", required_argument, NULL, 'w', }, + { NULL, 0, NULL, 0 } +}; + + +/* Prototypes for local functions. */ +static void usage PARAMS ((int status)) +#if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ > 4) || __GNUC__ > 2) + __attribute__ ((noreturn)) +#endif +; +static void error_print PARAMS ((void)); +static string_list_ty *read_name_from_file PARAMS ((const char *__file_name)); +static void exclude_directive_domain PARAMS ((po_ty *__pop, char *__name)); +static void exclude_directive_message PARAMS ((po_ty *__pop, char *__msgid, + lex_pos_ty *__msgid_pos, + char *__msgstr, + lex_pos_ty *__msgstr_pos)); +static void read_exclusion_file PARAMS ((char *__file_name)); +static void remember_a_message PARAMS ((message_list_ty *__mlp, + xgettext_token_ty *__tp)); +static void scan_c_file PARAMS ((const char *__file_name, + message_list_ty *__mlp, int __is_cpp_file)); +static void extract_constructor PARAMS ((po_ty *__that)); +static void extract_directive_domain PARAMS ((po_ty *__that, char *__name)); +static void extract_directive_message PARAMS ((po_ty *__that, char *__msgid, + lex_pos_ty *__msgid_pos, + char *__msgstr, + lex_pos_ty *__msgstr_pos)); +static void extract_parse_brief PARAMS ((po_ty *__that)); +static void extract_comment PARAMS ((po_ty *__that, const char *__s)); +static void extract_comment_dot PARAMS ((po_ty *__that, const char *__s)); +static void extract_comment_filepos PARAMS ((po_ty *__that, const char *__name, + int __line)); +static void extract_comment_special PARAMS ((po_ty *that, const char *s)); +static void read_po_file PARAMS ((const char *__file_name, + message_list_ty *__mlp)); +static long difftm PARAMS ((const struct tm *__a, const struct tm *__b)); +static message_ty *construct_header PARAMS ((void)); +static enum is_c_format test_whether_c_format PARAMS ((const char *__s)); + + +/* The scanners must all be functions returning void and taking one + string argument and a message list argument. */ +typedef void (*scanner_fp) PARAMS ((const char *, message_list_ty *)); + +static void scanner_c PARAMS ((const char *, message_list_ty *)); +static void scanner_cxx PARAMS ((const char *, message_list_ty *)); +static const char *extension_to_language PARAMS ((const char *)); +static scanner_fp language_to_scanner PARAMS ((const char *)); + + +int +main (argc, argv) + int argc; + char *argv[]; +{ + int cnt; + int optchar; + int do_help = 0; + int do_version = 0; + message_list_ty *mlp; + int join_existing = 0; + int sort_output = 0; + int sort_by_file = 0; + char *file_name; + const char *files_from = NULL; + string_list_ty *file_list; + char *output_file = NULL; + scanner_fp scanner = NULL; + + /* Set program name for messages. */ + program_name = argv[0]; + error_print_progname = error_print; + warn_id_len = WARN_ID_LEN; + +#ifdef HAVE_SETLOCALE + /* Set locale via LC_ALL. */ + setlocale (LC_ALL, ""); +#endif + + /* Set the text message domain. */ + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + /* Set initial value of variables. */ + line_comment = -1; + default_domain = MESSAGE_DOMAIN_DEFAULT; + + while ((optchar = getopt_long (argc, argv, + "ac::Cd:D:eEf:Fhijk::l:L:m::M::no:p:sTVw:x:", + long_options, NULL)) != EOF) + switch (optchar) + { + case '\0': /* Long option. */ + break; + case 'a': + extract_all = 1; + break; + case 'c': + if (optarg == NULL) + { + add_all_comments = 1; + comment_tag = NULL; + } + else + { + add_all_comments = 0; + comment_tag = optarg; + /* We ignore leading white space. */ + while (isspace (*comment_tag)) + ++comment_tag; + } + break; + case 'C': + scanner = language_to_scanner ("C++"); + break; + case 'd': + default_domain = optarg; + break; + case 'D': + dir_list_append (optarg); + break; + case 'e': + message_print_style_escape (0); + break; + case 'E': + message_print_style_escape (1); + break; + case 'f': + files_from = optarg; + break; + case 'F': + sort_by_file = 1; + break; + case 'h': + do_help = 1; + break; + case 'i': + message_print_style_indent (); + break; + case 'j': + join_existing = 1; + break; + case 'k': + if (optarg == NULL || *optarg != '\0') + xgettext_lex_keyword (optarg); + break; + case 'l': + { + char *endp; + size_t tmp_val = strtoul (optarg, &endp, 0); + if (endp[0] == '\0') + warn_id_len = tmp_val; + } + break; + case 'L': + scanner = language_to_scanner (optarg); + break; + case 'm': + /* -m takes an optional argument. If none is given "" is assumed. */ + msgstr_prefix = optarg == NULL ? "" : optarg; + break; + case 'M': + /* -M takes an optional argument. If none is given "" is assumed. */ + msgstr_suffix = optarg == NULL ? "" : optarg; + break; + case 'n': + line_comment = 1; + break; + case 'o': + output_file = optarg; + break; + case 'p': + { + size_t len = strlen (optarg); + + if (output_dir != NULL) + free (output_dir); + + if (optarg[len - 1] == '/') + output_dir = xstrdup (optarg); + else + { + asprintf (&output_dir, "%s/", optarg); + if (output_dir == NULL) + /* We are about to construct the absolute path to the + directory for the output files but asprintf failed. */ + error (EXIT_FAILURE, errno, _("while preparing output")); + } + } + break; + case 's': + sort_output = 1; + break; + case 'S': + message_print_style_uniforum (); + break; + case 'T': + xgettext_lex_trigraphs (); + break; + case 'V': + do_version = 1; + break; + case 'w': + { + int value; + char *endp; + value = strtol (optarg, &endp, 10); + if (endp != optarg) + message_page_width_set (value); + } + break; + case 'x': + read_exclusion_file (optarg); + break; + default: + usage (EXIT_FAILURE); + /* NOTREACHED */ + } + + /* Normalize selected options. */ + if (omit_header != 0 && line_comment < 0) + line_comment = 0; + + if (!line_comment && sort_by_file) + error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"), + "--no-location", "--sort-by-file"); + + if (sort_output && sort_by_file) + error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"), + "--sort-output", "--sort-by-file"); + + if (join_existing && strcmp (default_domain, "-") == 0) + error (EXIT_FAILURE, 0, _("\ +--join-existing cannot be used when output is written to stdout")); + + /* Version information requested. */ + if (do_version) + { + printf ("%s (GNU %s) %s\n", basename (program_name), PACKAGE, VERSION); + /* xgettext: no-wrap */ + printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\ +This is free software; see the source for copying conditions. There is NO\n\ +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ +"), + "1995, 1996, 1997, 1998"); + printf (_("Written by %s.\n"), "Ulrich Drepper"); + exit (EXIT_SUCCESS); + } + + /* Help is requested. */ + if (do_help) + usage (EXIT_SUCCESS); + + /* Test whether we have some input files given. */ + if (files_from == NULL && optind >= argc) + { + error (EXIT_SUCCESS, 0, _("no input file given")); + usage (EXIT_FAILURE); + } + + /* Canonize msgstr prefix/suffix. */ + if (msgstr_prefix != NULL && msgstr_suffix == NULL) + msgstr_suffix = ""; + else if (msgstr_prefix == NULL && msgstr_suffix != NULL) + msgstr_prefix = NULL; + + /* Default output directory is the current directory. */ + if (output_dir == NULL) + output_dir = "."; + + /* Construct the name of the ouput file. If the default domain has + the special name "-" we write to stdout. */ + if (output_file) + { + if (output_file[0] == '/' || + strcmp(output_dir, ".") == 0 || strcmp(output_file, "-") == 0) + file_name = xstrdup (output_file); + else + { + /* Please do NOT add a .po suffix! */ + file_name = xmalloc (strlen (output_dir) + + strlen (default_domain) + 2); + stpcpy (stpcpy (stpcpy (file_name, output_dir), "/"), output_file); + } + } + else if (strcmp (default_domain, "-") == 0) + file_name = "-"; + else + { + file_name = (char *) xmalloc (strlen (output_dir) + + strlen (default_domain) + + sizeof (".po") + 2); + stpcpy (stpcpy (stpcpy (stpcpy (file_name, output_dir), "/"), + default_domain), ".po"); + } + + /* Determine list of files we have to process. */ + if (files_from != NULL) + file_list = read_name_from_file (files_from); + else + file_list = string_list_alloc (); + /* Append names from command line. */ + for (cnt = optind; cnt < argc; ++cnt) + string_list_append_unique (file_list, argv[cnt]); + + /* Allocate a message list to remember all the messages. */ + mlp = message_list_alloc (); + + /* Generate a header, so that we know how and when this PO file was + created. */ + if (!omit_header) + message_list_append (mlp, construct_header ()); + + /* Read in the old messages, so that we can add to them. */ + if (join_existing) + read_po_file (file_name, mlp); + + /* Process all input files. */ + for (cnt = 0; cnt < file_list->nitems; ++cnt) + { + const char *fname; + scanner_fp scan_file; + + fname = file_list->item[cnt]; + + if (scanner) + scan_file = scanner; + else + { + const char *extension; + const char *language; + + /* Work out what the file extension is. */ + extension = strrchr (fname, '/'); + if (!extension) + extension = fname; + extension = strrchr (extension, '.'); + if (extension) + ++extension; + else + extension = ""; + + /* derive the language from the extension, and the scanner + function from the language. */ + language = extension_to_language (extension); + if (language == NULL) + { + error (0, 0, _("\ +warning: file `%s' extension `%s' is unknown; will try C"), fname, extension); + language = "C"; + } + scan_file = language_to_scanner (language); + } + + /* Scan the file. */ + scan_file (fname, mlp); + } + string_list_free (file_list); + + /* Sorting the list of messages. */ + if (sort_by_file) + message_list_sort_by_filepos (mlp); + else if (sort_output) + message_list_sort_by_msgid (mlp); + + /* Write the PO file. */ + message_list_print (mlp, file_name, force_po, do_debug); + + exit (EXIT_SUCCESS); +} + + +/* Display usage information and exit. */ +static void +usage (status) + int status; +{ + if (status != EXIT_SUCCESS) + fprintf (stderr, _("Try `%s --help' for more information.\n"), + program_name); + else + { + /* xgettext: no-wrap */ + printf (_("\ +Usage: %s [OPTION] INPUTFILE ...\n\ +Extract translatable string from given input files.\n\ +\n\ +Mandatory arguments to long options are mandatory for short options too.\n\ + -a, --extract-all extract all strings\n\ + -c, --add-comments[=TAG] place comment block with TAG (or those\n\ + preceding keyword lines) in output file\n\ + -C, --c++ shorthand for --language=C++\n\ + --debug more detailed formatstring recognision result\n\ + -d, --default-domain=NAME use NAME.po for output (instead of messages.po)\n\ + -D, --directory=DIRECTORY add DIRECTORY to list for input files search\n\ + -e, --no-escape do not use C escapes in output (default)\n\ + -E, --escape use C escapes in output, no extended chars\n\ + -f, --files-from=FILE get list of input files from FILE\n\ + --force-po write PO file even if empty\n\ + --foreign-user omit FSF copyright in output for foreign user\n\ + -F, --sort-by-file sort output by file location\n"), + program_name); + /* xgettext: no-wrap */ + printf (_("\ + -h, --help display this help and exit\n\ + -i, --indent write the .po file using indented style\n\ + -j, --join-existing join messages with existing file\n\ + -k, --keyword[=WORD] additonal keyword to be looked for (without\n\ + WORD means not to use default keywords)\n\ + -l, --string-limit=NUMBER set string length limit to NUMBER instead %u\n\ + -L, --language=NAME recognise the specified language (C, C++, PO),\n\ + otherwise is guessed from file extension\n\ + -m, --msgstr-prefix[=STRING] use STRING or \"\" as prefix for msgstr entries\n\ + -M, --msgstr-suffix[=STRING] use STRING or \"\" as suffix for msgstr entries\n\ + --no-location do not write '#: filename:line' lines\n"), + WARN_ID_LEN); + /* xgettext: no-wrap */ + fputs (_("\ + -n, --add-location generate '#: filename:line' lines (default)\n\ + --omit-header don't write header with `msgid \"\"' entry\n\ + -o, --output=FILE write output to specified file\n\ + -p, --output-dir=DIR output files will be placed in directory DIR\n\ + -s, --sort-output generate sorted output and remove duplicates\n\ + --strict write out strict Uniforum conforming .po file\n\ + -T, --trigraphs understand ANSI C trigraphs for input\n\ + -V, --version output version information and exit\n\ + -w, --width=NUMBER set output page width\n\ + -x, --exclude-file=FILE entries from FILE are not extracted\n\ +\n\ +If INPUTFILE is -, standard input is read.\n"), stdout); + fputs (_("Report bugs to <[email protected]>.\n"), + stdout); + } + + exit (status); +} + + +/* The address of this function will be assigned to the hook in the error + functions. */ +static void +error_print () +{ + /* We don't want the program name to be printed in messages. */ +} + + +/* Read list of files to process from file. */ +static string_list_ty * +read_name_from_file (file_name) + const char *file_name; +{ + size_t line_len = 0; + char *line_buf = NULL; + FILE *fp; + string_list_ty *result; + + if (strcmp (file_name, "-") == 0) + fp = stdin; + else + { + fp = fopen (file_name, "r"); + if (fp == NULL) + error (EXIT_FAILURE, errno, + _("error while opening \"%s\" for reading"), file_name); + } + + result = string_list_alloc (); + + while (!feof (fp)) + { + /* Read next line from file. */ + int len = getline (&line_buf, &line_len, fp); + + /* In case of an error leave loop. */ + if (len < 0) + break; + + /* Remove trailing '\n'. */ + if (len > 0 && line_buf[len - 1] == '\n') + line_buf[--len] = '\0'; + + /* Test if we have to ignore the line. */ + if (*line_buf == '\0' || *line_buf == '#') + continue; + + string_list_append_unique (result, line_buf); + } + + /* Free buffer allocated through getline. */ + if (line_buf != NULL) + free (line_buf); + + /* Close input stream. */ + if (fp != stdin) + fclose (fp); + + return result; +} + + +static void +exclude_directive_domain (pop, name) + po_ty *pop; + char *name; +{ + po_gram_error (_("this file may not contain domain directives")); +} + + +static void +exclude_directive_message (pop, msgid, msgid_pos, msgstr, msgstr_pos) + po_ty *pop; + char *msgid; + lex_pos_ty *msgid_pos; + char *msgstr; + lex_pos_ty *msgstr_pos; +{ + message_ty *mp; + + /* See if this message ID has been seen before. */ + if (exclude == NULL) + exclude = message_list_alloc (); + mp = message_list_search (exclude, msgid); + if (mp != NULL) + free (msgid); + else + { + mp = message_alloc (msgid); + /* Do not free msgid. */ + message_list_append (exclude, mp); + } + + /* All we care about is the msgid. Throw the msgstr away. + Don't even check for duplicate msgids. */ + free (msgstr); +} + + +/* So that the one parser can be used for multiple programs, and also + use good data hiding and encapsulation practices, an object + oriented approach has been taken. An object instance is allocated, + and all actions resulting from the parse will be through + invocations of method functions of that object. */ + +static po_method_ty exclude_methods = +{ + sizeof (po_ty), + NULL, /* constructor */ + NULL, /* destructor */ + exclude_directive_domain, + exclude_directive_message, + NULL, /* parse_brief */ + NULL, /* parse_debrief */ + NULL, /* comment */ + NULL, /* comment_dot */ + NULL, /* comment_filepos */ + NULL, /* comment_special */ +}; + + +static void +read_exclusion_file (file_name) + char *file_name; +{ + po_ty *pop; + + pop = po_alloc (&exclude_methods); + po_scan (pop, file_name); + po_free (pop); +} + + +static void +remember_a_message (mlp, tp) + message_list_ty *mlp; + xgettext_token_ty *tp; +{ + enum is_c_format is_c_format = undecided; + enum is_c_format do_wrap = undecided; + char *msgid; + message_ty *mp; + char *msgstr; + + msgid = tp->string; + + /* See whether we shall exclude this message. */ + if (exclude != NULL && message_list_search (exclude, msgid) != NULL) + { + /* Tell the lexer to reset its comment buffer, so that the next + message gets the correct comments. */ + xgettext_lex_comment_reset (); + + return; + } + + /* See if we have seen this message before. */ + mp = message_list_search (mlp, msgid); + if (mp != NULL) + { + free (msgid); + is_c_format = mp->is_c_format; + do_wrap = mp->do_wrap; + } + else + { + static lex_pos_ty pos = { __FILE__, __LINE__ }; + + /* Allocate a new message and append the message to the list. */ + mp = message_alloc (msgid); + /* Do not free msgid. */ + message_list_append (mlp, mp); + + /* Construct the msgstr from the prefix and suffix, otherwise use the + empty string. */ + if (msgstr_prefix) + { + msgstr = (char *) xmalloc (strlen (msgstr_prefix) + + strlen (msgid) + + strlen(msgstr_suffix) + 1); + stpcpy (stpcpy (stpcpy (msgstr, msgstr_prefix), msgid), + msgstr_suffix); + } + else + msgstr = ""; + message_variant_append (mp, MESSAGE_DOMAIN_DEFAULT, msgstr, &pos); + } + + /* Ask the lexer for the comments it has seen. Only do this for the + first instance, otherwise there could be problems; especially if + the same comment appears before each. */ + if (!mp->comment_dot) + { + int j; + + for (j = 0; ; ++j) + { + const char *s = xgettext_lex_comment (j); + if (s == NULL) + break; + + /* To reduce the possibility of unwanted matches be do a two + step match: the line must contains `xgettext:' and one of + the possible format description strings. */ + if (strstr (s, "xgettext:") != NULL) + { + is_c_format = parse_c_format_description_string (s); + do_wrap = parse_c_width_description_string (s); + + /* If we found a magic string we don't print it. */ + if (is_c_format != undecided || do_wrap != undecided) + continue; + } + if (add_all_comments + || (comment_tag != NULL && strncmp (s, comment_tag, + strlen (comment_tag)) == 0)) + message_comment_dot_append (mp, s); + } + } + + /* If not already decided, examine the msgid. */ + if (is_c_format == undecided) + is_c_format = test_whether_c_format (mp->msgid); + + mp->is_c_format = is_c_format; + mp->do_wrap = do_wrap == no ? no : yes; /* By default we wrap. */ + + /* Remember where we saw this msgid. */ + if (line_comment) + message_comment_filepos (mp, tp->file_name, tp->line_number); + + /* Tell the lexer to reset its comment buffer, so that the next + message gets the correct comments. */ + xgettext_lex_comment_reset (); +} + + +static void +scan_c_file(filename, mlp, is_cpp_file) + const char *filename; + message_list_ty *mlp; + int is_cpp_file; +{ + int state; + char *msgid = 0; + + /* Inform scanner whether we have C++ files or not. */ + if (is_cpp_file) + xgettext_lex_cplusplus (); + + /* The file is broken into tokens. Scan the token stream, looking for + a keyword, followed by a left paren, followed by a string. When we + see this sequence, we have something to remember. We assume we are + looking at a valid C or C++ program, and leave the complaints about + the grammar to the compiler. */ + xgettext_lex_open (filename); + + /* Start state is 0. */ + state = 0; + + while (1) + { + xgettext_token_ty token; + + /* A simple state machine is used to do the recognising: + State 0 = waiting for something to happen + State 1 = seen one of our keywords with string in first parameter + State 2 = was in state 1 and now saw a left paren + State 3 = seen one of our keywords with string in second parameter + State 4 = was in state 3 and now saw a left paren + State 5 = waiting for comma after being in state 4 + State 6 = saw comma after being in state 5 + State 7 = after comma and being in state 2 + State 8 = after string and being in state 7 + */ + xgettext_lex (&token); + + switch (token.type) + { + case xgettext_token_type_keyword1: + state = 1; + continue; + + case xgettext_token_type_keyword2: + state = 3; + continue; + + case xgettext_token_type_lp: + switch (state) + { + case 1: + state = 2; + break; + case 3: + state = 4; + break; + default: + state = 0; + } + continue; + + case xgettext_token_type_rp: + if (state == 2 || state == 8) { + token.string = strdup(msgid); + remember_a_message (mlp, &token); + free(msgid); + msgid = 0; + state = 0; + } + continue; + + case xgettext_token_type_comma: + switch (state) { + case 5: + state = 6; + break; + case 2: + state = 7; + break; + case 8: { + char *newstring = (char*)malloc(strlen(msgid) + 2); + strcpy(newstring, "_n:"); + strcat(newstring, msgid + 2); + free(msgid); + token.string = newstring; + remember_a_message (mlp, &token); + msgid = 0; + state = 0; + break; + } + default: + state = 0; + break; + } + continue; + + case xgettext_token_type_string_literal: + if (extract_all || state == 2 || state == 6) + { + if (msgid) + free(msgid); + msgid = strdup(token.string); + // state = 0; + } + else if (state == 7) + { + if (msgid) { + char *newstring = (char*)malloc(strlen(msgid) + strlen(token.string) + 20); + sprintf(newstring, "_: %s\n%s", msgid, token.string); + free(msgid); + free(token.string); + token.string = msgid = newstring; + state = 8; + } + } + else + { + free (token.string); + state = (state == 4 || state == 5) ? 5 : 0; + } + continue; + + case xgettext_token_type_symbol: + state = (state == 4 || state == 5) ? 5 : 0; + continue; + + default: + state = 0; + continue; + + case xgettext_token_type_eof: + break; + } + + break; + } + + /* Close scanner. */ + xgettext_lex_close (); +} + + +typedef struct extract_class_ty extract_class_ty; +struct extract_class_ty +{ + /* Inherited instance variables and methods. */ + PO_BASE_TY + + /* Cumulative list of messages. */ + message_list_ty *mlp; + + /* Cumulative comments for next message. */ + string_list_ty *comment; + string_list_ty *comment_dot; + + int is_fuzzy; + int is_c_format; + int do_wrap; + + int filepos_count; + lex_pos_ty *filepos; +}; + + +static void +extract_constructor (that) + po_ty *that; +{ + extract_class_ty *this = (extract_class_ty *) that; + + this->mlp = NULL; /* actually set in read_po_file, below */ + this->comment = NULL; + this->comment_dot = NULL; + this->is_fuzzy = 0; + this->is_c_format = undecided; + this->do_wrap = undecided; + this->filepos_count = 0; + this->filepos = NULL; +} + + +static void +extract_directive_domain (that, name) + po_ty *that; + char *name; +{ + po_gram_error (_("this file may not contain domain directives")); +} + + +static void +extract_directive_message (that, msgid, msgid_pos, msgstr, msgstr_pos) + po_ty *that; + char *msgid; + lex_pos_ty *msgid_pos; + char *msgstr; + lex_pos_ty *msgstr_pos; +{ + extract_class_ty *this = (extract_class_ty *)that; + message_ty *mp; + message_variant_ty *mvp; + size_t j; + + /* See whether we shall exclude this message. */ + if (exclude != NULL && message_list_search (exclude, msgid) != NULL) + goto discard; + + /* If the msgid is the empty string, it is the old header. + Throw it away, we have constructed a new one. */ + if (*msgid == '\0') + { + discard: + free (msgid); + free (msgstr); + if (this->comment != NULL) + string_list_free (this->comment); + if (this->comment_dot != NULL) + string_list_free (this->comment_dot); + if (this->filepos != NULL) + free (this->filepos); + this->comment = NULL; + this->comment_dot = NULL; + this->filepos_count = 0; + this->filepos = NULL; + this->is_fuzzy = 0; + this->is_c_format = undecided; + this->do_wrap = undecided; + return; + } + + /* See if this message ID has been seen before. */ + mp = message_list_search (this->mlp, msgid); + if (mp) + free (msgid); + else + { + mp = message_alloc (msgid); + message_list_append (this->mlp, mp); + } + + /* Add the accumulated comments to the message. Clear the + accumulation in preparation for the next message. */ + if (this->comment != NULL) + { + for (j = 0; j < this->comment->nitems; ++j) + message_comment_append (mp, this->comment->item[j]); + string_list_free (this->comment); + this->comment = NULL; + } + if (this->comment_dot != NULL) + { + for (j = 0; j < this->comment_dot->nitems; ++j) + message_comment_dot_append (mp, this->comment_dot->item[j]); + string_list_free (this->comment_dot); + this->comment_dot = NULL; + } + mp->is_fuzzy = this->is_fuzzy; + mp->is_c_format = this->is_c_format; + mp->do_wrap = this->do_wrap; + for (j = 0; j < this->filepos_count; ++j) + { + lex_pos_ty *pp; + + pp = &this->filepos[j]; + message_comment_filepos (mp, pp->file_name, pp->line_number); + free (pp->file_name); + } + if (this->filepos != NULL) + free (this->filepos); + this->filepos_count = 0; + this->filepos = NULL; + this->is_fuzzy = 0; + this->is_c_format = undecided; + this->do_wrap = undecided; + + /* See if this domain has been seen for this message ID. */ + mvp = message_variant_search (mp, MESSAGE_DOMAIN_DEFAULT); + if (mvp != NULL && strcmp (msgstr, mvp->msgstr) != 0) + { + gram_error_at_line (msgid_pos, _("duplicate message definition")); + gram_error_at_line (&mvp->pos, _("\ +...this is the location of the first definition")); + free (msgstr); + } + else + message_variant_append (mp, MESSAGE_DOMAIN_DEFAULT, msgstr, msgstr_pos); +} + + +static void +extract_parse_brief (that) + po_ty *that; +{ + po_lex_pass_comments (1); +} + + +static void +extract_comment (that, s) + po_ty *that; + const char *s; +{ + extract_class_ty *this = (extract_class_ty *) that; + + if (this->comment == NULL) + this->comment = string_list_alloc (); + string_list_append (this->comment, s); +} + + +static void +extract_comment_dot (that, s) + po_ty *that; + const char *s; +{ + extract_class_ty *this = (extract_class_ty *) that; + + if (this->comment_dot == NULL) + this->comment_dot = string_list_alloc (); + string_list_append (this->comment_dot, s); +} + + +static void +extract_comment_filepos (that, name, line) + po_ty *that; + const char *name; + int line; +{ + extract_class_ty *this = (extract_class_ty *) that; + size_t nbytes; + lex_pos_ty *pp; + + /* Write line numbers only if -n option is given. */ + if (line_comment != 0) + { + nbytes = (this->filepos_count + 1) * sizeof (this->filepos[0]); + this->filepos = xrealloc (this->filepos, nbytes); + pp = &this->filepos[this->filepos_count++]; + pp->file_name = xstrdup (name); + pp->line_number = line; + } +} + + +static void +extract_comment_special (that, s) + po_ty *that; + const char *s; +{ + extract_class_ty *this = (extract_class_ty *) that; + + if (strstr (s, "fuzzy") != NULL) + this->is_fuzzy = 1; + this->is_c_format = parse_c_format_description_string (s); + this->do_wrap = parse_c_width_description_string (s); +} + + +/* So that the one parser can be used for multiple programs, and also + use good data hiding and encapsulation practices, an object + oriented approach has been taken. An object instance is allocated, + and all actions resulting from the parse will be through + invocations of method functions of that object. */ + +static po_method_ty extract_methods = +{ + sizeof (extract_class_ty), + extract_constructor, + NULL, /* destructor */ + extract_directive_domain, + extract_directive_message, + extract_parse_brief, + NULL, /* parse_debrief */ + extract_comment, + extract_comment_dot, + extract_comment_filepos, + extract_comment_special +}; + + +/* Read the contents of the specified .po file into a message list. */ + +static void +read_po_file (file_name, mlp) + const char *file_name; + message_list_ty *mlp; +{ + po_ty *pop = po_alloc (&extract_methods); + ((extract_class_ty *) pop)->mlp = mlp; + po_scan (pop, file_name); + po_free (pop); +} + + +#define TM_YEAR_ORIGIN 1900 + +/* Yield A - B, measured in seconds. */ +static long +difftm (a, b) + const struct tm *a; + const struct tm *b; +{ + int ay = a->tm_year + (TM_YEAR_ORIGIN - 1); + int by = b->tm_year + (TM_YEAR_ORIGIN - 1); + /* Some compilers cannot handle this as a single return statement. */ + long days = ( + /* difference in day of year */ + a->tm_yday - b->tm_yday + /* + intervening leap days */ + + ((ay >> 2) - (by >> 2)) + - (ay / 100 - by / 100) + + ((ay / 100 >> 2) - (by / 100 >> 2)) + /* + difference in years * 365 */ + + (long) (ay - by) * 365l); + + return 60l * (60l * (24l * days + (a->tm_hour - b->tm_hour)) + + (a->tm_min - b->tm_min)) + + (a->tm_sec - b->tm_sec); +} + + +static message_ty * +construct_header () +{ + time_t now; + struct tm local_time; + message_ty *mp; + char *msgstr; + static lex_pos_ty pos = { __FILE__, __LINE__, }; + char tz_sign; + long tz_min; + + mp = message_alloc (""); + + if (foreign_user) + message_comment_append (mp, "\ +SOME DESCRIPTIVE TITLE.\n\ +FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n"); + else + message_comment_append (mp, "\ +SOME DESCRIPTIVE TITLE.\n\ +Copyright (C) YEAR Free Software Foundation, Inc.\n\ +FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n"); + + mp->is_fuzzy = 1; + + time (&now); + local_time = *localtime (&now); + tz_sign = '+'; + tz_min = difftm (&local_time, gmtime (&now)) / 60; + if (tz_min < 0) + { + tz_min = -tz_min; + tz_sign = '-'; + } + + asprintf (&msgstr, "\ +Project-Id-Version: PACKAGE VERSION\n\ +POT-Creation-Date: %d-%02d-%02d %02d:%02d%c%02d%02d\n\ +PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n\ +Last-Translator: FULL NAME <EMAIL@ADDRESS>\n\ +Language-Team: LANGUAGE <[email protected]>\n\ +MIME-Version: 1.0\n\ +Content-Type: text/plain; charset=CHARSET\n\ +Content-Transfer-Encoding: ENCODING\n", + local_time.tm_year + TM_YEAR_ORIGIN, + local_time.tm_mon + 1, + local_time.tm_mday, + local_time.tm_hour, + local_time.tm_min, + tz_sign, tz_min / 60, tz_min % 60); + + if (msgstr == NULL) + error (EXIT_FAILURE, errno, _("while preparing output")); + + message_variant_append (mp, MESSAGE_DOMAIN_DEFAULT, msgstr, &pos); + + return mp; +} + + +/* We make a pessimistic guess whether the given string is a format + string or not. Pessimistic means here that with the first + occurence of an unknown format element we say `impossible'. */ +static enum is_c_format +test_whether_c_format (s) + const char *s; +{ + struct printf_spec spec; + + if (s == NULL || *(s = find_spec (s)) == '\0') + /* We return `possible' here because sometimes strings are used + with printf even if they don't contain any format specifier. + If the translation in this case would contain a specifier, this + would result in an error. */ + return impossible; + + for (s = find_spec (s); *s != '\0'; s = spec.next_fmt) + { + size_t dummy; + + (void) parse_one_spec (s, 0, &spec, &dummy); + if (strchr ("iduoxXeEfgGcspnm", spec.info.spec) == NULL) + return impossible; + } + + return possible; +} + + +static void + scanner_c (filename, mlp) + const char *filename; + message_list_ty *mlp; +{ + scan_c_file (filename, mlp, 0); +} + + +static void +scanner_cxx (filename, mlp) + const char *filename; + message_list_ty *mlp; +{ + scan_c_file (filename, mlp, 1); +} + + +#define SIZEOF(a) (sizeof(a) / sizeof(a[0])) +#define ENDOF(a) ((a) + SIZEOF(a)) + + +static scanner_fp +language_to_scanner (name) + const char *name; +{ + typedef struct table_ty table_ty; + struct table_ty + { + const char *name; + scanner_fp func; + }; + + static table_ty table[] = + { + { "C", scanner_c, }, + { "C++", scanner_cxx, }, + { "PO", read_po_file, }, + /* Here will follow more languages and their scanners: awk, perl, + etc... Make sure new scanners honor the --exlude-file option. */ + }; + + table_ty *tp; + + for (tp = table; tp < ENDOF(table); ++tp) + { + if (strcasecmp(name, tp->name) == 0) + return tp->func; + } + error (EXIT_FAILURE, 0, _("language `%s' unknown"), name); + /* NOTREACHED */ + return NULL; +} + + +static const char * +extension_to_language (extension) + const char *extension; +{ + typedef struct table_ty table_ty; + struct table_ty + { + const char *extension; + const char *language; + }; + + static table_ty table[] = + { + { "c", "C", }, + { "C", "C++", }, + { "c++", "C++", }, + { "cc", "C++", }, + { "cxx", "C++", }, + { "h", "C", }, + { "po", "PO", }, + { "pot", "PO", }, + { "pox", "PO", }, + /* Here will follow more file extensions: sh, pl, tcl ... */ + }; + + table_ty *tp; + + for (tp = table; tp < ENDOF(table); ++tp) + { + if (strcmp(extension, tp->extension) == 0) + return tp->language; + } + return NULL; +} |