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