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