home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_11_11 / splash / regexp.h < prev    next >
Text File  |  1993-01-15  |  4KB  |  174 lines

  1. /*
  2.  * version 1.8
  3.  * Regexp is a class that encapsulates the Regular expression
  4.  * stuff. Hopefully this means I can plug in different regexp
  5.  * libraries without the rest of my code needing to be changed.
  6.  * Written by Jim Morris,  jegm@sgi.com
  7.  */
  8. #ifndef    _REGEXP_H
  9. #define _REGEXP_H
  10. #include    <iostream.h>
  11. #include    <stdlib.h>
  12. #include    <malloc.h>
  13. #include    <string.h>
  14. #include    <assert.h>
  15. #include    <ctype.h>
  16.  
  17. #include    "regex.h"
  18.  
  19. /*
  20.  * Note this is an inclusive range where it goes
  21.  * from start() to, and including, end()
  22.  */
  23. class Range
  24. {
  25. private:
  26.     int st, en, len;
  27.     
  28. public:
  29.     Range()
  30.     {
  31.     st=0; en= -1; len= 0;
  32.     }
  33.     
  34.     Range(int s, int e)
  35.     {
  36.     st= s; en= e; len= (en - st) + 1;
  37.      assert(st <= en && st >= 0); 
  38.     }
  39.  
  40.     // test validity of the range
  41.     operator void *() { return (st <= en && st >= 0)? this : 0;}
  42.     int start(void) const { return st;}
  43.     int end(void) const { return en;}
  44.     int length(void) const { return len;}
  45.  
  46.     void set(int a, int b)
  47.     {
  48.     st= a; en= b; len= (en - st) + 1;
  49.      assert(st <= en && st >= 0); 
  50.     }
  51.  
  52.     int operator<(const Range& r) const // for sorting
  53.     {
  54.         return ((st == r.st) ? (en < r.en) : (st < r.st));
  55.     }
  56.  
  57.     // x++ operator extends end of range by one
  58.     void operator++(int){ en++; len++; }
  59.     
  60.     // ++x operator extends start of range by one
  61.     void operator++(void){ st++; len--; }
  62.  
  63. #if 0
  64.     // Don't need these yet
  65.     Range operator&(const Range& r) const // returns intersection of two ranges
  66.     {
  67.         Range ret;
  68.         if(en >= 0 && r.en >= 0 && (st <= r.en) && (en >= r.st)){  // if any overlap
  69.             ret.st= (st > r.st) ? st : r.st;
  70.             ret.en= (en < r.en) ? en : r.en;
  71.         }
  72.         return ret;
  73.     }
  74.     
  75.     Range operator|(const Range& r) const // returns union of two ranges if consecutive
  76.     {
  77.         Range ret;
  78.         if(en >= 0 && r.en >= 0 && (st <= r.en+1) && (en >= r.st-1)){  // if any overlap or contiguous
  79.             ret.st= (st < r.st) ? st : r.st;
  80.             ret.en= (en > r.en) ? en : r.en;
  81.         }
  82.         return ret;
  83.     }
  84. #endif
  85.  
  86.     friend ostream& operator<<(ostream& os, const Range& r)
  87.     {
  88.         os << r.st << " - " << r.en << " (" << (r.en - r.st)+1 << ")";
  89.         return os;
  90.     }
  91. };
  92.  
  93. class Regexp
  94. {
  95. public:
  96.     enum options {def=0, nocase=1};
  97.     
  98. private:
  99.     regexp *repat;
  100.     const char *target; // only used as a base address to get an offset
  101.     int res;
  102.     int iflg;
  103. #ifndef    __TURBOC__
  104.     void strlwr(char *s)
  105.     {
  106.     while(*s){
  107.         *s= tolower(*s);
  108.         s++;
  109.     }
  110.     }
  111. #endif    
  112. public:
  113.     Regexp(const char *rege, int ifl= 0)
  114.     {
  115.         iflg= ifl;
  116.         if(iflg == nocase){ // lowercase fold
  117.             char *r= new char[strlen(rege)+1];
  118.             strcpy(r, rege);
  119.             strlwr(r);
  120.             if((repat=regcomp(r)) == NULL){
  121.             cerr << "regcomp() error" << endl;
  122.             exit(1);
  123.             }
  124.             delete [] r;
  125.     }else{
  126.         if((repat=regcomp (rege)) == NULL){
  127.             cerr << "regcomp() error" << endl;
  128.             exit(1);
  129.         }
  130.         }
  131.     }
  132.     
  133.     ~Regexp()
  134.     {
  135.     free(repat);
  136.     }    
  137.  
  138.     int match(const char *targ)
  139.     {
  140.         int res;
  141.         if(iflg == nocase){ // fold lowercase
  142.             char *r= new char[strlen(targ)+1];
  143.             strcpy(r, targ);
  144.             strlwr(r);
  145.             res= regexec(repat, r); 
  146.             target= r; // looks bad but is really ok, really
  147.             delete [] r;
  148.         }else{
  149.         res= regexec(repat, targ);
  150.         target= targ;
  151.     }
  152.  
  153.     return ((res == 0) ? 0 : 1);
  154.     }
  155.     
  156.     int groups(void) const
  157.     {
  158.     int res= 0;
  159.     for (int i=0; i<NSUBEXP; i++) {
  160.         if(repat->startp[i] == NULL) break;
  161.         res++;
  162.     }
  163.     return res;
  164.     }
  165.     
  166.     Range getgroup(int n) const
  167.     {
  168.     assert(n < NSUBEXP);
  169.     return Range((int)(repat->startp[n] - (char *)target),
  170.              (int)(repat->endp[n] - (char *)target) - 1);
  171.     }
  172. };
  173. #endif
  174.