# # include # include "constants.h" # include "globals.h" /* ** PRTOUT.C -- output routines ** ** Output routines for non-specific data structures ** (i.e. w_display is in [display.c]) ** ** Defines: ** w_con() ** w_op() ** w_var() ** w_key() ** w_new() ** begin_quote() ** end_quote() ** equate_lines() ** w_sync() ** w_flush() ** w_file() ** w_string() ** w_raw() ** Charcnt - number of characters already output ** on current line (used in [yylex.c]) ** ** ** Required By: ** semantic routines ** ** Files: ** globals.h ** constants.h ** ** History: ** 6/1/78 -- (marc) written */ extern int Fillcnt = FILLCNT; /* ** W_CON -- write out a constant ** Writes out a constant of type 'type' ** pointed to by 'string'. ** */ w_con(type, string) int type; char *string; { if (type == Tokens.sp_sconst) w_string(string, 1); else w_key(string); } /* ** W_OP -- Writes out a string which doesn't need a blank ** to separate it from a keyword. ** */ w_op(string) char *string; { w_raw(string); Lastc = OPCHAR; } /* ** W_VAR -- writes out code to send the ** value of a C variable down to ** the Quel scanner. ** ** Conserves the state of In_quote. ** */ w_var(disp, type) int type; struct display *disp; { register struct disp_node *d; register savestat; savestat = In_quote; /* if was In_quote, then will want a space before the * string written down */ if (savestat) w_key(""); if (type != opIDSTRING) { w_new("IIcvar("); if (type != opSTRING) w_op("&"); } else w_new("IIwrite("); w_display(disp); switch (type) { case opINT : w_op(",1,2);"); break; case opFLOAT : w_op(",2,4);"); break; case opSTRING : w_op(",3,0);"); break; case opDOUBLE : w_op(",4,8);"); break; case opCHAR : w_op(",5,1);"); break; case opLONG : w_op(",6,4);"); break; case opIDSTRING : w_op(");"); break; default : syserr("invalid type %d in w_var", type); } if (savestat) { begin_quote(); /* if was In_quote, then will want a space * before next keyword */ w_key(""); } } /* ** W_KEY -- write out a string needing a blank to ** separate it from other keywords. ** */ w_key(string) char *string; { if (Lastc == KEYCHAR) w_raw(" "); w_raw(string); Lastc = KEYCHAR; } /* ** W_NEW -- write out a string after getting out of ** any pending IIwrite's. ** */ w_new(string) char *string; { end_quote(); w_op(string); } /* ** BEGIN_QUOTE -- Issue an IIwrite(" ** */ begin_quote() { In_string = 1; In_quote = 1; Fillmode = 1; w_op("IIwrite(\""); } /* ** END_QUOTE -- End any pending IIwrite(" ** */ end_quote() { In_string = 0; if (In_quote) w_op("\");"); In_quote = 0; } /* ** EQUATE_LINES -- Make subsequent lines be output on the ** same line they were read (lines of C_CODE only). ** ** Note: Because of the algorithm used, it is possible that ** the correct line in the output has already been passed, ** in which case equate_lines does nothing. ** */ equate_lines() { Fillmode = 0; while (Lineout < yyline) w_raw("\n"); Lastc = OPCHAR; } /* ** W_SYNC -- Put out an IIsync() call ** */ w_sync() { w_new("IIsync("); w_file(); w_op(");"); } /* ** W_FLUSH -- Put out an IIflush_tup() call ** */ w_flush() { w_new("IIflushtup("); w_file(); w_op(");"); } /* ** W_FILE -- Writes out the name and line number of the ** input file if Rtdb is specified, else a 0. */ w_file() { char itemp [6]; if (Rtdb) { w_string(Input_file_name, 0); itoa(yyline, itemp); w_op(","); w_key(itemp); } else w_key("0"); } /* ** W_STRING -- Writes out a string ** ** String is output as a string constant if type == 0 ** otherwise writes out string inside an IIwrite( ** */ w_string(string, type) char *string; int type; { register char *t; register char *s; if (type) { if (!In_quote) begin_quote(); w_raw("\\"); } s = t = string; In_string += 1; w_raw("\""); for ( ;*t ; ) { if (*t == '\\') { if (t [1] == '\n') { *t = '\0'; w_raw(s); s = t = &t [2]; w_raw("\\\n"); } else { *t++ = '\0'; w_raw(s); s = t; /* note that this call must be atomic, * as w_raw would feel free to put newlines * in if not. */ if (type) w_raw("\\\\"); else w_raw("\\"); } } else if (*t == '"') { w_raw("\\\""); s = ++t; } else t++; } w_raw(s); In_string -= 1; if (type) w_raw("\\\""); else w_raw("\""); } /* ** W_RAW -- Lowest level output character routine ** ** Outputs string depending on Fillcnt and In_quote ** and In_string and Fillmode. ** When not in Fillmode does straight output. ** When on Fillmode, fills lines to Fillmode. ** ** NOTE : w_raw will feel free to output a newline after ** 'string' if the string causes more than Fillcnt ** characters to be output. ** Inside strings (In_string != 0) w_raw will put ** a '\\' before the newline issued. ** When In_quote != 0 when the fillcnt is exceeded, ** the IIwrite( is ended an continued on the next line ** so that the query string won't overflow the C ** pre-processor's line buffer. ** */ w_raw(string) char *string; { register char *s; register charcnt; charcnt = 0; for (s = string; *s; s++) { if (*s != '\n') { putc(*s, Out_file); charcnt++; } else { if (Fillmode == 0 || Charcnt + charcnt > Fillcnt || In_string) { putc(*s, Out_file); Lineout++; charcnt = 0; Charcnt = 0; } else { putc(' ', Out_file); charcnt++; } } } if ((Charcnt += charcnt) > Fillcnt && Fillmode == 1) { if (In_string) { if (In_quote) { puts("\");\nIIwrite(\"", Out_file); Charcnt = 9; } else { puts("\\\n", Out_file); Charcnt = 0; } } else { putc('\n', Out_file); Charcnt = 0; } Lineout++; } } /* ** PUTS -- put a string on an output file using putc() ** */ puts(s, file) char *s; FILE *file; { register char *sp; register FILE *f; f = file; for (sp = s; *sp; ) putc(*sp++, f); }