home *** CD-ROM | disk | FTP | other *** search
- /*
- Adjust DMakefile
-
- Chris Hind Genly
-
- 6/10/93
-
- Chris Hind Genly
-
- Eggplant Software Tools
-
- chris@Eggplant.New-Haven.CT.US
-
- This is a public domain file.
-
- */
-
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
-
- #define TRUE 1
- #define FALSE 0
-
- int lineNum;
-
- int filecnt = 0;
- char *files[100];
-
- typedef enum {C_NONE, C_DICE, C_SASC} CompilerType;
-
- CompilerType compiler = C_NONE;
- int force = FALSE;
-
- int commentsOn = FALSE;
- int inFor = FALSE;
-
- #define LINE_MAX 200
-
- char *skip_ws(char *p)
- {
- while(*p == ' ' || *p == '\t')
- ++p;
-
- return p;
- }
-
- void CopyBlanks(char **pl, char **pa)
- {
- char *l = *pl;
- char *a = *pa;
-
- while(*l == ' ' || *l == '\t')
- *a++ = *l++;
-
- *a = 0;
-
- *pl = l;
- *pa = a;
- }
-
- int IsOptChar(char c, int eq)
- {
- return 'a' <= c && c <= 'z'
- || 'A' <= c && c <= 'Z'
- || '0' <= c && c <= '9'
- || c == '-'
- || c == '_'
- || c == '.'
- || c == ':'
- || c == '/'
- || c == '=' && eq;
- }
-
- void CopyToMatch(char **pl, char**pt, char endchar)
- {
- char *l = *pl;
- char *t = *pt;
- char c;
-
- while(c = *l) {
- *t++ = *l++;
- if (c == endchar) break;
- }
-
- *t = 0;
-
- *pl = l;
- *pt = t;
- }
-
-
- typedef enum {T_EOL, T_MACRO, T_EQUAL, T_FILE, T_STRING, T_OTHER} TokenType;
-
- TokenType GetToken(char **pl, char *token, int eq)
- {
- char *l = *pl;
- char *t = token;
- TokenType type;
-
- switch(*l) {
- case '\n':
- type = T_EOL;
- *t++ = *l++;
- break;
- case '$':
- case '%':
- type = T_MACRO;
- *t++ = *l++;
- if (*l == '(')
- CopyToMatch(&l, &t, ')');
- else
- if (*l == '{')
- CopyToMatch(&l, &t, '}');
- else
- *t++ = *l++;
- break;
- case '"':
- type = T_STRING;
- *t++ = *l++;
- CopyToMatch(&l, &t, '"');
- break;
- case '=':
- if (eq) {
- type = T_EQUAL;
- *t++ = *l++;
- break;
- }
-
- default:
- while(IsOptChar(*l, !eq))
- *t++ = *l++;
-
- if (t >= token+2 && t[-2] == '.')
- type = T_FILE;
- else
- type = T_OTHER;
- break;
- }
-
- *t = 0;
- *pl = l;
-
- return type;
- }
-
- struct opt_tag {
- char *sasc;
- char *dcc;
- enum {C_PRESENT, C_MISSING, C_ALWAYS} copt;
- } optvec[] = {
- "AddSymbols", "-s", C_ALWAYS,
- "Code=near", "-mc", C_ALWAYS,
- "Code=far", "-mC", C_ALWAYS,
- "CPU=68020", "-020", C_ALWAYS,
- "CPU=68030", "-030", C_ALWAYS,
- "Data=near", "-md", C_ALWAYS,
- "Data=far", "-mD", C_ALWAYS,
- "IDIR=", "-I_", C_ALWAYS,
- "Define=", "-D_", C_ALWAYS,
- "Library=", "-l_", C_ALWAYS,
- "Math=68881", "-881", C_ALWAYS,
- "Math=68882", "-882", C_ALWAYS,
- "ObjectName=", "-o_", C_PRESENT,
- "ProgramName=", "-o_", C_MISSING,
- "StackExtend", "-gs", C_ALWAYS,
- "Startup=cres", "-r", C_ALWAYS,
- "Verbose", "-v", C_ALWAYS,
- 0
- };
-
- /*
-
- SASC options are case insensitive.
- DICE options are case sensitive.
-
- When scanning an SASC option, '=' in the table implies an optional
- '=' optionally surrounded by blanks in line.
-
- When scanning an SASC option, if the '=' is the last char in the
- table, then the following token on the line is to be copied to
- adjustedLine.
-
- When scanning a DICE option, '_' means optional spaces. The '_'
- should not be placed in to the adjusted line when generating
- DICE options. The following token on the line is to be copied
- to adjustedLine.
-
- When reading a dcc line, the qualifiers C_PRESENT and C_MISSING apply.
-
- C_PRESENT Entry applies when '-c' is present.
- C_MISSING Entry applies when '-c' is missing.
- C_ALWAYS Entry always applies regardless of whether or not
- '-c' is present, and regardless if this is a dcc or
- sc line.
-
- */
- struct opt_tag * SascFindOption(char **pl, int cflag)
- {
- struct opt_tag *opt;
- char *l, *d;
-
- for(opt = optvec; opt->sasc; ++opt) {
- if (opt->copt == C_PRESENT && cflag
- || opt->copt == C_MISSING && !cflag
- || opt->copt == C_ALWAYS)
- ;
- else
- continue;
-
- l=*pl;
- d=opt->dcc;
-
- while(1) {
- if (*d == '\0') {
- if (*l == ' ' || *l == '\t' || *l == 0 || *l == '\n') {
- *pl = l;
- return opt;
- } else
- break;
- } else
- if (*d == '_') {
- *pl = skip_ws(l);
- return opt;
- } else
- if (*d != *l)
- break;
-
- ++d;
- ++l;
- }
- }
-
- return 0;
- }
-
- struct opt_tag * DccFindOption(char **pl, int flag)
- {
- struct opt_tag *opt;
- char *l, *s;
-
- for(opt = optvec; opt->sasc; ++opt) {
- l = *pl;
- s = opt->sasc;
-
- while(1) {
- if (*s == '\0') {
- if (*l == ' ' || *l == '\t' || *l == 0 || *l == '\n') {
- *pl = l;
- return opt;
- } else
- break;
- } else
- if (*s == '=') {
- if (*l != ' ' && *l != '=' && *l != '\0') break;
- l = skip_ws(l);
- if (*l == '=') {
- ++l;
- l = skip_ws(l);
- }
- if (s[1] == '\0') {
- *pl = l;
- return opt;
- }
- --l;
- } else
- if (strnicmp(s, l, 1) != 0)
- break;
-
- ++s;
- ++l;
- }
- }
-
- return 0;
- }
-
- struct opt_tag * FindOption(char **pl, int flag)
- {
- switch(compiler) {
- case C_DICE:
- return DccFindOption(pl, flag);
- case C_SASC:
- return SascFindOption(pl, flag);
- }
- }
-
- void SascCopyOption(struct opt_tag *opt, char **pl, char **pa)
- {
- char *l = *pl;
- char *a = *pa;
-
- strcat(a, opt->sasc);
- a += strlen(a);
-
- /* If option ends with '=', an argument is expected to follow */
- if (a[-1] == '=') {
- l = skip_ws(l);
- GetToken(&l, a, FALSE);
- a += strlen(a);
- }
-
- *pl = l;
- *pa = a;
- }
-
- void DccCopyOption(struct opt_tag *opt, char **pl, char **pa)
- {
- char *l = *pl;
- char *a = *pa;
-
- strcpy(a, opt->dcc);
- a += strlen(a);
- if (a[-1] == '_') {
- a[-1] = ' ';
- l = skip_ws(l);
- GetToken(&l, a, FALSE);
- a += strlen(a);
- }
-
- *pl = l;
- *pa = a;
- }
-
- void CopyOption(struct opt_tag *opt, char **pl, char **pa)
- {
- switch(compiler) {
- case C_DICE:
- return DccCopyOption(opt, pl, pa);
- case C_SASC:
- return SascCopyOption(opt, pl, pa);
- }
- }
-
- int SascPreScan(char *line, char **pa, int isCommand)
- {
- char *a = *pa;
- char *p;
- int cflag;
-
- p = strstr(line, "-c");
- if (p && (p[2] == ' ' || p[2] == '\t' || p[2] == '\0' || p[2] == '\n')) {
- cflag = TRUE;
- if (p[-1] == ' ' || p[-1] == '\t')
- strcpy(p-1, p+2);
- else
- if (p[2] != 0)
- strcpy(p, p+3);
- else
- strcpy(p, p+2);
- } else
- cflag = FALSE;
-
- if (isCommand) {
- strcpy(a, " NoIcons ANSI");
- if (!cflag)
- strcat(a, " Link");
- a += strlen(a);
- } else
- if (cflag) {
- fprintf(stderr, "Line %d: -c found on line other than dcc line\n", lineNum);
- }
-
- *pa = a;
-
- return cflag;
- }
-
- int DccPreScan(char *line, char **pa, int isCommand)
- {
- char *a = *pa;
- char *p;
- int linkflag;
-
- p = strstr(line, "Link");
- if (p && (p[4] == ' ' || p[4] == '\t' || p[4] == '\0' || p[4] == '\n')) {
- linkflag = TRUE;
- if (p[-1] == ' ')
- --p;
- strcpy(p, p+5);
- } else
- linkflag = FALSE;
-
- p = strstr(line, "NoIcons");
- if (p) {
- if (p[-1] == ' ')
- --p;
- strcpy(p, p+8);
- }
-
- p = strstr(line, "ANSI");
- if (p) {
- if (p[-1] == ' ')
- --p;
- strcpy(p, p+5);
- }
-
- if (isCommand) {
- if (!linkflag) {
- strcat(a, " -c");
- a += strlen(a);
- }
- } else
- if (linkflag) {
- fprintf(stderr, "Line %d: Link found on line other than sc line\n", lineNum);
- }
-
- *pa = a;
-
- return linkflag;
- }
-
- int PreScan(char *line, char **pa, int isCommand)
- {
- switch(compiler) {
- case C_DICE:
- return DccPreScan(line, pa, isCommand);
- case C_SASC:
- return SascPreScan(line, pa, isCommand);
- }
- }
-
- int adjustOptions(char *line, char *adjustedLine, int isCommand)
- {
- static char token[200];
- struct opt_tag *opt;
- char *l, *a = adjustedLine;
- char *oldl;
- int flag;
-
- flag = PreScan(line, &a, isCommand);
-
- for(l=line; *l; ) {
- CopyBlanks(&l, &a);
- oldl = l;
- switch(GetToken(&l, token, TRUE)) {
- case T_EOL:
- case T_MACRO:
- case T_FILE:
- case T_STRING:
- case T_EQUAL:
- strcpy(a, token);
- a += strlen(a);
- break;
- default:
- l = oldl;
- opt = FindOption(&l, flag);
- if (opt == 0) {
- if (force) {
- fprintf(stderr, "Line %d: Ignoring unknown %s option %s\n",
- lineNum,
- compiler==C_DICE ? "sc":"dcc",
- token);
- GetToken(&l, token, TRUE);
- continue;
- } else {
- fprintf(stderr, "Line %d: Unknown %s option %s\n",
- lineNum,
- compiler==C_DICE ? "sc":"dcc",
- token);
- fprintf(stderr, " File will remain unchanged\n");
- return FALSE;
- }
- }
- CopyOption(opt, &l, &a);
- }
- }
-
- return TRUE;
- }
-
- int doFor(char *p, char *line, char *adjustedLine)
- {
- strcpy(adjustedLine, line);
-
- if (inFor) {
- fprintf(stderr, "Line %d: Nested '#for' not legal.\n", lineNum);
- return FALSE;
- }
-
- p = skip_ws(p);
- if (strnicmp(p, "sasc", 4) == 0)
- commentsOn = compiler != C_SASC;
- else
- if (strnicmp(p, "dice", 4) == 0)
- commentsOn = compiler != C_DICE;
- else {
- fprintf(stderr, "Line %d: Unrecognized compiler: %s\n", lineNum, p);
- return FALSE;
- }
-
- inFor = TRUE;
-
- return TRUE;
- }
-
- int doEnd(char *p, char *line, char *adjustedLine)
- {
- strcpy(adjustedLine, line);
-
- if (!inFor) {
- fprintf(stderr, "Line %d: '#end' without '#for'\n", lineNum);
- return FALSE;
- }
-
- inFor = commentsOn = FALSE;
-
- return TRUE;
- }
-
- int doMacroDef(char *p, char *line, char *adjustedLine)
- {
- int len = p - line;
-
- strncpy(adjustedLine, line, len);
- adjustedLine[len] = 0;
-
- return adjustOptions(p, adjustedLine+len, FALSE);
- }
-
- int doDcc(char *p, char *line, char *adjustedLine)
- {
- char *l, *a;
-
- if (compiler == C_DICE) {
- strcpy(adjustedLine, line);
- return TRUE;
- } else {
- l = line;
- a = adjustedLine;
- CopyBlanks(&l, &a);
- strcpy(a, "sc");
- a += strlen(a);
- return adjustOptions(p, a, TRUE);
- }
- }
-
- int doSc(char *p, char *line, char *adjustedLine)
- {
- char *l, *a;
-
- if (compiler == C_SASC) {
- strcpy(adjustedLine, line);
- return TRUE;
- } else {
- l = line;
- a = adjustedLine;
- CopyBlanks(&l, &a);
- strcpy(a, "dcc");
- a += strlen(a);
- return adjustOptions(p, a, TRUE);
- }
- }
-
- struct key_tag {
- char *text;
- int (*func)(char*, char*, char*);
- } keys[] = {
- "# for.", doFor,
- "# end", doEnd,
- "CFLAGS =", doMacroDef,
- "LIBS =", doMacroDef,
- "dcc.", doDcc,
- "sc.", doSc,
- 0
- };
-
- int adjustLine(char *line, char *adjustedLine)
- {
- char *p, *t;
- struct key_tag *kp;
-
- for(kp=keys; kp->text; ++kp) {
- p = skip_ws(line);
-
- for(t = kp->text; ; ++t) {
- if (*t == 0) {
- return (kp->func)(p, line, adjustedLine);
- } else
- if (*t == ' ') p = skip_ws(p);
- else
- if (*t == '.') {
- if (p == skip_ws(p))
- break;
- } else
- if (*t != *p)
- break;
- else
- ++p;
- }
- }
-
- if (inFor) {
- if (commentsOn) {
- if (line[0] == '#') {
- strcpy(adjustedLine, line);
- } else {
- strcpy(adjustedLine, "#");
- strcat(adjustedLine, line);
- }
- } else {
- if (line[0] == '#') {
- strcpy(adjustedLine, line+1);
- } else {
- strcpy(adjustedLine, line);
- }
- }
- } else
- strcpy(adjustedLine, line);
-
- return TRUE;
- }
-
- void adjust(char *fileName)
- {
- FILE *ifp=0, *ofp=0;
- static char line[LINE_MAX+1];
- static char adjustedLine[LINE_MAX+1];
- static char tmp1Name[LINE_MAX+1];
- static char tmp2Name[LINE_MAX+1];
-
- ifp = fopen(fileName, "r");
- if (ifp == 0) {
- perror(fileName);
- goto out;
- }
-
- strcpy(tmp1Name, fileName);
- strcat(tmp1Name, ".1.tmp");
-
- ofp = fopen(tmp1Name, "w");
- if (ofp == 0) {
- perror(tmp1Name);
- goto out;
- }
-
- lineNum = 0;
- while(fgets(line, LINE_MAX, ifp)) {
- ++lineNum;
-
- if (!adjustLine(line, adjustedLine))
- goto out;
-
- if (fputs(adjustedLine, ofp) == EOF) {
- perror(tmp1Name);
- goto out;
- }
- }
-
- fclose(ifp);
- fclose(ofp);
- ifp = ofp = 0;
-
- strcpy(tmp2Name, fileName);
- strcat(tmp2Name, ".2.tmp");
-
- if (rename(fileName, tmp2Name) != 0) {
- perror(fileName);
- goto out;
- }
-
- if (rename(tmp1Name, fileName) != 0) {
- perror(fileName);
- if (rename(tmp2Name, fileName) != 0) {
- perror(tmp2Name);
- }
- goto out;
- }
-
- if (unlink(tmp2Name) != 0) {
- perror(tmp2Name);
- }
-
- out:
- if (ifp)
- fclose(ifp);
-
- if (ofp) {
- fclose(ofp);
- unlink(tmp1Name);
- }
- }
-
- char *uvec[] = {
- " adj <switches> <files>",
- "",
- "<files>,"
- " DMakefiles to adjust. Default DMakefile.",
- "",
- " -dice Adjust DMakefile to use DICE.",
- " -sasc Adjust DMakefile to use SASC.",
- " -force Adjust even if unrecognized compiler options encountered.",
- " -help This message",
- " ? Same as -help",
- 0
- };
-
- void usage(void)
- {
- char **pp;
-
- for(pp=uvec; *pp; ++pp) {
- printf("%s\n", *pp);
- }
- }
-
-
- int main(int argc, char *argv[])
- {
- int i;
- int help = FALSE;
-
- for(i=1; i<argc; ++i) {
- if (strcmp(argv[i], "-dice") == 0)
- compiler = C_DICE;
- else
- if (strcmp(argv[i], "-sasc") == 0)
- compiler = C_SASC;
- else
- if (strcmp(argv[i], "-force") == 0)
- force = TRUE;
- else
- if (strcmp(argv[i], "-help") == 0)
- help = TRUE;
- else
- if (strcmp(argv[i], "-h") == 0)
- help = TRUE;
- else
- if (strcmp(argv[i], "?") == 0)
- help = TRUE;
- else
- if (argv[i][0] == '-') {
- fprintf(stderr, "Unrecognized switch %s\n", argv[i]);
- exit(10);
- } else
- files[filecnt++] = argv[i];
- }
-
- if (help) {
- usage();
- exit(0);
- }
-
- if (compiler == C_NONE) {
- fprintf(stderr, "Requires -dice, or -sasc\n");
- exit(10);
- }
-
- if (filecnt == 0) {
- files[filecnt++] = "DMakefile";
- }
-
- for(i=0; i<filecnt; ++i) {
- adjust(files[i]);
- }
- }
-