~ubuntu-branches/ubuntu/intrepid/cmake/intrepid-backports

« back to all changes in this revision

Viewing changes to Source/cmRegularExpression.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Maitland Bottoms
  • Date: 2002-02-14 18:36:25 UTC
  • Revision ID: james.westby@ubuntu.com-20020214183625-8m44isdas2k4l0f7
Tags: upstream-1.2
ImportĀ upstreamĀ versionĀ 1.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*=========================================================================
 
2
 
 
3
  Program:   Insight Segmentation & Registration Toolkit
 
4
  Module:    $RCSfile: cmRegularExpression.cxx,v $
 
5
  Language:  C++
 
6
  Date:      $Date: 2001/04/27 12:01:17 $
 
7
  Version:   $Revision: 1.4 $
 
8
 
 
9
Copyright (c) 2001 Insight Consortium
 
10
All rights reserved.
 
11
 
 
12
Redistribution and use in source and binary forms, with or without
 
13
modification, are permitted provided that the following conditions are met:
 
14
 
 
15
 * Redistributions of source code must retain the above copyright notice,
 
16
   this list of conditions and the following disclaimer.
 
17
 
 
18
 * Redistributions in binary form must reproduce the above copyright notice,
 
19
   this list of conditions and the following disclaimer in the documentation
 
20
   and/or other materials provided with the distribution.
 
21
 
 
22
 * The name of the Insight Consortium, nor the names of any consortium members,
 
23
   nor of any contributors, may be used to endorse or promote products derived
 
24
   from this software without specific prior written permission.
 
25
 
 
26
  * Modified source versions must be plainly marked as such, and must not be
 
27
    misrepresented as being the original software.
 
28
 
 
29
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
 
30
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
31
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
32
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
 
33
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
34
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 
35
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 
36
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 
37
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
38
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
39
 
 
40
=========================================================================*/
 
41
//
 
42
// Copyright (C) 1991 Texas Instruments Incorporated.
 
43
//
 
44
// Permission is granted to any individual or institution to use, copy, modify,
 
45
// and distribute this software, provided that this complete copyright and
 
46
// permission notice is maintained, intact, in all copies and supporting
 
47
// documentation.
 
48
//
 
49
// Texas Instruments Incorporated provides this software "as is" without
 
50
// express or implied warranty.
 
51
//
 
52
//
 
53
// Created: MNF 06/13/89  Initial Design and Implementation
 
54
// Updated: LGO 08/09/89  Inherit from Generic
 
55
// Updated: MBN 09/07/89  Added conditional exception handling
 
56
// Updated: MBN 12/15/89  Sprinkled "const" qualifiers all over the place!
 
57
// Updated: DLS 03/22/91  New lite version
 
58
//
 
59
 
 
60
#include "cmRegularExpression.h"        // Include class specification 
 
61
#include "cmStandardIncludes.h"
 
62
#include <stdio.h>
 
63
 
 
64
// cmRegularExpression -- Copies the given regular expression.
 
65
cmRegularExpression::cmRegularExpression (const cmRegularExpression& rxp) {
 
66
  int ind; 
 
67
  this->progsize = rxp.progsize;                // Copy regular expression size
 
68
  this->program = new char[this->progsize];     // Allocate storage
 
69
  for(ind=this->progsize; ind-- != 0;)          // Copy regular expresion
 
70
    this->program[ind] = rxp.program[ind];
 
71
  this->startp[0] = rxp.startp[0];              // Copy pointers into last
 
72
  this->endp[0] = rxp.endp[0];                  // Successful "find" operation
 
73
  this->regmust = rxp.regmust;                  // Copy field
 
74
  if (rxp.regmust != NULL) {
 
75
    char* dum = rxp.program;
 
76
    ind = 0;
 
77
    while (dum != rxp.regmust) {
 
78
      ++dum;
 
79
      ++ind;
 
80
    }
 
81
    this->regmust = this->program + ind;
 
82
  }
 
83
  this->regstart = rxp.regstart;                // Copy starting index
 
84
  this->reganch = rxp.reganch;                  // Copy remaining private data
 
85
  this->regmlen = rxp.regmlen;                  // Copy remaining private data
 
86
}
 
87
 
 
88
// operator== -- Returns true if two regular expressions have the same
 
89
// compiled program for pattern matching.
 
90
bool cmRegularExpression::operator== (const cmRegularExpression& rxp) const {
 
91
  if (this != &rxp) {                           // Same address?
 
92
    int ind = this->progsize;                   // Get regular expression size
 
93
    if (ind != rxp.progsize)                    // If different size regexp
 
94
      return false;                             // Return failure
 
95
    while(ind-- != 0)                           // Else while still characters
 
96
      if(this->program[ind] != rxp.program[ind]) // If regexp are different    
 
97
        return false;                            // Return failure             
 
98
  }
 
99
  return true;                                  // Else same, return success  
 
100
}
 
101
 
 
102
 
 
103
// deep_equal -- Returns true if have the same compiled regular expressions
 
104
// and the same start and end pointers.
 
105
 
 
106
bool cmRegularExpression::deep_equal (const cmRegularExpression& rxp) const {
 
107
  int ind = this->progsize;                     // Get regular expression size
 
108
  if (ind != rxp.progsize)                      // If different size regexp
 
109
    return false;                               // Return failure
 
110
  while(ind-- != 0)                             // Else while still characters
 
111
    if(this->program[ind] != rxp.program[ind])  // If regexp are different    
 
112
      return false;                             // Return failure             
 
113
  return (this->startp[0] == rxp.startp[0] &&   // Else if same start/end ptrs,
 
114
          this->endp[0] == rxp.endp[0]);        // Return true
 
115
}   
 
116
 
 
117
// The remaining code in this file is derived from the  regular expression code
 
118
// whose  copyright statement appears  below.  It has been  changed to work
 
119
// with the class concepts of C++ and COOL.
 
120
 
 
121
/*
 
122
 * compile and find 
 
123
 *
 
124
 *      Copyright (c) 1986 by University of Toronto.
 
125
 *      Written by Henry Spencer.  Not derived from licensed software.
 
126
 *
 
127
 *      Permission is granted to anyone to use this software for any
 
128
 *      purpose on any computer system, and to redistribute it freely,
 
129
 *      subject to the following restrictions:
 
130
 *
 
131
 *      1. The author is not responsible for the consequences of use of
 
132
 *              this software, no matter how awful, even if they arise
 
133
 *              from defects in it.
 
134
 *
 
135
 *      2. The origin of this software must not be misrepresented, either
 
136
 *              by explicit claim or by omission.
 
137
 *
 
138
 *      3. Altered versions must be plainly marked as such, and must not
 
139
 *              be misrepresented as being the original software.
 
140
 *
 
141
 * Beware that some of this code is subtly aware of the way operator
 
142
 * precedence is structured in regular expressions.  Serious changes in
 
143
 * regular-expression syntax might require a total rethink.
 
144
 */
 
145
 
 
146
/*
 
147
 * The "internal use only" fields in regexp.h are present to pass info from
 
148
 * compile to execute that permits the execute phase to run lots faster on
 
149
 * simple cases.  They are:
 
150
 *
 
151
 * regstart     char that must begin a match; '\0' if none obvious
 
152
 * reganch      is the match anchored (at beginning-of-line only)?
 
153
 * regmust      string (pointer into program) that match must include, or NULL
 
154
 * regmlen      length of regmust string
 
155
 *
 
156
 * Regstart and reganch permit very fast decisions on suitable starting points
 
157
 * for a match, cutting down the work a lot.  Regmust permits fast rejection
 
158
 * of lines that cannot possibly match.  The regmust tests are costly enough
 
159
 * that compile() supplies a regmust only if the r.e. contains something
 
160
 * potentially expensive (at present, the only such thing detected is * or +
 
161
 * at the start of the r.e., which can involve a lot of backup).  Regmlen is
 
162
 * supplied because the test in find() needs it and compile() is computing
 
163
 * it anyway.
 
164
 */
 
165
 
 
166
/*
 
167
 * Structure for regexp "program".  This is essentially a linear encoding
 
168
 * of a nondeterministic finite-state machine (aka syntax charts or
 
169
 * "railroad normal form" in parsing technology).  Each node is an opcode
 
170
 * plus a "next" pointer, possibly plus an operand.  "Next" pointers of
 
171
 * all nodes except BRANCH implement concatenation; a "next" pointer with
 
172
 * a BRANCH on both ends of it is connecting two alternatives.  (Here we
 
173
 * have one of the subtle syntax dependencies:  an individual BRANCH (as
 
174
 * opposed to a collection of them) is never concatenated with anything
 
175
 * because of operator precedence.)  The operand of some types of node is
 
176
 * a literal string; for others, it is a node leading into a sub-FSM.  In
 
177
 * particular, the operand of a BRANCH node is the first node of the branch.
 
178
 * (NB this is *not* a tree structure:  the tail of the branch connects
 
179
 * to the thing following the set of BRANCHes.)  The opcodes are:
 
180
 */
 
181
 
 
182
// definition   number  opnd?   meaning
 
183
#define END     0               // no   End of program.
 
184
#define BOL     1               // no   Match "" at beginning of line.
 
185
#define EOL     2               // no   Match "" at end of line.
 
186
#define ANY     3               // no   Match any one character.
 
187
#define ANYOF   4               // str  Match any character in this string.
 
188
#define ANYBUT  5               // str  Match any character not in this
 
189
                                // string.
 
190
#define BRANCH  6               // node Match this alternative, or the
 
191
                                // next...
 
192
#define BACK    7               // no   Match "", "next" ptr points backward.
 
193
#define EXACTLY 8               // str  Match this string.
 
194
#define NOTHING 9               // no   Match empty string.
 
195
#define STAR    10              // node Match this (simple) thing 0 or more
 
196
                                // times.
 
197
#define PLUS    11              // node Match this (simple) thing 1 or more
 
198
                                // times.
 
199
#define OPEN    20              // no   Mark this point in input as start of
 
200
                                // #n.
 
201
// OPEN+1 is number 1, etc.
 
202
#define CLOSE   30              // no   Analogous to OPEN.
 
203
 
 
204
/*
 
205
 * Opcode notes:
 
206
 *
 
207
 * BRANCH       The set of branches constituting a single choice are hooked
 
208
 *              together with their "next" pointers, since precedence prevents
 
209
 *              anything being concatenated to any individual branch.  The
 
210
 *              "next" pointer of the last BRANCH in a choice points to the
 
211
 *              thing following the whole choice.  This is also where the
 
212
 *              final "next" pointer of each individual branch points; each
 
213
 *              branch starts with the operand node of a BRANCH node.
 
214
 *
 
215
 * BACK         Normal "next" pointers all implicitly point forward; BACK
 
216
 *              exists to make loop structures possible.
 
217
 *
 
218
 * STAR,PLUS    '?', and complex '*' and '+', are implemented as circular
 
219
 *              BRANCH structures using BACK.  Simple cases (one character
 
220
 *              per match) are implemented with STAR and PLUS for speed
 
221
 *              and to minimize recursive plunges.
 
222
 *
 
223
 * OPEN,CLOSE   ...are numbered at compile time.
 
224
 */
 
225
 
 
226
/*
 
227
 * A node is one char of opcode followed by two chars of "next" pointer.
 
228
 * "Next" pointers are stored as two 8-bit pieces, high order first.  The
 
229
 * value is a positive offset from the opcode of the node containing it.
 
230
 * An operand, if any, simply follows the node.  (Note that much of the
 
231
 * code generation knows about this implicit relationship.)
 
232
 *
 
233
 * Using two bytes for the "next" pointer is vast overkill for most things,
 
234
 * but allows patterns to get big without disasters.
 
235
 */
 
236
 
 
237
#define OP(p)           (*(p))
 
238
#define NEXT(p)         (((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
 
239
#define OPERAND(p)      ((p) + 3)
 
240
 
 
241
const unsigned char MAGIC = 0234;
 
242
/*
 
243
 * Utility definitions.
 
244
 */
 
245
 
 
246
#define UCHARAT(p)      ((const unsigned char*)(p))[0]
 
247
 
 
248
 
 
249
#define FAIL(m) { regerror(m); return(NULL); }
 
250
#define ISMULT(c)       ((c) == '*' || (c) == '+' || (c) == '?')
 
251
#define META    "^$.[()|?+*\\"
 
252
 
 
253
 
 
254
/*
 
255
 * Flags to be passed up and down.
 
256
 */
 
257
#define HASWIDTH        01      // Known never to match null string.
 
258
#define SIMPLE          02      // Simple enough to be STAR/PLUS operand.
 
259
#define SPSTART         04      // Starts with * or +.
 
260
#define WORST           0       // Worst case.
 
261
 
 
262
 
 
263
 
 
264
/////////////////////////////////////////////////////////////////////////
 
265
//
 
266
//  COMPILE AND ASSOCIATED FUNCTIONS
 
267
//
 
268
/////////////////////////////////////////////////////////////////////////
 
269
 
 
270
 
 
271
/*
 
272
 * Global work variables for compile().
 
273
 */
 
274
static const char* regparse;    // Input-scan pointer.
 
275
static       int   regnpar;     // () count.
 
276
static       char  regdummy;
 
277
static       char* regcode;     // Code-emit pointer; &regdummy = don't.
 
278
static       long  regsize;     // Code size.
 
279
 
 
280
/*
 
281
 * Forward declarations for compile()'s friends.
 
282
 */
 
283
// #ifndef static
 
284
// #define      static  static
 
285
// #endif
 
286
static       char* reg (int, int*);
 
287
static       char* regbranch (int*);
 
288
static       char* regpiece (int*);
 
289
static       char* regatom (int*);
 
290
static       char* regnode (char);
 
291
static const char* regnext (register const char*);
 
292
static       char* regnext (register char*);
 
293
static void        regc (unsigned char);
 
294
static void        reginsert (char, char*);
 
295
static void        regtail (char*, const char*);
 
296
static void        regoptail (char*, const char*);
 
297
 
 
298
#ifdef STRCSPN
 
299
static int strcspn ();
 
300
#endif
 
301
 
 
302
 
 
303
 
 
304
/*
 
305
 * We can't allocate space until we know how big the compiled form will be,
 
306
 * but we can't compile it (and thus know how big it is) until we've got a
 
307
 * place to put the code.  So we cheat:  we compile it twice, once with code
 
308
 * generation turned off and size counting turned on, and once "for real".
 
309
 * This also means that we don't allocate space until we are sure that the
 
310
 * thing really will compile successfully, and we never have to move the
 
311
 * code and thus invalidate pointers into it.  (Note that it has to be in
 
312
 * one piece because free() must be able to free it all.)
 
313
 *
 
314
 * Beware that the optimization-preparation code in here knows about some
 
315
 * of the structure of the compiled regexp.
 
316
 */
 
317
 
 
318
 
 
319
// compile -- compile a regular expression into internal code
 
320
// for later pattern matching.
 
321
 
 
322
void cmRegularExpression::compile (const char* exp) {
 
323
    register const char* scan;
 
324
    register const char* longest;
 
325
    register unsigned long len;
 
326
             int         flags;
 
327
 
 
328
    if (exp == NULL) {
 
329
      //RAISE Error, SYM(cmRegularExpression), SYM(No_Expr),
 
330
      printf ("cmRegularExpression::compile(): No expression supplied.\n");
 
331
      return;
 
332
    }
 
333
 
 
334
    // First pass: determine size, legality.
 
335
    regparse = exp;
 
336
    regnpar = 1;
 
337
    regsize = 0L;
 
338
    regcode = &regdummy;
 
339
    regc(MAGIC);
 
340
    if(!reg(0, &flags))
 
341
      {
 
342
        printf ("cmRegularExpression::compile(): Error in compile.\n");
 
343
        return;
 
344
      }
 
345
    this->startp[0] = this->endp[0] = this->searchstring = NULL;
 
346
 
 
347
    // Small enough for pointer-storage convention? 
 
348
    if (regsize >= 32767L) {    // Probably could be 65535L. 
 
349
      //RAISE Error, SYM(cmRegularExpression), SYM(Expr_Too_Big),
 
350
      printf ("cmRegularExpression::compile(): Expression too big.\n");
 
351
      return;
 
352
    }
 
353
 
 
354
    // Allocate space. 
 
355
//#ifndef WIN32
 
356
    if (this->program != NULL) delete [] this->program;  
 
357
//#endif
 
358
    this->program = new char[regsize];
 
359
    this->progsize = (int) regsize;
 
360
 
 
361
    if (this->program == NULL) {
 
362
      //RAISE Error, SYM(cmRegularExpression), SYM(Out_Of_Memory),
 
363
      printf ("cmRegularExpression::compile(): Out of memory.\n"); 
 
364
      return;
 
365
    }
 
366
 
 
367
    // Second pass: emit code.
 
368
    regparse = exp;
 
369
    regnpar = 1;
 
370
    regcode = this->program;
 
371
    regc(MAGIC);
 
372
    reg(0, &flags);
 
373
 
 
374
    // Dig out information for optimizations.
 
375
    this->regstart = '\0';              // Worst-case defaults.
 
376
    this->reganch = 0;
 
377
    this->regmust = NULL;
 
378
    this->regmlen = 0;
 
379
    scan = this->program + 1;   // First BRANCH.
 
380
    if (OP(regnext(scan)) == END) {     // Only one top-level choice.
 
381
        scan = OPERAND(scan);
 
382
 
 
383
        // Starting-point info.
 
384
        if (OP(scan) == EXACTLY)
 
385
            this->regstart = *OPERAND(scan);
 
386
        else if (OP(scan) == BOL)
 
387
            this->reganch++;
 
388
 
 
389
         //
 
390
         // If there's something expensive in the r.e., find the longest
 
391
         // literal string that must appear and make it the regmust.  Resolve
 
392
         // ties in favor of later strings, since the regstart check works
 
393
         // with the beginning of the r.e. and avoiding duplication
 
394
         // strengthens checking.  Not a strong reason, but sufficient in the
 
395
         // absence of others. 
 
396
         //
 
397
        if (flags & SPSTART) {
 
398
            longest = NULL;
 
399
            len = 0;
 
400
            for (; scan != NULL; scan = regnext(scan))
 
401
                if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {
 
402
                    longest = OPERAND(scan);
 
403
                    len = strlen(OPERAND(scan));
 
404
                }
 
405
            this->regmust = longest;
 
406
            this->regmlen = len;
 
407
        }
 
408
    }
 
409
}
 
410
 
 
411
 
 
412
/*
 
413
 - reg - regular expression, i.e. main body or parenthesized thing
 
414
 *
 
415
 * Caller must absorb opening parenthesis.
 
416
 *
 
417
 * Combining parenthesis handling with the base level of regular expression
 
418
 * is a trifle forced, but the need to tie the tails of the branches to what
 
419
 * follows makes it hard to avoid.
 
420
 */
 
421
static char* reg (int paren, int *flagp) {
 
422
    register char* ret;
 
423
    register char* br;
 
424
    register char* ender;
 
425
    register int   parno =0;
 
426
             int   flags;
 
427
 
 
428
    *flagp = HASWIDTH;          // Tentatively.
 
429
 
 
430
    // Make an OPEN node, if parenthesized.
 
431
    if (paren) {
 
432
        if (regnpar >= NSUBEXP) {
 
433
          //RAISE Error, SYM(cmRegularExpression), SYM(Too_Many_Parens),
 
434
          printf ("cmRegularExpression::compile(): Too many parentheses.\n");
 
435
          return 0;
 
436
        }
 
437
        parno = regnpar;
 
438
        regnpar++;
 
439
        ret = regnode(OPEN + parno);
 
440
    }
 
441
    else
 
442
        ret = NULL;
 
443
 
 
444
    // Pick up the branches, linking them together.
 
445
    br = regbranch(&flags);
 
446
    if (br == NULL)
 
447
        return (NULL);
 
448
    if (ret != NULL)
 
449
        regtail(ret, br);       // OPEN -> first.
 
450
    else
 
451
        ret = br;
 
452
    if (!(flags & HASWIDTH))
 
453
        *flagp &= ~HASWIDTH;
 
454
    *flagp |= flags & SPSTART;
 
455
    while (*regparse == '|') {
 
456
        regparse++;
 
457
        br = regbranch(&flags);
 
458
        if (br == NULL)
 
459
            return (NULL);
 
460
        regtail(ret, br);       // BRANCH -> BRANCH.
 
461
        if (!(flags & HASWIDTH))
 
462
            *flagp &= ~HASWIDTH;
 
463
        *flagp |= flags & SPSTART;
 
464
      }
 
465
 
 
466
    // Make a closing node, and hook it on the end.
 
467
    ender = regnode((paren) ? CLOSE + parno : END);
 
468
    regtail(ret, ender);
 
469
 
 
470
    // Hook the tails of the branches to the closing node.
 
471
    for (br = ret; br != NULL; br = regnext(br))
 
472
        regoptail(br, ender);
 
473
 
 
474
    // Check for proper termination.
 
475
    if (paren && *regparse++ != ')') {
 
476
        //RAISE Error, SYM(cmRegularExpression), SYM(Unmatched_Parens),
 
477
        printf ("cmRegularExpression::compile(): Unmatched parentheses.\n");
 
478
        return 0;
 
479
    }
 
480
    else if (!paren && *regparse != '\0') {
 
481
        if (*regparse == ')') {
 
482
            //RAISE Error, SYM(cmRegularExpression), SYM(Unmatched_Parens),
 
483
            printf ("cmRegularExpression::compile(): Unmatched parentheses.\n");
 
484
            return 0;
 
485
        }
 
486
        else {
 
487
            //RAISE Error, SYM(cmRegularExpression), SYM(Internal_Error),
 
488
            printf ("cmRegularExpression::compile(): Internal error.\n");
 
489
            return 0;
 
490
        }
 
491
        // NOTREACHED
 
492
    }
 
493
    return (ret);
 
494
}
 
495
 
 
496
 
 
497
/*
 
498
 - regbranch - one alternative of an | operator
 
499
 *
 
500
 * Implements the concatenation operator.
 
501
 */
 
502
static char* regbranch (int *flagp) {
 
503
    register char* ret;
 
504
    register char* chain;
 
505
    register char* latest;
 
506
    int                  flags;
 
507
 
 
508
    *flagp = WORST;             // Tentatively.
 
509
 
 
510
    ret = regnode(BRANCH);
 
511
    chain = NULL;
 
512
    while (*regparse != '\0' && *regparse != '|' && *regparse != ')') {
 
513
        latest = regpiece(&flags);
 
514
        if (latest == NULL)
 
515
            return (NULL);
 
516
        *flagp |= flags & HASWIDTH;
 
517
        if (chain == NULL)      // First piece.
 
518
            *flagp |= flags & SPSTART;
 
519
        else
 
520
            regtail(chain, latest);
 
521
        chain = latest;
 
522
    }
 
523
    if (chain == NULL)          // Loop ran zero times.
 
524
        regnode(NOTHING);
 
525
 
 
526
    return (ret);
 
527
}
 
528
 
 
529
 
 
530
/*
 
531
 - regpiece - something followed by possible [*+?]
 
532
 *
 
533
 * Note that the branching code sequences used for ? and the general cases
 
534
 * of * and + are somewhat optimized:  they use the same NOTHING node as
 
535
 * both the endmarker for their branch list and the body of the last branch.
 
536
 * It might seem that this node could be dispensed with entirely, but the
 
537
 * endmarker role is not redundant.
 
538
 */
 
539
static char* regpiece (int *flagp) {
 
540
    register char* ret;
 
541
    register char  op;
 
542
    register char* next;
 
543
    int            flags;
 
544
 
 
545
    ret = regatom(&flags);
 
546
    if (ret == NULL)
 
547
        return (NULL);
 
548
 
 
549
    op = *regparse;
 
550
    if (!ISMULT(op)) {
 
551
        *flagp = flags;
 
552
        return (ret);
 
553
    }
 
554
 
 
555
    if (!(flags & HASWIDTH) && op != '?') {
 
556
        //RAISE Error, SYM(cmRegularExpression), SYM(Empty_Operand),
 
557
        printf ("cmRegularExpression::compile() : *+ operand could be empty.\n");
 
558
        return 0;
 
559
    }
 
560
    *flagp = (op != '+') ? (WORST | SPSTART) : (WORST | HASWIDTH);
 
561
 
 
562
    if (op == '*' && (flags & SIMPLE))
 
563
        reginsert(STAR, ret);
 
564
    else if (op == '*') {
 
565
        // Emit x* as (x&|), where & means "self".
 
566
        reginsert(BRANCH, ret); // Either x
 
567
        regoptail(ret, regnode(BACK));  // and loop
 
568
        regoptail(ret, ret);    // back
 
569
        regtail(ret, regnode(BRANCH));  // or
 
570
        regtail(ret, regnode(NOTHING)); // null.
 
571
    }
 
572
    else if (op == '+' && (flags & SIMPLE))
 
573
        reginsert(PLUS, ret);
 
574
    else if (op == '+') {
 
575
        // Emit x+ as x(&|), where & means "self".
 
576
        next = regnode(BRANCH); // Either
 
577
        regtail(ret, next);
 
578
        regtail(regnode(BACK), ret);    // loop back
 
579
        regtail(next, regnode(BRANCH)); // or
 
580
        regtail(ret, regnode(NOTHING)); // null.
 
581
    }
 
582
    else if (op == '?') {
 
583
        // Emit x? as (x|)
 
584
        reginsert(BRANCH, ret); // Either x
 
585
        regtail(ret, regnode(BRANCH));  // or
 
586
        next = regnode(NOTHING);// null.
 
587
        regtail(ret, next);
 
588
        regoptail(ret, next);
 
589
    }
 
590
    regparse++;
 
591
    if (ISMULT(*regparse)) {
 
592
        //RAISE Error, SYM(cmRegularExpression), SYM(Nested_Operand),
 
593
        printf ("cmRegularExpression::compile(): Nested *?+.\n");
 
594
        return 0;
 
595
    }
 
596
    return (ret);
 
597
}
 
598
 
 
599
 
 
600
/*
 
601
 - regatom - the lowest level
 
602
 *
 
603
 * Optimization:  gobbles an entire sequence of ordinary characters so that
 
604
 * it can turn them into a single node, which is smaller to store and
 
605
 * faster to run.  Backslashed characters are exceptions, each becoming a
 
606
 * separate node; the code is simpler that way and it's not worth fixing.
 
607
 */
 
608
static char* regatom (int *flagp) {
 
609
    register char* ret;
 
610
             int   flags;
 
611
 
 
612
    *flagp = WORST;             // Tentatively.
 
613
 
 
614
    switch (*regparse++) {
 
615
        case '^':
 
616
            ret = regnode(BOL);
 
617
            break;
 
618
        case '$':
 
619
            ret = regnode(EOL);
 
620
            break;
 
621
        case '.':
 
622
            ret = regnode(ANY);
 
623
            *flagp |= HASWIDTH | SIMPLE;
 
624
            break;
 
625
        case '[':{
 
626
                register int    rxpclass;
 
627
                register int    rxpclassend;
 
628
 
 
629
                if (*regparse == '^') { // Complement of range.
 
630
                    ret = regnode(ANYBUT);
 
631
                    regparse++;
 
632
                }
 
633
                else
 
634
                    ret = regnode(ANYOF);
 
635
                if (*regparse == ']' || *regparse == '-')
 
636
                    regc(*regparse++);
 
637
                while (*regparse != '\0' && *regparse != ']') {
 
638
                    if (*regparse == '-') {
 
639
                        regparse++;
 
640
                        if (*regparse == ']' || *regparse == '\0')
 
641
                            regc('-');
 
642
                        else {
 
643
                            rxpclass = UCHARAT(regparse - 2) + 1;
 
644
                            rxpclassend = UCHARAT(regparse);
 
645
                            if (rxpclass > rxpclassend + 1) {
 
646
                               //RAISE Error, SYM(cmRegularExpression), SYM(Invalid_Range),
 
647
                               printf ("cmRegularExpression::compile(): Invalid range in [].\n");
 
648
                               return 0;
 
649
                            }
 
650
                            for (; rxpclass <= rxpclassend; rxpclass++)
 
651
                                regc(rxpclass);
 
652
                            regparse++;
 
653
                        }
 
654
                    }
 
655
                    else
 
656
                        regc(*regparse++);
 
657
                }
 
658
                regc('\0');
 
659
                if (*regparse != ']') {
 
660
                    //RAISE Error, SYM(cmRegularExpression), SYM(Unmatched_Bracket),
 
661
                    printf ("cmRegularExpression::compile(): Unmatched [].\n");
 
662
                    return 0;
 
663
                }
 
664
                regparse++;
 
665
                *flagp |= HASWIDTH | SIMPLE;
 
666
            }
 
667
            break;
 
668
        case '(':
 
669
            ret = reg(1, &flags);
 
670
            if (ret == NULL)
 
671
                return (NULL);
 
672
            *flagp |= flags & (HASWIDTH | SPSTART);
 
673
            break;
 
674
        case '\0':
 
675
        case '|':
 
676
        case ')':
 
677
            //RAISE Error, SYM(cmRegularExpression), SYM(Internal_Error),
 
678
            printf ("cmRegularExpression::compile(): Internal error.\n"); // Never here
 
679
            return 0;
 
680
        case '?':
 
681
        case '+':
 
682
        case '*':
 
683
            //RAISE Error, SYM(cmRegularExpression), SYM(No_Operand),
 
684
            printf ("cmRegularExpression::compile(): ?+* follows nothing.\n");
 
685
            return 0;
 
686
        case '\\':
 
687
            if (*regparse == '\0') {
 
688
                //RAISE Error, SYM(cmRegularExpression), SYM(Trailing_Backslash),
 
689
                printf ("cmRegularExpression::compile(): Trailing backslash.\n");
 
690
                return 0;
 
691
            }
 
692
            ret = regnode(EXACTLY);
 
693
            regc(*regparse++);
 
694
            regc('\0');
 
695
            *flagp |= HASWIDTH | SIMPLE;
 
696
            break;
 
697
        default:{
 
698
                register int    len;
 
699
                register char   ender;
 
700
 
 
701
                regparse--;
 
702
                len = strcspn(regparse, META);
 
703
                if (len <= 0) {
 
704
                    //RAISE Error, SYM(cmRegularExpression), SYM(Internal_Error),
 
705
                    printf ("cmRegularExpression::compile(): Internal error.\n");
 
706
                    return 0;
 
707
                }
 
708
                ender = *(regparse + len);
 
709
                if (len > 1 && ISMULT(ender))
 
710
                    len--;      // Back off clear of ?+* operand.
 
711
                *flagp |= HASWIDTH;
 
712
                if (len == 1)
 
713
                    *flagp |= SIMPLE;
 
714
                ret = regnode(EXACTLY);
 
715
                while (len > 0) {
 
716
                    regc(*regparse++);
 
717
                    len--;
 
718
                }
 
719
                regc('\0');
 
720
            }
 
721
            break;
 
722
    }
 
723
    return (ret);
 
724
}
 
725
 
 
726
 
 
727
/*
 
728
 - regnode - emit a node
 
729
   Location.
 
730
 */
 
731
static char* regnode (char op) {
 
732
    register char* ret;
 
733
    register char* ptr;
 
734
 
 
735
    ret = regcode;
 
736
    if (ret == &regdummy) {
 
737
        regsize += 3;
 
738
        return (ret);
 
739
    }
 
740
 
 
741
    ptr = ret;
 
742
    *ptr++ = op;
 
743
    *ptr++ = '\0';              // Null "next" pointer.
 
744
    *ptr++ = '\0';
 
745
    regcode = ptr;
 
746
 
 
747
    return (ret);
 
748
}
 
749
 
 
750
 
 
751
/*
 
752
 - regc - emit (if appropriate) a byte of code
 
753
 */
 
754
static void regc (unsigned char b) {
 
755
    if (regcode != &regdummy)
 
756
        *regcode++ = b;
 
757
    else
 
758
        regsize++;
 
759
}
 
760
 
 
761
 
 
762
/*
 
763
 - reginsert - insert an operator in front of already-emitted operand
 
764
 *
 
765
 * Means relocating the operand.
 
766
 */
 
767
static void reginsert (char op, char* opnd) {
 
768
    register char* src;
 
769
    register char* dst;
 
770
    register char* place;
 
771
 
 
772
    if (regcode == &regdummy) {
 
773
        regsize += 3;
 
774
        return;
 
775
    }
 
776
 
 
777
    src = regcode;
 
778
    regcode += 3;
 
779
    dst = regcode;
 
780
    while (src > opnd)
 
781
        *--dst = *--src;
 
782
 
 
783
    place = opnd;               // Op node, where operand used to be.
 
784
    *place++ = op;
 
785
    *place++ = '\0';
 
786
    *place++ = '\0';
 
787
}
 
788
 
 
789
 
 
790
/*
 
791
 - regtail - set the next-pointer at the end of a node chain
 
792
 */
 
793
static void regtail (char* p, const char* val) {
 
794
    register char* scan;
 
795
    register char* temp;
 
796
    register int   offset;
 
797
 
 
798
    if (p == &regdummy)
 
799
        return;
 
800
 
 
801
    // Find last node.
 
802
    scan = p;
 
803
    for (;;) {
 
804
        temp = regnext(scan);
 
805
        if (temp == NULL)
 
806
            break;
 
807
        scan = temp;
 
808
    }
 
809
 
 
810
    if (OP(scan) == BACK)
 
811
        offset = (const char*)scan - val;
 
812
    else
 
813
        offset = val - scan;
 
814
    *(scan + 1) = (offset >> 8) & 0377;
 
815
    *(scan + 2) = offset & 0377;
 
816
}
 
817
 
 
818
 
 
819
/*
 
820
 - regoptail - regtail on operand of first argument; nop if operandless
 
821
 */
 
822
static void regoptail (char* p, const char* val) {
 
823
    // "Operandless" and "op != BRANCH" are synonymous in practice.
 
824
    if (p == NULL || p == &regdummy || OP(p) != BRANCH)
 
825
        return;
 
826
    regtail(OPERAND(p), val);
 
827
}
 
828
 
 
829
 
 
830
 
 
831
////////////////////////////////////////////////////////////////////////
 
832
// 
 
833
//  find and friends
 
834
// 
 
835
////////////////////////////////////////////////////////////////////////
 
836
 
 
837
 
 
838
/*
 
839
 * Global work variables for find().
 
840
 */
 
841
static const char*  reginput;   // String-input pointer.
 
842
static const char*  regbol;     // Beginning of input, for ^ check.
 
843
static const char* *regstartp;  // Pointer to startp array.
 
844
static const char* *regendp;    // Ditto for endp.
 
845
 
 
846
/*
 
847
 * Forwards.
 
848
 */
 
849
static int regtry (const char*, const char* *,
 
850
                   const char* *, const char*);
 
851
static int regmatch (const char*);
 
852
static int regrepeat (const char*);
 
853
 
 
854
#ifdef DEBUG
 
855
int          regnarrate = 0;
 
856
void         regdump ();
 
857
static char* regprop ();
 
858
#endif
 
859
 
 
860
bool cmRegularExpression::find (std::string const& s) 
 
861
{
 
862
  return find(s.c_str());
 
863
}
 
864
 
 
865
 
 
866
 
 
867
// find -- Matches the regular expression to the given string.
 
868
// Returns true if found, and sets start and end indexes accordingly.
 
869
 
 
870
bool cmRegularExpression::find (const char* string) {
 
871
    register const char* s;
 
872
 
 
873
    this->searchstring = string;
 
874
 
 
875
     // Check validity of program.
 
876
    if (!this->program || UCHARAT(this->program) != MAGIC) {
 
877
        //RAISE Error, SYM(cmRegularExpression), SYM(Internal_Error),
 
878
        printf ("cmRegularExpression::find(): Compiled regular expression corrupted.\n");
 
879
        return 0;
 
880
    }
 
881
    
 
882
    // If there is a "must appear" string, look for it.
 
883
    if (this->regmust != NULL) {
 
884
        s = string;
 
885
        while ((s = strchr(s, this->regmust[0])) != NULL) {
 
886
            if (strncmp(s, this->regmust, this->regmlen) == 0)
 
887
                break;          // Found it.
 
888
            s++;
 
889
        }
 
890
        if (s == NULL)          // Not present.
 
891
            return (0);
 
892
    }
 
893
     
 
894
    // Mark beginning of line for ^ .
 
895
    regbol = string;
 
896
 
 
897
    // Simplest case:  anchored match need be tried only once.
 
898
    if (this->reganch)
 
899
        return (regtry(string, this->startp, this->endp, this->program) != 0);
 
900
    
 
901
    // Messy cases:  unanchored match.
 
902
    s = string;
 
903
    if (this->regstart != '\0')
 
904
        // We know what char it must start with.
 
905
        while ((s = strchr(s, this->regstart)) != NULL) {
 
906
            if (regtry(s, this->startp, this->endp, this->program))
 
907
                return (1);
 
908
            s++;
 
909
          
 
910
        }
 
911
    else
 
912
        // We don't -- general case.
 
913
        do {
 
914
            if (regtry(s, this->startp, this->endp, this->program))
 
915
                return (1);
 
916
        } while (*s++ != '\0');
 
917
    
 
918
    // Failure.
 
919
    return (0);
 
920
}
 
921
 
 
922
 
 
923
/*
 
924
 - regtry - try match at specific point
 
925
   0 failure, 1 success
 
926
 */
 
927
static int regtry (const char* string, const char* *start,
 
928
                   const char* *end, const char* prog) {
 
929
    register       int    i;
 
930
    register const char* *sp1;
 
931
    register const char* *ep;
 
932
 
 
933
    reginput = string;
 
934
    regstartp = start;
 
935
    regendp = end;
 
936
 
 
937
    sp1 = start;
 
938
    ep = end;
 
939
    for (i = NSUBEXP; i > 0; i--) {
 
940
        *sp1++ = NULL;
 
941
        *ep++ = NULL;
 
942
    }
 
943
    if (regmatch(prog + 1)) {
 
944
        start[0] = string;
 
945
        end[0] = reginput;
 
946
        return (1);
 
947
    }
 
948
    else
 
949
        return (0);
 
950
}
 
951
 
 
952
 
 
953
/*
 
954
 - regmatch - main matching routine
 
955
 *
 
956
 * Conceptually the strategy is simple:  check to see whether the current
 
957
 * node matches, call self recursively to see whether the rest matches,
 
958
 * and then act accordingly.  In practice we make some effort to avoid
 
959
 * recursion, in particular by going through "ordinary" nodes (that don't
 
960
 * need to know whether the rest of the match failed) by a loop instead of
 
961
 * by recursion.
 
962
 * 0 failure, 1 success
 
963
 */
 
964
static int regmatch (const char* prog) {
 
965
    register const char* scan;  // Current node.
 
966
             const char* next;  // Next node.
 
967
 
 
968
    scan = prog;
 
969
 
 
970
    while (scan != NULL) {
 
971
 
 
972
        next = regnext(scan);
 
973
 
 
974
        switch (OP(scan)) {
 
975
            case BOL:
 
976
                if (reginput != regbol)
 
977
                    return (0);
 
978
                break;
 
979
            case EOL:
 
980
                if (*reginput != '\0')
 
981
                    return (0);
 
982
                break;
 
983
            case ANY:
 
984
                if (*reginput == '\0')
 
985
                    return (0);
 
986
                reginput++;
 
987
                break;
 
988
            case EXACTLY:{
 
989
                    register int         len;
 
990
                    register const char* opnd;
 
991
 
 
992
                    opnd = OPERAND(scan);
 
993
                    // Inline the first character, for speed.
 
994
                    if (*opnd != *reginput)
 
995
                        return (0);
 
996
                    len = strlen(opnd);
 
997
                    if (len > 1 && strncmp(opnd, reginput, len) != 0)
 
998
                        return (0);
 
999
                    reginput += len;
 
1000
                }
 
1001
                break;
 
1002
            case ANYOF:
 
1003
                if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL)
 
1004
                    return (0);
 
1005
                reginput++;
 
1006
                break;
 
1007
            case ANYBUT:
 
1008
                if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL)
 
1009
                    return (0);
 
1010
                reginput++;
 
1011
                break;
 
1012
            case NOTHING:
 
1013
                break;
 
1014
            case BACK:
 
1015
                break;
 
1016
            case OPEN + 1:
 
1017
            case OPEN + 2:
 
1018
            case OPEN + 3:
 
1019
            case OPEN + 4:
 
1020
            case OPEN + 5:
 
1021
            case OPEN + 6:
 
1022
            case OPEN + 7:
 
1023
            case OPEN + 8:
 
1024
            case OPEN + 9:{
 
1025
                    register       int    no;
 
1026
                    register const char* save;
 
1027
 
 
1028
                    no = OP(scan) - OPEN;
 
1029
                    save = reginput;
 
1030
 
 
1031
                    if (regmatch(next)) {
 
1032
 
 
1033
                        //
 
1034
                        // Don't set startp if some later invocation of the
 
1035
                        // same parentheses already has. 
 
1036
                        //
 
1037
                        if (regstartp[no] == NULL)
 
1038
                            regstartp[no] = save;
 
1039
                        return (1);
 
1040
                    }
 
1041
                    else
 
1042
                        return (0);
 
1043
                }
 
1044
//              break;
 
1045
            case CLOSE + 1:
 
1046
            case CLOSE + 2:
 
1047
            case CLOSE + 3:
 
1048
            case CLOSE + 4:
 
1049
            case CLOSE + 5:
 
1050
            case CLOSE + 6:
 
1051
            case CLOSE + 7:
 
1052
            case CLOSE + 8:
 
1053
            case CLOSE + 9:{
 
1054
                    register       int    no;
 
1055
                    register const char* save;
 
1056
 
 
1057
                    no = OP(scan) - CLOSE;
 
1058
                    save = reginput;
 
1059
 
 
1060
                    if (regmatch(next)) {
 
1061
 
 
1062
                        //
 
1063
                        // Don't set endp if some later invocation of the
 
1064
                        // same parentheses already has. 
 
1065
                        //
 
1066
                        if (regendp[no] == NULL)
 
1067
                            regendp[no] = save;
 
1068
                        return (1);
 
1069
                    }
 
1070
                    else
 
1071
                        return (0);
 
1072
                }
 
1073
//              break;
 
1074
            case BRANCH:{
 
1075
              
 
1076
              register const char* save;
 
1077
 
 
1078
                    if (OP(next) != BRANCH)     // No choice.
 
1079
                        next = OPERAND(scan);   // Avoid recursion.
 
1080
                    else {
 
1081
                        do {
 
1082
                            save = reginput;
 
1083
                            if (regmatch(OPERAND(scan)))
 
1084
                                return (1);
 
1085
                            reginput = save;
 
1086
                            scan = regnext(scan);
 
1087
                        } while (scan != NULL && OP(scan) == BRANCH);
 
1088
                        return (0);
 
1089
                        // NOTREACHED
 
1090
                    }
 
1091
                }
 
1092
                break;
 
1093
            case STAR:
 
1094
            case PLUS:{
 
1095
              register char   nextch;
 
1096
                    register int        no;
 
1097
                    register const char* save;
 
1098
                    register int        min_no;
 
1099
 
 
1100
                    //
 
1101
                    // Lookahead to avoid useless match attempts when we know
 
1102
                    // what character comes next. 
 
1103
                    //
 
1104
                    nextch = '\0';
 
1105
                    if (OP(next) == EXACTLY)
 
1106
                        nextch = *OPERAND(next);
 
1107
                    min_no = (OP(scan) == STAR) ? 0 : 1;
 
1108
                    save = reginput;
 
1109
                    no = regrepeat(OPERAND(scan));
 
1110
                    while (no >= min_no) {
 
1111
                        // If it could work, try it.
 
1112
                        if (nextch == '\0' || *reginput == nextch)
 
1113
                            if (regmatch(next))
 
1114
                                return (1);
 
1115
                        // Couldn't or didn't -- back up.
 
1116
                        no--;
 
1117
                        reginput = save + no;
 
1118
                    }
 
1119
                    return (0);
 
1120
                }
 
1121
//              break;
 
1122
            case END:
 
1123
                return (1);     // Success!
 
1124
 
 
1125
            default:
 
1126
                //RAISE Error, SYM(cmRegularExpression), SYM(Internal_Error),
 
1127
                printf ("cmRegularExpression::find(): Internal error -- memory corrupted.\n");
 
1128
                return 0;
 
1129
        }
 
1130
        scan = next;
 
1131
    }
 
1132
 
 
1133
    // 
 
1134
    //  We get here only if there's trouble -- normally "case END" is the
 
1135
    //  terminating point. 
 
1136
    // 
 
1137
    //RAISE Error, SYM(cmRegularExpression), SYM(Internal_Error),
 
1138
    printf ("cmRegularExpression::find(): Internal error -- corrupted pointers.\n");
 
1139
    return (0);
 
1140
}
 
1141
 
 
1142
 
 
1143
/*
 
1144
 - regrepeat - repeatedly match something simple, report how many
 
1145
 */
 
1146
static int regrepeat (const char* p) {
 
1147
    register       int   count = 0;
 
1148
    register const char* scan;
 
1149
    register const char* opnd;
 
1150
 
 
1151
    scan = reginput;
 
1152
    opnd = OPERAND(p);
 
1153
    switch (OP(p)) {
 
1154
        case ANY:
 
1155
            count = strlen(scan);
 
1156
            scan += count;
 
1157
            break;
 
1158
        case EXACTLY:
 
1159
            while (*opnd == *scan) {
 
1160
                count++;
 
1161
                scan++;
 
1162
            }
 
1163
            break;
 
1164
        case ANYOF:
 
1165
            while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
 
1166
                count++;
 
1167
                scan++;
 
1168
            }
 
1169
            break;
 
1170
        case ANYBUT:
 
1171
            while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
 
1172
                count++;
 
1173
                scan++;
 
1174
            }
 
1175
            break;
 
1176
        default:                // Oh dear.  Called inappropriately.
 
1177
            //RAISE Error, SYM(cmRegularExpression), SYM(Internal_Error),
 
1178
            printf ("cm RegularExpression::find(): Internal error.\n");
 
1179
            return 0;
 
1180
    }
 
1181
    reginput = scan;
 
1182
    return (count);
 
1183
}
 
1184
 
 
1185
 
 
1186
/*
 
1187
 - regnext - dig the "next" pointer out of a node
 
1188
 */
 
1189
static const char* regnext (register const char* p) {
 
1190
    register int offset;
 
1191
 
 
1192
    if (p == &regdummy)
 
1193
        return (NULL);
 
1194
 
 
1195
    offset = NEXT(p);
 
1196
    if (offset == 0)
 
1197
        return (NULL);
 
1198
 
 
1199
    if (OP(p) == BACK)
 
1200
        return (p - offset);
 
1201
    else
 
1202
        return (p + offset);
 
1203
}
 
1204
 
 
1205
 
 
1206
static char* regnext (register char* p) {
 
1207
    register int offset;
 
1208
 
 
1209
    if (p == &regdummy)
 
1210
        return (NULL);
 
1211
 
 
1212
    offset = NEXT(p);
 
1213
    if (offset == 0)
 
1214
        return (NULL);
 
1215
 
 
1216
    if (OP(p) == BACK)
 
1217
        return (p - offset);
 
1218
    else
 
1219
        return (p + offset);
 
1220
}