📄 regexp.c
字号:
* parentheses already has. */ if (regstartp[no] == (char *)NULL) regstartp[no] = save; return (1); } else return (0); } break; case CLOSE + 1: case CLOSE + 2: case CLOSE + 3: case CLOSE + 4: case CLOSE + 5: case CLOSE + 6: case CLOSE + 7: case CLOSE + 8: case CLOSE + 9:{ register int no; register char *save; no = OP(scan) - CLOSE; save = reginput; if (regmatch(nxt)) { /* * Don't set endp if some later invocation of the same * parentheses already has. */ if (regendp[no] == (char *)NULL) regendp[no] = save; return (1); } else return (0); } break; case BRANCH:{ register char *save; if (OP(nxt) != BRANCH) /* No choice. */ nxt = OPERAND(scan); /* Avoid recursion. */ else { do { save = reginput; if (regmatch(OPERAND(scan))) return (1); reginput = save; scan = regnext(scan); } while (scan != (char *)NULL && OP(scan) == BRANCH); return (0); /* NOTREACHED */ } } break; case STAR:{ register char nextch; register int no; register char *save; register int minimum; /* * Lookahead to avoid useless match attempts when we know * what character comes next. */ nextch = '\0'; if (OP(nxt) == EXACTLY) nextch = *OPERAND(nxt); minimum = (OP(scan) == STAR) ? 0 : 1; save = reginput; no = regrepeat(OPERAND(scan)); while (no >= minimum) { /* If it could work, try it. */ if (nextch == '\0' || *reginput == nextch) if (regmatch(nxt)) return (1); /* Couldn't or didn't -- back up. */ no--; reginput = save + no; } return (0); } break; case END: return (1); /* Success! */ break; default: regerror("memory corruption"); return (0); break; } scan = nxt; } /* * We get here only if there's trouble -- normally "case END" is the * terminating point. */ regerror("corrupted pointers"); return (0);}/* - regrepeat - repeatedly match something simple, report how many */#ifdef __STDC__static int regrepeat(char *p)#elsestatic int regrepeat(p)char *p;#endif{ register int count = 0; register char *scan; register char *opnd; scan = reginput; opnd = OPERAND(p); switch (OP(p)) { case ANY: count = strlen(scan); scan += count; break; case EXACTLY: while (*opnd == *scan) { count++; scan++; } break; case ANYOF: while (*scan != '\0' && strchr(opnd, *scan) != (char *)NULL) { count++; scan++; } break; case ANYBUT: while (*scan != '\0' && strchr(opnd, *scan) == (char *)NULL) { count++; scan++; } break; default: /* Oh dear. Called inappropriately. */ regerror("internal foulup"); count = 0; /* Best compromise. */ break; } reginput = scan; return (count);}/* - regnext - dig the "nxt" pointer out of a node */#ifdef __STDC__static char *regnext(register char *p)#elsestatic char *regnext(p)register char *p;#endif{ register int offset; if (p == ®dummy) return ((char *)NULL); offset = NEXT(p); if (offset == 0) return ((char *)NULL); if (OP(p) == BACK) return (p - offset); else return (p + offset);}#ifdef DEBUGSTATIC char *regprop();/* - regdump - dump a regexp onto stdout in vaguely comprehensible form */#ifdef __STDC__void regdump(regexp *r)#elsevoid regdump(r)regexp *r;#endif{ register char *s; register char op = EXACTLY; /* Arbitrary non-END op. */ register char *nxt; extern char *strchr(); s = r->program + 1; while (op != END) { /* While that wasn't END last time... */ op = OP(s); printf("%2d%s", s - r->program, regprop(s)); /* Where, what. */ nxt = regnext(s); if (nxt == (char *)NULL) /* nxt ptr. */ printf("(0)"); else printf("(%d)", (s - r->program) + (nxt - s)); s += 3; if (op == ANYOF || op == ANYBUT || op == EXACTLY) { /* Literal string, where present. */ while (*s != '\0') { putchar(*s); s++; } s++; } putchar('\n'); } /* Header fields of interest. */ if (r->regstart != '\0') printf("start `%c' ", r->regstart); if (r->reganch) printf("anchored "); if (r->regmust != (char *)NULL) printf("must have \"%s\"", r->regmust); printf("\n");}/* - regprop - printable representation of opcode */#ifdef __STDC__static char *regprop(char *op)#elsestatic char *regprop(op)char *op;#endif{ register char *p; static char buf[50]; strcpy(buf, ":"); switch (OP(op)) { case BOL: p = "BOL"; break; case EOL: p = "EOL"; break; case ANY: p = "ANY"; break; case ANYOF: p = "ANYOF"; break; case ANYBUT: p = "ANYBUT"; break; case BRANCH: p = "BRANCH"; break; case EXACTLY: p = "EXACTLY"; break; case NOTHING: p = "NOTHING"; break; case BACK: p = "BACK"; break; case END: p = "END"; break; case OPEN + 1: case OPEN + 2: case OPEN + 3: case OPEN + 4: case OPEN + 5: case OPEN + 6: case OPEN + 7: case OPEN + 8: case OPEN + 9: sprintf(buf + strlen(buf), "OPEN%d", OP(op) - OPEN); p = (char *)NULL; break; case CLOSE + 1: case CLOSE + 2: case CLOSE + 3: case CLOSE + 4: case CLOSE + 5: case CLOSE + 6: case CLOSE + 7: case CLOSE + 8: case CLOSE + 9: sprintf(buf + strlen(buf), "CLOSE%d", OP(op) - CLOSE); p = (char *)NULL; break; case STAR: p = "STAR"; break; default: regerror("corrupted opcode"); break; } if (p != (char *)NULL) strcat(buf, p); return (buf);}#endif/* * The following is provided for those people who do not have strcspn() in * their C libraries. They should get off their butts and do something * about it; at least one public-domain implementation of those (highly * useful) string routines has been published on Usenet. */#ifdef STRCSPN/* * strcspn - find length of initial segment of s1 consisting entirely * of characters not from s2 */#ifdef __STDC__static int strcspn(char *s1, char *s2)#elsestatic int strcspn(s1, s2)char *s1;char *s2;#endif{ register char *scan1; register char *scan2; register int count; count = 0; for (scan1 = s1; *scan1 != '\0'; scan1++) { for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */ if (*scan1 == *scan2++) return (count); count++; } return (count);}#endif/* - regsub - perform substitutions after a regexp match */#ifdef __STDC__void regsub(regexp *prog, char *source, char *dest)#elsevoid regsub(prog, source, dest)regexp *prog;char *source;char *dest;#endif{ register char *src; register char *dst; register char c; register int no; register int len; extern char *strncpy(); if (prog == (regexp *)NULL || source == (char *)NULL || dest == (char *)NULL) { regerror("NULL parm to regsub"); return; } if (UCHARAT(prog->program) != MAGIC) { regerror("damaged regexp fed to regsub"); return; } src = source; dst = dest; while ((c = *src++) != '\0') { if (c == '&') no = 0; else if (c == '\\' && '0' <= *src && *src <= '9') no = *src++ - '0'; else no = -1; if (no < 0) { /* Ordinary character. */ if (c == '\\' && (*src == '\\' || *src == '&')) c = *src++; *dst++ = c; } else if (prog->startp[no] != (char *)NULL && prog->endp[no] != (char *)NULL) { len = prog->endp[no] - prog->startp[no]; strncpy(dst, prog->startp[no], len); dst += len; if (len != 0 && *(dst - 1) == '\0') { /* strncpy hit NUL. */ regerror("damaged match string"); return; } } } *dst++ = '\0';}#ifdef __STDC__void regerror(char *s)#elsevoid regerror(s)char *s;#endif{ fprintf(stderr, "regexp(3): %s", s); exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -