summaryrefslogtreecommitdiff
path: root/usr/src/cmd/abi/spectrans/parser/frontend.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/abi/spectrans/parser/frontend.c')
-rw-r--r--usr/src/cmd/abi/spectrans/parser/frontend.c569
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);
-}