diff options
Diffstat (limited to 'usr/src/cmd/abi/spectrans/parser/frontend.c')
-rw-r--r-- | usr/src/cmd/abi/spectrans/parser/frontend.c | 569 |
1 files changed, 0 insertions, 569 deletions
diff --git a/usr/src/cmd/abi/spectrans/parser/frontend.c b/usr/src/cmd/abi/spectrans/parser/frontend.c deleted file mode 100644 index db33b99442..0000000000 --- a/usr/src/cmd/abi/spectrans/parser/frontend.c +++ /dev/null @@ -1,569 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <ctype.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <dlfcn.h> -#include <dirent.h> -#include <libgen.h> -#include <sys/param.h> -#include <errno.h> - -#include "parser.h" -#include "errlog.h" - -static char const *ARCH_I386 = "i386"; -static char const *ARCH_SPARC = "sparc"; -static char const *ARCH_SPARCV9 = "sparcv9"; -static char const *ARCH_IA64 = "ia64"; -static char const *ARCH_AMD64 = "amd64"; -static char const *ARCH_ALL = "all"; - -static int dofiles(const Translator_info *); -static int read_spec(const Translator_info *, char *); - -static int Curlineno; - -xlator_keyword_t *keywordlist; - -/* - * frontend entry point - * returns the number of errors encountered - */ -int -frontend(const Translator_info *T_info) -{ - int retval, i = 0, errors = 0; - - keywordlist = xlator_init(T_info); - if (keywordlist == NULL) { - errlog(ERROR, "Error: Unable to get keywordlist\n"); - return (1); - } - - if (T_info->ti_verbosity >= STATUS) { - errlog(STATUS, "interesting keywords:\n"); - while (keywordlist[i].key != NULL) { - errlog(STATUS, "\t%s\n", keywordlist[i].key); - ++i; - }; - } - - retval = xlator_startlib(T_info->ti_liblist); - switch (retval) { - case XLATOR_SKIP: - if (T_info->ti_verbosity >= STATUS) - errlog(STATUS, "Skipping %s\n", T_info->ti_liblist); - retval = 0; - break; - - case XLATOR_NONFATAL: - ++errors; - retval = 0; - break; - - case XLATOR_SUCCESS: - retval = dofiles(T_info); - errors += retval; - if ((retval = xlator_endlib()) != XLATOR_SUCCESS) - ++errors; - retval = 0; - break; - - default: - errlog(ERROR | FATAL, - "Error: Invalid return code from xlator_startlib()\n"); - exit(1); - } - - if ((retval = xlator_end()) != XLATOR_SUCCESS) - ++errors; - - return (errors); -} - -/* - * dofiles(const Translator_info *T_info); - * iterate through files specified in the command line and process - * them one by one - * requires spec files to have a ".spec" suffix - * returns the number of errors; - */ -static int -dofiles(const Translator_info *T_info) -{ - int nfiles, flen, findex, retval = 0, errors = 0; - - nfiles = T_info->ti_nfiles; - - for (findex = 0; findex < nfiles; ++findex) { - flen = strlen(filelist[findex]); - if ((flen <= 5) || - strcmp(&filelist[findex][flen-5], ".spec") != 0) { - errlog(ERROR, - "Error: File specified does not have the " - ".spec extension: %s\n", filelist[findex]); - ++errors; - continue; - }; - retval = read_spec(T_info, filelist[findex]); - errors += retval; - } - return (errors); -} - -/* - * read_spec - - * Given a filename, this function will reads the spec file to - * recognize keywords which it passes along with the corresponding - * value to the back-end translator to process. The following - * back-end interfaces are called: - * xlator_startfile - * xlator_start_if - * xlator_take_kvpair - * xlator_end_if - * xlator_endfile - */ -static int -read_spec(const Translator_info *T_info, char *spec_filename) -{ - FILE *spec_fp; - Meta_info meta_info; - char key[BUFSIZ], *value = NULL, *p = NULL; - char *buf2 = NULL; - int retval = 0, errors = 0, ki = 0; /* keyword indicator */ - int start_if_fail = 0, skip_if = 0; - int extends_err = 0; - - meta_info.mi_ext_cnt = 0; /* All info is non-extends */ - meta_info.mi_flags = 0; - - retval = xlator_startfile(spec_filename); - - switch (retval) { - case XLATOR_SKIP: - if (T_info->ti_verbosity >= WARNING) - errlog(WARNING, "Warning: Skipping %s\n", - spec_filename); - return (errors); - - case XLATOR_NONFATAL: - errlog(ERROR, "Error in xlator_startfile\n"); - ++errors; - return (errors); - - case XLATOR_SUCCESS: - break; - - default: - errlog(ERROR, - "Error: Invalid return code from xlator_startfile()\n"); - ++errors; - return (errors); - }; - - /* file processing */ - spec_fp = fopen(spec_filename, "r"); - if (spec_fp == NULL) { - errlog(ERROR, "Error: Unable to open spec file %s: %s\n", - spec_filename, strerror(errno)); - ++errors; - return (errors); - } - - (void) strncpy(meta_info.mi_filename, spec_filename, BUFSIZ); - meta_info.mi_line_number = 0; - Curlineno = meta_info.mi_line_number; - while (meta_info.mi_nlines = readline(&buf2, spec_fp)) { - meta_info.mi_line_number += meta_info.mi_nlines; - Curlineno = meta_info.mi_line_number; - if (!non_empty(buf2)) { - free(buf2); - buf2 = NULL; - continue; - } - p = realloc(value, sizeof (char)*(strlen(buf2)+1)); - if (p == NULL) { - errlog(ERROR | FATAL, - "Error: Unable to allocate memory for " - "value: %d\n", errno); - } - value = p; - split(buf2, key, value); - ki = interesting_keyword(keywordlist, key); - switch (ki) { - case XLATOR_KW_FUNC: /* Function keyword */ - case XLATOR_KW_DATA: /* Data keyword */ - meta_info.mi_extended = 0; - retval = xlator_start_if(meta_info, ki, value); - switch (retval) { - case XLATOR_FATAL: /* FATAL ERROR */ - if (T_info->ti_verbosity >= STATUS) { - errlog(STATUS, - "Error in xlator_start_if: "); - } - ++errors; - return (errors); - case XLATOR_NONFATAL: /* NON-FATAL ERROR */ - if (T_info->ti_verbosity >= STATUS) - errlog(STATUS, - "Error in xlator_start_if\n"); - ++errors; - start_if_fail = 1; - break; - case XLATOR_SUCCESS: /* OK */ - start_if_fail = 0; - extends_err = check4extends(spec_filename, - value, T_info->ti_archtoken, spec_fp); - switch (extends_err) { - case -1: /* Error */ - errlog(ERROR, "\"%s\", line %d: " - "Error occurred while " - "checking for extends clause\n", - spec_filename, Curlineno); - ++errors; - /*FALLTHRU*/ - case 0: /* No Extends */ - break; - case 1: /* Extends */ - meta_info.mi_extended = 1; - extends_err = do_extends(meta_info, - T_info, value); - if (extends_err) { - errors += extends_err; - } - break; - default: /* Programmer Error */ - errlog(ERROR | FATAL, - "Error: invalid return from " - "check4extends %d\n", extends_err); - } - break; - case XLATOR_SKIP: /* SKIP */ - if (T_info->ti_verbosity >= WARNING) - errlog(WARNING, "Warning: Skipping " - "interface %s\n", value); - skip_if = 1; - start_if_fail = 0; - break; - default: - /* Invalid Return */ - errlog(ERROR | FATAL, - "Error: Invalid return code " - "from xlator_start_if (): %d\n", retval); - } - break; - case XLATOR_KW_END: /* END keyword */ - if (start_if_fail == 0 && skip_if == 0) { - retval = xlator_end_if(meta_info, value); - if (retval) - ++errors; - } - skip_if = 0; - break; - case XLATOR_KW_NOTFOUND: - if (T_info->ti_verbosity >= TRACING) - errlog(TRACING, "uninteresting keyword: %s\n", - key); - break; - default: - if (skip_if == 0 && start_if_fail == 0) { - retval = xlator_take_kvpair(meta_info, - ki, value); - if (retval) { - if (T_info->ti_verbosity >= STATUS) - errlog(STATUS, "Error in " - "xlator_take_kvpair\n"); - ++errors; - } - } - } - free(buf2); - buf2 = NULL; - } - - if ((retval = xlator_endfile()) != XLATOR_SUCCESS) { - if (T_info->ti_verbosity >= STATUS) - errlog(STATUS, "Error in xlator_endfile\n"); - ++errors; - } - free(p); - (void) fclose(spec_fp); - return (errors); -} - -/* - * interesting_keyword(char **keywordlist, const char *key) { - * returns the token associated with key if key is found in keywordlist - * returns XLATOR_KW_NOTFOUND if key is NOT found in keywordlist - * "Function" and "End" are always interesting, return XLATOR_KW_FUNC - * and XLATOR_KW_DATA respectively; - * "End" is always interesting, return XLATOR_KW_END; - * - */ -int -interesting_keyword(xlator_keyword_t *keywordlist, const char *key) -{ - int i = 0; - - if (strcasecmp(key, "data") == 0) { - return (XLATOR_KW_DATA); - } - if (strcasecmp(key, "function") == 0) { - return (XLATOR_KW_FUNC); - } - - if (strcasecmp(key, "end") == 0) - return (XLATOR_KW_END); - - while (keywordlist[i].key != NULL) { - if (strcasecmp(keywordlist[i].key, key) == 0) - return (keywordlist[i].token); - ++i; - } - return (XLATOR_KW_NOTFOUND); -} - -/* - * line_to_buf(char *dest, const char *src) { - * appends src to dest, dynamically increasing the size of dest. - * replaces the trailing '\' continuation character with a space. - * - * if src is continuation of dest, dest != NULL, and - * the last character in dest before the newline must be a `\' - * if src is not continuation of dest, then dest must be NULL - */ -char * -line_to_buf(char *dest, const char *src) -{ - int slen = strlen(src); - int dlen; - - if (dest == NULL) { - /* We're being called for the first time */ - dest = malloc(sizeof (char) * (slen + 1)); - if (dest == NULL) { - errlog(ERROR | FATAL, - "Error: Unable to allocate memory for dest\n"); - } - (void) strcpy(dest, src); - return (dest); - } - - dlen = strlen(dest); - - dest = realloc(dest, (size_t)(sizeof (char) * (dlen+slen+1))); - if (dest == NULL) { - errlog(ERROR | FATAL, - "Error: Unable to allocate memory for dest\n"); - } - - if (dlen > 1) { - /* - * remove continuation character - * we replace the '\' from the previous line with a space - */ - if (dest[dlen-2] == '\\') { - dest[dlen-2] = ' '; - } - } - - /* join the two strings */ - (void) strcat(dest, src); - - return (dest); -} - -/* - * non_empty(const char *str) - * assumes str is non null - * checks if str is a non empty string - * returns 1 if string contains non whitespace - * returns 0 if string contains only whitespace - */ -int -non_empty(const char *str) -{ - while (*str != '\0') { - if (!isspace(*str)) - return (1); - ++str; - }; - return (0); -} - -/* - * split(const char *line, char *key, char *value); - * splits the line into keyword (key) and value pair - */ -void -split(const char *line, char *key, char *value) -{ - char *p; - - p = (char *)line; - - /* skip leading whitespace */ - while (isspace(*p)&& *p != '\0') - ++p; - - /* copy keyword from line into key */ - while (!isspace(*p) && *p != '\0') - *key++ = *p++; - - *key = '\0'; - - /* skip whitespace */ - while (isspace(*p) && *p != '\0') - p++; - - (void) strcpy(value, p); - -} - -/* - * check4extends(char *filename, char *value, int arch, FILE *fp) - * if no arch keyword is found or there is a MATCHING arch keyword - * returns 1 if value is of the form "data|function name extends" - * -1 for error - * 0 no other keyword after the function name - * else - * return 0 - * - * filename is used only for error reporting - */ -int -check4extends(const char *filename, const char *value, int arch, FILE *fp) -{ - char fun[BUFSIZ]; - char extends[BUFSIZ]; - int n; - - if (arch_match(fp, arch)) { - split(value, fun, extends); - n = strlen(extends); - if (extends[n-1] == '\n') - extends[n-1] = '\0'; - if (strncasecmp("extends", extends, 7) == 0) { - return (1); - } else { - if (*extends != '\0') { - errlog(ERROR, "\"%s\", line %d: Error: " - "Trailing garbage after function name\n", - filename, Curlineno); - return (-1); - } - } - } - return (0); -} - -/* - * remcomment (char *buf) - * replace comments with single whitespace - */ -/* XXX: There is currently no way to escape a comment character */ -void -remcomment(char const *buf) -{ - char *p; - p = strchr(buf, '#'); - if (p) { - *p = ' '; - *(p+1) = '\0'; - } -} - -/* - * arch_strtoi() - * - * input: string - * return: XLATOR_I386 if string == ARCH_I386 - * XLATOR_SPARC if string == ARCH_SPARC - * XLATOR_SPARCV9 if string == ARCH_SPARCV9 - * XLATOR_IA64 if string == ARCH_IA64 - * XLATOR_AMD64 if string == ARCH_AMD64 - * XLATOR_ALLARCH if string == ARCH_ALL - * 0 if outside the known set {i386, sparc, sparcv9, ia64, amd64}. - */ -int -arch_strtoi(const char *arch_str) -{ - if (arch_str != NULL) { - if (strcmp(arch_str, ARCH_I386) == 0) - return (XLATOR_I386); - else if (strcmp(arch_str, ARCH_SPARC) == 0) - return (XLATOR_SPARC); - else if (strcmp(arch_str, ARCH_SPARCV9) == 0) - return (XLATOR_SPARCV9); - else if (strcmp(arch_str, ARCH_IA64) == 0) - return (XLATOR_IA64); - else if (strcmp(arch_str, ARCH_AMD64) == 0) - return (XLATOR_AMD64); - else if (strcmp(arch_str, ARCH_ALL) == 0) - return (XLATOR_ALLARCH); - } else { - errlog(ERROR, "\"%s\", line %d: Error: " - "arch keyword with no value"); - } - return (0); -} - -int -readline(char **buffer, FILE *fp) -{ - int nlines = 0; - int len; - char buf[BUFSIZ]; - - if (fgets(buf, BUFSIZ, fp)) { - nlines++; - /* replace comments with single whitespace */ - remcomment(buf); - - /* get complete line */ - *buffer = line_to_buf(*buffer, buf); /* append buf to buffer */ - len = strlen(buf); - if (len > 1) { - /* handle continuation lines */ - while (buf[len-2] == '\\') { - if (!fgets(buf, BUFSIZ, fp)) { - *buffer = line_to_buf(*buffer, buf); - break; - } - nlines++; - len = strlen(buf); - *buffer = line_to_buf(*buffer, buf); - } - } /* end of 'get complete line' */ - } - return (nlines); -} |