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