• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Aucun tag

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

POSIX.1 National Language Support API for MinGW


Commit MetaInfo

Révisionaeedfdf6ea611f82e97fd878b15d872cf4c9a593 (tree)
l'heure2007-05-13 01:54:36
AuteurKeith Marshall <keithmarshall@user...>
CommiterKeith Marshall

Message de Log

Add support for single message deletion.

Change Summary

Modification

--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
1+2007-05-12 Keith Marshall <keithmarshall@users.sourceforge.net>
2+
3+ Add support for single message deletion.
4+
5+ * mcsource.c: More comment improvements.
6+ (mc_source): Set `this->base = NULL' on parsing a message number
7+ immediately followed by `newline'; this causes the message to be
8+ removed from the internal catalogue index, when the input record
9+ is merged.
10+
11+ * mcmerge.c (mc_merge): Reorganise logic; add section to remove
12+ entries with `set > 0 && msg > 0 && base == NULL'.
13+ Relocate logic block for processing `delset' requests; still need
14+ an implementation for this.
15+ Add logic block to catch and diagnose invalid index entries.
16+
17+ * include/gcmsgs.h (MSG_CATLOAD_FAILED): Renamed symbolic define...
18+ (MSG_BAD_CATALOGUE): ...to this.
19+ (MSG_INTERNAL_ERROR, MSG_BAD_INDEX): New message defines; used by
20+ `mc_merge', to diagnose invalid index entries.
21+
22+ * include/gencat.h (msgarg): New macro; used by `mc_merge', to
23+ associate `MSG_BAD_INDEX' with `MSG_INTERNAL_ERROR'.
24+
25+ * gencat.c (main): Use `MSG_BAD_CATALOGUE'.
26+
127 2007-05-11 Keith Marshall <keithmarshall@users.sourceforge.net>
228
329 * mcsource.c: Miscellaneous comment and layout improvements;
--- a/gencat.c
+++ b/gencat.c
@@ -8,7 +8,7 @@
88 * This file implements the `main' function for the `gencat' program.
99 *
1010 * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
11- * Last modification: 05-Mar-2007
11+ * Last modification: 12-May-2007
1212 *
1313 *
1414 * This is free software. It is provided AS IS, in the hope that it may
@@ -90,7 +90,6 @@ int main( int argc, char **argv )
9090 /* Initialise the message list, to incorporate any messages which
9191 * are already contained within the specified message catalogue.
9292 */
93-
9493 if( (cat = mc_load( msgcat = *++argv )) == NULL )
9594 switch( errno )
9695 {
@@ -102,13 +101,12 @@ int main( int argc, char **argv )
102101 break;
103102
104103 default:
105- fprintf( errmsg( MSG_CATLOAD_FAILED ), progname, msgcat );
104+ fprintf( errmsg( MSG_BAD_CATALOGUE ), progname, msgcat );
106105 return EXIT_FAILURE;
107106 }
108107
109108 /* Merge new or updated message definitions from input files.
110109 */
111-
112110 while( --argc )
113111 cat = mc_merge( cat, mc_source( *++argv ));
114112
@@ -199,7 +197,6 @@ int main( int argc, char **argv )
199197 /* User specified insufficient command line arguments.
200198 * Diagnose, and bail out.
201199 */
202-
203200 fprintf( errmsg( MSG_MISSING_ARGS ), progname );
204201 fprintf( errmsg( MSG_GENCAT_USAGE ), progname );
205202 return EXIT_FAILURE;
@@ -207,4 +204,4 @@ int main( int argc, char **argv )
207204 return EXIT_SUCCESS;
208205 }
209206
210-/* $RCSfile$Revision$: end of file */
207+/* $RCSfile$Revision: 1.1.1.1 $: end of file */
--- a/include/gcmsgs.h
+++ b/include/gcmsgs.h
@@ -40,7 +40,8 @@
4040 #define MSG_GENCAT_USAGE 1, 2, "usage: %s catalogue-name input-file ...\n"
4141 #define MSG_OUTPUT_NOFILE 1, 3, "%s: %s: cannot create temporary output file\n"
4242 #define MSG_OUT_OF_MEMORY 1, 4, "%s: out of memory\n"
43-#define MSG_CATLOAD_FAILED 2, 1, "%s: %s: catalogue exists, but failed to load\n"
43+#define MSG_INTERNAL_ERROR 1, 5, "%s: internal error: %s\n"
44+#define MSG_BAD_CATALOGUE 2, 1, "%s: %s: file is not a valid message catalogue\n"
4445 #define MSG_UNKNOWN_CODESET 2, 2, "%s: %s: unknown codeset descriptor\n"
4546 #define MSG_CODESET_CLASH 2, 3, "%s:%u: codeset `%s' conflicts with prior declaration\n"
4647 #define MSG_HAD_CODESET 2, 4, "%s:%u: codeset `%s' was previously declared here\n"
@@ -48,11 +49,12 @@
4849 #define MSG_MSGNUM_NOT_INCR 2, 6, "invalid message number: expecting > %d; got %d\n"
4950 #define MSG_REDEFINED 2, 7, "%s: %s:%u: redefinition of message %u in set %u\n"
5051 #define MSG_PREVIOUS_HERE 2, 8, "%s: %s:%u: previous definition was here\n"
51-#define MSG_DEL_UNSUPPORTED 3, 1, "%s: %s:%u: deletion of message entities not yet supported\n"
52+#define MSG_DEL_UNSUPPORTED 3, 1, "%s: %s:%u: `delset' operation not yet supported\n"
5253 #define MSG_EOF_IN_QUOTES 3, 2, "%s:%u: unexpected EOF encountered before closing quote\n"
5354 #define MSG_TEXT_DISCARDED 3, 3, "%s:%u: incomplete message marked for deletion\n"
5455 #define MSG_MISSING_NEWLINE 3, 4, "%s:%u: missing newline at end of file\n"
56+#define MSG_BAD_INDEX 3, 5, "invalid reference in message index"
5557 /* !
5658 * !$ end of file
5759 */
58-#endif /* !defined( GCMSGS_H ): $RCSfile$Revision$: end of file */
60+#endif /* !defined( GCMSGS_H ): $RCSfile$Revision: 1.1.1.1 $: end of file */
--- a/include/gencat.h
+++ b/include/gencat.h
@@ -11,7 +11,7 @@
1111 * the prototypes for the functions used to implement `gencat'.
1212 *
1313 * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
14- * Last modification: 27-Mar-2007
14+ * Last modification: 12-May-2007
1515 *
1616 *
1717 * This is free software. It is provided AS IS, in the hope that it may
@@ -89,10 +89,11 @@ extern struct msgdict *mc_merge( struct msgdict *, struct msgdict * );
8989 extern char *map_codeset( iconv_t *, char *, char * );
9090 extern size_t iconv_wrap( int, iconv_t, char *, size_t, char *, size_t );
9191
92+#define msgarg(MSG) catgets( gencat_messages, MSG )
9293 #define errmsg(MSG) stderr, catgets( gencat_messages, MSG )
9394 #define FATAL(MSG) input, linenum, catgets( gencat_messages, MSG )
9495
9596 #define GENCAT_MSG_SRC(REF) progname, (REF)->src, (REF)->lineno
9697 #define GENCAT_MSG_INPUT GENCAT_MSG_SRC( input )
9798
98-#endif /* !defined( GENCAT_H ): $RCSfile$Revision$: end of file */
99+#endif /* !defined( GENCAT_H ): $RCSfile$Revision: 1.1.1.1 $: end of file */
--- a/mcmerge.c
+++ b/mcmerge.c
@@ -10,7 +10,7 @@
1010 * any single source file into its current internal dictionary.
1111 *
1212 * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
13- * Last modification: 30-Dec-2006
13+ * Last modification: 12-May-2007
1414 *
1515 *
1616 * This is free software. It is provided AS IS, in the hope that it may
@@ -65,128 +65,196 @@ struct msgdict *mc_merge( struct msgdict *cat, struct msgdict *input )
6565
6666 while( input )
6767 {
68+ /* Save a pointer to the *next* input record;
69+ * we will use this later, to progress to the next record,
70+ * after we've freed the current reference structure.
71+ */
6872 struct msgdict *next = input->link;
6973
7074 dfprintf(( stderr, "Process entry from %s line %u\n", input->src, input->lineno ));
71- if( input->base == NULL )
72- {
73- /* This is a `delete' operation...
74- * FIXME: we don't have support for this yet!
75- */
76- fprintf( errmsg( MSG_DEL_UNSUPPORTED ), progname, input->src, input->lineno );
77- free( input );
78- }
7975
80- else
76+ if( input->set && input->msg )
8177 {
82- /* This is either an `insert' or a `replace' operation...
83- * locate the insertion point, within the current message list.
78+ /* The input reference specifies both set and message numbers.
79+ * Thus, the operation to be performed relates to a single message,
80+ * which is to be inserted, replaced or deleted at the appropriate
81+ * position within the current message list; before proceeding,
82+ * we must locate this position.
8483 */
85-
8684 struct msgdict *curr = mark;
8785 while( curr && (curr->key < input->key) )
8886 {
87+ /* We loop over the existing messages in the dictionary,
88+ * until we find the location at which the input message
89+ * should be placed; when we find it, we leave `curr'
90+ * pointing at the target location reference, while
91+ * `mark' points to its immediate predecessor.
92+ */
8993 mark = curr;
9094 curr = curr->link;
9195 }
9296
93- if( curr == NULL )
97+ /* Now that we've identified *where* the current input reference
98+ * belongs, in the current message list, we may determine *what*
99+ * action is to be performed for this record.
100+ */
101+ if( input->base && (curr == NULL) )
94102 {
95- /* This is appending to the end of the message list... */
96-
103+ /* The input record specifies actual message content,
104+ * which is to be appended to the end of the message list...
105+ */
97106 if( mark )
98107 {
99- /* ...extending an existing message list. */
100-
108+ /* ...extending an existing message list.
109+ */
101110 input->link = mark->link;
102111 mark->link = input;
103112 dfprintf(( stderr, "Append set %u message %u after set %u message %u\n",
104113 input->set, input->msg, mark->set, mark->msg
105114 ));
106115 }
107-
108116 else
109117 {
110- /* There is no current message list; start one now! */
111-
118+ /* ...there is no current message list; start one now!
119+ */
112120 cat = mark = input;
113121 mark->link = NULL;
114122 dfprintf(( stderr, "Initialise message list at set %u message %u\n", mark->set, mark->msg ));
115123 }
116124 }
117-
118125 else if( curr->key == input->key )
119126 {
120- /* This is replacement of an existing message. */
121-
122- if( curr->lineno > 0 )
127+ /* The input record refers to a message which is already present
128+ * in the current message list; the operation to be performed is
129+ * either deletion or replacement.
130+ */
131+ if( input->base == NULL )
123132 {
124- /* This a collision...
125- * diagnose, and ignore this redefinition.
133+ /* This input reference specifies no message content;
134+ * it is a request to delete the existing message.
135+ */
136+ if( curr == cat )
137+ /*
138+ * We are deleting the first message in the current list,
139+ * so we simply reassign the initial list entry.
140+ */
141+ cat = cat->link;
142+
143+ else
144+ /* We are deleting a message from within the list, so we
145+ * relink the immediately preceding reference, to chain it
146+ * directly to the immediately succeeding one.
147+ */
148+ mark->link = curr->link;
149+
150+ /* In either case, we may release the the memory allocated to
151+ * the defunct dictionary reference for the deleted message.
126152 */
153+ free( curr );
154+ }
127155
156+ else if( curr->lineno > 0 )
157+ {
158+ /* This a redefinition of a message which has previously been
159+ * sourced from another input file in the current input stream;
160+ * this represents a collision, which is probably unintentional,
161+ * so diagnose it, and ignore this redefinition.
162+ */
128163 fprintf( errmsg( MSG_REDEFINED ), GENCAT_MSG_INPUT, curr->msg, curr->set );
129164 fprintf( errmsg( MSG_PREVIOUS_HERE ), GENCAT_MSG_SRC( curr ));
130165 }
131166
132167 else
133168 {
169+ /* This is replacement of an existing message, which has
170+ * been inherited from a previously existing message catalogue;
171+ * such replacement is assumed to be intentional, so...
172+ */
134173 dfprintf(( stderr, "Replace set %u message %u\n", curr->set, curr->msg ));
135-
136174 if( curr == cat )
137175 {
138- /* This is the first message in the current list,
139- * so we simply replace it.
176+ /* ...when this is the first message in the current list,
177+ * we simply replace it.
140178 */
141-
142179 cat = input;
143180 }
144181
145182 else
146183 {
147- /* There are preceding messages in the list,
148- * so we must relink the predecessor to this replacement.
184+ /* ...but when there are preceding messages in the list,
185+ * we must relink the predecessor to this replacement.
149186 */
150-
151187 mark->link = input;
152188 }
153189
190+ /* Now, to complete the replacement of the original message,
191+ * link any successor to the new reference, release the memory
192+ * allocated to the replaced dictionary entry, and mark the
193+ * new entry as the current reference point.
194+ */
154195 input->link = curr->link;
155196 free( curr );
156197 mark = input;
157198 }
158199 }
159-
160200 else
161201 {
162- /* This is insertion of a new message within the current list,
163- * (maybe preceding all messages which are already in the list).
202+ /* There is no existing reference with set and message numbers
203+ * matching the current input record; thus the input record must
204+ * be inserted between the existing `mark' and `curr' entries.
164205 */
165-
166206 dfprintf(( stderr, "Insert set %u message %u ", input->set, input->msg ));
167207 if( mark == curr )
168208 {
169- /* This entry must precede any which is already in the list,
170- * so make it the new initial message.
209+ /* The `curr' entry is the first in the existing dictionary,
210+ * so we insert the input record before it, as the new initial
211+ * entry in the dictionary, leaving `mark' pointing to it.
171212 */
172-
173213 dfprintf(( stderr, "at start of list " ));
174214 cat = mark = input;
175215 }
176-
177216 else
178217 {
179- /* There is already an existing message which must precede this one,
180- * so link this new one to follow the existing predecessor.
218+ /* There is already an existing message which must precede this
219+ * new entry in the dictionary, so we link this new entry as its
220+ * immediate successor.
181221 */
182-
183222 dfprintf(( stderr, "after set %u message %u and ", mark->set, mark->msg ));
184223 mark->link = input;
185224 }
225+ /*
226+ * In either case, any existing `curr' entry must be linked as
227+ * successor to the inserted entry.
228+ */
186229 dfprintf(( stderr, "before set %u message %u\n", curr->set, curr->msg ));
187230 input->link = curr;
188231 }
189232 }
233+
234+ else if( input->set && (input->base == NULL) )
235+ {
236+ /* This is a a `delset' operation...
237+ * FIXME: we don't have support for this yet!
238+ */
239+ fprintf( errmsg( MSG_DEL_UNSUPPORTED ), progname, input->src, input->lineno );
240+ free( input );
241+ }
242+
243+ else
244+ {
245+ /* The input record contains an improperly formed message reference.
246+ * We should *never* get to here! If we do, then the entire message
247+ * catalogue dictionary structure is invalid; diagnose and abort.
248+ */
249+ fprintf( errmsg( MSG_INTERNAL_ERROR ), progname, msgarg( MSG_BAD_INDEX ) );
250+ exit( EXIT_FAILURE );
251+ }
252+
253+ /* Whatever operation we have just performed, if no fatal error
254+ * occurred we proceed to the next input record, if any, using the
255+ * pointer we saved earlier, since `input->link' may not now be
256+ * a valid reference; (`input' may have been `freed').
257+ */
190258 input = next;
191259 }
192260 # ifdef DEBUG
@@ -197,7 +265,11 @@ struct msgdict *mc_merge( struct msgdict *cat, struct msgdict *input )
197265 fprintf( stderr, "%s:%u: set %u message %u\n", curr->src, curr->lineno, curr->set, curr->msg );
198266 }
199267 # endif
268+
269+ /* When all input records have been processed,
270+ * we return the resultant message catalogue index to the caller.
271+ */
200272 return cat;
201273 }
202274
203-/* $RCSfile$Revision$: end of file */
275+/* $RCSfile$Revision: 1.1.1.1 $: end of file */
--- a/mcsource.c
+++ b/mcsource.c
@@ -9,7 +9,7 @@
99 * used internally by `gencat', to compile message dictionaries.
1010 *
1111 * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
12- * Last modification: 11-May-2007
12+ * Last modification: 12-May-2007
1313 *
1414 *
1515 * This is free software. It is provided AS IS, in the hope that it may
@@ -543,9 +543,16 @@ struct msgdict *mc_source( const char *input )
543543
544544 /* We may now complete the message details in the new
545545 * dictionary slot, and commit the record to the catalogue.
546+ * Note that, if the message number tag in the source file
547+ * is on an otherwise empty line, and is *immediately*
548+ * followed by a newline, with no intervening space,
549+ * then this message should be deleted; we flag this
550+ * by setting `this->base = NULL'. In all other cases,
551+ * the message is to be placed into the catalogue, so
552+ * we set 'this->base = messages'.
546553 */
547554 this->src = input;
548- this->base = messages;
555+ this->base = (c == L'\n') ? NULL : messages;
549556 this->lineno = linenum;
550557 this->set = setnum;
551558 this->msg = msgnum = accumulator;
@@ -573,8 +580,10 @@ struct msgdict *mc_source( const char *input )
573580
574581 else
575582 {
576- /* This doesn't satisfy the requirement for incrementing "msgnum",
577- * so complain, and bail out.
583+ /* This doesn't satisfy the POSIX requirement that,
584+ * within each set, messages must appear in strictly
585+ * incrementing "msgnum" order, so complain, and
586+ * bail out.
578587 */
579588 dfputc(( '\n', stderr ));
580589 gencat_errno = mc_errout( FATAL( MSG_MSGNUM_NOT_INCR ), msgnum, accumulator );
@@ -832,6 +841,12 @@ struct msgdict *mc_source( const char *input )
832841 dfprintf(( stderr, "\n\nAllocation adjusted to %u bytes\n", (unsigned)(msgloc) ));
833842 for( tail = head; tail != NULL; tail = tail->link )
834843 {
844+ /* Just do this for all entries in the list!
845+ * Don't assume we can optimise by quitting if we find a reference
846+ * which is already mapped to the correct address; the list could
847+ * have moved, and subsequently have moved back to the old address,
848+ * in which case a later entry could be invalid.
849+ */
835850 if( tail->base != NULL )
836851 /*
837852 * Update index entries *except* those with a NULL base pointer;
@@ -849,4 +864,4 @@ struct msgdict *mc_source( const char *input )
849864 return head;
850865 }
851866
852-/* $RCSfile$Revision: 1.4 $: end of file */
867+/* $RCSfile$Revision: 1.5 $: end of file */