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