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