~ubuntu-branches/ubuntu/utopic/gettext/utopic

« back to all changes in this revision

Viewing changes to gettext-tools/src/read-catalog-abstract.c

  • Committer: Colin Watson
  • Date: 2010-08-01 21:36:08 UTC
  • mfrom: (2.1.10 sid)
  • Revision ID: cjwatson@canonical.com-20100801213608-yy7vkm8lpatep3ci
merge from Debian 0.18.1.1-1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Reading PO files, abstract class.
2
 
   Copyright (C) 1995-1996, 1998, 2000-2007 Free Software Foundation, Inc.
 
2
   Copyright (C) 1995-1996, 1998, 2000-2009 Free Software Foundation, Inc.
3
3
 
4
4
   This file was written by Peter Miller <millerp@canb.auug.org.au>
5
5
 
24
24
/* Specification.  */
25
25
#include "read-catalog-abstract.h"
26
26
 
 
27
#include <limits.h>
27
28
#include <stdlib.h>
28
29
#include <string.h>
29
30
 
89
90
 
90
91
static inline void
91
92
call_directive_message (abstract_catalog_reader_ty *pop,
92
 
                        char *msgctxt,
93
 
                        char *msgid,
94
 
                        lex_pos_ty *msgid_pos,
95
 
                        char *msgid_plural,
96
 
                        char *msgstr, size_t msgstr_len,
97
 
                        lex_pos_ty *msgstr_pos,
98
 
                        char *prev_msgctxt,
99
 
                        char *prev_msgid,
100
 
                        char *prev_msgid_plural,
101
 
                        bool force_fuzzy, bool obsolete)
 
93
                        char *msgctxt,
 
94
                        char *msgid,
 
95
                        lex_pos_ty *msgid_pos,
 
96
                        char *msgid_plural,
 
97
                        char *msgstr, size_t msgstr_len,
 
98
                        lex_pos_ty *msgstr_pos,
 
99
                        char *prev_msgctxt,
 
100
                        char *prev_msgid,
 
101
                        char *prev_msgid_plural,
 
102
                        bool force_fuzzy, bool obsolete)
102
103
{
103
104
  if (pop->methods->directive_message)
104
105
    pop->methods->directive_message (pop, msgctxt,
105
 
                                     msgid, msgid_pos, msgid_plural,
106
 
                                     msgstr, msgstr_len, msgstr_pos,
107
 
                                     prev_msgctxt,
108
 
                                     prev_msgid,
109
 
                                     prev_msgid_plural,
110
 
                                     force_fuzzy, obsolete);
 
106
                                     msgid, msgid_pos, msgid_plural,
 
107
                                     msgstr, msgstr_len, msgstr_pos,
 
108
                                     prev_msgctxt,
 
109
                                     prev_msgid,
 
110
                                     prev_msgid_plural,
 
111
                                     force_fuzzy, obsolete);
111
112
}
112
113
 
113
114
static inline void
126
127
 
127
128
static inline void
128
129
call_comment_filepos (abstract_catalog_reader_ty *pop, const char *name,
129
 
                      size_t line)
 
130
                      size_t line)
130
131
{
131
132
  if (pop->methods->comment_filepos)
132
133
    pop->methods->comment_filepos (pop, name, line);
166
167
 
167
168
void
168
169
catalog_reader_parse (abstract_catalog_reader_ty *pop, FILE *fp,
169
 
                      const char *real_filename, const char *logical_filename,
170
 
                      catalog_input_format_ty input_syntax)
 
170
                      const char *real_filename, const char *logical_filename,
 
171
                      catalog_input_format_ty input_syntax)
171
172
{
172
173
  /* Parse the stream's content.  */
173
174
  parse_start (pop);
176
177
 
177
178
  if (error_message_count > 0)
178
179
    po_xerror (PO_SEVERITY_FATAL_ERROR, NULL,
179
 
               /*real_filename*/ NULL, (size_t)(-1), (size_t)(-1), false,
180
 
               xasprintf (ngettext ("found %d fatal error",
181
 
                                    "found %d fatal errors",
182
 
                                    error_message_count),
183
 
                          error_message_count));
 
180
               /*real_filename*/ NULL, (size_t)(-1), (size_t)(-1), false,
 
181
               xasprintf (ngettext ("found %d fatal error",
 
182
                                    "found %d fatal errors",
 
183
                                    error_message_count),
 
184
                          error_message_count));
184
185
  error_message_count = 0;
185
186
}
186
187
 
204
205
   seen.  */
205
206
void
206
207
po_callback_message (char *msgctxt,
207
 
                     char *msgid, lex_pos_ty *msgid_pos, char *msgid_plural,
208
 
                     char *msgstr, size_t msgstr_len, lex_pos_ty *msgstr_pos,
209
 
                     char *prev_msgctxt,
210
 
                     char *prev_msgid,
211
 
                     char *prev_msgid_plural,
212
 
                     bool force_fuzzy, bool obsolete)
 
208
                     char *msgid, lex_pos_ty *msgid_pos, char *msgid_plural,
 
209
                     char *msgstr, size_t msgstr_len, lex_pos_ty *msgstr_pos,
 
210
                     char *prev_msgctxt,
 
211
                     char *prev_msgid,
 
212
                     char *prev_msgid_plural,
 
213
                     bool force_fuzzy, bool obsolete)
213
214
{
214
215
  /* assert(callback_arg); */
215
216
  call_directive_message (callback_arg, msgctxt,
216
 
                          msgid, msgid_pos, msgid_plural,
217
 
                          msgstr, msgstr_len, msgstr_pos,
218
 
                          prev_msgctxt, prev_msgid, prev_msgid_plural,
219
 
                          force_fuzzy, obsolete);
 
217
                          msgid, msgid_pos, msgid_plural,
 
218
                          msgstr, msgstr_len, msgstr_pos,
 
219
                          prev_msgctxt, prev_msgid, prev_msgid_plural,
 
220
                          force_fuzzy, obsolete);
220
221
}
221
222
 
222
223
 
254
255
}
255
256
 
256
257
 
257
 
/* Parse a special comment and put the result in *fuzzyp, formatp, *wrapp.  */
 
258
/* Parse a special comment and put the result in *fuzzyp, formatp, *rangep,
 
259
   *wrapp.  */
258
260
void
259
261
po_parse_comment_special (const char *s,
260
 
                          bool *fuzzyp, enum is_format formatp[NFORMATS],
261
 
                          enum is_wrap *wrapp)
 
262
                          bool *fuzzyp, enum is_format formatp[NFORMATS],
 
263
                          struct argument_range *rangep, enum is_wrap *wrapp)
262
264
{
263
265
  size_t i;
264
266
 
265
267
  *fuzzyp = false;
266
268
  for (i = 0; i < NFORMATS; i++)
267
269
    formatp[i] = undecided;
 
270
  rangep->min = -1;
 
271
  rangep->max = -1;
268
272
  *wrapp = undecided;
269
273
 
270
274
  while (*s != '\0')
273
277
 
274
278
      /* Skip whitespace.  */
275
279
      while (*s != '\0' && strchr ("\n \t\r\f\v,", *s) != NULL)
276
 
        s++;
 
280
        s++;
277
281
 
278
282
      /* Collect a token.  */
279
283
      t = s;
280
284
      while (*s != '\0' && strchr ("\n \t\r\f\v,", *s) == NULL)
281
 
        s++;
 
285
        s++;
282
286
      if (s != t)
283
 
        {
284
 
          size_t len = s - t;
285
 
 
286
 
          /* Accept fuzzy flag.  */
287
 
          if (len == 5 && memcmp (t, "fuzzy", 5) == 0)
288
 
            {
289
 
              *fuzzyp = true;
290
 
              continue;
291
 
            }
292
 
 
293
 
          /* Accept format description.  */
294
 
          if (len >= 7 && memcmp (t + len - 7, "-format", 7) == 0)
295
 
            {
296
 
              const char *p;
297
 
              size_t n;
298
 
              enum is_format value;
299
 
 
300
 
              p = t;
301
 
              n = len - 7;
302
 
 
303
 
              if (n >= 3 && memcmp (p, "no-", 3) == 0)
304
 
                {
305
 
                  p += 3;
306
 
                  n -= 3;
307
 
                  value = no;
308
 
                }
309
 
              else if (n >= 9 && memcmp (p, "possible-", 9) == 0)
310
 
                {
311
 
                  p += 9;
312
 
                  n -= 9;
313
 
                  value = possible;
314
 
                }
315
 
              else if (n >= 11 && memcmp (p, "impossible-", 11) == 0)
316
 
                {
317
 
                  p += 11;
318
 
                  n -= 11;
319
 
                  value = impossible;
320
 
                }
321
 
              else
322
 
                value = yes;
323
 
 
324
 
              for (i = 0; i < NFORMATS; i++)
325
 
                if (strlen (format_language[i]) == n
326
 
                    && memcmp (format_language[i], p, n) == 0)
327
 
                  {
328
 
                    formatp[i] = value;
329
 
                    break;
330
 
                  }
331
 
              if (i < NFORMATS)
332
 
                continue;
333
 
            }
334
 
 
335
 
          /* Accept wrap description.  */
336
 
          if (len == 4 && memcmp (t, "wrap", 4) == 0)
337
 
            {
338
 
              *wrapp = yes;
339
 
              continue;
340
 
            }
341
 
          if (len == 7 && memcmp (t, "no-wrap", 7) == 0)
342
 
            {
343
 
              *wrapp = no;
344
 
              continue;
345
 
            }
346
 
 
347
 
          /* Unknown special comment marker.  It may have been generated
348
 
             from a future xgettext version.  Ignore it.  */
349
 
        }
 
287
        {
 
288
          size_t len = s - t;
 
289
 
 
290
          /* Accept fuzzy flag.  */
 
291
          if (len == 5 && memcmp (t, "fuzzy", 5) == 0)
 
292
            {
 
293
              *fuzzyp = true;
 
294
              continue;
 
295
            }
 
296
 
 
297
          /* Accept format description.  */
 
298
          if (len >= 7 && memcmp (t + len - 7, "-format", 7) == 0)
 
299
            {
 
300
              const char *p;
 
301
              size_t n;
 
302
              enum is_format value;
 
303
 
 
304
              p = t;
 
305
              n = len - 7;
 
306
 
 
307
              if (n >= 3 && memcmp (p, "no-", 3) == 0)
 
308
                {
 
309
                  p += 3;
 
310
                  n -= 3;
 
311
                  value = no;
 
312
                }
 
313
              else if (n >= 9 && memcmp (p, "possible-", 9) == 0)
 
314
                {
 
315
                  p += 9;
 
316
                  n -= 9;
 
317
                  value = possible;
 
318
                }
 
319
              else if (n >= 11 && memcmp (p, "impossible-", 11) == 0)
 
320
                {
 
321
                  p += 11;
 
322
                  n -= 11;
 
323
                  value = impossible;
 
324
                }
 
325
              else
 
326
                value = yes;
 
327
 
 
328
              for (i = 0; i < NFORMATS; i++)
 
329
                if (strlen (format_language[i]) == n
 
330
                    && memcmp (format_language[i], p, n) == 0)
 
331
                  {
 
332
                    formatp[i] = value;
 
333
                    break;
 
334
                  }
 
335
              if (i < NFORMATS)
 
336
                continue;
 
337
            }
 
338
 
 
339
          /* Accept range description "range: <min>..<max>".  */
 
340
          if (len == 6 && memcmp (t, "range:", 6) == 0)
 
341
            {
 
342
              /* Skip whitespace.  */
 
343
              while (*s != '\0' && strchr ("\n \t\r\f\v,", *s) != NULL)
 
344
                s++;
 
345
 
 
346
              /* Collect a token.  */
 
347
              t = s;
 
348
              while (*s != '\0' && strchr ("\n \t\r\f\v,", *s) == NULL)
 
349
                s++;
 
350
              /* Parse it.  */
 
351
              if (*t >= '0' && *t <= '9')
 
352
                {
 
353
                  unsigned int min = 0;
 
354
 
 
355
                  for (; *t >= '0' && *t <= '9'; t++)
 
356
                    {
 
357
                      if (min <= INT_MAX / 10)
 
358
                        {
 
359
                          min = 10 * min + (*t - '0');
 
360
                          if (min > INT_MAX)
 
361
                            min = INT_MAX;
 
362
                        }
 
363
                      else
 
364
                        /* Avoid integer overflow.  */
 
365
                        min = INT_MAX;
 
366
                    }
 
367
                  if (*t++ == '.')
 
368
                    if (*t++ == '.')
 
369
                      if (*t >= '0' && *t <= '9')
 
370
                        {
 
371
                          unsigned int max = 0;
 
372
                          for (; *t >= '0' && *t <= '9'; t++)
 
373
                            {
 
374
                              if (max <= INT_MAX / 10)
 
375
                                {
 
376
                                  max = 10 * max + (*t - '0');
 
377
                                  if (max > INT_MAX)
 
378
                                    max = INT_MAX;
 
379
                                }
 
380
                              else
 
381
                                /* Avoid integer overflow.  */
 
382
                                max = INT_MAX;
 
383
                            }
 
384
                          if (min <= max)
 
385
                            {
 
386
                              rangep->min = min;
 
387
                              rangep->max = max;
 
388
                              continue;
 
389
                            }
 
390
                        }
 
391
                }
 
392
            }
 
393
 
 
394
          /* Accept wrap description.  */
 
395
          if (len == 4 && memcmp (t, "wrap", 4) == 0)
 
396
            {
 
397
              *wrapp = yes;
 
398
              continue;
 
399
            }
 
400
          if (len == 7 && memcmp (t, "no-wrap", 7) == 0)
 
401
            {
 
402
              *wrapp = no;
 
403
              continue;
 
404
            }
 
405
 
 
406
          /* Unknown special comment marker.  It may have been generated
 
407
             from a future xgettext version.  Ignore it.  */
 
408
        }
350
409
    }
351
410
}
352
411
 
365
424
  while (*s != '\0')
366
425
    {
367
426
      while (*s == ' ' || *s == '\t' || *s == '\n')
368
 
        s++;
 
427
        s++;
369
428
      if (*s != '\0')
370
 
        {
371
 
          const char *string_start = s;
372
 
 
373
 
          do
374
 
            s++;
375
 
          while (!(*s == '\0' || *s == ' ' || *s == '\t' || *s == '\n'));
376
 
 
377
 
          /* See if there is a COLON and NUMBER after the STRING, separated
378
 
             through optional spaces.  */
379
 
          {
380
 
            const char *p = s;
381
 
 
382
 
            while (*p == ' ' || *p == '\t' || *p == '\n')
383
 
              p++;
384
 
 
385
 
            if (*p == ':')
386
 
              {
387
 
                p++;
388
 
 
389
 
                while (*p == ' ' || *p == '\t' || *p == '\n')
390
 
                  p++;
391
 
 
392
 
                if (*p >= '0' && *p <= '9')
393
 
                  {
394
 
                    /* Accumulate a number.  */
395
 
                    size_t n = 0;
396
 
 
397
 
                    do
398
 
                      {
399
 
                        n = n * 10 + (*p - '0');
400
 
                        p++;
401
 
                      }
402
 
                    while (*p >= '0' && *p <= '9');
403
 
 
404
 
                    if (*p == '\0' || *p == ' ' || *p == '\t' || *p == '\n')
405
 
                      {
406
 
                        /* Parsed a GNU style file comment with spaces.  */
407
 
                        const char *string_end = s;
408
 
                        size_t string_length = string_end - string_start;
409
 
                        char *string = XNMALLOC (string_length + 1, char);
410
 
 
411
 
                        memcpy (string, string_start, string_length);
412
 
                        string[string_length] = '\0';
413
 
 
414
 
                        po_callback_comment_filepos (string, n);
415
 
 
416
 
                        free (string);
417
 
 
418
 
                        s = p;
419
 
                        continue;
420
 
                      }
421
 
                  }
422
 
              }
423
 
          }
424
 
 
425
 
          /* See if there is a COLON at the end of STRING and a NUMBER after
426
 
             it, separated through optional spaces.  */
427
 
          if (s[-1] == ':')
428
 
            {
429
 
              const char *p = s;
430
 
 
431
 
              while (*p == ' ' || *p == '\t' || *p == '\n')
432
 
                p++;
433
 
 
434
 
              if (*p >= '0' && *p <= '9')
435
 
                {
436
 
                  /* Accumulate a number.  */
437
 
                  size_t n = 0;
438
 
 
439
 
                  do
440
 
                    {
441
 
                      n = n * 10 + (*p - '0');
442
 
                      p++;
443
 
                    }
444
 
                  while (*p >= '0' && *p <= '9');
445
 
 
446
 
                  if (*p == '\0' || *p == ' ' || *p == '\t' || *p == '\n')
447
 
                    {
448
 
                      /* Parsed a GNU style file comment with spaces.  */
449
 
                      const char *string_end = s - 1;
450
 
                      size_t string_length = string_end - string_start;
451
 
                      char *string = XNMALLOC (string_length + 1, char);
452
 
 
453
 
                      memcpy (string, string_start, string_length);
454
 
                      string[string_length] = '\0';
455
 
 
456
 
                      po_callback_comment_filepos (string, n);
457
 
 
458
 
                      free (string);
459
 
 
460
 
                      s = p;
461
 
                      continue;
462
 
                    }
463
 
                }
464
 
            }
465
 
 
466
 
          /* See if there is a COLON and NUMBER at the end of the STRING,
467
 
             without separating spaces.  */
468
 
          {
469
 
            const char *p = s;
470
 
 
471
 
            while (p > string_start)
472
 
              {
473
 
                p--;
474
 
                if (!(*p >= '0' && *p <= '9'))
475
 
                  {
476
 
                    p++;
477
 
                    break;
478
 
                  }
479
 
              }
480
 
 
481
 
            /* p now points to the beginning of the trailing digits segment
482
 
               at the end of STRING.  */
483
 
 
484
 
            if (p < s
485
 
                && p > string_start + 1
486
 
                && p[-1] == ':')
487
 
              {
488
 
                /* Parsed a GNU style file comment without spaces.  */
489
 
                const char *string_end = p - 1;
490
 
 
491
 
                /* Accumulate a number.  */
492
 
                {
493
 
                  size_t n = 0;
494
 
 
495
 
                  do
496
 
                    {
497
 
                      n = n * 10 + (*p - '0');
498
 
                      p++;
499
 
                    }
500
 
                  while (p < s);
501
 
 
502
 
                  {
503
 
                    size_t string_length = string_end - string_start;
504
 
                    char *string = XNMALLOC (string_length + 1, char);
505
 
 
506
 
                    memcpy (string, string_start, string_length);
507
 
                    string[string_length] = '\0';
508
 
 
509
 
                    po_callback_comment_filepos (string, n);
510
 
 
511
 
                    free (string);
512
 
 
513
 
                    continue;
514
 
                  }
515
 
                }
516
 
              }
517
 
          }
518
 
 
519
 
          /* Parsed a file comment without line number.  */
520
 
          {
521
 
            const char *string_end = s;
522
 
            size_t string_length = string_end - string_start;
523
 
            char *string = XNMALLOC (string_length + 1, char);
524
 
 
525
 
            memcpy (string, string_start, string_length);
526
 
            string[string_length] = '\0';
527
 
 
528
 
            po_callback_comment_filepos (string, (size_t)(-1));
529
 
 
530
 
            free (string);
531
 
          }
532
 
        }
 
429
        {
 
430
          const char *string_start = s;
 
431
 
 
432
          do
 
433
            s++;
 
434
          while (!(*s == '\0' || *s == ' ' || *s == '\t' || *s == '\n'));
 
435
 
 
436
          /* See if there is a COLON and NUMBER after the STRING, separated
 
437
             through optional spaces.  */
 
438
          {
 
439
            const char *p = s;
 
440
 
 
441
            while (*p == ' ' || *p == '\t' || *p == '\n')
 
442
              p++;
 
443
 
 
444
            if (*p == ':')
 
445
              {
 
446
                p++;
 
447
 
 
448
                while (*p == ' ' || *p == '\t' || *p == '\n')
 
449
                  p++;
 
450
 
 
451
                if (*p >= '0' && *p <= '9')
 
452
                  {
 
453
                    /* Accumulate a number.  */
 
454
                    size_t n = 0;
 
455
 
 
456
                    do
 
457
                      {
 
458
                        n = n * 10 + (*p - '0');
 
459
                        p++;
 
460
                      }
 
461
                    while (*p >= '0' && *p <= '9');
 
462
 
 
463
                    if (*p == '\0' || *p == ' ' || *p == '\t' || *p == '\n')
 
464
                      {
 
465
                        /* Parsed a GNU style file comment with spaces.  */
 
466
                        const char *string_end = s;
 
467
                        size_t string_length = string_end - string_start;
 
468
                        char *string = XNMALLOC (string_length + 1, char);
 
469
 
 
470
                        memcpy (string, string_start, string_length);
 
471
                        string[string_length] = '\0';
 
472
 
 
473
                        po_callback_comment_filepos (string, n);
 
474
 
 
475
                        free (string);
 
476
 
 
477
                        s = p;
 
478
                        continue;
 
479
                      }
 
480
                  }
 
481
              }
 
482
          }
 
483
 
 
484
          /* See if there is a COLON at the end of STRING and a NUMBER after
 
485
             it, separated through optional spaces.  */
 
486
          if (s[-1] == ':')
 
487
            {
 
488
              const char *p = s;
 
489
 
 
490
              while (*p == ' ' || *p == '\t' || *p == '\n')
 
491
                p++;
 
492
 
 
493
              if (*p >= '0' && *p <= '9')
 
494
                {
 
495
                  /* Accumulate a number.  */
 
496
                  size_t n = 0;
 
497
 
 
498
                  do
 
499
                    {
 
500
                      n = n * 10 + (*p - '0');
 
501
                      p++;
 
502
                    }
 
503
                  while (*p >= '0' && *p <= '9');
 
504
 
 
505
                  if (*p == '\0' || *p == ' ' || *p == '\t' || *p == '\n')
 
506
                    {
 
507
                      /* Parsed a GNU style file comment with spaces.  */
 
508
                      const char *string_end = s - 1;
 
509
                      size_t string_length = string_end - string_start;
 
510
                      char *string = XNMALLOC (string_length + 1, char);
 
511
 
 
512
                      memcpy (string, string_start, string_length);
 
513
                      string[string_length] = '\0';
 
514
 
 
515
                      po_callback_comment_filepos (string, n);
 
516
 
 
517
                      free (string);
 
518
 
 
519
                      s = p;
 
520
                      continue;
 
521
                    }
 
522
                }
 
523
            }
 
524
 
 
525
          /* See if there is a COLON and NUMBER at the end of the STRING,
 
526
             without separating spaces.  */
 
527
          {
 
528
            const char *p = s;
 
529
 
 
530
            while (p > string_start)
 
531
              {
 
532
                p--;
 
533
                if (!(*p >= '0' && *p <= '9'))
 
534
                  {
 
535
                    p++;
 
536
                    break;
 
537
                  }
 
538
              }
 
539
 
 
540
            /* p now points to the beginning of the trailing digits segment
 
541
               at the end of STRING.  */
 
542
 
 
543
            if (p < s
 
544
                && p > string_start + 1
 
545
                && p[-1] == ':')
 
546
              {
 
547
                /* Parsed a GNU style file comment without spaces.  */
 
548
                const char *string_end = p - 1;
 
549
 
 
550
                /* Accumulate a number.  */
 
551
                {
 
552
                  size_t n = 0;
 
553
 
 
554
                  do
 
555
                    {
 
556
                      n = n * 10 + (*p - '0');
 
557
                      p++;
 
558
                    }
 
559
                  while (p < s);
 
560
 
 
561
                  {
 
562
                    size_t string_length = string_end - string_start;
 
563
                    char *string = XNMALLOC (string_length + 1, char);
 
564
 
 
565
                    memcpy (string, string_start, string_length);
 
566
                    string[string_length] = '\0';
 
567
 
 
568
                    po_callback_comment_filepos (string, n);
 
569
 
 
570
                    free (string);
 
571
 
 
572
                    continue;
 
573
                  }
 
574
                }
 
575
              }
 
576
          }
 
577
 
 
578
          /* Parsed a file comment without line number.  */
 
579
          {
 
580
            const char *string_end = s;
 
581
            size_t string_length = string_end - string_start;
 
582
            char *string = XNMALLOC (string_length + 1, char);
 
583
 
 
584
            memcpy (string, string_start, string_length);
 
585
            string[string_length] = '\0';
 
586
 
 
587
            po_callback_comment_filepos (string, (size_t)(-1));
 
588
 
 
589
            free (string);
 
590
          }
 
591
        }
533
592
    }
534
593
}
535
594
 
559
618
      const char *string_end;
560
619
 
561
620
      {
562
 
        const char *p = s + 6;
 
621
        const char *p = s + 6;
563
622
 
564
 
        while (*p == ' ' || *p == '\t')
565
 
          p++;
566
 
        string_start = p;
 
623
        while (*p == ' ' || *p == '\t')
 
624
          p++;
 
625
        string_start = p;
567
626
      }
568
627
 
569
628
      for (string_end = string_start; *string_end != '\0'; string_end++)
570
 
        {
571
 
          const char *p = string_end;
572
 
 
573
 
          while (*p == ' ' || *p == '\t')
574
 
            p++;
575
 
 
576
 
          if (*p == ',')
577
 
            {
578
 
              p++;
579
 
 
580
 
              while (*p == ' ' || *p == '\t')
581
 
                p++;
582
 
 
583
 
              if (p[0] == 'l' && p[1] == 'i' && p[2] == 'n' && p[3] == 'e')
584
 
                {
585
 
                  p += 4;
586
 
 
587
 
                  while (*p == ' ' || *p == '\t')
588
 
                    p++;
589
 
 
590
 
                  if (p[0] == 'n' && p[1] == 'u' && p[2] == 'm'
591
 
                      && p[3] == 'b' && p[4] == 'e' && p[5] == 'r')
592
 
                    {
593
 
                      p += 6;
594
 
                      while (*p == ' ' || *p == '\t')
595
 
                        p++;
596
 
                    }
597
 
 
598
 
                  if (*p == ':')
599
 
                    {
600
 
                      p++;
601
 
 
602
 
                      if (*p >= '0' && *p <= '9')
603
 
                        {
604
 
                          /* Accumulate a number.  */
605
 
                          size_t n = 0;
606
 
 
607
 
                          do
608
 
                            {
609
 
                              n = n * 10 + (*p - '0');
610
 
                              p++;
611
 
                            }
612
 
                          while (*p >= '0' && *p <= '9');
613
 
 
614
 
                          while (*p == ' ' || *p == '\t' || *p == '\n')
615
 
                            p++;
616
 
 
617
 
                          if (*p == '\0')
618
 
                            {
619
 
                              /* Parsed a Sun style file comment.  */
620
 
                              size_t string_length = string_end - string_start;
621
 
                              char *string =
622
 
                                XNMALLOC (string_length + 1, char);
623
 
 
624
 
                              memcpy (string, string_start, string_length);
625
 
                              string[string_length] = '\0';
626
 
 
627
 
                              po_callback_comment_filepos (string, n);
628
 
 
629
 
                              free (string);
630
 
                              return true;
631
 
                            }
632
 
                        }
633
 
                    }
634
 
                }
635
 
            }
636
 
        }
 
629
        {
 
630
          const char *p = string_end;
 
631
 
 
632
          while (*p == ' ' || *p == '\t')
 
633
            p++;
 
634
 
 
635
          if (*p == ',')
 
636
            {
 
637
              p++;
 
638
 
 
639
              while (*p == ' ' || *p == '\t')
 
640
                p++;
 
641
 
 
642
              if (p[0] == 'l' && p[1] == 'i' && p[2] == 'n' && p[3] == 'e')
 
643
                {
 
644
                  p += 4;
 
645
 
 
646
                  while (*p == ' ' || *p == '\t')
 
647
                    p++;
 
648
 
 
649
                  if (p[0] == 'n' && p[1] == 'u' && p[2] == 'm'
 
650
                      && p[3] == 'b' && p[4] == 'e' && p[5] == 'r')
 
651
                    {
 
652
                      p += 6;
 
653
                      while (*p == ' ' || *p == '\t')
 
654
                        p++;
 
655
                    }
 
656
 
 
657
                  if (*p == ':')
 
658
                    {
 
659
                      p++;
 
660
 
 
661
                      if (*p >= '0' && *p <= '9')
 
662
                        {
 
663
                          /* Accumulate a number.  */
 
664
                          size_t n = 0;
 
665
 
 
666
                          do
 
667
                            {
 
668
                              n = n * 10 + (*p - '0');
 
669
                              p++;
 
670
                            }
 
671
                          while (*p >= '0' && *p <= '9');
 
672
 
 
673
                          while (*p == ' ' || *p == '\t' || *p == '\n')
 
674
                            p++;
 
675
 
 
676
                          if (*p == '\0')
 
677
                            {
 
678
                              /* Parsed a Sun style file comment.  */
 
679
                              size_t string_length = string_end - string_start;
 
680
                              char *string =
 
681
                                XNMALLOC (string_length + 1, char);
 
682
 
 
683
                              memcpy (string, string_start, string_length);
 
684
                              string[string_length] = '\0';
 
685
 
 
686
                              po_callback_comment_filepos (string, n);
 
687
 
 
688
                              free (string);
 
689
                              return true;
 
690
                            }
 
691
                        }
 
692
                    }
 
693
                }
 
694
            }
 
695
        }
637
696
    }
638
697
 
639
698
  return false;
652
711
    {
653
712
      s++;
654
713
      /* There is usually a space before the comment.  People don't
655
 
         consider it part of the comment, therefore remove it here.  */
 
714
         consider it part of the comment, therefore remove it here.  */
656
715
      if (*s == ' ')
657
 
        s++;
 
716
        s++;
658
717
      po_callback_comment_dot (s);
659
718
    }
660
719
  else if (*s == ':')
661
720
    {
662
721
      /* Parse the file location string.  The appropriate callback will be
663
 
         invoked.  */
 
722
         invoked.  */
664
723
      po_parse_comment_filepos (s + 1);
665
724
    }
666
725
  else if (*s == ',' || *s == '!')
671
730
  else
672
731
    {
673
732
      /* It looks like a plain vanilla comment, but Solaris-style file
674
 
         position lines do, too.  Try to parse the lot.  If the parse
675
 
         succeeds, the appropriate callback will be invoked.  */
 
733
         position lines do, too.  Try to parse the lot.  If the parse
 
734
         succeeds, the appropriate callback will be invoked.  */
676
735
      if (po_parse_comment_solaris_filepos (s))
677
 
        /* Do nothing, it is a Sun-style file pos line.  */ ;
 
736
        /* Do nothing, it is a Sun-style file pos line.  */ ;
678
737
      else
679
 
        {
680
 
          /* There is usually a space before the comment.  People don't
681
 
             consider it part of the comment, therefore remove it here.  */
682
 
          if (*s == ' ')
683
 
            s++;
684
 
          po_callback_comment (s);
685
 
        }
 
738
        {
 
739
          /* There is usually a space before the comment.  People don't
 
740
             consider it part of the comment, therefore remove it here.  */
 
741
          if (*s == ' ')
 
742
            s++;
 
743
          po_callback_comment (s);
 
744
        }
686
745
    }
687
746
}