home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / zip / gnu / gawk213s.lzh / GAWK213S / RE.C < prev    next >
C/C++ Source or Header  |  1993-07-29  |  3KB  |  145 lines

  1. /*
  2.  * re.c - compile regular expressions.
  3.  */
  4.  
  5. /* 
  6.  * Copyright (C) 1991 the Free Software Foundation, Inc.
  7.  * 
  8.  * This file is part of GAWK, the GNU implementation of the
  9.  * AWK Progamming Language.
  10.  * 
  11.  * GAWK is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 1, or (at your option)
  14.  * any later version.
  15.  * 
  16.  * GAWK is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  * 
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with GAWK; see the file COPYING.  If not, write to
  23.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  */
  25.  
  26. #include "awk.h"
  27.  
  28. /* Generate compiled regular expressions */
  29. Regexp *
  30. make_regexp(s, ignorecase, dfa)
  31. NODE *s;
  32. int ignorecase;
  33. int dfa;
  34. {
  35.     Regexp *rp;
  36.     char *err;
  37.  
  38.     emalloc(rp, Regexp *, sizeof(*rp), "make_regexp");
  39.     memset((char *) rp, 0, sizeof(*rp));
  40.     emalloc(rp->pat.buffer, char *, 16, "make_regexp");
  41.     rp->pat.allocated = 16;
  42.     emalloc(rp->pat.fastmap, char *, 256, "make_regexp");
  43.  
  44.     if (ignorecase)
  45.         rp->pat.translate = casetable;
  46.     else
  47.         rp->pat.translate = NULL;
  48.     if ((err = re_compile_pattern(s->stptr, (size_t) s->stlen, &(rp->pat))) != NULL)
  49.         fatal("%s: /%s/", err, s->stptr);
  50.     if (dfa && !ignorecase) {
  51.         regcompile(s->stptr, s->stlen, &(rp->dfareg), 1);
  52.         rp->dfa = 1;
  53.     } else
  54.         rp->dfa = 0;
  55.     free_temp(s);
  56.     return rp;
  57. }
  58.  
  59. int
  60. research(rp, str, len, need_start)
  61. Regexp *rp;
  62. register char *str;
  63. register int len;
  64. int need_start;
  65. {
  66.     int count;
  67.     int try_backref;
  68.     char save1;
  69.     char save2;
  70.     char *ret = &save2;
  71.  
  72.     if (rp->dfa) {
  73.         save1 = str[len];
  74.         str[len] = '\n';
  75.         save2 = str[len+1];
  76.         ret = regexecute(&(rp->dfareg), str, str+len+1, 0, &count,
  77.                     &try_backref);
  78.         str[len] = save1;
  79.         str[len+1] = save2;
  80.     }
  81.     if (ret) {
  82.         if (need_start || rp->dfa == 0)
  83.             return re_search(&(rp->pat), str, len, 0, len, &(rp->regs));
  84.         else
  85.             return 1;
  86.      } else
  87.         return -1;
  88. }
  89.  
  90. void
  91. refree(rp)
  92. Regexp *rp;
  93. {
  94.     free(rp->pat.buffer);
  95.     free(rp->pat.fastmap);
  96.     if (rp->dfa)
  97.         regfree(&(rp->dfareg));
  98.     free(rp);
  99. }
  100.  
  101. void
  102. regerror(s)
  103. const char *s;
  104. {
  105.     fatal(s);
  106. }
  107.  
  108. Regexp *
  109. re_update(t)
  110. NODE *t;
  111. {
  112.     NODE *t1;
  113.  
  114. #    define    CASE    1
  115.     if ((t->re_flags & CASE) == IGNORECASE) {
  116.         if (t->re_flags & CONST)
  117.             return t->re_reg;
  118.         t1 = force_string(tree_eval(t->re_exp));
  119.         if (t->re_text) {
  120.             if (cmp_nodes(t->re_text, t1) == 0) {
  121.                 free_temp(t1);
  122.                 return t->re_reg;
  123.             }
  124.             unref(t->re_text);
  125.         }
  126.         t->re_text = dupnode(t1);
  127.         free_temp(t1);
  128.     }
  129.     if (t->re_reg)
  130.         refree(t->re_reg);
  131.     if (t->re_cnt)
  132.         t->re_cnt++;
  133.     if (t->re_cnt > 10)
  134.         t->re_cnt = 0;
  135.     if (!t->re_text) {
  136.         t1 = force_string(tree_eval(t->re_exp));
  137.         t->re_text = dupnode(t1);
  138.         free_temp(t1);
  139.     }
  140.     t->re_reg = make_regexp(t->re_text, IGNORECASE, t->re_cnt);
  141.     t->re_flags &= ~CASE;
  142.     t->re_flags |= IGNORECASE;
  143.     return t->re_reg;
  144. }
  145.