~vcs-imports/gawk/master

« back to all changes in this revision

Viewing changes to dfa.c

  • Committer: Arnold D. Robbins
  • Date: 2014-10-28 18:33:36 UTC
  • mfrom: (408.5.317)
  • mto: (408.27.1) (615.1.1)
  • mto: This revision was merged to the branch mainline in revision 531.
  • Revision ID: git-v1:0182312b0fc945a20a3d7aeac1488540b5518e3a
Merge branch 'gawk-4.1-stable'

Show diffs side-by-side

added added

removed removed

Lines of Context:
432
432
                                   slots so far, not counting trans[-1].  */
433
433
  int trcount;                  /* Number of transition tables that have
434
434
                                   actually been built.  */
 
435
  int min_trcount;              /* Minimum of number of transition tables.
 
436
                                   Always keep the number, even after freeing
 
437
                                   the transition tables.  It is also the
 
438
                                   number of initial states.  */
435
439
  state_num **trans;            /* Transition tables for states that can
436
440
                                   never accept.  If the transitions for a
437
441
                                   state have not yet been computed, or the
450
454
                                   newline is stored separately and handled
451
455
                                   as a special case.  Newline is also used
452
456
                                   as a sentinel at the end of the buffer.  */
 
457
  state_num initstate_letter;   /* Initial state for letter context.  */
 
458
  state_num initstate_others;   /* Initial state for other contexts.  */
453
459
  struct dfamust *musts;        /* List of strings, at least one of which
454
460
                                   is known to appear in any r.e. matching
455
461
                                   the dfa.  */
2588
2594
 
2589
2595
  /* Build the initial state.  */
2590
2596
  separate_contexts = state_separate_contexts (&merged);
2591
 
  state_index (d, &merged,
2592
 
               (separate_contexts & CTX_NEWLINE
2593
 
                ? CTX_NEWLINE : separate_contexts ^ CTX_ANY));
 
2597
  if (separate_contexts & CTX_NEWLINE)
 
2598
    state_index (d, &merged, CTX_NEWLINE);
 
2599
  d->initstate_others = d->min_trcount
 
2600
    = state_index (d, &merged, separate_contexts ^ CTX_ANY);
 
2601
  if (separate_contexts & CTX_LETTER)
 
2602
    d->initstate_letter = d->min_trcount
 
2603
      = state_index (d, &merged, CTX_LETTER);
 
2604
  else
 
2605
    d->initstate_letter = d->initstate_others;
 
2606
  d->min_trcount++;
2594
2607
 
2595
2608
  free (posalloc);
2596
2609
  free (stkalloc);
2927
2940
  /* Set an upper limit on the number of transition tables that will ever
2928
2941
     exist at once.  1024 is arbitrary.  The idea is that the frequently
2929
2942
     used transition tables will be quickly rebuilt, whereas the ones that
2930
 
     were only needed once or twice will be cleared away.  However, do
2931
 
     not clear the initial state, as it's always used.  */
 
2943
     were only needed once or twice will be cleared away.  However, do not
 
2944
     clear the initial D->min_trcount states, since they are always used.  */
2932
2945
  if (d->trcount >= 1024)
2933
2946
    {
2934
 
      for (i = 1; i < d->tralloc; ++i)
 
2947
      for (i = d->min_trcount; i < d->tralloc; ++i)
2935
2948
        {
2936
2949
          free (d->trans[i]);
2937
2950
          free (d->fails[i]);
2938
2951
          d->trans[i] = d->fails[i] = NULL;
2939
2952
        }
2940
 
      d->trcount = 1;
 
2953
      d->trcount = d->min_trcount;
2941
2954
    }
2942
2955
 
2943
2956
  ++d->trcount;
3308
3321
   expression "\\" accepts the codepoint 0x5c, but should not accept the second
3309
3322
   byte of the codepoint 0x815c.  Then the initial state must skip the bytes
3310
3323
   that are not a single byte character nor the first byte of a multibyte
3311
 
   character.  */
 
3324
   character.
 
3325
 
 
3326
   Given DFA state d, use mbs_to_wchar to advance MBP until it reaches or
 
3327
   exceeds P.  If WCP is non-NULL, set *WCP to the final wide character
 
3328
   processed, or if no wide character is processed, set it to WEOF.
 
3329
   Both P and MBP must be no larger than END.  */
3312
3330
static unsigned char const *
3313
3331
skip_remains_mb (struct dfa *d, unsigned char const *p,
3314
 
                 unsigned char const *mbp, char const *end)
 
3332
                 unsigned char const *mbp, char const *end, wint_t *wcp)
3315
3333
{
3316
 
  wint_t wc;
 
3334
  wint_t wc = WEOF;
3317
3335
  while (mbp < p)
3318
3336
    mbp += mbs_to_wchar (&wc, (char const *) mbp,
3319
3337
                         end - (char const *) mbp, d);
 
3338
  if (wcp != NULL)
 
3339
    *wcp = wc;
3320
3340
  return mbp;
3321
3341
}
3322
3342
 
3378
3398
            {
3379
3399
              s1 = s;
3380
3400
 
3381
 
              if (s == 0)
 
3401
              if (s < d->min_trcount)
3382
3402
                {
3383
 
                  if (d->states[s].mbps.nelem == 0)
 
3403
                  if (d->min_trcount == 1)
3384
3404
                    {
3385
 
                      do
 
3405
                      if (d->states[s].mbps.nelem == 0)
3386
3406
                        {
3387
 
                          while (t[*p] == 0)
3388
 
                            p++;
3389
 
                          p = mbp = skip_remains_mb (d, p, mbp, end);
 
3407
                          do
 
3408
                            {
 
3409
                              while (t[*p] == 0)
 
3410
                                p++;
 
3411
                              p = mbp = skip_remains_mb (d, p, mbp, end, NULL);
 
3412
                            }
 
3413
                          while (t[*p] == 0);
3390
3414
                        }
3391
 
                      while (t[*p] == 0);
 
3415
                      else
 
3416
                        p = mbp = skip_remains_mb (d, p, mbp, end, NULL);
3392
3417
                    }
3393
3418
                  else
3394
 
                    p = mbp = skip_remains_mb (d, p, mbp, end);
 
3419
                    {
 
3420
                      wint_t wc;
 
3421
                      mbp = skip_remains_mb (d, p, mbp, end, &wc);
 
3422
 
 
3423
                      /* If d->min_trcount is greater than 1, maybe
 
3424
                         transit to another initial state after skip.  */
 
3425
                      if (p < mbp)
 
3426
                        {
 
3427
                          int context = wchar_context (wc);
 
3428
                          if (context == CTX_LETTER)
 
3429
                            s = d->initstate_letter;
 
3430
                          else
 
3431
                            /* It's CTX_NONE.  CTX_NEWLINE cannot happen,
 
3432
                               as we assume that a newline is always a
 
3433
                               single byte character.  */
 
3434
                            s = d->initstate_others;
 
3435
                          p = mbp;
 
3436
                          s1 = s;
 
3437
                        }
 
3438
                    }
3395
3439
                }
3396
3440
 
3397
3441
              if (d->states[s].mbps.nelem == 0)