1*753d2d2eSraf /*
2*753d2d2eSraf * CDDL HEADER START
3*753d2d2eSraf *
4*753d2d2eSraf * The contents of this file are subject to the terms of the
5*753d2d2eSraf * Common Development and Distribution License, Version 1.0 only
6*753d2d2eSraf * (the "License"). You may not use this file except in compliance
7*753d2d2eSraf * with the License.
8*753d2d2eSraf *
9*753d2d2eSraf * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*753d2d2eSraf * or http://www.opensolaris.org/os/licensing.
11*753d2d2eSraf * See the License for the specific language governing permissions
12*753d2d2eSraf * and limitations under the License.
13*753d2d2eSraf *
14*753d2d2eSraf * When distributing Covered Code, include this CDDL HEADER in each
15*753d2d2eSraf * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*753d2d2eSraf * If applicable, add the following below this CDDL HEADER, with the
17*753d2d2eSraf * fields enclosed by brackets "[]" replaced with your own identifying
18*753d2d2eSraf * information: Portions Copyright [yyyy] [name of copyright owner]
19*753d2d2eSraf *
20*753d2d2eSraf * CDDL HEADER END
21*753d2d2eSraf */
22*753d2d2eSraf /*
23*753d2d2eSraf * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24*753d2d2eSraf * Use is subject to license terms.
25*753d2d2eSraf */
26*753d2d2eSraf
27*753d2d2eSraf #pragma ident "%Z%%M% %I% %E% SMI"
28*753d2d2eSraf
29*753d2d2eSraf #include <stdio.h>
30*753d2d2eSraf #include <ctype.h>
31*753d2d2eSraf #include <stdlib.h>
32*753d2d2eSraf #include <unistd.h>
33*753d2d2eSraf #include <string.h>
34*753d2d2eSraf #include <dlfcn.h>
35*753d2d2eSraf #include <dirent.h>
36*753d2d2eSraf #include <libgen.h>
37*753d2d2eSraf #include <sys/param.h>
38*753d2d2eSraf #include <errno.h>
39*753d2d2eSraf
40*753d2d2eSraf #include "parser.h"
41*753d2d2eSraf #include "errlog.h"
42*753d2d2eSraf
43*753d2d2eSraf static char const *ARCH_I386 = "i386";
44*753d2d2eSraf static char const *ARCH_SPARC = "sparc";
45*753d2d2eSraf static char const *ARCH_SPARCV9 = "sparcv9";
46*753d2d2eSraf static char const *ARCH_IA64 = "ia64";
47*753d2d2eSraf static char const *ARCH_AMD64 = "amd64";
48*753d2d2eSraf static char const *ARCH_ALL = "all";
49*753d2d2eSraf
50*753d2d2eSraf static int dofiles(const Translator_info *);
51*753d2d2eSraf static int read_spec(const Translator_info *, char *);
52*753d2d2eSraf
53*753d2d2eSraf static int Curlineno;
54*753d2d2eSraf
55*753d2d2eSraf xlator_keyword_t *keywordlist;
56*753d2d2eSraf
57*753d2d2eSraf /*
58*753d2d2eSraf * frontend entry point
59*753d2d2eSraf * returns the number of errors encountered
60*753d2d2eSraf */
61*753d2d2eSraf int
frontend(const Translator_info * T_info)62*753d2d2eSraf frontend(const Translator_info *T_info)
63*753d2d2eSraf {
64*753d2d2eSraf int retval, i = 0, errors = 0;
65*753d2d2eSraf
66*753d2d2eSraf keywordlist = xlator_init(T_info);
67*753d2d2eSraf if (keywordlist == NULL) {
68*753d2d2eSraf errlog(ERROR, "Error: Unable to get keywordlist\n");
69*753d2d2eSraf return (1);
70*753d2d2eSraf }
71*753d2d2eSraf
72*753d2d2eSraf if (T_info->ti_verbosity >= STATUS) {
73*753d2d2eSraf errlog(STATUS, "interesting keywords:\n");
74*753d2d2eSraf while (keywordlist[i].key != NULL) {
75*753d2d2eSraf errlog(STATUS, "\t%s\n", keywordlist[i].key);
76*753d2d2eSraf ++i;
77*753d2d2eSraf };
78*753d2d2eSraf }
79*753d2d2eSraf
80*753d2d2eSraf retval = xlator_startlib(T_info->ti_liblist);
81*753d2d2eSraf switch (retval) {
82*753d2d2eSraf case XLATOR_SKIP:
83*753d2d2eSraf if (T_info->ti_verbosity >= STATUS)
84*753d2d2eSraf errlog(STATUS, "Skipping %s\n", T_info->ti_liblist);
85*753d2d2eSraf retval = 0;
86*753d2d2eSraf break;
87*753d2d2eSraf
88*753d2d2eSraf case XLATOR_NONFATAL:
89*753d2d2eSraf ++errors;
90*753d2d2eSraf retval = 0;
91*753d2d2eSraf break;
92*753d2d2eSraf
93*753d2d2eSraf case XLATOR_SUCCESS:
94*753d2d2eSraf retval = dofiles(T_info);
95*753d2d2eSraf errors += retval;
96*753d2d2eSraf if ((retval = xlator_endlib()) != XLATOR_SUCCESS)
97*753d2d2eSraf ++errors;
98*753d2d2eSraf retval = 0;
99*753d2d2eSraf break;
100*753d2d2eSraf
101*753d2d2eSraf default:
102*753d2d2eSraf errlog(ERROR | FATAL,
103*753d2d2eSraf "Error: Invalid return code from xlator_startlib()\n");
104*753d2d2eSraf exit(1);
105*753d2d2eSraf }
106*753d2d2eSraf
107*753d2d2eSraf if ((retval = xlator_end()) != XLATOR_SUCCESS)
108*753d2d2eSraf ++errors;
109*753d2d2eSraf
110*753d2d2eSraf return (errors);
111*753d2d2eSraf }
112*753d2d2eSraf
113*753d2d2eSraf /*
114*753d2d2eSraf * dofiles(const Translator_info *T_info);
115*753d2d2eSraf * iterate through files specified in the command line and process
116*753d2d2eSraf * them one by one
117*753d2d2eSraf * requires spec files to have a ".spec" suffix
118*753d2d2eSraf * returns the number of errors;
119*753d2d2eSraf */
120*753d2d2eSraf static int
dofiles(const Translator_info * T_info)121*753d2d2eSraf dofiles(const Translator_info *T_info)
122*753d2d2eSraf {
123*753d2d2eSraf int nfiles, flen, findex, retval = 0, errors = 0;
124*753d2d2eSraf
125*753d2d2eSraf nfiles = T_info->ti_nfiles;
126*753d2d2eSraf
127*753d2d2eSraf for (findex = 0; findex < nfiles; ++findex) {
128*753d2d2eSraf flen = strlen(filelist[findex]);
129*753d2d2eSraf if ((flen <= 5) ||
130*753d2d2eSraf strcmp(&filelist[findex][flen-5], ".spec") != 0) {
131*753d2d2eSraf errlog(ERROR,
132*753d2d2eSraf "Error: File specified does not have the "
133*753d2d2eSraf ".spec extension: %s\n", filelist[findex]);
134*753d2d2eSraf ++errors;
135*753d2d2eSraf continue;
136*753d2d2eSraf };
137*753d2d2eSraf retval = read_spec(T_info, filelist[findex]);
138*753d2d2eSraf errors += retval;
139*753d2d2eSraf }
140*753d2d2eSraf return (errors);
141*753d2d2eSraf }
142*753d2d2eSraf
143*753d2d2eSraf /*
144*753d2d2eSraf * read_spec -
145*753d2d2eSraf * Given a filename, this function will reads the spec file to
146*753d2d2eSraf * recognize keywords which it passes along with the corresponding
147*753d2d2eSraf * value to the back-end translator to process. The following
148*753d2d2eSraf * back-end interfaces are called:
149*753d2d2eSraf * xlator_startfile
150*753d2d2eSraf * xlator_start_if
151*753d2d2eSraf * xlator_take_kvpair
152*753d2d2eSraf * xlator_end_if
153*753d2d2eSraf * xlator_endfile
154*753d2d2eSraf */
155*753d2d2eSraf static int
read_spec(const Translator_info * T_info,char * spec_filename)156*753d2d2eSraf read_spec(const Translator_info *T_info, char *spec_filename)
157*753d2d2eSraf {
158*753d2d2eSraf FILE *spec_fp;
159*753d2d2eSraf Meta_info meta_info;
160*753d2d2eSraf char key[BUFSIZ], *value = NULL, *p = NULL;
161*753d2d2eSraf char *buf2 = NULL;
162*753d2d2eSraf int retval = 0, errors = 0, ki = 0; /* keyword indicator */
163*753d2d2eSraf int start_if_fail = 0, skip_if = 0;
164*753d2d2eSraf int extends_err = 0;
165*753d2d2eSraf
166*753d2d2eSraf meta_info.mi_ext_cnt = 0; /* All info is non-extends */
167*753d2d2eSraf meta_info.mi_flags = 0;
168*753d2d2eSraf
169*753d2d2eSraf retval = xlator_startfile(spec_filename);
170*753d2d2eSraf
171*753d2d2eSraf switch (retval) {
172*753d2d2eSraf case XLATOR_SKIP:
173*753d2d2eSraf if (T_info->ti_verbosity >= WARNING)
174*753d2d2eSraf errlog(WARNING, "Warning: Skipping %s\n",
175*753d2d2eSraf spec_filename);
176*753d2d2eSraf return (errors);
177*753d2d2eSraf
178*753d2d2eSraf case XLATOR_NONFATAL:
179*753d2d2eSraf errlog(ERROR, "Error in xlator_startfile\n");
180*753d2d2eSraf ++errors;
181*753d2d2eSraf return (errors);
182*753d2d2eSraf
183*753d2d2eSraf case XLATOR_SUCCESS:
184*753d2d2eSraf break;
185*753d2d2eSraf
186*753d2d2eSraf default:
187*753d2d2eSraf errlog(ERROR,
188*753d2d2eSraf "Error: Invalid return code from xlator_startfile()\n");
189*753d2d2eSraf ++errors;
190*753d2d2eSraf return (errors);
191*753d2d2eSraf };
192*753d2d2eSraf
193*753d2d2eSraf /* file processing */
194*753d2d2eSraf spec_fp = fopen(spec_filename, "r");
195*753d2d2eSraf if (spec_fp == NULL) {
196*753d2d2eSraf errlog(ERROR, "Error: Unable to open spec file %s: %s\n",
197*753d2d2eSraf spec_filename, strerror(errno));
198*753d2d2eSraf ++errors;
199*753d2d2eSraf return (errors);
200*753d2d2eSraf }
201*753d2d2eSraf
202*753d2d2eSraf (void) strncpy(meta_info.mi_filename, spec_filename, BUFSIZ);
203*753d2d2eSraf meta_info.mi_line_number = 0;
204*753d2d2eSraf Curlineno = meta_info.mi_line_number;
205*753d2d2eSraf while (meta_info.mi_nlines = readline(&buf2, spec_fp)) {
206*753d2d2eSraf meta_info.mi_line_number += meta_info.mi_nlines;
207*753d2d2eSraf Curlineno = meta_info.mi_line_number;
208*753d2d2eSraf if (!non_empty(buf2)) {
209*753d2d2eSraf free(buf2);
210*753d2d2eSraf buf2 = NULL;
211*753d2d2eSraf continue;
212*753d2d2eSraf }
213*753d2d2eSraf p = realloc(value, sizeof (char)*(strlen(buf2)+1));
214*753d2d2eSraf if (p == NULL) {
215*753d2d2eSraf errlog(ERROR | FATAL,
216*753d2d2eSraf "Error: Unable to allocate memory for "
217*753d2d2eSraf "value: %d\n", errno);
218*753d2d2eSraf }
219*753d2d2eSraf value = p;
220*753d2d2eSraf split(buf2, key, value);
221*753d2d2eSraf ki = interesting_keyword(keywordlist, key);
222*753d2d2eSraf switch (ki) {
223*753d2d2eSraf case XLATOR_KW_FUNC: /* Function keyword */
224*753d2d2eSraf case XLATOR_KW_DATA: /* Data keyword */
225*753d2d2eSraf meta_info.mi_extended = 0;
226*753d2d2eSraf retval = xlator_start_if(meta_info, ki, value);
227*753d2d2eSraf switch (retval) {
228*753d2d2eSraf case XLATOR_FATAL: /* FATAL ERROR */
229*753d2d2eSraf if (T_info->ti_verbosity >= STATUS) {
230*753d2d2eSraf errlog(STATUS,
231*753d2d2eSraf "Error in xlator_start_if: ");
232*753d2d2eSraf }
233*753d2d2eSraf ++errors;
234*753d2d2eSraf return (errors);
235*753d2d2eSraf case XLATOR_NONFATAL: /* NON-FATAL ERROR */
236*753d2d2eSraf if (T_info->ti_verbosity >= STATUS)
237*753d2d2eSraf errlog(STATUS,
238*753d2d2eSraf "Error in xlator_start_if\n");
239*753d2d2eSraf ++errors;
240*753d2d2eSraf start_if_fail = 1;
241*753d2d2eSraf break;
242*753d2d2eSraf case XLATOR_SUCCESS: /* OK */
243*753d2d2eSraf start_if_fail = 0;
244*753d2d2eSraf extends_err = check4extends(spec_filename,
245*753d2d2eSraf value, T_info->ti_archtoken, spec_fp);
246*753d2d2eSraf switch (extends_err) {
247*753d2d2eSraf case -1: /* Error */
248*753d2d2eSraf errlog(ERROR, "\"%s\", line %d: "
249*753d2d2eSraf "Error occurred while "
250*753d2d2eSraf "checking for extends clause\n",
251*753d2d2eSraf spec_filename, Curlineno);
252*753d2d2eSraf ++errors;
253*753d2d2eSraf /*FALLTHRU*/
254*753d2d2eSraf case 0: /* No Extends */
255*753d2d2eSraf break;
256*753d2d2eSraf case 1: /* Extends */
257*753d2d2eSraf meta_info.mi_extended = 1;
258*753d2d2eSraf extends_err = do_extends(meta_info,
259*753d2d2eSraf T_info, value);
260*753d2d2eSraf if (extends_err) {
261*753d2d2eSraf errors += extends_err;
262*753d2d2eSraf }
263*753d2d2eSraf break;
264*753d2d2eSraf default: /* Programmer Error */
265*753d2d2eSraf errlog(ERROR | FATAL,
266*753d2d2eSraf "Error: invalid return from "
267*753d2d2eSraf "check4extends %d\n", extends_err);
268*753d2d2eSraf }
269*753d2d2eSraf break;
270*753d2d2eSraf case XLATOR_SKIP: /* SKIP */
271*753d2d2eSraf if (T_info->ti_verbosity >= WARNING)
272*753d2d2eSraf errlog(WARNING, "Warning: Skipping "
273*753d2d2eSraf "interface %s\n", value);
274*753d2d2eSraf skip_if = 1;
275*753d2d2eSraf start_if_fail = 0;
276*753d2d2eSraf break;
277*753d2d2eSraf default:
278*753d2d2eSraf /* Invalid Return */
279*753d2d2eSraf errlog(ERROR | FATAL,
280*753d2d2eSraf "Error: Invalid return code "
281*753d2d2eSraf "from xlator_start_if (): %d\n", retval);
282*753d2d2eSraf }
283*753d2d2eSraf break;
284*753d2d2eSraf case XLATOR_KW_END: /* END keyword */
285*753d2d2eSraf if (start_if_fail == 0 && skip_if == 0) {
286*753d2d2eSraf retval = xlator_end_if(meta_info, value);
287*753d2d2eSraf if (retval)
288*753d2d2eSraf ++errors;
289*753d2d2eSraf }
290*753d2d2eSraf skip_if = 0;
291*753d2d2eSraf break;
292*753d2d2eSraf case XLATOR_KW_NOTFOUND:
293*753d2d2eSraf if (T_info->ti_verbosity >= TRACING)
294*753d2d2eSraf errlog(TRACING, "uninteresting keyword: %s\n",
295*753d2d2eSraf key);
296*753d2d2eSraf break;
297*753d2d2eSraf default:
298*753d2d2eSraf if (skip_if == 0 && start_if_fail == 0) {
299*753d2d2eSraf retval = xlator_take_kvpair(meta_info,
300*753d2d2eSraf ki, value);
301*753d2d2eSraf if (retval) {
302*753d2d2eSraf if (T_info->ti_verbosity >= STATUS)
303*753d2d2eSraf errlog(STATUS, "Error in "
304*753d2d2eSraf "xlator_take_kvpair\n");
305*753d2d2eSraf ++errors;
306*753d2d2eSraf }
307*753d2d2eSraf }
308*753d2d2eSraf }
309*753d2d2eSraf free(buf2);
310*753d2d2eSraf buf2 = NULL;
311*753d2d2eSraf }
312*753d2d2eSraf
313*753d2d2eSraf if ((retval = xlator_endfile()) != XLATOR_SUCCESS) {
314*753d2d2eSraf if (T_info->ti_verbosity >= STATUS)
315*753d2d2eSraf errlog(STATUS, "Error in xlator_endfile\n");
316*753d2d2eSraf ++errors;
317*753d2d2eSraf }
318*753d2d2eSraf free(p);
319*753d2d2eSraf (void) fclose(spec_fp);
320*753d2d2eSraf return (errors);
321*753d2d2eSraf }
322*753d2d2eSraf
323*753d2d2eSraf /*
324*753d2d2eSraf * interesting_keyword(char **keywordlist, const char *key) {
325*753d2d2eSraf * returns the token associated with key if key is found in keywordlist
326*753d2d2eSraf * returns XLATOR_KW_NOTFOUND if key is NOT found in keywordlist
327*753d2d2eSraf * "Function" and "End" are always interesting, return XLATOR_KW_FUNC
328*753d2d2eSraf * and XLATOR_KW_DATA respectively;
329*753d2d2eSraf * "End" is always interesting, return XLATOR_KW_END;
330*753d2d2eSraf *
331*753d2d2eSraf */
332*753d2d2eSraf int
interesting_keyword(xlator_keyword_t * keywordlist,const char * key)333*753d2d2eSraf interesting_keyword(xlator_keyword_t *keywordlist, const char *key)
334*753d2d2eSraf {
335*753d2d2eSraf int i = 0;
336*753d2d2eSraf
337*753d2d2eSraf if (strcasecmp(key, "data") == 0) {
338*753d2d2eSraf return (XLATOR_KW_DATA);
339*753d2d2eSraf }
340*753d2d2eSraf if (strcasecmp(key, "function") == 0) {
341*753d2d2eSraf return (XLATOR_KW_FUNC);
342*753d2d2eSraf }
343*753d2d2eSraf
344*753d2d2eSraf if (strcasecmp(key, "end") == 0)
345*753d2d2eSraf return (XLATOR_KW_END);
346*753d2d2eSraf
347*753d2d2eSraf while (keywordlist[i].key != NULL) {
348*753d2d2eSraf if (strcasecmp(keywordlist[i].key, key) == 0)
349*753d2d2eSraf return (keywordlist[i].token);
350*753d2d2eSraf ++i;
351*753d2d2eSraf }
352*753d2d2eSraf return (XLATOR_KW_NOTFOUND);
353*753d2d2eSraf }
354*753d2d2eSraf
355*753d2d2eSraf /*
356*753d2d2eSraf * line_to_buf(char *dest, const char *src) {
357*753d2d2eSraf * appends src to dest, dynamically increasing the size of dest.
358*753d2d2eSraf * replaces the trailing '\' continuation character with a space.
359*753d2d2eSraf *
360*753d2d2eSraf * if src is continuation of dest, dest != NULL, and
361*753d2d2eSraf * the last character in dest before the newline must be a `\'
362*753d2d2eSraf * if src is not continuation of dest, then dest must be NULL
363*753d2d2eSraf */
364*753d2d2eSraf char *
line_to_buf(char * dest,const char * src)365*753d2d2eSraf line_to_buf(char *dest, const char *src)
366*753d2d2eSraf {
367*753d2d2eSraf int slen = strlen(src);
368*753d2d2eSraf int dlen;
369*753d2d2eSraf
370*753d2d2eSraf if (dest == NULL) {
371*753d2d2eSraf /* We're being called for the first time */
372*753d2d2eSraf dest = malloc(sizeof (char) * (slen + 1));
373*753d2d2eSraf if (dest == NULL) {
374*753d2d2eSraf errlog(ERROR | FATAL,
375*753d2d2eSraf "Error: Unable to allocate memory for dest\n");
376*753d2d2eSraf }
377*753d2d2eSraf (void) strcpy(dest, src);
378*753d2d2eSraf return (dest);
379*753d2d2eSraf }
380*753d2d2eSraf
381*753d2d2eSraf dlen = strlen(dest);
382*753d2d2eSraf
383*753d2d2eSraf dest = realloc(dest, (size_t)(sizeof (char) * (dlen+slen+1)));
384*753d2d2eSraf if (dest == NULL) {
385*753d2d2eSraf errlog(ERROR | FATAL,
386*753d2d2eSraf "Error: Unable to allocate memory for dest\n");
387*753d2d2eSraf }
388*753d2d2eSraf
389*753d2d2eSraf if (dlen > 1) {
390*753d2d2eSraf /*
391*753d2d2eSraf * remove continuation character
392*753d2d2eSraf * we replace the '\' from the previous line with a space
393*753d2d2eSraf */
394*753d2d2eSraf if (dest[dlen-2] == '\\') {
395*753d2d2eSraf dest[dlen-2] = ' ';
396*753d2d2eSraf }
397*753d2d2eSraf }
398*753d2d2eSraf
399*753d2d2eSraf /* join the two strings */
400*753d2d2eSraf (void) strcat(dest, src);
401*753d2d2eSraf
402*753d2d2eSraf return (dest);
403*753d2d2eSraf }
404*753d2d2eSraf
405*753d2d2eSraf /*
406*753d2d2eSraf * non_empty(const char *str)
407*753d2d2eSraf * assumes str is non null
408*753d2d2eSraf * checks if str is a non empty string
409*753d2d2eSraf * returns 1 if string contains non whitespace
410*753d2d2eSraf * returns 0 if string contains only whitespace
411*753d2d2eSraf */
412*753d2d2eSraf int
non_empty(const char * str)413*753d2d2eSraf non_empty(const char *str)
414*753d2d2eSraf {
415*753d2d2eSraf while (*str != '\0') {
416*753d2d2eSraf if (!isspace(*str))
417*753d2d2eSraf return (1);
418*753d2d2eSraf ++str;
419*753d2d2eSraf };
420*753d2d2eSraf return (0);
421*753d2d2eSraf }
422*753d2d2eSraf
423*753d2d2eSraf /*
424*753d2d2eSraf * split(const char *line, char *key, char *value);
425*753d2d2eSraf * splits the line into keyword (key) and value pair
426*753d2d2eSraf */
427*753d2d2eSraf void
split(const char * line,char * key,char * value)428*753d2d2eSraf split(const char *line, char *key, char *value)
429*753d2d2eSraf {
430*753d2d2eSraf char *p;
431*753d2d2eSraf
432*753d2d2eSraf p = (char *)line;
433*753d2d2eSraf
434*753d2d2eSraf /* skip leading whitespace */
435*753d2d2eSraf while (isspace(*p)&& *p != '\0')
436*753d2d2eSraf ++p;
437*753d2d2eSraf
438*753d2d2eSraf /* copy keyword from line into key */
439*753d2d2eSraf while (!isspace(*p) && *p != '\0')
440*753d2d2eSraf *key++ = *p++;
441*753d2d2eSraf
442*753d2d2eSraf *key = '\0';
443*753d2d2eSraf
444*753d2d2eSraf /* skip whitespace */
445*753d2d2eSraf while (isspace(*p) && *p != '\0')
446*753d2d2eSraf p++;
447*753d2d2eSraf
448*753d2d2eSraf (void) strcpy(value, p);
449*753d2d2eSraf
450*753d2d2eSraf }
451*753d2d2eSraf
452*753d2d2eSraf /*
453*753d2d2eSraf * check4extends(char *filename, char *value, int arch, FILE *fp)
454*753d2d2eSraf * if no arch keyword is found or there is a MATCHING arch keyword
455*753d2d2eSraf * returns 1 if value is of the form "data|function name extends"
456*753d2d2eSraf * -1 for error
457*753d2d2eSraf * 0 no other keyword after the function name
458*753d2d2eSraf * else
459*753d2d2eSraf * return 0
460*753d2d2eSraf *
461*753d2d2eSraf * filename is used only for error reporting
462*753d2d2eSraf */
463*753d2d2eSraf int
check4extends(const char * filename,const char * value,int arch,FILE * fp)464*753d2d2eSraf check4extends(const char *filename, const char *value, int arch, FILE *fp)
465*753d2d2eSraf {
466*753d2d2eSraf char fun[BUFSIZ];
467*753d2d2eSraf char extends[BUFSIZ];
468*753d2d2eSraf int n;
469*753d2d2eSraf
470*753d2d2eSraf if (arch_match(fp, arch)) {
471*753d2d2eSraf split(value, fun, extends);
472*753d2d2eSraf n = strlen(extends);
473*753d2d2eSraf if (extends[n-1] == '\n')
474*753d2d2eSraf extends[n-1] = '\0';
475*753d2d2eSraf if (strncasecmp("extends", extends, 7) == 0) {
476*753d2d2eSraf return (1);
477*753d2d2eSraf } else {
478*753d2d2eSraf if (*extends != '\0') {
479*753d2d2eSraf errlog(ERROR, "\"%s\", line %d: Error: "
480*753d2d2eSraf "Trailing garbage after function name\n",
481*753d2d2eSraf filename, Curlineno);
482*753d2d2eSraf return (-1);
483*753d2d2eSraf }
484*753d2d2eSraf }
485*753d2d2eSraf }
486*753d2d2eSraf return (0);
487*753d2d2eSraf }
488*753d2d2eSraf
489*753d2d2eSraf /*
490*753d2d2eSraf * remcomment (char *buf)
491*753d2d2eSraf * replace comments with single whitespace
492*753d2d2eSraf */
493*753d2d2eSraf /* XXX: There is currently no way to escape a comment character */
494*753d2d2eSraf void
remcomment(char const * buf)495*753d2d2eSraf remcomment(char const *buf)
496*753d2d2eSraf {
497*753d2d2eSraf char *p;
498*753d2d2eSraf p = strchr(buf, '#');
499*753d2d2eSraf if (p) {
500*753d2d2eSraf *p = ' ';
501*753d2d2eSraf *(p+1) = '\0';
502*753d2d2eSraf }
503*753d2d2eSraf }
504*753d2d2eSraf
505*753d2d2eSraf /*
506*753d2d2eSraf * arch_strtoi()
507*753d2d2eSraf *
508*753d2d2eSraf * input: string
509*753d2d2eSraf * return: XLATOR_I386 if string == ARCH_I386
510*753d2d2eSraf * XLATOR_SPARC if string == ARCH_SPARC
511*753d2d2eSraf * XLATOR_SPARCV9 if string == ARCH_SPARCV9
512*753d2d2eSraf * XLATOR_IA64 if string == ARCH_IA64
513*753d2d2eSraf * XLATOR_AMD64 if string == ARCH_AMD64
514*753d2d2eSraf * XLATOR_ALLARCH if string == ARCH_ALL
515*753d2d2eSraf * 0 if outside the known set {i386, sparc, sparcv9, ia64, amd64}.
516*753d2d2eSraf */
517*753d2d2eSraf int
arch_strtoi(const char * arch_str)518*753d2d2eSraf arch_strtoi(const char *arch_str)
519*753d2d2eSraf {
520*753d2d2eSraf if (arch_str != NULL) {
521*753d2d2eSraf if (strcmp(arch_str, ARCH_I386) == 0)
522*753d2d2eSraf return (XLATOR_I386);
523*753d2d2eSraf else if (strcmp(arch_str, ARCH_SPARC) == 0)
524*753d2d2eSraf return (XLATOR_SPARC);
525*753d2d2eSraf else if (strcmp(arch_str, ARCH_SPARCV9) == 0)
526*753d2d2eSraf return (XLATOR_SPARCV9);
527*753d2d2eSraf else if (strcmp(arch_str, ARCH_IA64) == 0)
528*753d2d2eSraf return (XLATOR_IA64);
529*753d2d2eSraf else if (strcmp(arch_str, ARCH_AMD64) == 0)
530*753d2d2eSraf return (XLATOR_AMD64);
531*753d2d2eSraf else if (strcmp(arch_str, ARCH_ALL) == 0)
532*753d2d2eSraf return (XLATOR_ALLARCH);
533*753d2d2eSraf } else {
534*753d2d2eSraf errlog(ERROR, "\"%s\", line %d: Error: "
535*753d2d2eSraf "arch keyword with no value");
536*753d2d2eSraf }
537*753d2d2eSraf return (0);
538*753d2d2eSraf }
539*753d2d2eSraf
540*753d2d2eSraf int
readline(char ** buffer,FILE * fp)541*753d2d2eSraf readline(char **buffer, FILE *fp)
542*753d2d2eSraf {
543*753d2d2eSraf int nlines = 0;
544*753d2d2eSraf int len;
545*753d2d2eSraf char buf[BUFSIZ];
546*753d2d2eSraf
547*753d2d2eSraf if (fgets(buf, BUFSIZ, fp)) {
548*753d2d2eSraf nlines++;
549*753d2d2eSraf /* replace comments with single whitespace */
550*753d2d2eSraf remcomment(buf);
551*753d2d2eSraf
552*753d2d2eSraf /* get complete line */
553*753d2d2eSraf *buffer = line_to_buf(*buffer, buf); /* append buf to buffer */
554*753d2d2eSraf len = strlen(buf);
555*753d2d2eSraf if (len > 1) {
556*753d2d2eSraf /* handle continuation lines */
557*753d2d2eSraf while (buf[len-2] == '\\') {
558*753d2d2eSraf if (!fgets(buf, BUFSIZ, fp)) {
559*753d2d2eSraf *buffer = line_to_buf(*buffer, buf);
560*753d2d2eSraf break;
561*753d2d2eSraf }
562*753d2d2eSraf nlines++;
563*753d2d2eSraf len = strlen(buf);
564*753d2d2eSraf *buffer = line_to_buf(*buffer, buf);
565*753d2d2eSraf }
566*753d2d2eSraf } /* end of 'get complete line' */
567*753d2d2eSraf }
568*753d2d2eSraf return (nlines);
569*753d2d2eSraf }
570