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