bob@reed.UUCP (Bob Ankeney) (04/10/91)
#!/bin/sh # this is part 2 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # file io.c continued # CurArch=2 if test ! -r s2_seq_.tmp then echo "Please unpack part 1 first!" exit 1; fi ( read Scheck if test "$Scheck" != $CurArch then echo "Please unpack part $Scheck next!" exit 1; else exit 0; fi ) < s2_seq_.tmp || exit 1 sed 's/^X//' << 'SHAR_EOF' >> io.c X} X X/* X * Print all white space up first new-line (if any). X * Move white_space_start to point past first new-line. X */ Xout_pre_line(token) XTOKEN *token; X{ X while ((token->white_space_start < token->white_space_end) && X (*token->white_space_start != '\n')) { X out_char(*token->white_space_start); X token->white_space_start++; X } X} X X/* X * Print all white space up to but not including last new-line. X * Move white_space_start to point to last new-line. X */ Xout_pre_white(token) XTOKEN *token; X{ X char *ptr; X int length; X X for (ptr = token->white_space_end; X (ptr > token->white_space_start) && (*(ptr - 1) != '\n') ; ) X ptr--; X X if (ptr == token->white_space_start) X return; X X /* Compute length of white space */ X length = ptr - token->white_space_start - 1; X X if (length) X out_data(token->white_space_start, length); X X token->white_space_start = ptr - 1; X} X X/* X * Output token name X */ Xout_token_name(token) XTOKEN *token; X{ X if (is_a_type(token)) X out_type(token->token_type); X else X out_data(token->token_name, strlen(token->token_name)); X} X X/* X * Output white space and token name X */ Xout_token(token) XTOKEN *token; X{ X out_white_space(token); X out_token_name(token); X} X X/* X * Output guaranteed white space and token name X */ Xout_must_token(token) XTOKEN *token; X{ X out_must_white(token); X out_token_name(token); X} X X/* X * Output case converted token name X */ Xout_cvt_name(token) XTOKEN *token; X{ X char *ptr; X X for (ptr = token->token_name; *ptr; ptr++) { X if (is_a_lc_char(*ptr)) X out_char(*ptr - 32); X else X if (is_a_uc_char(*ptr)) X out_char(*ptr + 32); X else X out_char(*ptr); X } X} X X/* X * Output string X */ Xout_str(string) Xchar *string; X{ X out_data(string, strlen(string)); X} X X/* X * Output character X */ Xout_char(ch) Xchar ch; X{ X out_data(&ch, 1); X} X X/* X * Output new-line if not at start of line X */ Xout_to_start() X{ X if (last_out_ch != LF) X out_char(LF); X} X X/* X * Output type X */ Xout_type(type) Xint type; X{ X switch (type) { X X case BYTE : X#ifdef CONVERT_TYPES X out_str(TYPE_BYTE); X#else X out_str("BYTE"); X#endif X break; X X case WORD : X#ifdef CONVERT_TYPES X out_str(TYPE_WORD); X#else X out_str("WORD"); X#endif X break; X X case DWORD : X#ifdef CONVERT_TYPES X out_str(TYPE_DWORD); X#else X out_str("DWORD"); X#endif X break; X X case INTEGER : X#ifdef CONVERT_TYPES X out_str(TYPE_INTEGER); X#else X out_str("INTEGER"); X#endif X break; X X case REAL : X#ifdef CONVERT_TYPES X out_str(TYPE_REAL); X#else X out_str("REAL"); X#endif X break; X X case POINTER : X out_str(TYPE_POINTER); X break; X X default : X parse_error("Unknown type"); X } X} X X/* X * Initialize variables for I/O. X */ Xout_init() X{ X out_string = NULL; X last_out_ch = '\0'; X parsing_literal = FALSE; X} X X/* X * Output string constant of form 'WXYZ' in form: X * 'W' << 24 | 'X' << 16 | 'Y' << 8 | Z X * where len specifies the number of bytes in the string to output. X */ Xout_str_const(str_ptr, len) Xchar *str_ptr; Xint len; X{ X while (len-- && *str_ptr) { X out_char('\''); X if (*str_ptr == '\'') X out_char('\\'); X out_char(*str_ptr++); X out_char('\''); X X if (len) { X out_str(" << "); X out_str(str_shifts[len]); X if (*str_ptr) X out_str(" | "); X } X } X} X X/* X * Convert NUMERIC constant to octal constant X */ Xcvt_octal(token, octal_string) XTOKEN *token; Xchar octal_string[]; X{ X int octal; X char ch, *ptr; X X octal = 0; X octal_string[0] = '\\'; X octal_string[4] = '\0'; X X ch = *(token->token_start + token->token_length - 1); X X /* Determine base of numeric */ X if (ch == 'H') { X /* Hex */ X for (ptr = token->token_name + 2; *ptr; ptr++) { X octal *= 16; X if ((*ptr >= '0') && (*ptr <= '9')) X octal += *ptr - '0'; X else X if ((*ptr >= 'A') && (*ptr <= 'Z')) X octal += *ptr - 'A' + 10; X else X if ((*ptr >= 'a') && (*ptr <= 'z')) X octal += *ptr - 'a' + 10; X else { X parse_error("Illegal hex character"); X return; X } X } X } else X X if ((ch == 'O') || (ch == 'Q')) { X /* Octal constant */ X for (ptr = token->token_name + 1; *ptr; ptr++) { X octal *= 8; X if ((*ptr >= '0') && (*ptr <= '7')) X octal += *ptr - '0'; X else { X parse_error("Illegal decimal character"); X return; X } X } X } else { X X /* Decimal constant */ X for (ptr = token->token_name + 1; *ptr; ptr++) { X octal *= 10; X if ((*ptr >= '0') && (*ptr <= '9')) X octal += *ptr - '0'; X else { X parse_error("Illegal decimal character"); X return; X } X } X } X X X /* Generate octal constant */ X octal_string[1] = ((octal >> 6) & 3) + '0'; X octal_string[2] = ((octal >> 3) & 7) + '0'; X octal_string[3] = (octal & 7) + '0'; X} SHAR_EOF chmod 0660 io.c || echo "restore of io.c fails" sed 's/^X//' << 'SHAR_EOF' > lit.c && X /********************************************************************* X ********************************************************************* X ** ** X ** ** X ** LITERALS ** X ** ** X ** ** X ** Revision History: SCO #23 (12/11/84) ** X ** SCO #31 (02/12/86) {SCO31.DOC} ** X ** SCO #33 (06/03/86) {SCO33.DOC} ** X ** SCO #34 (10/28/86) {SCO34.DOC} ** X ** SCO #36 (07/16/86) {SCO36.DOC} ** X ** SCO #48 (03/21/87) {SCO48.DOC} ** X ** ** X ********************************************************************* X *********************************************************************/ X X X X X X#define POWER_FAIL_SENSE_LATCH 0x0080 X#define INTERRUPT_CONTROLLER_PORT_1 0x00C0 X#define INTERRUPT_CONTROLLER_PORT_2 0x00C2 X#define INSTRUCTION_WORD_1 0x13 X#define INSTRUCTION_WORD_2 0x20 X#define INSTRUCTION_WORD_3 0x01 X#define END_OF_PARITY_INTERRUPT 0x60 X#define END_OF_EXCEPTION_INTERRUPT 0x61 X#define END_OF_REFRESH_INTERRUPT 0x62 X#define END_OF_CYCLE_INTERRUPT 0x63 X#define END_OF_SHORT_INTERRUPT 0x67 X#define INTERRUPT_CONTROLLER_MASK_0 0x0F0 X#define INTERRUPT_CONTROLLER_MASK_1 0x0FC X#define INTERRUPT_CONTROLLER_MASK_2 0x0F8 X#define INTERRUPT_CONTROLLER_MASK_3 0x0F4 X#define INTERVAL_TIMER_PORT_1 0x0D2 X#define INTERVAL_TIMER_PORT_2 0x0D6 X#define CONTROL_WORD 0x74 X#define DATA_WORD_1 0x12 X#define DATA_WORD_2 0x7A X#define CONTROL_WORD_87 0x033C X#define DPM_CONTROL_WORD_87 0x0F3C X#define BIT_CONTROL_WORD_87 0x0F3C X#define INTERFACE_1_START_CODE 0x01 X#define INTERFACE_2_START_CODE 0x01 X#define HCP_NORMAL 0x00 X#define HCP_TEST_MODE 0x01 X#define HCP_ADVANCE 0x02 X#define HCP_RESET 0x03 X#define HCP_ALTITUDE_HOLD_RESET 0x04 X#define HCP_FAIL 0x07 X X#define IS = X#define VALID 0x55 X#define NO_COMPUTED_DATA 0x66 X#define FUNCTIONAL_TEST 0x99 X#define TEST_MODE 0x0AA /*{SCO36.DOC}*/ X#define FLIGHT_MODE 0x55 /*{SCO36.DOC}*/ X#define POSITIVE_BIAS 0 /*{SCO31.DOC}*/ X#define NEGATIVE_BIAS 1 /*{SCO31.DOC}*/ X#define RESET 0x0AA X#define PASS 0x55 X#define ON 0x55 X#define TO_VOR 0x55 X#define FROM_VOR 0x99 X#define ILS 0x55 /*{SCO48.DOC}*/ X#define VOR 0x0AA /*{SCO48.DOC}*/ X#define INVALID 0x0AA X#define OFF 0x0AA X#define PUSHED 0x55 X#define SET 0x55 X#define FAIL 0x0AA X#define FAILED 0x0FF X#define VMC 4 X#define IMC 5 X#define CRZ 6 X#define TOGA 7 X#define BLANK 10 X#define NEGATIVE_SIGN 11 X X#define ERROR_DISPLAY 0x5554 X#define PFM_KEY_COUNTER 0x5555 X#define PFM_TIMER 0x5556 X#define COMPUTER_FAULT 0x5557 X#define KEY1 5 X#define KEY2 4 X#define KEY3 3 X#define KEY4 2 X#define KEY5 1 X#define KEY6 0 X#define DISPLAY_GENERATOR_PORT 0x0C000 X#define DISPLAY_GENERATOR_HALT_CODE 3 X#define DISPLAY_GENERATOR_START_CODE 4 X#define DISPLAY_HALT_ENABLE_CODE 0 X#define DG_HALT 0x0005 X#define LOAD_ROTATION_ANGLE 0x0007 X#define LOAD_PRESENT_POSITION 0x0008 X#define DRAW_VECTOR 0x0009 X#define LOAD_BORDERS 0x000D X#define ZERO_DEGREE_ANGLE 0 X#define NINETY_DEGREE_ANGLE 0x4000 X#define NEG_NINETY_DEGREE_ANGLE 0x0C000 X#define ONE_EIGHTY_DEGREE_ANGLE 0x8000 X#define FIRST_HALF_OF_BUFFER 0 X#define SECOND_HALF_OF_BUFFER 750 X#define WINDOW_COMPARATOR_FAIL 0 X#define WINDOW_COMPARATOR_PASS 7 X#define TWENTY_CYCLES 20 X#define FORTY_CYCLES 40 X X#define IOS1_CODE_CHECKSUM_ERROR 0x11 /*{SCO31.DOC}*/ X#define IOS1_RAM_ERROR 0x12 /*{SCO31.DOC}*/ X#define IOS1_80186_ERROR 0x13 /*{SCO31.DOC}*/ X#define IOS1_8087_ERROR 0x14 /*{SCO31.DOC}*/ X#define IOS1_CONVERTOR_ERROR 0x15 /*{SCO31.DOC}*/ X#define IOS1_HUD_POWER_SUPPLY_ERROR 0x16 /*{SCO31.DOC}*/ X#define IOS2_CODE_CHECKSUM_ERROR 0x21 /*{SCO31.DOC}*/ X#define IOS2_RAM_ERROR 0x22 /*{SCO31.DOC}*/ X#define IOS2_80186_ERROR 0x23 /*{SCO31.DOC}*/ X#define IOS2_8087_ERROR 0x24 /*{SCO31.DOC}*/ X#define IOS2_CONVERTOR_ERROR 0x25 /*{SCO31.DOC}*/ X#define CLP_CODE_CHECKSUM_ERROR 0x31 /*{SCO31.DOC}*/ X#define CLP_RAM_ERROR 0x32 /*{SCO31.DOC}*/ X#define CLP_8086_ERROR 0x33 /*{SCO31.DOC}*/ X#define CLP_8087_ERROR 0x34 /*{SCO31.DOC}*/ X#define SM_CODE_CHECKSUM_ERROR 0x41 /*{SCO31.DOC}*/ X#define SM_RAM_ERROR 0x42 /*{SCO31.DOC}*/ X#define SM_8086_ERROR 0x43 /*{SCO31.DOC}*/ X#define SM_8087_ERROR 0x44 /*{SCO31.DOC}*/ X#define SYSTEM_MONITOR_INACTIVE 0x45 /*{SCO31.DOC}*/ X#define DISPLAY_GENERATOR_ERROR 0x51 /*{SCO31.DOC}*/ X#define SYMBOL_MISPOSITIONED_1 0x52 /*{SCO31.DOC}*/ X#define OHU_VIDEO_FAIL 0x63 /*{SCO31.DOC}*/ X#define OHU_HVPS_FAIL 0x64 /*{SCO31.DOC}*/ X#define OHU_95_OR_30_VOLT_SUPPLY_FAIL 0x65 /*{SCO31.DOC}*/ X#define SYMBOL_MISPOSITIONED_2 0x71 /*{SCO31.DOC}*/ X#define WINDOW_COMPARATOR_ERROR 0x77 /*{SCO31.DOC}*/ X#define DEU_VERTICAL_DEFLECTION_FAIL 0x7A /*{SCO31.DOC}*/ X#define DEU_HORIZONTAL_DEFLECTION_FAIL 0x7B /*{SCO31.DOC}*/ X#define DEU_DC_SUPPLY_FAIL 0x7C /*{SCO31.DOC}*/ X#define DEU_BOOST_SUPPLY_FAIL 0x7D /*{SCO31.DOC}*/ X#define DEU_DEFLECTION_SUPPLY_FAIL 0x7E /*{SCO31.DOC}*/ X#define TEST_ERROR_DISPLAY 0x88 X#define DISPLAY_GENERATOR_TEST 0x89 X#define HCP_FAILURE 0x91 /*{SCO31.DOC}*/ X#define RSU_FAILURE 0x0A1 /*{SCO34.DOC}*/ X#define COMBINER_NOT_LOCKED 0x0B1 /*{SCO33.DOC}*/ X#define EIGHTH_SECOND 3 X#define ONE_SIXTH_SECOND 3 X#define QUARTER_SECOND 5 X#define ONE_THIRD_SECOND 6 X#define HALF_SECOND 10 X#define ONE_SECOND 20 X#define ONE_POINT_FIVE_SECONDS 30 X#define TWO_SECONDS 40 X#define FIVE_SECONDS 100 X X#define HALF_PI 1.57079633F X#define PI 3.14159265F X#define TWO_PI 6.28318531F X#define TEN_KNOTS 16.9F X#define TEN_DEGREES 0.1745F X#define FIFTEEN_DEGREES 0.2618F X#define MAXIMUM_NUMBER 99999.9F X X#define FOREVER while (1) X SHAR_EOF chmod 0660 lit.c || echo "restore of lit.c fails" sed 's/^X//' << 'SHAR_EOF' > main.c && X#include <stdio.h> X#ifdef IBMPC X#include <stdlib.h> X#include <sys\stat.h> X#else X#include <sys/types.h> X#include <sys/stat.h> X#endif X#include <fcntl.h> X#include "misc.h" X#include "defs.h" X#include "cvt.h" X#include "struct.h" X#include "tokens.h" X#include "tkn_defs.h" X Xchar *text_buffer, *text_ptr; Xint line_count; Xchar *line_ptr; Xchar current_file_name[128]; Xchar out_file_name[128]; Xint at_decl_count; Xchar at_decl_list[MAX_AT_DECLS][MAX_TOKEN_LENGTH]; XFILE *ofd; X Xint file_depth; X XFILE *fopen(); X X/* X * Get list of AT declaration variables for EXTERNAL declaration checks X */ Xget_at_decl() X{ X int i, fd; X char ch; X X at_decl_count = 0; X if ((fd = open("at_decl.cvt", O_RDONLY)) == -1) X /* Not found */ X return; X X while (read(fd, &ch, 1) == 1) { X i = 0; X if (!is_a_char(ch)) { X fprintf(stderr, "Illegal identifier in line %d at_decl.cvt\n", X at_decl_count + 1); X exit(1); X } X do { X#ifdef CONVERT_CASE X if (is_a_uc_char(ch)) X /* Convert to lower case */ X ch += 32; X else X if (is_a_lc_char(ch)) X /* Convert to upper case */ X ch -= 32; X#endif X at_decl_list[at_decl_count][i++] = ch; X if (read(fd, &ch, 1) != 1) { X fprintf(stderr, "Unexpected EOF in at_decl.cvt\n"); X exit(1); X } X } while ((ch != '\n') && (ch != ' ')); X X at_decl_list[at_decl_count++][i] = '\0'; X } X} X X/* X * Open specified file, init options, and parse. X */ Xcvt_file(file_name) Xchar *file_name; X{ X int fd, nr; X struct stat file_stat; X TOKEN token, fname_token, token_module, token_do; X int token_class; X char *tmp_text_buffer, *tmp_text_ptr, *tmp_line_ptr; X char *tmp_ptr; X int tmp_line_count; X char tmp_file_name[128]; X X char *get_mem(); X X /* Is this the first file? */ X if (file_depth) { X /* No - save old text pointers */ X tmp_text_buffer = text_buffer; X tmp_text_ptr = text_ptr; X tmp_line_ptr = line_ptr; X tmp_line_count = line_count; X (void) strcpy(tmp_file_name, current_file_name); X } X X /* Save file name */ X (void) strcpy(current_file_name, file_name); X X /* Open file */ X if ((fd = open(file_name, O_RDONLY)) == -1) { X (void) fprintf(stderr, "Cannot open input file %s", file_name); X perror(""); X exit(1); X } X X /* Get length */ X if (fstat(fd, &file_stat)) { X perror("Cannot stat input file"); X exit(1); X } X X /* Allocate that much RAM */ X text_buffer = get_mem((unsigned int) file_stat.st_size + 1); X X /* Read file */ X if ((nr = read(fd, text_buffer, (int) file_stat.st_size)) == -1) { X perror("Cannot read input file"); X exit(1); X } X X /* Insert End-of-file Mark */ X text_buffer[nr] = '\0'; X (void) close(fd); X X /* Init pointers */ X text_ptr = text_buffer; X line_ptr = text_ptr; X line_count = 1; X X /* Init I/O */ X out_init(); X X /* Start with initial context using file name */ X (void) strcpy(fname_token.token_name, file_name); X fname_token.token_class = IDENTIFIER; X new_context(MODULE, &fname_token); X X /* Is this the first file? */ X if (file_depth++ == 0) { X /* Yes - open output file */ X if ((ofd = fopen(out_file_name, "w")) == NULL) { X (void) fprintf(stderr, "Cannot create output file %s", X out_file_name); X exit(1); X } X X /* Check for module name */ X token_class = get_token(&token_module); X out_pre_white(&token_module); X tmp_ptr = token_module.token_start; X if ((token_class == IDENTIFIER) && X /* Maybe got module name - Check for : */ X (get_token(&token) == LABEL) && X /* Check for DO; */ X ((get_token(&token_do) == RESERVED) && X (token_do.token_type == DO)) && X (get_token(&token) == END_OF_LINE)) { X X /* Got module header */ X out_pre_white(&token_do); X X /* Parse to END [<module name>] */ X parse_till_end(&token); X out_white_space(&token); X X token_class = get_token(&token); X if (token_class == IDENTIFIER) { X out_pre_white(&token); X token_class = get_token(&token); X } X X /* Should be at end of line */ X if (token_class != END_OF_LINE) { X parse_error("';' expected"); X } X X /* Should be at end of file */ X if (get_token(&token) != END_OF_FILE) { X parse_error("End of file expected"); X } X out_white_space(&token); X } else { X out_pre_white(&token_do); X parse_warning("Module name expected"); X text_ptr = tmp_ptr; X parse_file(); X } X } else X parse_file(); X X free(text_buffer); X X /* Was this the first file? */ X if (--file_depth) { X /* No - restore old text pointers */ X text_buffer = tmp_text_buffer; X text_ptr = tmp_text_ptr; X line_ptr = tmp_line_ptr; X line_count = tmp_line_count; X (void) strcpy(current_file_name, tmp_file_name); X } else X exit(0); X} X X/* X * Open file and init options X */ Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X int i; X char ch; X X if (argc != 2) { X (void) fprintf(stderr, "usage: %s filename\n", argv[0]); X exit(1); X } X X /* Search for a '.' in filename */ X for (i = strlen(argv[1]) - 1; i; i--) { X ch = argv[1][i]; X if ((ch == '.') || (ch == '/') || (ch == '\\')) X break; X } X X if (ch != '.') X i = strlen(argv[1]); X X /* Append a '.c' */ X (void) strncpy(out_file_name, argv[1], i); X out_file_name[i] = '\0'; X (void) strcat(out_file_name, ".c"); X (void) printf("Output to: %s\n", out_file_name); X X /* Get AT declaration list */ X get_at_decl(); X X /* Init context */ X init_context(); X X file_depth = 0; X X /* Parse main file */ X cvt_file(argv[1]); X} SHAR_EOF chmod 0660 main.c || echo "restore of main.c fails" sed 's/^X//' << 'SHAR_EOF' > makefile && X# Makefile for Unix X XSRCS = convert.c \ X parse.c \ X declare.c \ X decl_out.c \ X control.c \ X io.c \ X token.c \ X context.c \ X mem.c \ X error.c \ X version.c \ X main.c X XOBJS = convert.o \ X parse.o \ X declare.o \ X decl_out.o \ X control.o \ X io.o \ X token.o \ X context.o \ X mem.o \ X error.o \ X version.o \ X main.o X XLNKS = convert parse declare decl_out control io token context mem error version main X XTOKEN_HDRS = misc.h defs.h struct.h cvt.h cvt_id.h tokens.h XHDRS = $(TOKEN_HDRS) tkn_defs.h tkn_ext.h X XOPTS = -c -O X Xplm2c: $(OBJS) X $(CC) -o plm2c $(OBJS) X Xconvert.o: convert.c $(TOKEN_HDRS) X $(CC) $(OPTS) convert.c X Xparse.o: parse.c $(TOKEN_HDRS) cvt_id.h X $(CC) $(OPTS) parse.c X Xdeclare.o: declare.c $(TOKEN_HDRS) X $(CC) $(OPTS) declare.c X Xcontrol.o: control.c $(TOKEN_HDRS) tkn_ext.h X $(CC) $(OPTS) control.c X Xdecl_out.o: decl_out.c $(TOKEN_HDRS) X $(CC) $(OPTS) decl_out.c X Xio.o: io.c $(TOKEN_HDRS) tkn_ext.h X $(CC) $(OPTS) io.c X Xtoken.o: token.c $(TOKEN_HDRS) tkn_ext.h X $(CC) $(OPTS) token.c X Xcontext.o: context.c $(TOKEN_HDRS) X $(CC) $(OPTS) context.c X Xmem.o: mem.c $(TOKEN_HDRS) X $(CC) $(OPTS) mem.c X Xerror.o: error.c $(TOKEN_HDRS) X $(CC) $(OPTS) error.c X Xversion.o: version.c X $(CC) $(OPTS) version.c X Xmain.o: main.c $(TOKEN_HDRS) tkn_defs.h X $(CC) $(OPTS) main.c X Xbackup: X cp $(HDRS) Makefile bak X cp $(SRCS) bak X Xlint: X lint $(SRCS) X Xclean: X rm -f $(OBJS) SHAR_EOF chmod 0660 makefile || echo "restore of makefile fails" sed 's/^X//' << 'SHAR_EOF' > makefile.ibm && X# Makefile for IBM-PC MSDOS X XSRCS = convert.c \ X parse.c \ X declare.c \ X decl_out.c \ X control.c \ X io.c \ X token.c \ X context.c \ X mem.c \ X error.c \ X version.c \ X main.c X XOBJS = convert.obj \ X parse.obj \ X declare.obj \ X decl_out.obj \ X control.obj \ X io.obj \ X token.obj \ X context.obj \ X mem.obj \ X error.obj \ X version.obj \ X main.obj X XLNKS = convert parse declare decl_out control io token context mem error version main X XTOKEN_HDRS = misc.h defs.h struct.h cvt.h cvt_id.h tokens.h XHDRS = $(TOKEN_HDRS) tkn_defs.h tkn_ext.h X XMDL = m XOPTS = -c -N -v -DIBMPC -m$(MDL) X Xplm2c: $(OBJS) X tlink /c /v c:\tc\lib\c0$(MDL) $(LNKS), plm2c, plm2c, c:\tc\lib\c$(MDL) X Xconvert.obj: convert.c $(TOKEN_HDRS) X tcc $(OPTS) convert X Xparse.obj: parse.c $(TOKEN_HDRS) cvt_id.h X tcc $(OPTS) parse X Xdeclare.obj: declare.c $(TOKEN_HDRS) X tcc $(OPTS) declare X Xcontrol.obj: control.c $(TOKEN_HDRS) tkn_ext.h X tcc $(OPTS) control X Xdecl_out.obj: decl_out.c $(TOKEN_HDRS) X tcc $(OPTS) decl_out X Xio.obj: io.c $(TOKEN_HDRS) tkn_ext.h X tcc $(OPTS) io X Xtoken.obj: token.c $(TOKEN_HDRS) tkn_ext.h X tcc $(OPTS) token X Xcontext.obj: context.c $(TOKEN_HDRS) X tcc $(OPTS) context X Xmem.obj: mem.c $(TOKEN_HDRS) X tcc $(OPTS) mem X Xerror.obj: error.c $(TOKEN_HDRS) X tcc $(OPTS) error X Xversion.obj: version.c X tcc $(OPTS) version X Xmain.obj: main.c $(TOKEN_HDRS) tkn_defs.h X tcc $(OPTS) main X Xbackup: X cp $(HDRS) Makefile bak X cp $(SRCS) bak X Xfloppy: X cp $(HDRS) makefile a: X cp $(SRCS) a: X Xlint: X lint $(SRCS) X SHAR_EOF chmod 0660 makefile.ibm || echo "restore of makefile.ibm fails" sed 's/^X//' << 'SHAR_EOF' > mem.c && X#ifdef IBMPC X#include <alloc.h> X#endif X#include "misc.h" X#include "defs.h" X#include "cvt.h" X#include "struct.h" X X/* X * Memory allocation and deallocation routines. X */ X X/* X * Allocate memory X */ Xchar *get_mem(size) Xunsigned int size; X{ X char *malloc_ptr; X void *malloc(); X X if ((malloc_ptr = (char *)malloc(size)) == NULL) { X parse_error("Out of memory"); X exit(1); X } X return malloc_ptr; X} X X/* X * Generate a new context. X */ Xget_context_ptr(context) XCONTEXT **context; X{ X *context = (CONTEXT *) get_mem(sizeof(CONTEXT)); X (*context)->decl_head = NULL; X (*context)->next_context = NULL; X} X X/* X * Malloc memory for a TOKEN. X */ Xget_token_ptr(token) XTOKEN **token; X{ X *token = (TOKEN *) get_mem(sizeof(TOKEN)); X} X X/* X * Malloc memory for a DECL_ID. X */ Xget_var_ptr(var) XDECL_ID **var; X{ X *var = (DECL_ID *) get_mem(sizeof(DECL_ID)); X (*var)->name = NULL; X (*var)->based_name = NULL; X (*var)->next_var = NULL; X (*var)->is_ext_at = FALSE; X} X X/* X * Free a linked list of variables. X */ Xfree_var_list(list_ptr) XDECL_ID *list_ptr; X{ X DECL_ID *next_ptr; X X while (list_ptr) { X if (list_ptr->name) X free( (char *) list_ptr->name); X if (list_ptr->based_name) X free( (char *) list_ptr->based_name); X next_ptr = list_ptr->next_var; X free((char *) list_ptr); X list_ptr = next_ptr; X } X} X X/* X * Malloc space for a DECL_MEMBER structure and return pointer. X */ Xget_element_ptr(element) XDECL_MEMBER **element; X{ X DECL_MEMBER *el_ptr; X X /* Malloc space for element */ X el_ptr = (DECL_MEMBER *) get_mem(sizeof(DECL_MEMBER)); X X /* Init pointers */ X el_ptr->name_list = NULL; X el_ptr->literal = NULL; X#ifdef PARSE_LITERALS X el_ptr->literal_token = NULL; X#endif X el_ptr->array_bound = NULL; X el_ptr->type = NULL; X el_ptr->struct_list = NULL; X el_ptr->at_ptr = NULL; X el_ptr->init_ptr = NULL; X el_ptr->next_member = NULL; X X el_ptr->attributes = NONE; X el_ptr->initialization = NONE; X X *element = el_ptr; X} X X/* X * Free a DECL_MEMBER list. X */ Xfree_decl_list(element) XDECL_MEMBER *element; X{ X DECL_MEMBER *el_ptr; X X while (element) { X if (element->name_list) X free_var_list(element->name_list); X if (element->literal) X free((char *) element->literal); X if (element->array_bound) X free((char *) element->array_bound); X if (element->type) X free((char *) element->type); X if (element->struct_list) X free_decl_list(element->struct_list); X if (element->at_ptr) X free(element->at_ptr); X X el_ptr = element->next_member; X free((char *) element); X element = el_ptr; X } X} X X/* X * Malloc space for a procedure parameter X */ Xget_param_ptr(param) XPARAM_LIST **param; X{ X *param = (PARAM_LIST *) get_mem(sizeof(PARAM_LIST)); X (*param)->next_param = NULL; X} X X/* X * Free parameter list X */ Xfree_param_list(param_list) XPARAM_LIST *param_list; X{ X PARAM_LIST *param_ptr; X X while (param_list) { X param_ptr = param_list->next_param; X free((char *) param_list); X param_list = param_ptr; X } X} X X/* X * Malloc space for a DECLARE statement X */ Xget_decl_ptr(decl) XDECL **decl; X{ X *decl = (DECL *) get_mem(sizeof(DECL)); X (*decl)->decl_list = NULL; X (*decl)->next_decl = NULL; X} X X/* X * Free DECL list X */ Xfree_decl(decl_list) XDECL *decl_list; X{ X DECL *decl_ptr; X X while (decl_list) { X decl_ptr = decl_list->next_decl; X#ifdef FREE_DECL_TOKEN X if (decl_list->decl_token) X free((char *) decl_list->decl_token); X#endif X if (decl_list->decl_list) X free_decl_list(decl_list->decl_list); X free((char *) decl_list); X decl_list = decl_ptr; X } X} X X SHAR_EOF chmod 0660 mem.c || echo "restore of mem.c fails" sed 's/^X//' << 'SHAR_EOF' > misc.h && X/* X * Miscellaneous defines X */ Xtypedef unsigned char BYTE; Xtypedef unsigned char BOOLEAN; X X X#ifndef TRUE X#define TRUE 1 X#endif X X#ifndef FALSE X#define FALSE 0 X#endif X X#ifndef NULL X#define NULL 0 X#endif X X/* X * White space characters X */ X#define SPACE ' ' X#define TAB 9 X#define CR 13 X#define LF 10 X X/* X * Useful defines X */ X#define is_a_uc_char(char) ((char >= 'A') && (char <= 'Z')) X#define is_a_lc_char(char) ((char >= 'a') && (char <= 'z')) X#define is_a_char(char) (((char & 0x5F) >= 'A') && ((char & 0x5F) <= 'Z')) X#define is_a_digit(char) ((char >= '0') && (char <= '9')) X X#define is_a_type(token) ((token->token_class == RESERVED) && \ X (token->token_type >= BYTE) && (token->token_type <= REAL)) X X#define is_white(ch) ((ch == ' ') || (ch == TAB)) X X#define NONE 0 X Xchar *strcat(), *strncat(), *strcpy(), *strncpy(); X#ifdef IBMPC Xint sprintf(); X#endif SHAR_EOF chmod 0660 misc.h || echo "restore of misc.h fails" sed 's/^X//' << 'SHAR_EOF' > parse.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 "cvt_id.h" X#include "tokens.h" X Xextern char *text_buffer, *text_ptr; Xextern int line_count; Xextern char *out_string; X X/* X * Parse a procedure parameter list. X * Return head of linked list of parameters. X */ Xget_param_list(param_head) XPARAM_LIST **param_head; X{ X PARAM_LIST *list_ptr, *param_ptr; X int token_class; X TOKEN sep_token; X X *param_head = NULL; X list_ptr = NULL; X X do { X get_param_ptr(¶m_ptr); X if (*param_head == NULL) X *param_head = param_ptr; X if (list_ptr) X list_ptr->next_param = param_ptr; X list_ptr = param_ptr; X token_class = get_token(¶m_ptr->param); X if (token_class != IDENTIFIER) { X parse_error("Identifier expected"); X free_param_list(*param_head); X } X /* Get ',' or ')' */ X token_class = get_token(&sep_token); X } while (token_class == COMMA); X X if (token_class != RIGHT_PAREN) { X parse_error("')' expected"); X free_param_list(*param_head); X } X} X X/* X * Parse parameter list. X * Parse DECLARE statements until all parameters in param_list X * have been found. Split declare statements into those used in X * param_list and those not. Return pointers to head of both X * DECL_MEMBER lists. X */ Xparse_param_list(param_list, decl_list, extra_decl_list) XPARAM_LIST *param_list; XDECL **decl_list, **extra_decl_list; X{ X DECL *extra_decl, *extra_decl_ptr; X DECL *list, *list_ptr; X DECL_MEMBER *extra_list_ptr; X DECL_MEMBER *el_ptr, *last_el_ptr, *next_el_ptr; X DECL_MEMBER *extra_el_ptr; X int token_class; X TOKEN *decl_token; X DECL_ID *var_ptr, *last_var_ptr, *next_var_ptr; X DECL_ID *extra_last_var_ptr; X PARAM_LIST *param_ptr, *last_param; X X *decl_list = NULL; X *extra_decl_list = NULL; X /* Pointer to next DECL_MEMBER in decl_ptr */ X list_ptr = NULL; X /* Pointer to next DECL in extra_decl_list */ X extra_decl_ptr = NULL; X X while (param_list) { X /* Get declaration */ X get_token_ptr(&decl_token); X token_class = get_token(decl_token); X if ((token_class != RESERVED) || X (decl_token->token_type != DECLARE)) { X parse_error("DECLARE expected"); X free((char *) decl_token); X return; X } X /* Get declaration list */ X get_decl_ptr(&list); X get_decl_list(list); X list->decl_token = decl_token; X X /* Points to start of extra declaration list */ X extra_list_ptr = NULL; X X /* Pointer to previous el_ptr */ X last_el_ptr = NULL; X X /* Check each element of the DECLARE statement */ X el_ptr = list->decl_list; X while (el_ptr) { X X /* Point to next member */ X next_el_ptr = el_ptr->next_member; X X /* Pointer to next DECL_MEMBER in extra_decl_ptr */ X extra_el_ptr = NULL; X X /* Points to last variable in variable list */ X last_var_ptr = NULL; X /* Contains not found variables in name_list */ X extra_last_var_ptr = NULL; X X /* Check each variable in name list */ X for (var_ptr = el_ptr->name_list; var_ptr; ) { X /* Point to following var_ptr */ X next_var_ptr = var_ptr->next_var; X X /* Is this variable in param list? */ X last_param = NULL; X for (param_ptr = param_list; param_ptr; X param_ptr = param_ptr->next_param) { X if (!strcmp(param_ptr->param.token_name, X var_ptr->name->token_name)) X break; X else X last_param = param_ptr; X } X X if (param_ptr) { X X /* Variable found */ X /* Remove from parameter list */ X if (last_param) X last_param->next_param = param_ptr->next_param; X else X param_list = param_ptr->next_param; X X free((char *) param_ptr); X last_var_ptr = var_ptr; X } else { X/* X * Variable not found - Add to extra variable list X */ X if (extra_el_ptr == NULL) { X/* X * Create new element and copy DECLARE info X */ X get_element_ptr(&extra_el_ptr); X element_copy(el_ptr, extra_el_ptr); X extra_last_var_ptr = NULL; X/* X * Link new extra element into extra_list_ptr X */ X if (extra_list_ptr) { X extra_list_ptr->next_member = extra_el_ptr; X } else { X/* X * Create new extra declaration X */ X get_decl_ptr(&extra_decl); X X /* Point to DECLARE token */ X extra_decl->decl_token = X list->decl_token; X extra_decl->decl_list = extra_el_ptr; X/* X * Link new extra declaration into extra_decl_list X */ X if (extra_decl_ptr) X extra_decl_ptr->next_decl = extra_decl; X else X *extra_decl_list = extra_decl; X X extra_decl_ptr = extra_decl; X } X extra_list_ptr = extra_el_ptr; X } X X /* Add var_ptr to extra list */ X if (extra_last_var_ptr) X extra_last_var_ptr->next_var = var_ptr; X else X extra_list_ptr->name_list = var_ptr; X X extra_last_var_ptr = var_ptr; X X /* Remove from DECLARE list */ X if (last_var_ptr) X last_var_ptr->next_var = next_var_ptr; X else X el_ptr->name_list = next_var_ptr; X X var_ptr->next_var = NULL; X } X X var_ptr = next_var_ptr; X } X X/* X * Check for empty name list X */ X if (el_ptr->name_list == NULL) { X/* X * Empty name list - unlink and discard element from declaration list X */ X if (last_el_ptr) X last_el_ptr->next_member = next_el_ptr; X else X list->decl_list = next_el_ptr; X X el_ptr->next_member = NULL; X free((char *) el_ptr); X } else X last_el_ptr = el_ptr; X X el_ptr = next_el_ptr; X } X X /* Save found items in decl_list */ X if (list->decl_list->name_list) { X if (*decl_list) X list_ptr->next_decl = list; X else X *decl_list = list; X list_ptr = list; X } else X free((char *) list); X X } X} X X/* X * Parse until desired token type appears X */ Xparse_till(type, token) Xint type; XTOKEN *token; X{ X while (get_token(token) != type) X out_token(token); X} X X/* X * Parse until END statement X */ Xparse_till_end(token) XTOKEN *token; X{ X int token_class; X X while (1) { X token_class = get_token(token); X X if (token_class == END_OF_FILE) { X parse_error("Premature end-of-file"); X exit(1); X } X X if ((token_class == RESERVED) && (token->token_type == END)) X return; X X parse_statement(token); X } X} X X/* X * Parse through END statement X */ Xparse_to_end() X{ X TOKEN token; X X parse_till_end(&token); X parse_statement(&token); X} X X/* X * Check for end of line (';') X */ Xcheck_eol() X{ X TOKEN token; X X if (get_token(&token) != END_OF_LINE) X parse_error("';' expected"); X else X out_token(&token); X} X X/* X * Parse simple variable and return variable token and following token. X * Passed with initial identifier in token. X * Returns with next_token terminating variable. X * Handles [ .<identifier> ] ... X */ Xparse_simple_variable(token, next_token) XTOKEN *token, *next_token; X{ X int token_class; X X while (1) { X token_class = get_token(next_token); X if (token_class != PERIOD) X return token_class; X X /* Process .<identifier> */ X token_class = get_token(next_token); X if (token_class != IDENTIFIER) { X parse_error("Illegal identifier"); X return ERROR; X } X /* Add .<identifier> to original token name */ X (void) strcat(token->token_name, "."); X (void) strcat(token->token_name, next_token->token_name); X /* Parse for additional member */ X return parse_simple_variable(token, next_token); X } X} X X/* X * Parse variable identifier. If pointer, output (*ident) else X * If variable has BASED attribute, output (*based_name). X * Otherwise, output ident. X */ Xout_ident(ident, decl, decl_id) XTOKEN *ident; XDECL_MEMBER *decl; XDECL_ID *decl_id; X{ X if (decl->at_ptr || decl_id->is_ext_at) { X out_white_space(ident); X out_str("(*"); X out_token_name(ident); X out_char(')'); X } else X X if (decl_id->based_name) { X out_white_space(ident); X out_str("(**"); X out_token_name(decl_id->name); X out_char(')'); X } else X out_token(ident); X} X X/* X * Parse variable name or structure element and output appropriate tokens. X * Passed with identifier in token, and declaration for token in decl. X * Returns with token terminating variable. X * Handles <member> { [ ( <expression> ) ] [ .<identifier> ] } X */ Xparse_member(token, decl, decl_id) XTOKEN *token; XDECL_MEMBER *decl; XDECL_ID *decl_id; X{ X int token_class; X TOKEN member; X DECL_MEMBER *var_decl; X DECL_ID *var_decl_id; X X /* Check for literal */ X if (decl->literal) { X /* Yes - output case converted literal */ X out_white_space(token); X out_cvt_name(token); X /* Return next token */ X token_class = get_token(token); X return token_class; X } X X token_copy(token, &member); X X token_class = get_token(token); X X /* Check for array subscript */ X if (decl->array_bound) { X out_ident(&member, decl, decl_id); X X if (token_class == LEFT_PAREN) { X /* Convert to open square bracket */ X token->token_name[0] = '['; X out_token(token); X X /* Parse expression to right parenthesis */ X token_class = parse_expression(token); X if (token_class != RIGHT_PAREN) { X parse_error("')' expected"); X return ERROR; X } X X /* Convert to close square bracket */ X token->token_name[0] = ']'; X out_token(token); X X token_class = get_token(token); X } X } X X /* Check for .<identifier> */ X if ((decl->type->token_type == STRUCTURE) && (token_class == PERIOD)) { X X if (decl->array_bound) X /* Already printed identifier */ X out_token(token); X else { X if (decl->at_ptr || decl_id->based_name) { X/* X * --- Note: Does not handle BASED AT variables! X */ X /* Print 'member->' */ X out_token(&member); X out_str("->"); X } else { X /* Print 'member.' */ X out_ident(&member, decl, decl_id); X out_token(token); X } X } X X token_class = get_token(token); X if (token_class != IDENTIFIER) { X parse_error("Illegal structure member"); X return ERROR; X } X X /* Find variable in list */ X if (!find_list_symbol(token, decl->struct_list, X &var_decl, &var_decl_id)) { X parse_error("Undefined structure member"); X return ERROR; X } X X /* Parse this member now */ X token_class = parse_member(token, var_decl, var_decl_id); X } else X if (decl->array_bound == NULL) X out_ident(&member, decl, decl_id); X X return token_class; X} X X/* X * Parse variable and output appropriate tokens. X * Passed with initial identifier in token. X * Returns with token terminating variable. X * Handles { [ ( <expression> ) ] [ .<identifier> ] } ... X */ Xparse_variable(token, var_decl, var_decl_id) XTOKEN *token; XDECL_MEMBER **var_decl; XDECL_ID **var_decl_id; X{ X if (!find_symbol(token, var_decl, var_decl_id)) { X parse_error("Undefined variable"); X return ERROR; X } X X return parse_member(token, *var_decl, *var_decl_id); X} X X/* X * See if token is in cvt_list. X * If found, return pointer to conversion string. X */ Xcheck_cvt_id(token, cvt_id, cvt_string) XTOKEN *token; XCVT_ID *cvt_id; Xchar **cvt_string; X{ X /* Check each string in cvt_id */ X while (*(cvt_id->id_name)) { X if (!strcmp(token->token_name, cvt_id->id_name)) { X /* Found match - return new string */ X *cvt_string = cvt_id->new_id; X return TRUE; X } X X cvt_id++; X } X X return FALSE; X} X X/* X * Parse function call X */ Xparse_function(token) XTOKEN *token; X{ X int token_class; X BOOLEAN left_shift, right_shift; X char *new_func; X DECL_MEMBER *decl_ptr; X DECL_ID *decl_id; X X /* Function call - check for SHL or SHR */ X out_white_space(token); X left_shift = !strcmp(token->token_name, "shl") || X !strcmp(token->token_name, "SHL"); X right_shift = !strcmp(token->token_name, "shr") || X !strcmp(token->token_name, "SHR"); X if (left_shift || right_shift) { X /* SHL(expr, expr) or SHR(expr, expr) */ X /* Check for '(' */ X token_class = get_token(token); X if (token_class != LEFT_PAREN) { X parse_error("'(' expected"); X return ERROR; X } X out_token(token); X X /* Output first expression */ X out_char('('); X token_class = parse_expression(token); X if (token_class != COMMA) { X parse_error("',' expected"); X return ERROR; X } X X out_str(left_shift ? ") << (" : ") >> ("); X X /* Output second expression */ X token_class = parse_expression(token); X if (token_class != RIGHT_PAREN) { X parse_error("Missing ')'"); X return ERROR; X } X out_char(')'); X out_token(token); X } else { X X /* Check for a type cast function */ X if (check_cvt_id(token, &cast_functions[0], &new_func)) { X /* Convert to a cast */ X out_char('('); X out_str(new_func); X out_str(") "); X } else X X /* Check for a function conversion */ X if (check_cvt_id(token, &cvt_functions[0], &new_func)) { X /* Convert to desired function */ X out_str(new_func); X } else { X X /* Output function name */ X out_token_name(token); X X /* Check for parameter list */ X if (find_symbol(token, &decl_ptr, &decl_id)) { X if (decl_ptr->type->token_type != PROCEDURE) { X parse_error("Illegal function call"); X return ERROR; X } X if (decl_ptr->initialization != DATA) { X /* No param list */ X token_class = get_token(token); X return token_class; X } X } X } X X /* Check for parameter list */ X token_class = get_token(token); X if (token_class != LEFT_PAREN) { X parse_warning("Parameter list expected"); X return token_class; X } X out_token(token); X X /* Parse to closing right paren */ X do { X token_class = parse_expression(token); X out_token(token); X } while (token_class == COMMA); X X if (token_class != RIGHT_PAREN) { X parse_error("Missing ')'"); X return ERROR; X } X } X /* Return token following function */ X token_class = get_token(token); X return token_class; X} X X/* X * Parse expression and output appropriate tokens. X * Return token at end of expression. X */ Xparse_expression(token) XTOKEN *token; X{ X int token_class; X int i, last_class, temp_class; X DECL_MEMBER *id_type; X DECL_ID *id_id; X char *new_id; X char string_const[MAX_TOKEN_LENGTH], octal_const[5]; X X last_class = OPERATOR; X X token_class = get_token(token); X X while (1) { X X switch (token_class) { X X case LEFT_PAREN : X if (last_class != OPERATOR) { X parse_error("Missing operator"); X return ERROR; X } X X /* Sub-expression */ X out_token(token); X /* Parse to closing right paren */ X token_class = parse_expression(token); X if (token_class != RIGHT_PAREN) { X parse_error("Missing ')'"); X return ERROR; X } X X out_token(token); X break; X X case RIGHT_PAREN : X return token_class; X X case OPERATOR : X out_white_space(token); X if (token->token_type == EQUAL) X /* Make it a '==' */ X out_str("=="); X else X X /* Check for address operator '@' or '.' */ X if ((token->token_type == AT_OP) || X (token->token_type == PERIOD)) { X token_class = get_token(token); X if (token_class == IDENTIFIER) { X /* Make it a '&' */ X out_char('&'); X X /* See if it's a function reference */ X if (find_symbol(token, &id_type, &id_id) && X (id_type->type->token_type != PROCEDURE)) { X /* Variable - parse it */ X temp_class = parse_member(token, id_type, id_id); X } else { X X /* Function call - Check for */ X /* a function conversion */ X if (check_cvt_id(token, &cvt_functions[0], &new_id)) X /* Convert to desired function */ X out_str(new_id); X else X /* Function call - output name */ X out_token_name(token); X X temp_class = get_token(token); X } X } else X X if (token_class == LEFT_PAREN) { X /* Constant list - convert to string */ X out_char('"'); X string_const[0] = '\0'; X X do { X token_class = get_token(token); X if (token_class == STRING) X (void) strcat(string_const, token->token_name); X else X if (token_class == NUMERIC) { X cvt_octal(token, octal_const); X (void) strcat(string_const, octal_const); X } else { X parse_error("Illegal constant"); X return ERROR; X } X X token_class = get_token(token); X } while (token_class == COMMA); X X if (token_class != RIGHT_PAREN) { X parse_error("')' expected"); X return ERROR; X } X X i = strlen(string_const); X if ((i >= 4) && X (!strcmp(string_const + i - 4, "\\000"))) X /* Discard trailing null */ X string_const[i - 4] = '\0'; X out_str(string_const); X out_char('"'); X } else { X parse_error("Illegal operator"); X return ERROR; X } X } else X X out_token_name(token); X break; X X case IDENTIFIER : X /* Check for identifier conversion */ X if (check_cvt_id(token, &cvt_identifiers[0], &new_id)) { X out_white_space(token); X out_str(new_id); X temp_class = get_token(token); X } else X X /* See if variable in context */ X if (find_symbol(token, &id_type, &id_id) && X (id_type->type->token_type != PROCEDURE)) { X /* Variable - parse it */ X temp_class = parse_member(token, id_type, id_id); X } else X X /* Function call - parse it */ X temp_class = parse_function(token); X break; X X case NUMERIC : X out_token(token); X break; X X case STRING : X out_white_space(token); X /* Convert to a numeric constant */ X if (token->token_length > 4) { X parse_error("Illegal string constant"); X return ERROR; X } X X if (token->token_length > 1) X out_char('('); X X out_str_const(token->token_name, token->token_length); X X if (token->token_length > 1) X out_char(')'); X break; X X default : X /* Must not be part of an expression! */ X return token_class; X } X X last_class = token_class; X X token_class = (last_class == IDENTIFIER) ? X temp_class : get_token(token); X } X} X X/* X * DO statement X * Handles DO;, DO CASE, DO WHILE, and iterative DO X */ Xparse_do(first_token) XTOKEN *first_token; X{ X TOKEN token; X int token_class; X int case_line; X char case_statement[MAX_TOKEN_LENGTH]; X char case_output[MAX_CASE_STATEMENT_SIZE]; X char var_string[MAX_TOKEN_LENGTH]; X char *temp_out_string, *temp_out_string1; X DECL_MEMBER *var_decl; X DECL_ID *var_decl_id; X X /* Create new context */ X new_context(DO, (TOKEN *) NULL); X X out_white_space(first_token); X X /* Determine what kind of DO statement */ X token_class = get_token(&token); X X switch (token_class) { X X case END_OF_LINE : X /* DO; */ X out_white_space(&token); X out_char('{'); /* } for dumb vi */ X parse_to_end(); X break; X X case IDENTIFIER : X /* DO counter = start TO limit BY step */ X out_str("for"); X out_must_white(&token); X out_char('('); X X /* Put full variable in var_string */ X var_string[0] = '\0'; X temp_out_string = out_string; X out_string = var_string; X token_class = parse_variable(&token, &var_decl, &var_decl_id); SHAR_EOF echo "End of part 2, continue with part 3" echo "3" > s2_seq_.tmp exit 0