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