#include #include "tools.h" /* * Make a pattern template from the strinng pointed to by arg. Stop * when delim or '\000' or '\n' is found in arg. Return a pointer to * the pattern template. * * The pattern template used here are somewhat different than those * used in the "Software Tools" book; each token is a structure of * the form TOKEN (see tools.h). A token consists of an identifier, * a pointer to a string, a literal character and a pointer to another * token. This last is 0 if there is no subsequent token. * * The one strangeness here is caused (again) by CLOSURE which has * to be put in front of the previous token. To make this insertion a * little easier, the 'next' field of the last to point at the chain * (the one pointed to by 'tail) is made to point at the previous node. * When we are finished, tail->next is set to 0. */ TOKEN * makepat(arg, delim) char *arg; int delim; { TOKEN *head, *tail, *ntok; char buf[CLS_SIZE]; int error; extern char *malloc (); /* * Check for characters that aren't legal at the beginning of * a template. */ if (*arg=='\0' || *arg==delim || *arg=='\n' || *arg==CLOSURE) return(0); error = 0; tail = head = NULL; while (*arg && *arg != delim && *arg != '\n' && !error) { ntok = (TOKEN *)malloc(TOKSIZE); ntok->lchar = '\000'; ntok->next = 0; switch(*arg) { case ANY: ntok->tok = ANY; break; case BOL: if (head == 0) /* then this is the first symbol */ ntok->tok = BOL; else ntok->tok = LITCHAR; ntok->lchar = BOL; break; case EOL: if(*(arg+1) == delim || *(arg+1) == '\000' || *(arg+1) == '\n') { ntok->tok = EOL; } else { ntok->tok = LITCHAR; ntok->lchar = EOL; } break; case CLOSURE: if (head != 0) { switch (tail->tok) { case BOL: case EOL: case CLOSURE: return (0); default: ntok->tok = CLOSURE; } } break; case CCL: if(*(arg + 1) == NEGATE) { ntok->tok = NCCL; arg += 2; } else { ntok->tok = CCL; arg++; } if( ntok->bitmap = makebitmap(CLS_SIZE) ) arg = dodash(CCLEND, arg, ntok->bitmap ); else { fprintf(stderr,"Not enough memory for pat\n"); error = 1; } break; default: ntok->tok = LITCHAR; ntok->lchar = esc(&arg); } if (error || ntok == 0) { unmakepat(head); return (0); } else if (head == 0) { /* This is the first node in the chain. */ ntok->next = 0; head = tail = ntok; } else if (ntok->tok != CLOSURE) { /* Insert at end of list (after tail) */ tail->next = ntok; ntok->next = tail; tail = ntok; } else if (head != tail) { /* * More than one node in the chain. Insert the * CLOSURE node immediately in front of tail. */ (tail->next)->next = ntok; ntok->next = tail; } else { /* * Only one node in the chain, Insert the CLOSURE * node at the head of the linked list. */ ntok->next = head; tail->next = ntok; head = ntok; } arg++; } tail->next = 0; return (head); }