123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905 |
- /*
- **************************************************************************
- *
- * Utility program to optimize the output of the BCC compiler
- *
- * Module: copt.c
- * Purpose: Optimize BCC assembler output
- * Entries: main
- *
- * This program is based on an idea from Christopher W. Fraser.
- *
- **************************************************************************
- *
- * Copyright (C) 1995,1996,1997 Gero Kuhlmann <gero@gkminix.han.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
- /*
- #include "utility.h"
- #include "../../headers/general.h"
- #include "../../headers/version.h"
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #define KEEPCOMMENTS
- #define MAXLINE 1024
- #ifdef __BCC__
- #define HASHSIZE 107
- #else
- #define HASHSIZE 1999
- #endif
- #define NOCHAR '\177'
- #define VARNUM 10
- /* Struct containing each string of an input file */
- struct line_s {
- char *text;
- struct line_s *prev;
- struct line_s *next;
- int comment_flg;
- };
- /* Struct containing one rule */
- struct rule_s {
- struct line_s *old;
- struct line_s *new;
- struct rule_s *next;
- };
- /* Hash table to store strings in a space saving way */
- struct hash_s {
- char *text;
- struct hash_s *next;
- };
- /*
- * Global variables
- */
- static struct rule_s *first = NULL; /* first rule */
- static struct rule_s *last = NULL; /* last rule */
- static struct line_s *infile = NULL; /* list of strings in input file */
- static struct hash_s *htab[HASHSIZE]; /* string hash table */
- static int hash_init = 0; /* flag if hash table initialized */
- static char *vars[VARNUM]; /* variable table */
- static char *progname; /* program name */
- /*
- * Allocate memory and print error if none available
- */
- static void *mymalloc(int size)
- {
- void *p;
- if ((p = malloc(size)) == NULL) {
- fprintf(stderr, "%s: no memory\n", progname);
- exit(1);
- }
- return(p);
- }
- /*
- * Insert a string into the hash table. If the string is already in there
- * just return the pointer to that string.
- */
- static char *install(char *str, int slen)
- {
- struct hash_s *hp;
- char *chkstr;
- char *cp;
- unsigned int hashval;
- /* Clear the hashing table if not already done */
- if (!hash_init) {
- for (hashval = 0; hashval < HASHSIZE; hashval++)
- htab[hashval] = NULL;
- hash_init++;
- }
- /* Get check string */
- if (slen < 0)
- slen = strlen(str);
- chkstr = mymalloc(slen + 1);
- strncpy(chkstr, str, slen);
- chkstr[slen] = '\0';
- /* Determine hashing value of string */
- hashval = 0;
- for (cp = chkstr; *cp; cp++)
- hashval = hashval*75 + *cp;
- hashval %= HASHSIZE;
- /* Check if the string is already in the hashing table */
- for (hp = htab[hashval]; hp != NULL; hp = hp->next)
- if (!strcmp(chkstr, hp->text)) {
- free(chkstr);
- return(hp->text);
- }
- /* String is not in hash table, so create a new entry */
- hp = (struct hash_s *)mymalloc(sizeof(struct hash_s));
- hp->text = chkstr;
- hp->next = htab[hashval];
- htab[hashval] = hp;
- return(hp->text);
- }
- /*
- * Read one line from input file and skip all blanks at the beginning
- */
- static char *readline(FILE *fp)
- {
- static char buf[MAXLINE];
- char *cp;
- /* Read line from input file */
- if (fgets(buf, MAXLINE-1, fp) == NULL)
- return(NULL);
- buf[MAXLINE-1] = '\0';
- /* Delete trailing newline */
- if ((cp = strchr(buf, '\n')) != NULL)
- *cp = '\0';
- /* Delete leading white spaces */
- for (cp = buf; *cp && isspace(*cp); cp++) ;
- if (cp != buf && *cp)
- memmove(buf, cp, strlen(cp) + 1);
- return(buf);
- }
- /*
- * Read a list of input lines. Terminate reading when the 'quit' character
- * has been found in the first column of the input line. All lines with the
- * 'comment' character in the first position will be skipped.
- *
- * If 'havequit' is non-null, then the boolean '*havequit' says whether we
- * saw an input line with the 'quit' character.
- */
- static struct line_s *readlist(FILE *fp, int quit, int comment, int *havequit)
- {
- struct line_s *lp;
- struct line_s *first_line = NULL;
- struct line_s *last_line = NULL;
- char *cp;
- while ((cp = readline(fp)) != NULL) {
- if (quit != NOCHAR && quit == *cp)
- break;
- if (comment != NOCHAR && comment == *cp)
- if (quit != NOCHAR)
- continue;
- if (*cp == '\0')
- continue;
- lp = mymalloc(sizeof(struct line_s));
- lp->text = install(cp, -1);
- lp->prev = last_line;
- lp->next = NULL;
- lp->comment_flg = (comment != NOCHAR && *cp == comment);
- if (first_line == NULL)
- first_line = lp;
- if (last_line != NULL)
- last_line->next = lp;
- last_line = lp;
- }
- if (havequit)
- *havequit = (cp != NULL);
- return(first_line);
- }
- /*
- * Read pattern file
- */
- static void readpattern(char *rulesdir, char *filename)
- {
- static char path[MAXLINE];
- int havequit;
- struct rule_s *rp;
- FILE *fp;
- /* Open pattern file */
- if (rulesdir != NULL)
- sprintf(path, "%s/%s", rulesdir, filename);
- else
- sprintf(path, "%s", filename);
- if ((fp = fopen(path, "r")) == NULL) {
- fprintf(stderr, "%s: can't open pattern file %s\n", progname, path);
- exit(1);
- }
- /* Read every line of the pattern file */
- while (!feof(fp)) {
- rp = (struct rule_s *)mymalloc(sizeof(struct rule_s));
- rp->old = readlist(fp, '=', '#', &havequit);
- rp->new = readlist(fp, '\0', '#', NULL);
- if (rp->old == NULL || !havequit) {
- free(rp);
- break;
- }
- /* This put the rules into the table in reverse order; this is confusing *
- rp->next = first;
- first = rp;
- if (last == NULL)
- last = rp;
- */
- rp->next = NULL;
- if (last) {
- last->next = rp;
- last = rp;
- } else {
- first = last = rp;
- }
- }
- /* Close pattern file */
- (void)fclose(fp);
- }
- /*
- * Clear pattern list to allow for another run
- */
- static void clearpattern(void)
- {
- struct rule_s *rp1, *rp2;
- struct line_s *lp1, *lp2;
- rp1 = first;
- while (rp1 != NULL) {
- /* Clear old rule text list */
- lp1 = rp1->old;
- while (lp1 != NULL) {
- lp2 = lp1;
- lp1 = lp1->next;
- free(lp2);
- }
- /* Clear new rule text list */
- lp1 = rp1->new;
- while (lp1 != NULL) {
- lp2 = lp1;
- lp1 = lp1->next;
- free(lp2);
- }
- /* Clear rule itself */
- rp2 = rp1;
- rp1 = rp1->next;
- free(rp2);
- }
- first = NULL;
- last = NULL;
- }
- /*
- * Read input file
- */
- static void readinfile(char *filename, int comment)
- {
- FILE *fp;
- fp = stdin;
- if (filename != NULL && (fp = fopen(filename, "r")) == NULL) {
- fprintf(stderr, "%s: can't open input file %s\n", progname, filename);
- exit(1);
- }
- infile = readlist(fp, NOCHAR, comment, NULL);
- if (fp != stdin)
- (void)fclose(fp);
- }
- #define NO_OP 0
- #define ADD_OP 1
- #define SUB_OP 2
- #define MUL_OP 3
- #define DIV_OP 4
- #define SHL_OP 5
- #define SHR_OP 6
- long retval = 0;
- long num = 0;
- int sign = 1;
- int base = 10;
- int op = NO_OP;
- /* Apply operation to current numeric value */
- static void doretval(void)
- {
- switch (op) {
- case NO_OP: retval = num * sign;
- break;
- case ADD_OP: retval += num * sign;
- break;
- case SUB_OP: retval -= num * sign;
- break;
- case MUL_OP: retval *= num * sign;
- break;
- case DIV_OP: retval /= num * sign;
- break;
- case SHL_OP: retval <<= num;
- break;
- case SHR_OP: retval >>= num;
- break;
- }
- op = NO_OP;
- num = 0;
- sign = 1;
- base = 10;
- }
- /*
- * Eval an expression into an integer number
- */
- static long eval(char *str, int len)
- {
- char *cp, c;
- int state = 0;
- int i, varnum;
- retval = 0;
- num = 0;
- sign = 1;
- base = 10;
- op = NO_OP;
- /* Scan through whole string and decode it */
- for (cp = str, i = 0; *cp && i < len; cp++, i++) {
- c = toupper(*cp);
- if (c == '-' && (state == 0 || state == 5)) {
- state = 1;
- sign = -1;
- } else if (c == '+' && (state == 0 || state == 5)) {
- state = 1;
- sign = 1;
- } else if (c == '%' && isdigit(*(cp + 1)) && (state < 2 || state == 5)) {
- state = 4;
- varnum = *(cp + 1) - '0';
- if (vars[varnum] == NULL || i >= len)
- return(0);
- num = eval(vars[varnum], strlen(vars[varnum]));
- doretval();
- cp++; i++;
- } else if (c == '$' && (state < 2 || state == 5)) {
- state = 2;
- base = 16;
- } else if (base == 10 && (c >= '0' && c <= '9') &&
- (state <= 3 || state == 5)) {
- state = 3;
- num = num * 10 + (c - '0');
- } else if (base == 16 &&
- ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) &&
- (state <= 3 || state == 5)) {
- state = 3;
- num = num * 16 + (c >= 'A' ? c - '0' - 7 : c - '0');
- } else if (c == ' ' && (state == 3 || state == 4 || state == 5)) {
- if (state == 3) {
- doretval();
- state = 4;
- }
- } else if (strchr("+-*/<>", c) != NULL && (state == 3 || state == 4)) {
- if (state == 3)
- doretval();
- state = 5;
- switch (c) {
- case '+': op = ADD_OP;
- break;
- case '-': op = SUB_OP;
- break;
- case '*': op = MUL_OP;
- break;
- case '/': op = DIV_OP;
- break;
- case '<': op = SHL_OP;
- break;
- case '>': op = SHR_OP;
- break;
- }
- } else
- return(0);
- }
- /* Check if the string has been terminated correctly */
- if (state != 3 && state != 4)
- return(0);
- if (state == 3)
- doretval();
- return(retval);
- }
- /*
- * Compare an infile string with a pattern string. If there is any variable
- * defined, it will be inserted into the variable list from the pattern
- * string.
- */
- static int match(char *ins, char *pat)
- {
- char *cp, *oldpat;
- long val;
- int varnum;
- int len = 0;
- while (*ins && *pat)
- {
- if (pat[0] != '%')
- {
- if (*pat++ != *ins++)
- return(0);
- else
- continue;
- }
- if (pat[1] == '%') {
- /* '%%' actually means '%' */
- if (*ins != '%')
- return(0);
- pat += 2;
- } else if ((pat[1] == '*' || isdigit(pat[1]))) {
- /* Copy variable text into vars array */
- pat += 2;
- for (cp = ins; *ins && !match(ins, pat); ins++) ;
- if (pat[-1] == '*')
- continue;
- len = ins - cp;
- varnum = pat[-1] - '0';
- if (vars[varnum] == NULL)
- vars[varnum] = install(cp, len);
- else if (strlen(vars[varnum]) != len ||
- strncmp(vars[varnum], cp, len))
- return(0);
- } else if (pat[1] == '[') {
- /* Copy only specific variable text into vars array */
- if ((cp = strchr(pat + 2, ']')) == NULL ||
- (*(cp + 1) != '*' && !isdigit(*(cp + 1)))) {
- if (*ins != '[')
- return(0);
- pat += 2;
- continue;
- }
- oldpat = pat + 1;
- pat = cp + 2;
- /* Seperate allowable patterns and compare them with ins */
- while (*oldpat && *oldpat != ']') {
- oldpat++;
- len = strcspn(oldpat, "|]");
- if (!strncmp(ins, oldpat, len))
- break;
- oldpat += len;
- }
- if (!*oldpat || *oldpat == ']')
- return(0);
- ins += len;
- if (!match(ins, pat))
- return(0);
- /* Install new string into variable table */
- if (*(cp + 1) == '*')
- continue;
- varnum = *(cp + 1) - '0';
- if (vars[varnum] == NULL)
- vars[varnum] = install(oldpat, len);
- else if (strlen(vars[varnum]) != len ||
- strncmp(vars[varnum], oldpat, len))
- return(0);
- } else if (pat[1] == '!') {
- /* Match only if the pattern string is not found */
- if (pat[2] != '[' || (cp = strchr(pat + 3, ']')) == NULL) {
- if (*ins != '!')
- return(0);
- pat += 3;
- continue;
- }
- oldpat = pat + 2;
- pat = cp + 1;
- /* Seperate allowable patterns and compare them with ins */
- while (*oldpat && *oldpat != ']') {
- oldpat++;
- len = strcspn(oldpat, "|]");
- if (!strncmp(ins, oldpat, len))
- return(0);
- oldpat += len;
- }
- } else if (pat[1] == '(') {
- /* Match ins with expression */
- if ((cp = strchr(pat + 2, ')')) == NULL) {
- if (*ins != '(')
- return(0);
- pat += 2;
- continue;
- }
- oldpat = pat + 2;
- pat = cp + 1;
- len = cp - oldpat;
- val = eval(oldpat, len);
- for (cp = ins; *ins && !match(ins, pat); ins++) ;
- len = ins - cp;
- if (val != eval(cp, len))
- return(0);
- }
- else /* Bad % format cannot match */
- return(0);
- }
- return(*ins == *pat);
- }
- /*
- * Substitute variables in a string
- */
- static char *subst(char *pat)
- {
- char buf[MAXLINE];
- char *cp, *cp1, *cp2, *varptr;
- long num;
- int i = 0;
- int j, pos;
- while (*pat)
- if (pat[0] == '%' && isdigit(pat[1])) {
- /* Substitute with value of variable */
- cp = vars[pat[1] - '0'];
- while (cp != NULL && *cp) {
- buf[i++] = *cp++;
- if (i >= MAXLINE - 1) {
- fprintf(stderr, "%s: line too long\n", progname);
- exit(1);
- }
- }
- pat += 2;
- } else if (pat[0] == '%' && pat[1] == '(') {
- /* Substitute with expression */
- cp = pat + 2;
- if ((pat = strchr(cp, ')')) == NULL || pat - cp <= 0)
- num = 0;
- else
- num = eval(cp, pat - cp);
- if (i >= MAXLINE - 20) {
- fprintf(stderr, "%s: line too long\n", progname);
- exit(1);
- }
- i += sprintf(&buf[i], "%s$%lx", num < 0 ? "-" : "", labs(num));
- pat++;
- } else if (pat[0] == '%' && pat[1] == '=') {
- /* Substitute with converted variable */
- /* First seperate all parts of the pattern string */
- cp = pat + 2;
- cp1 = cp2 = varptr = NULL;
- if (*cp == '[') {
- cp1 = ++cp;
- while (*cp && *cp != ']')
- cp++;
- if (cp[0] == ']' && cp[1] == '[') {
- cp += 2;
- cp2 = cp;
- while (*cp && *cp != ']')
- cp++;
- if (cp[0] == ']' && isdigit(cp[1]))
- varptr = vars[cp[1] - '0'];
- }
- }
- if (cp1 == NULL || cp2 == NULL || varptr == NULL) {
- buf[i++] = *pat++;
- if (i >= MAXLINE - 1) {
- fprintf(stderr, "%s: line too long\n", progname);
- exit(1);
- }
- continue;
- }
- pat = cp + 2;
- /* Now scan through the first string to find variable value */
- cp1--;
- pos = 0;
- while (*cp1 != ']') {
- cp1++;
- j = strcspn(cp1, "|]");
- if (strlen(varptr) == j && !strncmp(cp1, varptr, j))
- break;
- pos++;
- cp1 += j;
- }
- if (*cp1 == ']')
- continue;
- /* Scan through the second string to find the conversion */
- cp2--;
- while (*cp2 != ']' && pos > 0) {
- cp2++;
- j = strcspn(cp2, "|]");
- pos--;
- cp2 += j;
- }
- if (*cp2 == ']' || pos != 0)
- continue;
- /* Insert conversion string into destination */
- cp2++;
- while (*cp2 != '|' && *cp2 != ']') {
- buf[i++] = *cp2++;
- if (i >= MAXLINE - 1) {
- fprintf(stderr, "%s: line too long\n", progname);
- exit(1);
- }
- }
- } else {
- buf[i++] = *pat++;
- if (i >= MAXLINE - 1) {
- fprintf(stderr, "%s: line too long\n", progname);
- exit(1);
- }
- }
- buf[i] = '\0';
- return(install(buf, i));
- }
- /*
- * Optimize one line of the input file
- */
- static struct line_s *optline(struct line_s *cur)
- {
- struct rule_s *rp;
- struct line_s *ins, *pat;
- struct line_s *lp1, *lp2;
- int i;
- for (rp = first; rp != NULL; rp = rp->next) {
- /* Clear variable array */
- for (i = 0; i < VARNUM; i++)
- vars[i] = NULL;
- /* Scan through pattern texts and match them against the input file */
- ins = cur;
- pat = rp->old;
- while (ins != NULL
- && pat != NULL
- && ( ins->comment_flg ||
- ( /* (pat->text[0]=='%' || ins->text[0]==pat->text[0]) && */
- match(ins->text, pat->text)))) {
- if (!ins->comment_flg)
- pat = pat->next;
- else if (ins->text[0]==pat->text[0]) /* Matching a comment! */
- {
- if (match(ins->text, pat->text))
- pat = pat->next;
- }
- ins = ins->next;
- }
- /* Current pattern matched input line, so replace input with new */
- if (pat == NULL) {
- /* Clear all lines in the source file for this pattern */
- lp1 = cur;
- cur = cur->prev;
- while (lp1 != ins) {
- #if 0
- if( lp1->comment_flg )
- {
- lp2 = lp1;
- lp1 = lp1->next;
- lp2->next = cur->next;
- cur->next = lp2;
- lp2->prev = cur;
- cur=cur->next;
- }
- else
- #endif
- {
- lp2 = lp1;
- lp1 = lp1->next;
- free(lp2);
- }
- }
- /* Insert new lines into list */
- pat = rp->new;
- lp1 = cur;
- lp2 = NULL;
- while (pat != NULL) {
- lp2 = mymalloc(sizeof(struct line_s));
- lp2->text = subst(pat->text);
- lp2->next = NULL;
- lp2->prev = lp1;
- lp2->comment_flg = 0;
- if (lp1 != NULL)
- lp1->next = lp2;
- else
- infile = lp2;
- lp1 = lp2;
- pat = pat->next;
- }
- if (ins != NULL)
- ins->prev = lp2;
- if (lp2 != NULL)
- lp2->next = ins;
- else if (lp1 != NULL)
- lp1->next = NULL;
- else
- infile = NULL;
- return(cur);
- }
- }
- return(cur->next);
- }
- /*
- * Actually optimize all strings in the input file
- */
- static void optimize(int backup)
- {
- struct line_s *cur, *lp;
- int i;
- int in_asm = 0;
- /* Scan through all lines in the input file */
- cur = infile;
- while (cur != NULL) {
- if (cur->comment_flg || in_asm)
- {
- lp=cur->next;
- if (memcmp(cur->text, "!BCC_", 5) == 0)
- in_asm = (memcmp(cur->text+5, "ASM", 3) == 0);
- }
- else
- if ((lp = optline(cur)) != NULL && lp != cur->next) {
- for (i = 0; i < backup && lp != NULL; i++)
- lp = lp->prev;
- if (lp == NULL)
- lp = infile;
- }
- cur = lp;
- }
- }
- /*
- * Write out into destination file
- */
- static void writeoutf(char *filename, char *headstr)
- {
- FILE *fp;
- struct line_s *lp;
- fp = stdout;
- if (filename != NULL && (fp = fopen(filename, "w")) == NULL) {
- fprintf(stderr, "%s: can't open output file %s\n", progname, filename);
- exit(1);
- }
- if (headstr != NULL) {
- fprintf(fp, "%s", headstr);
- fprintf(fp, "\n");
- }
- for (lp = infile; lp != NULL; lp = lp->next)
- fprintf(fp, "%s\n", lp->text);
- if (fp != stdout)
- (void)fclose(fp);
- }
- /*
- * Print usage
- */
- static void usage(void)
- {
- fprintf(stderr, "usage: %s [-c<comment-char>] [-f<src-file>] [-o<out-file>]\n"
- "\t\t[-b<backup-num>] [-h<head-str>] [-d<ruls-dir>] "
- "<rules-file> ...\n", progname);
- exit(1);
- }
- /*
- * Main program
- */
- int
- main(int argc, char **argv)
- {
- char comment = NOCHAR;
- char *srcfile = NULL;
- char *outfile = NULL;
- char *headstr = NULL;
- char *rulesdir = NULL;
- int backup = 0;
- int i;
- /* Get program name */
- if ((progname = strrchr(argv[0], '/')) == NULL)
- progname = argv[0];
- else
- progname++;
- /* Make life easy for bcc */
- if ( argc > 4 && strcmp(argv[2], "-o") == 0 && argv[1][0] != '-' )
- {
- srcfile = argv[1];
- argv++,argc--;
- }
- /* Get options from command line */
- for (i = 1; i < argc; i++)
- if (!strncmp(argv[i], "-c", 2))
- comment = argv[i][2];
- else if (!strncmp(argv[i], "-b", 2))
- backup = atoi(&(argv[i][3]));
- else if (!strncmp(argv[i], "-f", 2))
- srcfile = &(argv[i][2]);
- else if (!strncmp(argv[i], "-o", 2))
- {
- if(argv[i][2])
- outfile = &(argv[i][2]);
- else if(++i<argc)
- outfile = argv[i];
- else
- usage();
- }
- else if (!strncmp(argv[i], "-h", 2))
- headstr = &(argv[i][2]);
- else if (!strncmp(argv[i], "-d", 2))
- rulesdir = &(argv[i][2]);
- else if (argv[i][0] == '-')
- usage();
- else
- break;
- /* Have to have enough parameters for rule file names */
- if ((argc - i) < 1)
- usage();
- /* Read source file and optimze it with every rules file */
- readinfile(srcfile, comment);
- for ( ; i < argc; i++) {
- readpattern(rulesdir, argv[i]);
- optimize(backup);
- clearpattern();
- }
- writeoutf(outfile, headstr);
- exit(0);
- }
|