home *** CD-ROM | disk | FTP | other *** search
- From: bob@reed.UUCP (Bob Ankeney)
- Newsgroups: alt.sources
- Subject: PL/M to C converter Part 01/03
- Message-ID: <16303@reed.UUCP>
- Date: 9 Apr 91 17:00:59 GMT
-
-
- #!/bin/sh
- # shar: Shell Archiver (v1.22)
- #
- # This is part 1 of a multipart archive
- # do not concatenate these parts, unpack them in order with /bin/sh
- #
- # Run the following text with /bin/sh to create:
- # README
- # CAVEATS.DOC
- # FILES
- # at_decl.cvt
- # const.c
- # context.c
- # control.c
- # convert.c
- # cvt.h
- # cvt_id.h
- # decl_out.c
- # declare.c
- # defs.h
- # error.c
- # io.c
- # lit.c
- # main.c
- # makefile
- # makefile.ibm
- # mem.c
- # misc.h
- # parse.c
- # struct.h
- # test.c.out
- # test.plm
- # tkn_defs.h
- # tkn_ext.h
- # token.c
- # tokens.h
- # typedefs.c
- # version.c
- #
- if test -r s2_seq_.tmp
- then echo "Must unpack archives in sequence!"
- next=`cat s2_seq_.tmp`; echo "Please unpack part $next next"
- exit 1; fi
- sed 's/^X//' << 'SHAR_EOF' > README &&
- X This is a PL/M to C converter. It will take most PL/M code and do a nice
- Xjob of converting it to C. It tries to be intelligent about leaving formatting
- Xand comments intact. This version supports PL/M-286. It is something I wrote
- Xabout a year ago to convert several meg of source code, and it did a 99.5%
- Xconversion. I was later handed some source code that it crashed on, and I
- Xextended it to support that code too.
- X Please keep in mind that this may well not work for your code. It has
- Xbeen tested only on a few sets of code, each following its own set of coding
- Xstandards. Also, don't expect a lot of support from me, as my interest in
- XPL/M is next to none. I no longer work for the employer for whom I wrote
- Xthis converter, but they have given me permission to own and post the sources.
- XI will, time permitting, collect bug fixes and post patches to the software.
- XPlease mail fixes directly to me, as I may miss any posting of them. If
- Xanyone is interested in taking over maintenance of this code, please let me
- Xknow!
- X The source code compiles under Unix. I've compiled it on a Sun-4, a VAX
- Xrunning Ultrix, and a VAX running Mt. Xinu. At one time I had a version that
- Xran under MSDOS, but I can't guarantee it will now. I've included a makefile
- Xfor use with Turbo-C. You need to define IBMPC to compile it. What it could
- Xreally use is tuning for a large memory model, as in it's present state, it
- Xcan only handle small source files. It could also benefit from a good man
- Xpage.
- X The converter expects source code to be in "proper" format (i.e. proper
- Xuse of EXTERNAL declarations, and following of the Intel PL/M grammar as the
- Xconverter knows it.) It has some moderate error-recovery, but may well dump
- Xcore if it expects one thing and gets another.
- X I've included a garbage file test.plm; typeing "plm2c test.plm" should
- Xresult in a test.c file that is identical to the provided test.c.out.
- X See the file CAVEATS.DOC for compatibility issues.
- X
- X Hope you find it useful!
- X
- X Robert Ankeney
- X April 9, 1991
- X ...!tektronix!bob@reed.bitnet
- X
- X
- SHAR_EOF
- chmod 0644 README || echo "restore of README fails"
- sed 's/^X//' << 'SHAR_EOF' > CAVEATS.DOC &&
- XSome notes about the PL/M to C converter:
- X
- XWith case conversion enabled by the "ifdef" in main.c, all upper case
- Xcharacters in an identifier are converted to lower case, and all lower case
- Xcharacters are converted to upper case except for identifiers declared
- XLITERALLY, in which case the identifier is not case converted.
- X
- XDollar signs used in identifiers are discarded.
- X
- XThe use of the AND, OR and NOT operators are converted to &&, ||, and !
- Xoperators respectively. This should work, but conversion to &, |, and ~
- Xmay be desirable in many cases. There is no clear way to distinguish which
- Xconversion to use, thus the previous conversions were chosen. A #define
- Xin tokens.h allows either convention to be chosen. A more intelligent
- Xexpression parser could do a better job of determining use of these operators.
- X
- XLabels are limited in scope to that defined in C. That is, use of labels is
- Xlimited to the current function. PL/M allows external labels.
- X
- XThe dot operator is treated the same as the @ operator (converted to a &
- Xreference).
- X
- XConstant lists of the form:
- X @('string', 0)
- Xare converted to:
- X "string"
- X
- XConstant lists of the form:
- X @('string')
- Xare converted to:
- X 's', 't', 'r', 'i', 'n', 'g'
- X
- XBYTE strings of the form:
- X 'string'
- Xare converted to:
- X 's', 't', 'r', 'i', 'n', 'g'
- X
- XADDRESSes and SELECTORs are not supported.
- X
- XVariables declared AT in one module and EXTERNAL in another will produce
- Xincorrect results, as the EXTERNAL declared variable will not be treated
- Xas a pointer. For example, in module A:
- X
- X PL/M code: C code:
- X --------------------------------- ----------------------------------
- X DECLARE MEMVAR BYTE AT(8000H); BYTE *memvar = (BYTE *) 0x8000;
- X MEMVAR = 14H; (*memvar) = 0x14;
- X
- XAnd in module B:
- X
- X PL/M code: C code:
- X --------------------------------- ----------------------------------
- X DECLARE MEMVAR BYTE EXTERNAL; BYTE memvar;
- X MEMVAR = 14H; memvar = 0x14;
- X
- XTo avoid this problem, list each AT variable used on a single line in a file
- Xcalled "at_decl.cvt".
- X
- XVariable declarations within a procedure with the PUBLIC attribute *probably*
- Xshould be placed prior to the procedure definition. Currently, the PUBLIC
- Xattribute is ignored.
- X
- XVariable declarations of type POINTER are treated as type void.
- XBASED variables are treated as a pointer to the based variable.
- XFor example, for the following declarations, the associated C code is
- Xgenerated:
- X
- X PL/M code: C code:
- X --------------------------------- ----------------------------------
- X DECLARE I BYTE; BYTE i;
- X DECLARE ITEM_PTR POINTER; void *item_ptr;
- X DECLARE ITEM BASED ITEM_PTR BYTE; BYTE **item = (BYTE **) &item_ptr;
- X ITEM_PTR = @I; item_ptr = &i;
- X ITEM = 77H; (**item) = 0x77;
- X
- X
- XCare should be taken in the use of LITERALLY declared variables. Such
- Xdeclarations are converted to a #define directive. With the cvt.h flag
- XPARSE_LITERALS defined, the converter attempts to parse the contents of
- Xall LITERALLY declared variables as the definition for the #define
- Xdirective. With PARSE_LITERALS undefined, no parsing takes place. Thus,
- Xfor the declaration:
- X DECLARE MAX_COUNT LITERALLY '55H';
- Xthe code generated with PARSE_LITERALS defined is:
- X #define MAX_COUNT 0x55
- Xand the code generated with PARSE_LITERALS undefined is:
- X #define MAX_COUNT 55H
- X
- X
- XControl directives within comments are ignored.
- X
- XThe procedure attribute REENTRANT is ignored. Technically, all PL/M variables
- Xare static and could be declared as such in all but REENTRANT procedures.
- XThis was not done, as it was deemed improbable that any problems would result.
- XThe user should keep this fact in mind though. Especially in cases where the
- XC compiler warns about using a variable before it has been defined.
- X
- XIn most cases, white space (spaces, tabs, returns, line-feeds and comments)
- Xare retained in their appropriate place. In obscure instances, white space
- Xmay be discarded for the sake of simpler code. For example, white space in
- Xsome portions of a DECLARE statement is discarded, since the structure of
- Xa DECLARE statement is drastically converted.
- X
- XArray subscripts and function calls appear to be ambiguous. The converter
- Xkeeps a symbol table of DECLARATIONS to try to correctly distinguish one from
- Xthe other.
- X
- X
- SHAR_EOF
- chmod 0660 CAVEATS.DOC || echo "restore of CAVEATS.DOC fails"
- sed 's/^X//' << 'SHAR_EOF' > FILES &&
- XREADME
- XCAVEATS.DOC
- XFILES
- Xat_decl.cvt
- Xconst.c
- Xcontext.c
- Xcontrol.c
- Xconvert.c
- Xcvt.h
- Xcvt_id.h
- Xdecl_out.c
- Xdeclare.c
- Xdefs.h
- Xerror.c
- Xio.c
- Xlit.c
- Xmain.c
- Xmakefile
- Xmakefile.ibm
- Xmem.c
- Xmisc.h
- Xparse.c
- Xstruct.h
- Xtest.c.out
- Xtest.plm
- Xtkn_defs.h
- Xtkn_ext.h
- Xtoken.c
- Xtokens.h
- Xtypedefs.c
- Xversion.c
- SHAR_EOF
- chmod 0644 FILES || echo "restore of FILES fails"
- sed 's/^X//' << 'SHAR_EOF' > at_decl.cvt &&
- SHAR_EOF
- chmod 0644 at_decl.cvt || echo "restore of at_decl.cvt fails"
- sed 's/^X//' << 'SHAR_EOF' > const.c &&
- X
- X
- Xfoop(i, j)
- Xshort i, j;
- X{
- X}
- X
- Xfloat foo()
- X{
- X}
- X
- X WORD bletch;
- X void *ptr;
- X
- X farp("Hi\014\037\253\036");
- X farp(&foo, &bar, &bletch);
- X bletch = foo + foop(1, 2);
- X bletch = foo + foop;
- X ptr = (void *) &foo;
- X ptr = (void *) &bar;
- X ptr = (void *) &bletch;
- X foo();
- X bar();
- X (*ptr)();
- X (*bletch)();
- X (*ptr)(1, 2);
- X
- SHAR_EOF
- chmod 0660 const.c || echo "restore of const.c fails"
- sed 's/^X//' << 'SHAR_EOF' > context.c &&
- X#include "misc.h"
- X#include "defs.h"
- X#include "cvt.h"
- X#include "struct.h"
- X
- X/*
- X * Pointer to the current context
- X */
- XCONTEXT *context_head;
- X/*
- X * Pointer to all popped contexts
- X */
- XCONTEXT *old_context;
- X
- X/*
- X * Search DECL_MEMBER list for symbol and if found, return TRUE
- X * and pointer to DECL_ID for that symbol.
- X */
- Xfind_member_symbol(symbol, decl_ptr, decl_id)
- XTOKEN *symbol;
- XDECL_MEMBER *decl_ptr;
- XDECL_ID **decl_id;
- X{
- X DECL_ID *var_ptr;
- X
- X for (var_ptr = decl_ptr->name_list; var_ptr;
- X var_ptr = var_ptr->next_var) {
- X if (!strcmp(var_ptr->name->token_name, symbol->token_name)) {
- X *decl_id = var_ptr;
- X return TRUE;
- X }
- X }
- X *decl_id = NULL;
- X return FALSE;
- X}
- X
- X/*
- X * Search DECL_MEMBER list for symbol.
- X * If found, return pointer to DECL_MEMBER containing that symbol
- X * in decl_found, and return TRUE.
- X * If not found, return null pointer in decl_found, and return FALSE.
- X */
- Xfind_list_symbol(symbol, decl_ptr, decl_found, decl_id)
- XTOKEN *symbol;
- XDECL_MEMBER *decl_ptr, **decl_found;
- XDECL_ID **decl_id;
- X{
- X for (*decl_found = decl_ptr; *decl_found;
- X *decl_found = (*decl_found)->next_member) {
- X if (find_member_symbol(symbol, *decl_found, decl_id))
- X return TRUE;
- X }
- X return FALSE;
- X}
- X
- X/*
- X * Search context for symbol.
- X * If found, return pointer to DECL_MEMBER containing that symbol
- X * in decl_found, return DECL_ID for that symbol in decl_id, and
- X * return TRUE.
- X * If not found, return null pointers in decl_found and decl_id,
- X * and return FALSE.
- X */
- Xfind_symbol(symbol, decl_found, decl_id)
- XTOKEN *symbol;
- XDECL_MEMBER **decl_found;
- XDECL_ID **decl_id;
- X{
- X CONTEXT *context_ptr;
- X
- X for (context_ptr = context_head; context_ptr;
- X context_ptr = context_ptr->next_context) {
- X if (find_list_symbol(symbol, context_ptr->decl_head,
- X decl_found, decl_id))
- X return TRUE;
- X }
- X return FALSE;
- X}
- X
- X/*
- X * Add a declaration to current context
- X */
- Xadd_to_context(decl)
- XDECL_MEMBER *decl;
- X{
- X DECL_MEMBER *decl_ptr;
- X
- X /* Find end of declaration list */
- X for (decl_ptr = decl; decl_ptr->next_member; )
- X decl_ptr = decl_ptr->next_member;
- X
- X /* Add current declarations to tail of new list */
- X decl_ptr->next_member = context_head->decl_head;
- X context_head->decl_head = decl;
- X}
- X
- X/*
- X * Add a DECL list to context and NULL the list pointer
- X */
- Xadd_decl_to_context(decl)
- XDECL *decl;
- X{
- X DECL *decl_ptr;
- X
- X /* Find end of declaration list */
- X for (decl_ptr = decl; decl_ptr; decl_ptr = decl_ptr->next_decl) {
- X if (decl_ptr->decl_list)
- X add_to_context(decl_ptr->decl_list);
- X decl_ptr->decl_list = NULL;
- X }
- X}
- X
- X/*
- X * Push a new context of specified type and name
- X */
- Xnew_context(type, name)
- Xint type;
- XTOKEN *name;
- X{
- X CONTEXT *new_context;
- X
- X get_context_ptr(&new_context);
- X new_context->context_type = type;
- X if (name) {
- X get_token_ptr(&new_context->context_name);
- X token_copy(name, new_context->context_name);
- X } else
- X new_context->context_name = NULL;
- X new_context->next_context = context_head;
- X context_head = new_context;
- X}
- X
- X/*
- X * Pop current context and place on old context
- X */
- Xpop_context()
- X{
- X CONTEXT *popped_context;
- X
- X popped_context = context_head;
- X context_head = popped_context->next_context;
- X popped_context->next_context = old_context;
- X old_context = popped_context;
- X}
- X
- X/*
- X * Initializes context pointers
- X */
- Xinit_context()
- X{
- X context_head = NULL;
- X old_context = NULL;
- X}
- X
- SHAR_EOF
- chmod 0660 context.c || echo "restore of context.c fails"
- sed 's/^X//' << 'SHAR_EOF' > control.c &&
- X#include "misc.h"
- X#include "defs.h"
- X#include "cvt.h"
- X#include "struct.h"
- X#include "tokens.h"
- X#include "tkn_ext.h"
- X
- Xextern char *text_buffer;
- Xextern char *text_ptr;
- X
- X/*
- X * Parse a control directive.
- X * Handles: Abbreviation:
- X * $INCLUDE $IC
- X * $SET
- X * $RESET
- X * $IF
- X * $ELSE
- X * $ELSEIF
- X * $ENDIF
- X */
- Xparse_control()
- X{
- X TOKEN ctl_token, token;
- X int token_class;
- X RESERVED_WORD *word_ptr;
- X char include_file[128], *include_ptr;
- X
- X token_class = get_token(&ctl_token);
- X if (token_class != IDENTIFIER) {
- X control_error("Invalid directive");
- X return;
- X }
- X
- X for (word_ptr = &control_directives[0]; word_ptr->token != END_OF_FILE;
- X word_ptr++) {
- X if ((strlen(word_ptr->name) == ctl_token.token_length) &&
- X !strncmp(word_ptr->name, ctl_token.token_start,
- X ctl_token.token_length)) {
- X switch (word_ptr->token) {
- X
- X case C_INCLUDE :
- X token_class = get_token(&token);
- X if (token_class != LEFT_PAREN) {
- X control_error("'(' expected");
- X return;
- X }
- X /* Copy and send file name (up to ')') */
- X include_ptr = include_file;
- X while (*text_ptr != ')') {
- X if ((*text_ptr >= 'A') && (*text_ptr <= 'Z'))
- X /* Convert to lower case */
- X *include_ptr++ = *text_ptr++ + ' ';
- X else
- X *include_ptr++ = *text_ptr++;
- X }
- X *include_ptr++ = '\0';
- X
- X /* Skip ')' */
- X text_ptr++;
- X
- X /* Parse include file */
- X cvt_file(include_file);
- X
- X /* Convert .plm to .c */
- X if (strcmp(include_ptr - 5, "plm")) {
- X (void) strcpy(include_ptr - 5, ".c");
- X include_ptr -= 2;
- X }
- X
- X out_to_start();
- X out_str("#include");
- X out_must_white(&token);
- X out_char('"');
- X out_str(include_file);
- X
- X out_char('"');
- X return;
- X
- X default :
- X control_error("Non-supported directive");
- X return;
- X }
- X }
- X }
- X
- X control_error("Invalid directive");
- X}
- X
- SHAR_EOF
- chmod 0660 control.c || echo "restore of control.c fails"
- sed 's/^X//' << 'SHAR_EOF' > convert.c &&
- X#include <stdio.h>
- X#ifdef IBMPC
- X#include <stdlib.h>
- X#endif
- X#include "misc.h"
- X#include "defs.h"
- X#include "cvt.h"
- X#include "struct.h"
- X#include "tokens.h"
- X
- XBOOLEAN syntax_error;
- X
- Xextern char *text_buffer, *text_ptr;
- Xextern int line_count;
- X
- X/*
- X * Determine statement type and call appropriate parse routine.
- X * Return statement class or, if a reserved word, reserved word token.
- X */
- Xparse_statement(first_token)
- XTOKEN *first_token;
- X{
- X int token_type;
- X
- X /* Flush standard output and standard error */
- X (void) fflush(stdout);
- X (void) fflush(stderr);
- X
- X /* Flag no error yet */
- X syntax_error = FALSE;
- X
- X switch (first_token->token_class) {
- X
- X case RESERVED:
- X token_type = first_token->token_type;
- X
- X switch (token_type) {
- X
- X case DECLARE :
- X parse_declare(first_token);
- X break;
- X
- X case DO :
- X parse_do(first_token);
- X break;
- X
- X case IF :
- X parse_if(first_token);
- X break;
- X
- X case THEN :
- X parse_then();
- X break;
- X
- X case ELSE :
- X parse_else(first_token);
- X break;
- X
- X case GOTO :
- X parse_goto(first_token);
- X break;
- X
- X case GO :
- X parse_go(first_token);
- X break;
- X
- X case CALL :
- X parse_call(first_token);
- X break;
- X
- X case RETURN :
- X parse_return(first_token);
- X break;
- X
- X case END :
- X parse_end(first_token);
- X break;
- X
- X case DISABLE :
- X parse_int_ctl(first_token);
- X break;
- X
- X case ENABLE :
- X parse_int_ctl(first_token);
- X break;
- X
- X case OUTPUT :
- X parse_output(first_token);
- X break;
- X
- X case OUTWORD :
- X parse_outword(first_token);
- X break;
- X
- X case OUTHWORD :
- X parse_outhword(first_token);
- X break;
- X
- X default :
- X parse_error("Illegal reserved word");
- X return ERROR;
- X }
- X
- X return token_type;
- X
- X case IDENTIFIER:
- X parse_identifier(first_token);
- X break;
- X
- X case LABEL:
- X parse_label();
- X break;
- X
- X case END_OF_LINE:
- X parse_eol(first_token);
- X break;
- X
- X case END_OF_FILE:
- X out_white_space(first_token);
- X return END_OF_FILE;
- X
- X default:
- X parse_error("Illegal statement");
- X return ERROR;
- X
- X }
- X
- X return first_token->token_class;
- X}
- X
- Xparse_new_statement()
- X{
- X TOKEN first_token;
- X
- X /* Get first token on line */
- X (void) get_token(&first_token);
- X
- X return parse_statement(&first_token);
- X}
- X
- Xparse_file()
- X{
- X while (parse_new_statement() != END_OF_FILE) ;
- X}
- X
- SHAR_EOF
- chmod 0660 convert.c || echo "restore of convert.c fails"
- sed 's/^X//' << 'SHAR_EOF' > cvt.h &&
- X/*
- X * Parse LITERALLY declared strings
- X */
- X#define PARSE_LITERALS
- X
- X/*
- X * Ignore Invalid control errors
- X */
- X#define IGNORE_CONTROL_ERRORS
- X
- X/*
- X * Convert lower case to upper and upper to lower in identifiers
- X */
- X#define CONVERT_CASE
- X
- X/*
- X * If CONVERT_TYPES defined, use the following type conversions.
- X */
- X#define CONVERT_TYPES
- X
- X/*
- X * Type conversions
- X */
- X#define TYPE_BYTE "BYTE"
- X#define TYPE_WORD "WORD"
- X#define TYPE_DWORD "DWORD"
- X#define TYPE_INTEGER "short"
- X#define TYPE_REAL "float"
- X
- X/*
- X * For initialized DATA, use this prefix.
- X * Probably should be "const" or "static".
- X */
- X#define TYPE_DATA "const"
- X
- X/*
- X * Default POINTER type.
- X */
- X#define TYPE_POINTER "void"
- X
- X/*
- X * Sizes of data types
- X */
- X#define SIZE_BYTE 1
- X#define SIZE_WORD 2
- X#define SIZE_DWORD 4
- X
- X/*
- X * Conversion operators
- X */
- X#define AND_OP "&&"
- X#define OR_OP "||"
- X#define NOT_OP "!"
- X/*
- X#define AND_OP "&"
- X#define OR_OP "|"
- X#define NOT_OP "~"
- X*/
- X/*
- X#define AND_OP "AND"
- X#define OR_OP "OR"
- X#define NOT_OP "NOT"
- X*/
- X
- X/*
- X * Function call equivalent to OUTPUT(port) = expr
- X * Becomes: FUNC_OUTPUT(port, expr)
- X */
- X#define FUNC_OUTPUT "outportb"
- X
- X/*
- X * Function call equivalent to OUTWORD(port) = expr
- X * Becomes: FUNC_OUTWORD(port, expr)
- X */
- X#define FUNC_OUTWORD "outport"
- X
- X/*
- X * Function call equivalent to OUTHWORD(port) = expr
- X * Becomes: FUNC_OUTHWORD(port, expr)
- X */
- X#define FUNC_OUTHWORD "outporth"
- X
- SHAR_EOF
- chmod 0660 cvt.h || echo "restore of cvt.h fails"
- sed 's/^X//' << 'SHAR_EOF' > cvt_id.h &&
- X/*
- X * PL/M Cast function equivalents
- X */
- XCVT_ID cast_functions[] = {
- X "float", TYPE_REAL,
- X "real", TYPE_REAL,
- X "fix", TYPE_INTEGER,
- X "int", TYPE_INTEGER,
- X "signed", TYPE_INTEGER,
- X "integer", TYPE_INTEGER,
- X "unsign", TYPE_WORD,
- X "word", TYPE_WORD,
- X "byte", TYPE_BYTE,
- X "dword", TYPE_DWORD,
- X "pointer", TYPE_POINTER,
- X "", ""
- X};
- X
- X/*
- X * PL/M function equivalents
- X */
- XCVT_ID cvt_functions[] = {
- X "size", "sizeof",
- X "abs", "fabs",
- X "iabs", "abs",
- X "input", "inportb",
- X "inword", "inport",
- X "setinterrupt", "signal",
- X "initrealmathunit", "_fpreset",
- X "", ""
- X};
- X
- X/*
- X * PL/M identifier equivalents
- X */
- XCVT_ID cvt_identifiers[] = {
- X "getrealerror", "_status87()",
- X "", ""
- X};
- X
- SHAR_EOF
- chmod 0660 cvt_id.h || echo "restore of cvt_id.h fails"
- sed 's/^X//' << 'SHAR_EOF' > decl_out.c &&
- X#include "misc.h"
- X#include "defs.h"
- X#include "cvt.h"
- X#include "struct.h"
- X#include "tokens.h"
- X
- Xextern char *text_ptr;
- Xextern int at_decl_count;
- Xextern char at_decl_list[MAX_AT_DECLS][MAX_TOKEN_LENGTH];
- X
- X/*
- X * Output *<name> if use_parens == NULL, else (*<name>).
- X */
- Xout_pointer(name, use_parens)
- XTOKEN *name;
- XBOOLEAN use_parens;
- X{
- X /* Use parentheses? */
- X if (use_parens) {
- X /* Yes - make it (*name) */
- X out_str("(*");
- X out_token_name(name);
- X out_char(')');
- X } else {
- X /* No - make it *name */
- X out_char('*');
- X out_token_name(name);
- X }
- X}
- X
- X/*
- X * Output array bound (if any)
- X */
- Xout_bound(bound)
- XTOKEN *bound;
- X{
- X if (bound) {
- X out_char('[');
- X out_token(bound);
- X out_char(']');
- X }
- X}
- X
- X/*
- X * Output a declaration type.
- X */
- Xout_decl_type(decl_ptr)
- XDECL_MEMBER *decl_ptr;
- X{
- X if (decl_ptr->type->token_type != STRUCTURE) {
- X out_type(decl_ptr->type->token_type);
- X } else {
- X out_struct(decl_ptr->struct_list);
- X }
- X}
- X
- X/*
- X * Output structure contents.
- X */
- Xout_struct(el_ptr)
- XDECL_MEMBER *el_ptr;
- X{
- X DECL_ID *var_ptr;
- X
- X out_str("struct {");
- X
- X while (el_ptr) {
- X /* Use initial white space before type */
- X var_ptr = el_ptr->name_list;
- X if (var_ptr)
- X out_must_white(var_ptr->name);
- X
- X out_decl_type(el_ptr);
- X out_char(' ');
- X
- X while (var_ptr) {
- X out_token_name(var_ptr->name);
- X out_bound(el_ptr->array_bound);
- X var_ptr = var_ptr->next_var;
- X if (var_ptr) {
- X out_char(',');
- X out_must_white(var_ptr->name);
- X }
- X }
- X if ((el_ptr = el_ptr->next_member) != NULL)
- X out_char(';');
- X }
- X out_char('}');
- X}
- X
- X/*
- X * Output C declaration list member.
- X */
- Xout_decl_member(decl_list, decl_token)
- XDECL_MEMBER *decl_list;
- XTOKEN *decl_token;
- X{
- X int i;
- X TOKEN token, tmp_token;
- X int token_class;
- X int name_count;
- X char count_str[8];
- X DECL_ID *var_ptr;
- X char *tmp_white_start, *tmp_white_end;
- X char *tmp_text_ptr;
- X BOOLEAN typedefed, is_at;
- X int string_len, string_size;
- X char *string_ptr;
- X
- X /* Output characters up to CR */
- X out_pre_white(decl_token);
- X
- X if (decl_list->type->token_type == LABEL)
- X /* Ignore label declarations */
- X return;
- X
- X var_ptr = decl_list->name_list;
- X
- X if (decl_list->type->token_type == LITERALLY) {
- X /* Make sure we're at start of new line */
- X out_pre_white(var_ptr->name);
- X out_to_start();
- X
- X /* Convert to a #define */
- X out_str("#define ");
- X out_cvt_name(var_ptr->name);
- X out_char(' ');
- X out_str(decl_list->literal);
- X/*
- X out_str("\n");
- X*/
- X return;
- X }
- X
- X var_ptr->name->white_space_start = decl_token->white_space_start;
- X var_ptr->name->white_space_end = decl_token->white_space_end;
- X
- X /* Swap white space between type and first identifier */
- X /* and eat any new_lines prior to first identifier */
- X tmp_white_start = decl_list->type->white_space_start;
- X tmp_white_end = decl_list->type->white_space_end;
- X
- X while ((tmp_white_start < tmp_white_end) && (*tmp_white_start < ' '))
- X tmp_white_start++;
- X
- X decl_list->type->white_space_start = var_ptr->name->white_space_start;
- X var_ptr->name->white_space_start = tmp_white_start;
- X decl_list->type->white_space_end = var_ptr->name->white_space_end;
- X var_ptr->name->white_space_end = tmp_white_end;
- X
- X out_white_space(decl_list->type);
- X
- X if (decl_list->attributes == EXTERNAL) {
- X out_str("extern ");
- X
- X /* Check if declared AT in another module */
- X for (i = 0; i < at_decl_count; i++)
- X if (!strcmp(var_ptr->name->token_name, at_decl_list[i]))
- X /* Yes - flag as so */
- X var_ptr->is_ext_at = TRUE;
- X } else
- X
- X if (decl_list->initialization == DATA) {
- X out_str(TYPE_DATA);
- X out_char(' ');
- X }
- X
- X
- X is_at = (decl_list->at_ptr != NULL) || var_ptr->is_ext_at;
- X
- X /* Determine if a structure with an AT attribute */
- X typedefed = (decl_list->type->token_type == STRUCTURE) && is_at;
- X
- X /* Output type */
- X /* Is this a structure with an AT attribute? */
- X if (typedefed) {
- X /* Yes - output typedefed structure */
- X out_str("typedef ");
- X out_struct(decl_list->struct_list);
- X out_must_white(var_ptr->name);
- X#ifdef USE_DEFINES
- X out_char('_');
- X#endif
- X out_cvt_name(var_ptr->name);
- X if (decl_list->array_bound)
- X out_bound(decl_list->array_bound);
- X out_str(";\n");
- X out_white_space(decl_token);
- X#ifdef USE_DEFINES
- X out_char('_');
- X#endif
- X out_cvt_name(var_ptr->name);
- X } else
- X out_decl_type(decl_list);
- X
- X /* Walk through name list */
- X name_count = 0;
- X while (var_ptr) {
- X if (is_at) {
- X /* AT (<expression>) -
- X OK... don't panic...
- X we can handle this
- X */
- X/*
- X * Output:
- X * <type> *<ident> = (<type> *) <AT expr> + name_count
- X *
- X * NOTE: BASED variables are not dealt with.
- X */
- X out_must_white(var_ptr->name);
- X /* Is this an array? */
- X if ((decl_list->array_bound) && !typedefed)
- X /* Yes - output ( *<ident> ) */
- X out_char('(');
- X out_char('*');
- X#ifdef USE_DEFINES
- X /* Output case converted name */
- X out_cvt_name(var_ptr->name);
- X#else
- X out_token_name(var_ptr->name);
- X#endif
- X if ((decl_list->array_bound) && !typedefed) {
- X out_char(')');
- X /* Output array bound (if any) */
- X out_bound(decl_list->array_bound);
- X }
- X
- X if (decl_list->attributes != EXTERNAL) {
- X out_str(" = (");
- X /* Is this a structure? */
- X if (decl_list->type->token_type == STRUCTURE) {
- X /* Yes - output structure name prefix */
- X#ifdef USE_DEFINES
- X out_char('_');
- X#endif
- X out_cvt_name(decl_list->name_list->name);
- X } else
- X out_decl_type(decl_list);
- X out_str(" *) ");
- X
- X out_str(decl_list->at_ptr);
- X if (name_count) {
- X (void) sprintf(count_str, " + %d", name_count);
- X out_str(count_str);
- X }
- X }
- X } else {
- X /* Not an AT expression (whew!) */
- X out_must_white(var_ptr->name);
- X
- X /* Is variable based? */
- X if (var_ptr->based_name) {
- X /* Yes - Output **name = */
- X /* (type **) &based_name */
- X if (decl_list->array_bound) {
- X /* Use (**name)[] */
- X out_str("(**");
- X out_token_name(var_ptr->name);
- X out_str(")[]");
- X } else {
- X out_str("**");
- X out_token_name(var_ptr->name);
- X }
- X
- X out_str(" = (");
- X out_decl_type(decl_list);
- X out_str(" **) &");
- X out_token_name(var_ptr->based_name);
- X } else
- X
- X if (decl_list->type->token_type == POINTER) {
- X /* Yes - if based on an array */
- X /* output (*name) else output *name */
- X out_pointer(var_ptr->name,
- X (BOOLEAN) decl_list->array_bound);
- X } else {
- X /* Output variable name */
- X out_token_name(var_ptr->name);
- X
- X /* Output array bound (if any) */
- X out_bound(decl_list->array_bound);
- X }
- X }
- X
- X /* Get next name */
- X if ((var_ptr = var_ptr->next_var) != NULL) {
- X out_char(',');
- X name_count++;
- X }
- X }
- X
- X /* Check for INITIAL or DATA initializers */
- X if (decl_list->initialization != NONE) {
- X out_str(" = ");
- X /* Point back to initializer string */
- X tmp_text_ptr = text_ptr;
- X text_ptr = decl_list->init_ptr;
- X if (decl_list->array_bound) {
- X out_char('{');
- X /* Array - determine if just a single string */
- X switch (decl_list->type->token_type) {
- X
- X case BYTE :
- X string_size = SIZE_BYTE;
- X break;
- X
- X case WORD :
- X string_size = SIZE_WORD;
- X break;
- X
- X case DWORD :
- X string_size = SIZE_DWORD;
- X break;
- X
- X case STRUCTURE :
- X/*
- X * Oh, SH-T!! fake it!
- X */
- X string_size = SIZE_BYTE;
- X break;
- X
- X default :
- X string_size = 0;
- X }
- X
- X if (string_size && (get_token(&token) == STRING) &&
- X (get_token(&tmp_token) == RIGHT_PAREN)) {
- X /* Single string - break up into */
- X /* Pieces of sizeof(<type>) size */
- X string_ptr = token.token_name;
- X string_len = token.token_length;
- X while (string_len) {
- X out_str_const(string_ptr, string_size);
- X if (string_size > string_len)
- X string_size = string_len;
- X string_ptr += string_size;
- X if (string_len -= string_size)
- X out_char(',');
- X }
- X } else {
- X /* Point back to init string */
- X text_ptr = decl_list->init_ptr;
- X do {
- X token_class = parse_expression(&token);
- X if (token_class == COMMA)
- X out_token(&token);
- X } while (token_class == COMMA);
- X }
- X
- X out_char('}');
- X /* Point past init string */
- X text_ptr = token.token_start + token.token_length + 2;
- X token_class = get_token(&token);
- X } else {
- X token_class = parse_expression(&token);
- X }
- X if (token_class != RIGHT_PAREN)
- X parse_error("')' expected");
- X text_ptr = tmp_text_ptr;
- X }
- X
- X out_char(';');
- X
- X#ifdef USE_DEFINES
- X /* Walk through name list and check for BASED variables */
- X var_ptr = decl_list->name_list;
- X while (var_ptr) {
- X /* See if variable is BASED */
- X if (var_ptr->based_name) {
- X /* Make sure we're at start of new line */
- X out_to_start();
- X out_str("#define");
- X out_must_token(var_ptr->based_name);
- X out_white_space(var_ptr->name);
- X out_str("(*");
- X out_token_name(var_ptr->name);
- X out_str(")\n");
- X }
- X
- X /* See if variable is AT */
- X if (is_at) {
- X /* Make sure we're at start of new line */
- X out_to_start();
- X out_str("#define");
- X out_must_token(var_ptr->name);
- X out_white_space(var_ptr->name);
- X out_str("(*");
- X out_cvt_name(var_ptr->name);
- X out_str(")\n");
- X }
- X
- X var_ptr = var_ptr->next_var;
- X }
- X#endif
- X}
- X
- Xout_decl(decl)
- XDECL *decl;
- X{
- X DECL_MEMBER *decl_list;
- X
- X while (decl) {
- X for (decl_list = decl->decl_list; decl_list;
- X decl_list = decl_list->next_member)
- X out_decl_member(decl_list, decl->decl_token);
- X decl = decl->next_decl;
- X }
- X}
- SHAR_EOF
- chmod 0660 decl_out.c || echo "restore of decl_out.c fails"
- sed 's/^X//' << 'SHAR_EOF' > declare.c &&
- X#include "misc.h"
- X#include "defs.h"
- X#include "cvt.h"
- X#include "struct.h"
- X#include "tokens.h"
- X
- Xextern char *text_ptr;
- Xextern char *out_string;
- X
- X/*
- X * Routines to process DECLARE statements.
- X */
- X
- X/*
- X * Skip to closing right parenthesis
- X */
- Xfind_right_paren()
- X{
- X TOKEN token;
- X int token_class;
- X int paren_count;
- X
- X paren_count = 1;
- X do {
- X token_class = get_token(&token);
- X if (token_class == LEFT_PAREN)
- X paren_count++;
- X else
- X if (token_class == RIGHT_PAREN)
- X paren_count--;
- X } while (paren_count);
- X}
- X
- X/*
- X * Copy an element from source to destination
- X */
- Xelement_copy(src, dest)
- XDECL_MEMBER *src, *dest;
- X{
- X /* Don't copy name list */
- X dest->name_list = NULL;
- X /* Don't copy link */
- X dest->next_member = NULL;
- X dest->literal = src->literal;
- X dest->array_bound = src->array_bound;
- X dest->type = src->type;
- X dest->attributes = src->attributes;
- X dest->initialization = src->initialization;
- X dest->at_ptr = src->at_ptr;
- X dest->init_ptr = src->init_ptr;
- X if (src->struct_list)
- X element_copy(src->struct_list, dest->struct_list);
- X}
- X
- X/*
- X * Generate a linked list of variables of the form:
- X * <id> [BASED <id>[.<id>]] or
- X * ( <id> [BASED <id>[.<id>]] [ ,<id> [BASED <id>[.<id>]] ] ... )
- X * Return token following variable list.
- X */
- Xget_var_list(list_ptr, sep_token)
- XDECL_ID **list_ptr;
- XTOKEN *sep_token;
- X{
- X DECL_ID *var_ptr, *last_var;
- X TOKEN *token;
- X int token_class;
- X BOOLEAN multi_list;
- X char *par_white_start, *par_white_end;
- X
- X *list_ptr = NULL;
- X /* Get first token */
- X get_token_ptr(&token);
- X token_class = get_token(token);
- X
- X /* Determine if <var> or list of ( <var> [,<var>] ... ) */
- X if (token_class == LEFT_PAREN) {
- X /* List of ( <var> [,<var>] ... ) */
- X multi_list = TRUE;
- X
- X /* Use white space before '(' for first identifier */
- X par_white_start = token->white_space_start;
- X par_white_end = token->white_space_end;
- X
- X /* Get first identifier */
- X token_class = get_token(token);
- X token->white_space_start = par_white_start;
- X token->white_space_end = par_white_end;
- X } else
- X /* <var> */
- X multi_list = FALSE;
- X
- X /* Process identifier list */
- X last_var = NULL;
- X while (1) {
- X if (token_class != IDENTIFIER) {
- X parse_error("Identifier expected");
- X free_var_list(*list_ptr);
- X free((char *) token);
- X *list_ptr = NULL;
- X return ERROR;
- X }
- X
- X /* Get a variable structure */
- X get_var_ptr(&var_ptr);
- X
- X if (*list_ptr == NULL)
- X /* Point to first variable */
- X *list_ptr = var_ptr;
- X
- X if (last_var)
- X last_var->next_var = var_ptr;
- X last_var = var_ptr;
- X
- X /* Save variable name */
- X var_ptr->name = token;
- X
- X /* Check for BASED */
- X token_class = get_token(sep_token);
- X
- X if ((token_class == RESERVED) &&
- X (sep_token->token_type == BASED)) {
- X /* BASED <id>[ .<id> ] */
- X /* Get based name */
- X get_token_ptr(&token);
- X token_class = get_token(token);
- X if (token_class != IDENTIFIER) {
- X parse_error("Identifier expected");
- X free_var_list(*list_ptr);
- X free((char *) token);
- X *list_ptr = NULL;
- X return ERROR;
- X }
- X token_class = parse_simple_variable(token, sep_token);
- X
- X#ifdef USE_DEFINES
- X /* Swap variable name with based name */
- X var_ptr->based_name = var_ptr->name;
- X var_ptr->name = token;
- X#else
- X var_ptr->based_name = token;
- X#endif
- X }
- X
- X if (!multi_list)
- X return token_class;
- X
- X if (token_class != COMMA)
- X break;
- X
- X /* Get next variable */
- X get_token_ptr(&token);
- X token_class = get_token(token);
- X }
- X
- X if (token_class == RIGHT_PAREN) {
- X /* Get next token */
- X token_class = get_token(sep_token);
- X return token_class;
- X } else {
- X parse_error("')' expected");
- X free_var_list(*list_ptr);
- X *list_ptr = NULL;
- X return ERROR;
- X }
- X}
- X
- X/*
- X * Parse a structure declaration of the form:
- X * STRUCTURE ( <member> [ ,<member> ] ... )
- X * where:
- X * <member> ::= { <id> | ( <id> [ ,<id> ] ... ) } [ ( <numeric> ) ] <type>
- X */
- Xparse_structure(list_ptr)
- XDECL_MEMBER **list_ptr;
- X{
- X DECL_MEMBER *struct_ptr, *last_struct;
- X TOKEN token;
- X int token_class;
- X
- X *list_ptr = NULL;
- X
- X /* Get left paren */
- X token_class = get_token(&token);
- X if (token_class != LEFT_PAREN) {
- X parse_error("'(' expected");
- X return;
- X }
- X
- X last_struct = NULL;
- X do {
- X /* Get a DECL_MEMBER structure */
- X get_element_ptr(&struct_ptr);
- X
- X if (*list_ptr == NULL)
- X /* Point to first structure */
- X *list_ptr = struct_ptr;
- X
- X if (last_struct)
- X last_struct->next_member = struct_ptr;
- X last_struct = struct_ptr;
- X
- X /* Get variable list */
- X token_class = get_var_list(&struct_ptr->name_list, &token);
- X
- X /* Get type and optional array designator */
- X get_token_ptr(&struct_ptr->type);
- X token_class = parse_type(struct_ptr, &token);
- X
- X /* Get seperator */
- X token_class = get_token(&token);
- X } while (token_class == COMMA);
- X
- X if (token_class != RIGHT_PAREN) {
- X parse_error("'(' expected");
- X free_decl_list(*list_ptr);
- X *list_ptr = NULL;
- X return;
- X }
- X}
- X
- X/*
- X * Parse type and optional array designator.
- X * Passed initial token.
- X * Returns RESERVED if appropriate type found, else returns END_OF_LINE.
- X */
- Xparse_type(el_ptr, token)
- XDECL_MEMBER *el_ptr;
- XTOKEN *token;
- X{
- X TOKEN *temp_token;
- X int token_class;
- X
- X token_class = token->token_class;
- X if (token_class == LEFT_PAREN) {
- X /* Array specifier */
- X /* Get numeric or '*' */
- X get_token_ptr(&temp_token);
- X token_class = get_token(temp_token);
- X
- X if ((token_class == NUMERIC) ||
- X ((token_class == OPERATOR) &&
- X (temp_token->token_type == TIMES))) {
- X if (token_class != NUMERIC)
- X /* array(*) specified - ignore '*' */
- X temp_token->token_name[0] = '\0';
- X
- X /* Save array bound token */
- X el_ptr->array_bound = temp_token;
- X } else {
- X parse_error("Illegal array bound");
- X free((char *) temp_token);
- X return ERROR;
- X }
- X
- X /* Get right paren */
- X token_class = get_token(token);
- X if (token_class != RIGHT_PAREN) {
- X parse_error("')' expected");
- X free((char *) temp_token);
- X return ERROR;
- X }
- X
- X /* Get type */
- X token_class = get_token(token);
- X }
- X
- X if ((token_class == RESERVED) && (token->token_type >= BYTE) &&
- X (token->token_type <= STRUCTURE)) {
- X
- X /* Save type token */
- X token_copy(token, el_ptr->type);
- X
- X if (token->token_type == STRUCTURE) {
- X /* Get structure list */
- X parse_structure(&el_ptr->struct_list);
- X }
- X return token_class;
- X } else {
- X parse_error("Illegal type");
- X return ERROR;
- X }
- X}
- X
- X/*
- X * Parse a DECLARE element.
- X * Return token terminating DECLARE element.
- X */
- Xget_element(element, token)
- XDECL_MEMBER **element;
- XTOKEN *token;
- X{
- X DECL_MEMBER *el_ptr;
- X TOKEN temp_token, eof_token;
- X int token_class;
- X char *tmp_text_ptr;
- X char *tmp_out_string;
- X
- X char *get_mem();
- X
- X get_element_ptr(element);
- X
- X /* Point to element */
- X el_ptr = *element;
- X
- X /* Get name list */
- X token_class = get_var_list(&el_ptr->name_list, token);
- X
- X /* Malloc space for type */
- X get_token_ptr(&el_ptr->type);
- X
- X if (token_class == RESERVED)
- X switch (token->token_type) {
- X
- X case LABEL :
- X /* LABEL declaration */
- X token_copy(token, el_ptr->type);
- X
- X /* Check for PUBLIC or EXTERNAL */
- X token_class = get_token(token);
- X if ((token_class == RESERVED) &&
- X ((token->token_type == PUBLIC) ||
- X (token->token_type == EXTERNAL)))
- X /* Indeed, who cares? */
- X token_class = get_token(token);
- X return token_class;
- X
- X case LITERALLY :
- X token_copy(token, el_ptr->type);
- X
- X /* Check for 'string' */
- X if (get_token(token) != STRING) {
- X parse_error("String expected");
- X free_decl_list(el_ptr);
- X return ERROR;
- X }
- X
- X el_ptr->literal = get_mem(MAX_LITERAL_SIZE);
- X#ifdef PARSE_LITERALS
- X /* Parse literal string if only one token in string */
- X tmp_text_ptr = text_ptr;
- X text_ptr = token->token_name;
- X
- X /* Parse token in string */
- X if (get_token(&temp_token) == END_OF_FILE)
- X el_ptr->literal[0] = '\0';
- X else
- X if (get_token(&eof_token) == END_OF_FILE) {
- X /* Single token literal */
- X (void) strcpy(el_ptr->literal, temp_token.token_name);
- X /* Save parsed token */
- X get_token_ptr(&el_ptr->literal_token);
- X token_copy(&temp_token, el_ptr->literal_token);
- X } else
- X (void) strcpy(el_ptr->literal, token->token_name);
- X
- X text_ptr = tmp_text_ptr;
- X#else
- X /* Put string in literal */
- X (void) strcpy(el_ptr->literal, token->token_name);
- X#endif
- X
- X /* Return following token */
- X token_class = get_token(token);
- X return token_class;
- X }
- X
- X if (parse_type(el_ptr, token) != RESERVED) {
- X /* Error occurred */
- X free_decl_list(el_ptr);
- X return END_OF_LINE;
- X }
- X
- X /* Process attribute information (if any) */
- X /* Check for EXTERNAL [ DATA ] */
- X token_class = get_token(token);
- X if (token_class != RESERVED)
- X return token_class;
- X
- X if (token->token_type == EXTERNAL) {
- X el_ptr->attributes = EXTERNAL;
- X
- X /* Check for DATA attribute */
- X token_class = get_token(token);
- X if (token_class == RESERVED) {
- X if (token->token_type == DATA) {
- X/*
- X * Ignore attribute
- X * el_ptr->initialization = DATA;
- X */
- X token_class = get_token(token);
- X } else {
- X parse_error("Illegal attribute");
- X free_decl_list(el_ptr);
- X return ERROR;
- X }
- X }
- X
- X return token_class;
- X } else
- X
- X /* Check for PUBLIC */
- X if (token->token_type == PUBLIC) {
- X el_ptr->attributes = PUBLIC;
- X token_class = get_token(token);
- X }
- X
- X if (token_class != RESERVED)
- X return token_class;
- X
- X /* Check for AT ( <expr> ) */
- X if (token->token_type == AT) {
- X /* Check for '(' */
- X token_class = get_token(token);
- X
- X if (token_class != LEFT_PAREN) {
- X parse_error("'(' expected");
- X free_decl_list(el_ptr);
- X return ERROR;
- X }
- X
- X /* Generate a string for the AT expression */
- X el_ptr->at_ptr = get_mem(MAX_AT_EXPR_SIZE);
- X el_ptr->at_ptr[0] = '\0';
- X tmp_out_string = out_string;
- X out_string = el_ptr->at_ptr;
- X
- X /* Parse the expression into at_ptr */
- X token_class = parse_expression(token);
- X if (token_class != RIGHT_PAREN) {
- X parse_error("')' expected");
- X free_decl_list(el_ptr);
- X return ERROR;
- X }
- X out_string = tmp_out_string;
- X token_class = get_token(token);
- X }
- X
- X if (token_class != RESERVED)
- X return token_class;
- X
- X /* Check for INITIAL or DATA ( <expr> ) */
- X if ((token->token_type == INITIAL) ||
- X (token->token_type == DATA)) {
- X
- X el_ptr->initialization = token->token_type;
- X
- X /* Check for '(' */
- X token_class = get_token(token);
- X
- X if (token_class != LEFT_PAREN) {
- X parse_error("'(' expected");
- X free_decl_list(el_ptr);
- X return ERROR;
- X }
- X
- X el_ptr->init_ptr = text_ptr;
- X /* Skip to ')' */
- X find_right_paren();
- X token_class = get_token(token);
- X }
- X return token_class;
- X}
- X
- X/*
- X * Parse a DECLARE list.
- X * Passed a pointer to a DECL, returns with DECL filled.
- X */
- Xget_decl_list(decl)
- XDECL *decl;
- X{
- X DECL_MEMBER *el_ptr, *decl_ptr;
- X TOKEN token;
- X int token_class;
- X
- X decl->decl_list = NULL;
- X decl->next_decl = NULL;
- X decl_ptr = NULL;
- X
- X do {
- X /* Get a declaration element */
- X token_class = get_element(&el_ptr, &token);
- X
- X if (decl->decl_list == NULL)
- X decl->decl_list = el_ptr;
- X
- X /* Link previous element */
- X if (decl_ptr)
- X decl_ptr->next_member = el_ptr;
- X decl_ptr = el_ptr;
- X } while (token_class == COMMA);
- X}
- X
- X/*
- X * Parse a DECLARE statement.
- X */
- Xparse_declare(first_token)
- XTOKEN *first_token;
- X{
- X DECL decl;
- X
- X decl.decl_token = first_token;
- X get_decl_list(&decl);
- X out_decl(&decl);
- X add_to_context(decl.decl_list);
- X}
- SHAR_EOF
- chmod 0660 declare.c || echo "restore of declare.c fails"
- sed 's/^X//' << 'SHAR_EOF' > defs.h &&
- X/*
- X * Maximum number of characters in a token
- X */
- X#define MAX_TOKEN_LENGTH 512
- X
- X/*
- X * Maximum number of characters in an individual DO CASE statement
- X */
- X#define MAX_CASE_STATEMENT_SIZE 10240
- X
- X/*
- X * Maximum number of characters in an AT expression
- X */
- X#define MAX_AT_EXPR_SIZE 128
- X
- X/*
- X * Maximum number of characters in a literal string
- X */
- X#define MAX_LITERAL_SIZE 512
- X
- X/*
- X * Maximum number of identifier names in at_decl.cvt
- X */
- X#define MAX_AT_DECLS 64
- SHAR_EOF
- chmod 0660 defs.h || echo "restore of defs.h fails"
- sed 's/^X//' << 'SHAR_EOF' > error.c &&
- X#include <stdio.h>
- X#include <string.h>
- X#include "misc.h"
- X#include "defs.h"
- X#include "cvt.h"
- X#include "struct.h"
- X#include "tokens.h"
- X#include "tkn_ext.h"
- X
- Xextern BOOLEAN syntax_error;
- X
- Xextern char *text_ptr;
- Xextern int line_count;
- Xextern char *line_ptr;
- Xextern char current_file_name[];
- X
- X/*
- X * parse_mesg() - Print given message, message type, and current
- X * line number. Skip to error_eol.
- X */
- Xparse_mesg(error_string, error_type, error_eol)
- Xchar *error_string, *error_type;
- Xchar error_eol;
- X{
- X char *err_ptr;
- X int i, offset;
- X TOKEN token;
- X
- X syntax_error = TRUE;
- X
- X offset = text_ptr - line_ptr - 1;
- X
- X /* Find end of line */
- X for (err_ptr = line_ptr; (*err_ptr != '\0') &&
- X (*err_ptr != LF); err_ptr++) ;
- X
- X if (*error_string) {
- X (void) fprintf(stderr, "\n%s - Parse %s: %s.\nOccurred at line %d near:\n",
- X current_file_name, error_type, error_string, line_count);
- X
- X /* Print offending line */
- X (void) fwrite(line_ptr, err_ptr - line_ptr + 1, 1, stderr);
- X
- X for (i = 0; i < offset; i++)
- X if (line_ptr[i] < ' ')
- X (void) fputc(line_ptr[i], stderr);
- X else
- X (void) fputc(' ', stderr);
- X (void) fputc('^', stderr);
- X
- X if (*err_ptr == '\0')
- X (void) fputc(LF, stderr);
- X }
- X
- X if (*err_ptr != '\0')
- X err_ptr++;
- X
- X /* Skip to end-of-line */
- X if (error_eol == '\0')
- X return;
- X else
- X
- X if (error_eol == LF) {
- X text_ptr = err_ptr;
- X line_ptr = err_ptr;
- X line_count++;
- X } else {
- X
- X if (*(text_ptr - 1) != ';') {
- X do {
- X i = get_token(&token);
- X } while ((i != END_OF_FILE) && (i != END_OF_LINE));
- X }
- X
- X /* Point at end of line */
- X text_ptr--;
- X }
- X}
- X
- X/*
- X * parse_error() - Print given error message and current line number.
- X * Called when an unrecognised or unprocessable token
- X * appears.
- X */
- Xparse_error(error_string)
- Xchar *error_string;
- X{
- X if (syntax_error)
- X /* Already had an error on this line */
- X return;
- X
- X parse_mesg(error_string, "error", END_OF_LINE);
- X}
- X
- X/*
- X * Do a parse_error(), but move to END_OF_LINE, not ';'
- X */
- Xcontrol_error(error_string)
- Xchar *error_string;
- X{
- X#ifdef IGNORE_CONTROL_ERRORS
- X parse_mesg("", "", LF);
- X#else
- X parse_mesg(error_string, "error", LF);
- X#endif
- X}
- X
- X/*
- X * parse_warning - Generate a warning message
- X */
- Xparse_warning(warning_string)
- Xchar *warning_string;
- X{
- X parse_mesg(warning_string, "warning", '\0');
- X}
- X
- SHAR_EOF
- chmod 0660 error.c || echo "restore of error.c fails"
- sed 's/^X//' << 'SHAR_EOF' > io.c &&
- X#include <stdio.h>
- X#ifdef IBMPC
- X#include <stdlib.h>
- X#endif
- X#include "misc.h"
- X#include "defs.h"
- X#include "cvt.h"
- X#include "struct.h"
- X#include "tokens.h"
- X
- Xchar *out_string;
- Xchar last_out_ch;
- X
- Xchar *str_shifts[] = { "0", "8", "16", "24" };
- X
- Xextern char *text_buffer, *text_ptr;
- Xextern int line_count;
- Xextern int file_depth;
- Xextern FILE *ofd;
- X
- Xextern BOOLEAN parsing_literal;
- Xextern TOKEN literal_token;
- X
- X/*
- X * Output data of specified length.
- X * If out_string is not NULL, append string to out_string.
- X * Otherwise write string to stdout.
- X */
- Xout_data(string, length)
- Xchar *string;
- Xint length;
- X{
- X if (length) {
- X if (out_string)
- X (void) strncat(out_string, string, length);
- X else
- X if (file_depth == 1)
- X#ifdef DEBUG
- X (void) fwrite(string, length, 1, stdout);
- X#else
- X (void) fwrite(string, length, 1, ofd);
- X#endif
- X else
- X return;
- X
- X /* Save last character output */
- X last_out_ch = *(string + length - 1);
- X }
- X}
- X
- X/*
- X * Print white space
- X */
- Xout_white_space(token)
- XTOKEN *token;
- X{
- X int length;
- X
- X /* Compute length of white space */
- X length = token->white_space_end - token->white_space_start;
- X
- X if (length)
- X out_data(token->white_space_start, length);
- X}
- X
- X/*
- X * Print white space, if any. If start of white space string is not
- X * white, prefix with a space.
- X */
- Xout_must_white(token)
- XTOKEN *token;
- X{
- X if (!is_white(*(token->white_space_start)))
- X out_char(' ');
- X out_white_space(token);
- SHAR_EOF
- echo "End of part 1, continue with part 2"
- echo "2" > s2_seq_.tmp
- exit 0
-