1: /* $Header: rule.c,v 1.2 85/05/16 12:49:56 nicklin Exp $ */
2:
3: /*
4: * Author: Peter J. Nicklin
5: */
6: #include "Mkmf.h"
7: #include "null.h"
8: #include "rule.h"
9: #include "slist.h"
10: #include "suffix.h"
11: #include "system.h"
12: #include "yesno.h"
13:
14: #define MAXNAMLEN 255
15:
16: static RULEBLK *Ruletab[RULETABSIZE]; /* rules table */
17: static SLIST *Rulelist = NULL; /* transformation rule list */
18:
19: /*
20: * buildruletable() converts a list of transformation rules into a hash table
21: * for fast lookup. Returns YES if successful, otherwise NO.
22: */
23: buildruletable()
24: {
25: extern char *DEFRULE[]; /* default preprocessor rules */
26: int i; /* default rule list counter */
27: int instalrule(); /* instale rule in hash table */
28: SLBLK *rblk; /* singly-linked rulename block */
29:
30: /* process default rules */
31: for (i = 0; DEFRULE[i] != NULL; i++)
32: {
33: if (instalrule(DEFRULE[i]) == NO)
34: {
35: warn("out of memory");
36: return(NO);
37: }
38: }
39:
40: /* process rules found in makefile */
41: if (Rulelist != NULL)
42: {
43: for (rblk = Rulelist->head; rblk != NULL; rblk = rblk->next)
44: {
45: if (instalrule(rblk->key) == NO)
46: {
47: warn("out of memory");
48: return(NO);
49: }
50: }
51: }
52: return(YES);
53: }
54:
55:
56:
57: /*
58: * findrule() searchs a line for a transformation rule. Returns the
59: * name of the transformation rule, or NULL if not found.
60: */
61: char *
62: findrule(rulename, bp)
63: char *rulename; /* transformation rule buffer */
64: register char *bp; /* I/O buffer pointer */
65: {
66: register char *rp; /* rule name pointer */
67: int dotcount = 0; /* number of '.'s in rule */
68:
69: for (rp = rulename; *bp != ':' && *bp != ' ' && *bp != '\t'; rp++, bp++)
70: {
71: if ((*rp = *bp) == '.')
72: dotcount++;
73: }
74: *rp = '\0';
75:
76: /* eat up white space between rule and ':' */
77: if (*bp != ':')
78: {
79: while (*bp == ' ' || *bp == '\t')
80: bp++;
81: if (*bp != ':')
82: return(NULL);
83: }
84:
85: return((dotcount == 2) ? rulename : NULL);
86: }
87:
88:
89:
90: /*
91: * instalrule() installs a source transformation rule in the rule lookup
92: * table. The rule table consists of a set of singly-linked lists, indexed
93: * by the first character of the suffix of the target file. The index of
94: * the target file is used by lookuprule() to find out the name of the file
95: * from which it was derived. Returns YES if successful, otherwise NO.
96: */
97: instalrule(rule)
98: char *rule; /* rule to be installed in Rule table */
99: {
100: char *malloc(); /* memory allocator */
101: char *rindex(); /* find last occurrence of character */
102: char *strsav(); /* save a string somewhere */
103: char *target; /* target suffix */
104: int lookupsfx(); /* get suffix type */
105: int ruleindex; /* index into rule table */
106: RULEBLK *rblk; /* rule list block */
107:
108: target = rindex(rule, '.') + 1;
109: if (lookupsfx(target) == SFXSRC)
110: {
111: ruleindex = target[0];
112: if ((rblk = (RULEBLK *) malloc(sizeof(RULEBLK))) == NULL)
113: return(NO);
114: if ((rblk->r_rule = strsav(rule)) == NULL)
115: return(NO);
116: rblk->r_next = Ruletab[ruleindex];
117: Ruletab[ruleindex] = rblk;
118: }
119: return(YES);
120: }
121:
122:
123:
124: /*
125: * lookuprule() applies successive transformation rules to filename, and
126: * checks to see if the file exists. Returns YES if filename exists,
127: * otherwise NO.
128: */
129: lookuprule(target, source)
130: char *target; /* name of (transformed) file */
131: char *source; /* name of source file */
132: {
133: register char *r; /* rule pointer */
134: register char *s; /* source buffer pointer */
135: char *rindex(); /* find last occurrence of character */
136: char *sourcesuffix; /* source file suffix */
137: char *strcpy(); /* string copy */
138: char *rulesuffix; /* target suffix in each rule */
139: char *targetsuffix; /* transformed file suffix string */
140: int ruleindex; /* index into rule table */
141: int strcmp(); /* string comparison */
142: RULEBLK *rblk; /* rule list block */
143:
144: if ((targetsuffix = rindex(target, '.')) == NULL)
145: return(NO);
146: ruleindex = targetsuffix[1];
147: if (Ruletab[ruleindex] != NULL)
148: {
149: strcpy(source, target);
150: sourcesuffix = rindex(source, '.');
151: for (rblk=Ruletab[ruleindex]; rblk != NULL; rblk=rblk->r_next)
152: {
153: rulesuffix = rindex(rblk->r_rule, '.');
154: if (strcmp(rulesuffix, targetsuffix) == 0)
155: {
156: r = rblk->r_rule;
157: s = sourcesuffix;
158: while (*++s = *++r)
159: if (*s == '.')
160: {
161: *s = '\0';
162: break;
163: }
164: if (FILEXIST(source))
165: return(YES);
166: }
167: }
168: }
169: return(NO);
170: }
171:
172:
173:
174: /*
175: * storerule() appends a transformation rule to the end of a singly-linked
176: * list. Returns integer NO if out of memory, otherwise YES.
177: */
178: storerule(rulename)
179: char *rulename; /* transformation rule name */
180: {
181: char *slappend(); /* append rule to list */
182: SLIST *slinit(); /* initialize transformation list */
183:
184: if (Rulelist == NULL)
185: Rulelist = slinit();
186: if (slappend(rulename, Rulelist) == NULL)
187: return(NO);
188: return(YES);
189: }
Defined functions
Defined variables
Defined macros