final 3.6 release - took out TIMEBOMB code
[unix-history] / usr / src / usr.bin / error / subr.c
CommitLineData
a88a9a03
BJ
1static char *sccsid = "@(#)subr.c 1.1 (Berkeley) %G%";
2#include <stdio.h>
3#include <ctype.h>
4#include "error.h"
5/*
6 * go through and arrayify a list of rules
7 */
8arrayify(e_length, e_array, header)
9 int *e_length;
10 struct error_desc ***e_array;
11 struct error_desc *header;
12{
13 register struct error_desc *errorp;
14 register struct error_desc **array;
15 register int listlength;
16 register int listindex;
17
18 for (errorp = header, listlength = 0;
19 errorp; errorp = errorp->error_next, listlength++)
20 continue;
21 array = (struct error_desc **)Calloc(listlength+1,sizeof (struct error_desc*));
22 for(listindex = 0, errorp = header;
23 listindex < listlength;
24 listindex++, errorp = errorp->error_next){
25 array[listindex] = errorp;
26 errorp->error_position = listindex;
27 }
28 array[listindex] = (struct error_desc *)0;
29 *e_length = listlength;
30 *e_array = array;
31}
32
33/*VARARGS1*/
34error(msg, a1, a2, a3)
35 char *msg;
36{
37 fprintf(stderr, "Error: ");
38 fprintf(stderr, msg, a1, a2, a3);
39 fprintf(stderr, "\n");
40 fflush(stdout);
41 fflush(stderr);
42 exit(6);
43}
44/*ARGSUSED*/
45char *Calloc(nelements, size)
46 int nelements;
47 int size;
48{
49 char *back;
50 if ( (back = (char *)calloc(nelements, size)) == (char *)NULL){
51 error("Ran out of memory.\n");
52 exit(1);
53 }
54 return(back);
55}
56
57char *strsave(instring)
58 char *instring;
59{
60 char *outstring;
61 strcpy(outstring = (char *)Calloc(1, strlen(instring) + 1), instring);
62 return(outstring);
63}
64/*
65 * find the position of a given character in a string
66 * (one based)
67 */
68int position(string, ch)
69 register char *string;
70 register char ch;
71{
72 register int i;
73 for (i=1; *string; string++, i++){
74 if (*string == ch)
75 return(i);
76 }
77 return(-1);
78}
79/*
80 * clobber the first occurance of ch in string by the new character
81 */
82char *substitute(string, chold, chnew)
83 char *string;
84 char chold, chnew;
85{
86 register char *cp = string;
87
88 while (*cp){
89 if (*cp == chold){
90 *cp = chnew;
91 break;
92 }
93 cp++;
94 }
95 return(string);
96}
97
98char lastchar(string)
99 char *string;
100{
101 int length;
102 length = strlen(string);
103 if (length >= 1)
104 return(string[length-1]);
105 else
106 return('\0');
107}
108
109char firstchar(string)
110 char *string;
111{
112 return(string[0]);
113}
114
115char next_lastchar(string)
116 char *string;
117{
118 int length;
119 length = strlen(string);
120 if (length >= 2)
121 return(string[length - 2]);
122 else
123 return('\0');
124}
125
126clob_last(string, newstuff)
127 char *string, newstuff;
128{
129 int length;
130 length = strlen(string);
131 if (length >= 1)
132 string[length - 1] = newstuff;
133}
134
135/*
136 * parse a string that is the result of a format %s(%d)
137 * return TRUE if this is of the proper format
138 */
139boolean persperdexplode(string, r_perd, r_pers)
140 char *string;
141 char **r_perd, **r_pers;
142{
143 register char *cp;
144 int length;
145
146 length = strlen(string);
147 if ( (length >= 4)
148 && (string[length - 1] == ')' ) ){
149 for (cp = &string[length - 2];
150 (isdigit(*cp)) && (*cp != '(');
151 --cp)
152 continue;
153 if (*cp == '('){
154 string[length - 1] = '\0'; /* clobber the ) */
155 *r_perd = strsave(cp+1);
156 string[length - 1] = ')';
157 *cp = '\0'; /* clobber the ( */
158 *r_pers = strsave(string);
159 *cp = '(';
160 return(TRUE);
161 }
162 }
163 return(FALSE);
164}
165/*
166 * parse a quoted string that is the result of a format \"%s\"(%d)
167 * return TRUE if this is of the proper format
168 */
169boolean qpersperdexplode(string, r_perd, r_pers)
170 char *string;
171 char **r_perd, **r_pers;
172{
173 register char *cp;
174 int length;
175
176 length = strlen(string);
177 if ( (length >= 4)
178 && (string[length - 1] == ')' ) ){
179 for (cp = &string[length - 2];
180 (isdigit(*cp)) && (*cp != '(');
181 --cp)
182 continue;
183 if (*cp == '(' && *(cp - 1) == '"'){
184 string[length - 1] = '\0';
185 *r_perd = strsave(cp+1);
186 string[length - 1] = ')';
187 *(cp - 1) = '\0'; /* clobber the " */
188 *r_pers = strsave(string + 1);
189 *(cp - 1) = '"';
190 return(TRUE);
191 }
192 }
193 return(FALSE);
194}
195
196static char cincomment[] = CINCOMMENT;
197static char coutcomment[] = COUTCOMMENT;
198static char fincomment[] = FINCOMMENT;
199static char foutcomment[] = FOUTCOMMENT;
200static char newline[] = NEWLINE;
201static char piincomment[] = PIINCOMMENT;
202static char pioutcomment[] = PIOUTCOMMENT;
203static char lispincomment[] = LISPINCOMMENT;
204static char riincomment[] = RIINCOMMENT;
205static char rioutcomment[] = RIOUTCOMMENT;
206
207struct lang_desc lang_table[] = {
208 /*INUNKNOWN 0*/ "unknown", cincomment, coutcomment,
209 /*INCPP 1*/ "cpp", cincomment, coutcomment,
210 /*INCC 2*/ "cc", cincomment, coutcomment,
211 /*INAS 3*/ "as", ASINCOMMENT, newline,
212 /*INLD 4*/ "ld", cincomment, coutcomment,
213 /*INLINT 5*/ "lint", cincomment, coutcomment,
214 /*INF77 6*/ "f77", fincomment, foutcomment,
215 /*INPI 7*/ "pi", piincomment, pioutcomment,
216 /*INPC 8*/ "pc", piincomment, pioutcomment,
217 /*INFRANZ 9*/ "franz",lispincomment, newline,
218 /*INLISP 10*/ "lisp", lispincomment, newline,
219 /*INVAXIMA 11*/ "vaxima",lispincomment,newline,
220 /*INRATFOR 12*/ "ratfor",fincomment, foutcomment,
221 /*INLEX 13*/ "lex", cincomment, coutcomment,
222 /*INYACC 14*/ "yacc", cincomment, coutcomment,
223 /*INAPL 15*/ "apl", ".lm", newline,
224 /*INMAKE 16*/ "make", ASINCOMMENT, newline,
225 /*INRI 17*/ "ri", riincomment, rioutcomment,
226 0, 0, 0
227};
228
229printerrors(look_at_subclass, errorc, errorv)
230 boolean look_at_subclass;
231 int errorc;
232 struct error_desc *errorv[];
233{
234 register int i;
235 register struct error_desc *errorp;
236 for (errorp = errorv[i = 0]; i < errorc; errorp = errorv[++i]){
237 if (errorp->error_e_class == C_IGNORE)
238 continue;
239 if (look_at_subclass && errorp->error_s_class == C_DUPL)
240 continue;
241 printf("Error %d, (%s error) [%s], text = \"",
242 i,
243 class_table[errorp->error_e_class],
244 lang_table[errorp->error_language].lang_name);
245 wordvprint(stdout,errorp->error_lgtext,errorp->error_text);
246 printf("\"\n");
247 }
248}
249
250wordvprint(fyle, wordc, wordv)
251 FILE *fyle;
252 int wordc;
253 char *wordv[];
254{
255 int i;
256 for(i = 0; i < wordc; i++){
257 fprintf(fyle, "%s",wordv[i]);
258 if (i != wordc - 1)
259 fprintf(fyle, " ");
260 }
261}
262
263/*
264 * Given a string, parse it into a number of words, and build
265 * a wordc wordv combination pointing into it.
266 */
267wordvbuild(string, r_wordc, r_wordv)
268 char *string;
269 int *r_wordc;
270 char ***r_wordv;
271{
272 register char *cp;
273 char *saltedbuffer;
274 char **wordv;
275 int wordcount;
276 int wordindex;
277
278 saltedbuffer = strsave(string);
279 for (wordcount = 0, cp = saltedbuffer; *cp; wordcount++){
280 while (*cp && isspace(*cp))
281 cp++;
282 if (*cp == 0)
283 break;
284 while (!isspace(*cp))
285 cp++;
286 }
287 wordv = (char **)Calloc(wordcount + 1, sizeof (char *));
288 for (cp=saltedbuffer,wordindex=0; wordcount; wordindex++,--wordcount){
289 while (*cp && isspace(*cp))
290 cp++;
291 if (*cp == 0)
292 break;
293 wordv[wordindex] = cp;
294 while(!isspace(*cp))
295 cp++;
296 *cp++ = '\0';
297 }
298 if (wordcount != 0)
299 error("Initial miscount of the number of words in a line\n");
300 wordv[wordindex] = (char *)0;
301#ifdef FULLDEBUG
302 for (wordcount = 0; wordcount < wordindex; wordcount++)
303 printf("Word %d = \"%s\"\n", wordcount, wordv[wordcount]);
304 printf("\n");
305#endif
306 *r_wordc = wordindex;
307 *r_wordv = wordv;
308}
309/*
310 * Compare two 0 based wordvectors
311 */
312int wordvcmp(wordv1, wordc, wordv2)
313 char **wordv1;
314 int wordc;
315 char **wordv2;
316{
317 register int i;
318 int back;
319 for (i = 0; i < wordc; i++){
320 if (back = strcmp(wordv1[i], wordv2[i])){
321 return(back);
322 }
323 }
324 return(0); /* they are equal */
325}
326
327/*
328 * splice a 0 basedword vector onto the tail of a
329 * new wordv, allowing the first emptyhead slots to be empty
330 */
331char **wordvsplice(emptyhead, wordc, wordv)
332 int emptyhead;
333 int wordc;
334 char **wordv;
335{
336 register char **nwordv;
337 int nwordc = emptyhead + wordc;
338 register int i;
339
340 nwordv = (char **)Calloc(nwordc, sizeof (char *));
341 for (i = 0; i < emptyhead; i++)
342 nwordv[i] = 0;
343 for(i = emptyhead; i < nwordc; i++){
344 nwordv[i] = wordv[i-emptyhead];
345 }
346 return(nwordv);
347}