pike.git / src / modules / Regexp / pike_regexp.c

version» Context lines:

pike.git/src/modules/Regexp/pike_regexp.c:208:   #define SPSTART 04 /* Starts with * */   #define WORST 0 /* Worst case. */      /*    * Global work variables for regcomp().    */   static short *regparse; /* Input-scan pointer. */   static int regnpar; /* () count. */   static char *regcode; /* Code-emit pointer; &regdummy = don't. */   static long regsize; /* Code size. */ - static char regdummy; + static char regdummy[3] = { NOTHING, 0, 0 };      /*    * Forward declarations for regcomp()'s friends.    */   static char *reg(int, int *);   static char *regbranch(int *);   static char *regpiece(int *);   static char *regatom(int *);   static char *regnode(char);   static char *regnext(char *);
pike.git/src/modules/Regexp/pike_regexp.c:293:    break;    default:    *dest++ = c;    }    }       /* First pass: determine size, legality. */    regparse = exp2;    regnpar = 1;    regsize = 0L; -  regcode = &regdummy; +  regcode = regdummy;    if (reg(0, &flags) == NULL)    goto exit_regcomp;       /* Small enough for pointer-storage convention? */    if (regsize >= 32767L) /* Probably could be 65535L. */    {    free(exp2);    FAIL("regexp too big");    }   
pike.git/src/modules/Regexp/pike_regexp.c:402:    ret = NULL;       /* Pick up the branches, linking them together. */    br = regbranch(&flags);    if (br == NULL)    return (NULL);    if (ret != NULL)    regtail(ret, br); /* OPEN -> first. */    else    ret = br; +     if (!(flags & HASWIDTH))    *flagp &= ~HASWIDTH;    *flagp |= flags & SPSTART; -  +     while (*regparse == OR_OP) {    regparse++;    br = regbranch(&flags);    if (br == NULL)    return (NULL);    regtail(ret, br); /* BRANCH -> BRANCH. */    if (!(flags & HASWIDTH))    *flagp &= ~HASWIDTH;    *flagp |= flags & SPSTART;    }
pike.git/src/modules/Regexp/pike_regexp.c:434:    /* Check for proper termination. */    if (paren && *regparse++ != RBRAC) {    FAIL("unmatched ()");    } else if (!paren && *regparse != '\0') {    if (*regparse == RBRAC) {    FAIL("unmatched ()");    } else    FAIL("junk on end");/* "Can't happen". */    /* NOTREACHED */    } +     return (ret);   }      /*    - regbranch - one alternative of an | operator    *    * Implements the concatenation operator.    */   static char *regbranch(int *flagp)   {
pike.git/src/modules/Regexp/pike_regexp.c:493:       ret = regatom(&flags);    if (ret == NULL)    return (NULL);       op = *regparse;    if (!ISMULT(op)) {    *flagp = flags;    return (ret);    } +  +  /* FIXME: + can not be empty */    if (!(flags & HASWIDTH))    FAIL("* or + operand could be empty");    *flagp = (WORST | SPSTART);       if(op == ASTERIX)    {    if (flags & SIMPLE)    {    reginsert(STAR, ret);    }
pike.git/src/modules/Regexp/pike_regexp.c:585:    break;    case LSQBRAC:{    int range;    int rangeend;       if (*regparse == CARET) { /* Complement of range. */    ret = regnode(ANYBUT);    regparse++;    } else    ret = regnode(ANYOF); +     if (*regparse == RSQBRAC || *regparse == '-')    regc((char)(*regparse++)); -  +     while (*regparse != '\0' && *regparse != RSQBRAC) {    if (*regparse == '-') {    regparse++;    if (*regparse == RSQBRAC || *regparse == '\0')    regc('-');    else { -  range = (CHARBITS & *(regparse - 2)) + 1; +  range = (CHARBITS & *(regparse - 2));    rangeend = (CHARBITS & *(regparse)); -  if (range > rangeend + 1) +  if (range > rangeend)    FAIL("invalid [] range"); -  for (; range <= rangeend; range++) +  for (range++; range <= rangeend; range++)    regc((char)range);    regparse++;    }    } else    regc((char)(*regparse++));    }    regc('\0');    if (*regparse != RSQBRAC)    FAIL("unmatched []");    regparse++;
pike.git/src/modules/Regexp/pike_regexp.c:622:    ret = reg(1, &flags);    if (ret == NULL)    return (NULL);    *flagp |= flags & (HASWIDTH | SPSTART);    break;    case '\0':    case OR_OP:    case RBRAC:    FAIL("internal urp"); /* Supposed to be caught earlier. */    +  case PLUS:    case ASTERIX: -  FAIL("* follows nothing\n"); +  FAIL("*/+ follows nothing\n");       default:{ -  int len; +  size_t len;    short ender;       regparse--;    for (len=0; regparse[len] &&    !(regparse[len]&SPECIAL) && regparse[len] != RSQBRAC; len++) ;    if (len <= 0) -  { +     FAIL("internal disaster"); -  } +     ender = *(regparse + len);    if (len > 1 && ISMULT(ender)) -  len--; /* Back off clear of * operand. */ +  len--; /* Back off clear of +,* operand. */    *flagp |= HASWIDTH;    if (len == 1)    *flagp |= SIMPLE;    ret = regnode(EXACTLY); -  while (len > 0) { +  for (; len > 0; len--)    regc((char)(*regparse++)); -  len--; -  } +     regc('\0');    }    break;    }       return (ret);   }      /*    - regnode - emit a node    */   static char *regnode(char op)   { -  char *ret; +  char *ret = regcode;    char *ptr;    -  ret = regcode; -  if (ret == &regdummy) { +  if (ret == regdummy) {    regsize += 3;    return (ret);    } -  +     ptr = ret;    *ptr++ = op;    *ptr++ = '\0'; /* Null "next" pointer. */    *ptr++ = '\0';    regcode = ptr;       return (ret);   }      /*    - regc - emit (if appropriate) a byte of code    */   static void regc(char b)   { -  if (regcode != &regdummy) +  if (regcode != regdummy)    *regcode++ = b;    else    regsize++;   }      /*    - reginsert - insert an operator in front of already-emitted operand    *    * Means relocating the operand.    */   static void reginsert(char op, char *opnd)   {    char *place;    -  if (regcode == &regdummy) { +  if (regcode == regdummy) {    regsize += 3;    return;    }       memmove(opnd+3, opnd, (size_t)(regcode - opnd));    regcode += 3;       place = opnd; /* Op node, where operand used to be. */    *place++ = op;    *place++ = '\0';
pike.git/src/modules/Regexp/pike_regexp.c:720:      /*    - regtail - set the next-pointer at the end of a node chain    */   static void regtail(char *p, const char *val)   {    char *scan;    char *temp;    ptrdiff_t offset;    -  if (p == &regdummy) +  if (p == regdummy)    return;       /* Find last node. */ -  scan = p; -  for (;;) { -  temp = regnext(scan); -  if (temp == NULL) -  break; -  scan = temp; -  } +  for (scan = p; (temp = regnext(scan)) != NULL; scan = temp) +  continue;       if (OP(scan) == BACK)    offset = scan - val;    else    offset = val - scan;    *(scan + 1) = DO_NOT_WARN((offset >> 8) & 0377);    *(scan + 2) = DO_NOT_WARN(offset & 0377);   }      /*    - regoptail - regtail on operand of first argument; nop if operandless    */   static void regoptail(char *p, const char *val)   {    /* "Operandless" and "op != BRANCH" are synonymous in practice. */ -  if (p == NULL || p == &regdummy || OP(p) != BRANCH) +  if (p == NULL || p == regdummy || OP(p) != BRANCH)    return;    regtail(OPERAND(p), val);   }      /*    * regexec and friends    */      /*    * Global work variables for regexec().
pike.git/src/modules/Regexp/pike_regexp.c:803:    /* Mark beginning of line for ^ . */    regbol = string;       /* Simplest case: anchored match need be tried only once. */    if (prog->reganch)    return (regtry(prog, string));       /* Messy cases: unanchored match. */    s = string;    if (prog->regstart != '\0') +  {    /* We know what char it must start with. */ -  while ((s = strchr(s, prog->regstart)) != NULL) { +  for (s = string; s != NULL; s = strchr(s+1, prog->regstart))    if (regtry(prog, s)) -  return (1); -  s++; +  return(1); +  return(0);    }    else -  +  {    /* We don't -- general case. */ -  do { -  if (regtry(prog, s)) -  return (1); -  } while (*s++ != '\0'); +  for (s = string; !regtry(prog, s); s++) +  if (*s == '\0') +  return(0); +  return(1); +  }    -  /* Failure. */ +  /* NOTREACHED */    return (0);   }      /*    - regtry - try match at specific point    */   static int regtry(regexp *prog, char *string)   {    int i;    char **stp;
pike.git/src/modules/Regexp/pike_regexp.c:938:    strchr(OPERAND(scan), *reginput) != NULL)    return (0);    reginput++;    break;    case NOTHING:    break;    case BACK:    break;       case BRANCH:{ -  char *save; -  +     if (OP(next) != BRANCH) /* No choice. */    next = OPERAND(scan); /* Avoid recursion. */    else { -  +  /* FIXME: This loop is different upstream. */ +  char *save = reginput;    do { -  save = reginput; +     if (regmatch(OPERAND(scan)))    return (1);    reginput = save;    scan = regnext(scan);    } while (scan != NULL && OP(scan) == BRANCH);    return (0);    /* NOTREACHED */    }    }    break;
pike.git/src/modules/Regexp/pike_regexp.c:979:    }    return (0);    }       case END:    return (1); /* Success! */       default:    if(OP(scan) >= OPEN && OP(scan)<OPEN+NSUBEXP)    { -  int no; -  char *input; +  int no = OP(scan) - OPEN; +  char *input = reginput;    -  no = OP(scan) - OPEN; -  input = reginput; -  +     if (regmatch(next)) {    /*    * Don't set startp if some later invocation of the same    * parentheses already has.    */    if (regstartp[no] == NULL)    regstartp[no] = input;    return (1);    } else    return (0);    }       if(OP(scan) >= CLOSE && OP(scan)<CLOSE+NSUBEXP)    { -  int no; -  char *input; +  int no = OP(scan) - CLOSE; +  char *input = reginput;    -  no = OP(scan) - CLOSE; -  input = reginput; -  +     if (regmatch(next)) {    /*    * Don't set endp if some later invocation of the same    * parentheses already has.    */    if (regendp[no] == NULL)    regendp[no] = input;    return (1);    } else    return (0);
pike.git/src/modules/Regexp/pike_regexp.c:1037:    */    regerror("corrupted pointers");    return (0);   }      /*    - regrepeat - repeatedly match something simple, report how many    */   static size_t regrepeat(const char *node)   { -  size_t count = 0; -  char *scan; -  char ch; -  +     switch (OP(node)) {    case ANY:    return(strlen(reginput));    break;    case EXACTLY: -  ch = *OPERAND(node); -  count = 0; +  { +  char *scan; +  char ch = *OPERAND(node); +  size_t count = 0; +     for (scan = reginput; *scan == ch; scan++)    count++;    return(count); -  +  }    break;    case ANYOF:    return(strspn(reginput, OPERAND(node)));    break;    case ANYBUT:    return(strcspn(reginput, OPERAND(node)));    break;    default: /* Oh dear. Called inappropriately. */    regerror("internal foulup");    return(0); /* Best compromise. */
pike.git/src/modules/Regexp/pike_regexp.c:1072:    }    /* NOREACHED */   }         /*    - regnext - dig the "next" pointer out of a node    */   static char *regnext(char *p)   { -  int offset; +  int offset = NEXT(p);    -  if (p == &regdummy) -  return (NULL); -  -  offset = NEXT(p); +     if (offset == 0)    return (NULL);       if (OP(p) == BACK)    return (p - offset);    else    return (p + offset);   }      #ifdef PIKE_DEBUG