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