/* %Z%%M% %I% %E% */ /* * Copyright (c) 1991, 1992, 1993, 1994, 1995 by Wayne C. Gramlich. * All rights reserved. * * Permission to use, copy, modify, distribute, and sell this software * for any purpose is hereby granted without fee provided that the above * copyright notice and this permission are retained. The author makes * no representations about the suitability of this software for any purpose. * It is provided "as is" without express or implied warranty. */ /* This file contains code for doing output: */ #ifndef ERROR_EXPORTS_H #include "error_exports.h" #endif #ifndef LINT_H #include "lint.h" #endif #ifndef OUT_EXPORTS_H #include "out_exports.h" #endif #ifndef ROUTINE_DEFS_H #include "routine_defs.h" #endif #ifndef ROUTINE_EXPORTS_H #include "routine_exports.h" #endif #ifndef STR_EXPORTS_H #include "str_exports.h" #endif #ifndef TABLE_EXPORTS_H #include "table_exports.h" #endif #ifndef TYPE_DEFS_H #include "type_defs.h" #endif #ifndef UNIX_ASSERT_H #include "unix_assert.h" #endif #ifndef UNIX_CTYPE_H #include "unix_ctype.h" #endif #ifndef UNIX_STDARG_H #include "unix_stdarg.h" #endif #ifndef UNIX_UNISTD_H #include "unix_unistd.h" #endif #ifndef VECTOR_EXPORTS_H #include "vector_exports.h" #endif static Table(Str, Str) c_keywords = (Table(Str, Str))0; /* * out(out_file, format, arg1, ..., argN) * This routine will print "arg1" through "argN" to "out_file" using * "format" to control formatting. See out_format() for a complete * description of the formating control characters. */ #if defined(lint) /* ARGSUSED */ /* VARARGS2 */ void out( Stdio out_file, Str format, ...) { va_list args; args = (va_list)0; out_format(out_file, format, args); } #else /* defined(lint */ void out( Stdio out_file, Str format, ...) { va_list args; va_start(args, format); out_format(out_file, format, args); va_end(args); } #endif /* defined(lint */ /* * out_count_read(in_file) * This routine will read and return a count from "in_file". */ int out_count_read( Stdio in_file) { int count; count = getw(in_file); if (count > 5000) { count = count; /* Plant breakpoint here! */ assert_fail(); } return count; } /* * out_count_write(out_file, count) * This routine will write "count" to "out_file". */ void out_count_write( Stdio out_file, int count) { (void)putw(count, out_file); } /* * lint has all sorts of pointer alignment problems with va_arg(). * Make lint shut up by redefining va_arg(). */ #if defined(lint) #undef va_arg #define va_arg(var, type) ((type)(0 + (int)(var))) #endif /* defined(lint */ /* * out_format(out_file, format, args_ptr) * This routine takes the arguments pointed to by "args_ptr" and prints * them to "out_file" usign "format". Look at the comments inside of * this routine to see what formating is avaiable. */ void out_format( Stdio out_file, Str format, va_list args) { char chr; Str comment; int indent; if (out_file == (Stdio)0) { out_file = stdout; } while ((chr = *format++) != '\0') { if (chr != '%') { (void)fputc(chr, out_file); continue; } chr = *format++; switch (chr) { case '\0': format--; break; case '\t': /* Beginning-of-line indentation */ indent = va_arg(args, int); assert(indent < 500); while (indent > 1) { (void)fputc('\t', out_file); indent -= 2; } if (indent == 1) { (void)fputs(" ", out_file); } break; case '\n': /* End-of-line comment */ comment = va_arg(args, Str); if (comment != (Str)0) { (void)fputs("\t/* ", out_file); (void)fputs(comment + 1, out_file); (void)fputs(" */", out_file); } (void)fputc('\n', out_file); break; case '\'': out_quoted_string(out_file, va_arg(args, Str), '\'', 0); break; case '"': out_quoted_string(out_file, va_arg(args, Str), '"', 0); break; case '#': out_quoted_string(out_file, va_arg(args, Str), '"', 1); break; case '@': { Type_ref type_ref; type_ref = va_arg(args, Type_ref); if (!strequal(type_ref->name, "global__")) { (void)fputc('@', out_file); type_ref_print(type_ref, out_file); } break; } case 'c': /* Character */ (void)fputc(va_arg(args, int), out_file); break; case 'd': /* Decimal */ (void)fprintf(out_file, "%d", va_arg(args, int)); break; case 'I': /* Inititial object: */ (void)fputs(va_arg(args, Str), out_file); (void)fputs("___initial", out_file); break; case 'M': /* Type reference list mangle */ type_refs_mangle(va_arg(args, Type_refs), 0, out_file); break; case 'm': /* Type reference mangle */ type_ref_mangle(va_arg(args, Type_ref), out_file); break; case 'q': (void)fputc('{', out_file); type_refs_print(va_arg(args, Type_refs), out_file); (void)fputc('}', out_file); break; case 'r': { Type_ref type_ref; type_ref = va_arg(args, Type_ref); type_ref_print(type_ref, out_file); break; } case 'R': { Routine_ref routine_ref; routine_ref = va_arg(args, Routine_ref); (void)fputs(routine_ref->name, out_file); if (routine_ref->type_ref != (Type_ref)0) { (void)fputc('@', out_file); (void)fputs(routine_ref->type_ref->name, out_file); } break; } case 's': /* Regular string without keyword conversion: */ { Str str; assert(c_keywords != (Table(Str, Str))0); str = va_arg(args, Str); if (str == (Str)0) { str = "(null)"; } (void)fputs(str, out_file); break; } case 'S': /* Regular string with keyword conversion: */ { Str str; Str new_str; assert(c_keywords != (Table(Str, Str))0); str = va_arg(args, Str); if (str == (Str)0) { str = "(null)"; } else { new_str = table_lookup(Str, Str, c_keywords, str); if (new_str != (Str)0) { str = new_str; } } (void)fputs(str, out_file); break; } case 'T': /* Type string: */ (void)fputs(va_arg(args, Str), out_file); (void)fputs("___type", out_file); break; case 'X': /* Hexadecimal */ (void)fprintf(out_file, "0x%x", va_arg(args, int)); break; default: error_abort("Bad format character %c (=%d)", chr, chr); /* NOTREACHED */ } } } /* * out_initialize(heap) * Will initialize the C keyword table table. */ void out_initialize( Heap heap) { c_keywords = table_create(Str, Str, 50, strequal, strhash, (Str)0, heap); (void)table_insert(Str, Str, c_keywords, "auto", "out__keyword"); (void)table_insert(Str, Str, c_keywords, "case", "case__keyword"); (void)table_insert(Str, Str, c_keywords, "char", "char__keyword"); (void)table_insert(Str, Str, c_keywords, "double", "double__keyword"); (void)table_insert(Str, Str, c_keywords, "else", "else__keyword"); (void)table_insert(Str, Str, c_keywords, "enum", "else__keyword"); (void)table_insert(Str, Str, c_keywords, "extern", "extern__keyword"); (void)table_insert(Str, Str, c_keywords, "float", "float__keyword"); (void)table_insert(Str, Str, c_keywords, "goto", "goto__keyword"); (void)table_insert(Str, Str, c_keywords, "if", "if__keyword"); (void)table_insert(Str, Str, c_keywords, "int", "int__keyword"); (void)table_insert(Str, Str, c_keywords, "long", "long__keyword"); (void)table_insert(Str, Str, c_keywords, "short", "short__keyword"); (void)table_insert(Str, Str, c_keywords, "signed", "signed__keyword"); (void)table_insert(Str, Str, c_keywords, "static", "static__keyword"); (void)table_insert(Str, Str, c_keywords, "struct", "static__keyword"); (void)table_insert(Str, Str, c_keywords, "switch", "switch__keyword"); (void)table_insert(Str, Str, c_keywords, "typedef", "typedef__keyword"); (void)table_insert(Str, Str, c_keywords, "union", "unsigned__keyword"); (void)table_insert(Str, Str, c_keywords, "unsigned", "unsigned__keyword"); (void)table_insert(Str, Str, c_keywords, "void", "void__keyword"); (void)table_insert(Str, Str, c_keywords, "while", "while__keyword"); } /* * out_marker_read(in_file, marker) * This routine will verify that "marker" is next in "in_file". */ void out_marker_read( Stdio in_file, Str marker) { int temp; static int marker_count = 0; static int marker_match = 0; temp = getw(in_file); marker_count++; if (marker_count == marker_match) { temp = temp; /* Plant breakpoint here! */ } if (strhash(marker) != temp) { temp = temp; /* Plant breakpoint here! */ assert_fail(); } } /* * out_marker_write(out_file, marker) * This routine will write "marker" to "out_file". */ void out_marker_write( Stdio out_file, Str marker) { (void)putw(strhash(marker), out_file); } /* * out_quoted_string(out_file, str, quote, prepend_length) * This routine will print "str" to "out_file" enclosed in "quote". */ void out_quoted_string( Stdio out_file, Str str, char quote, int prepend_length) { char chr; int size; Str text; if (prepend_length) { size = strlen(str); assert(size < 255); (void)fprintf(out_file, "%c\\%03o", quote, size); } else { (void)fputc(quote, out_file); } for (text = str, size = strlen(str), chr = *text++; size-- > 0; chr = *text++) { if (isprint(chr)) { if ((chr == quote) || (chr == '\\')) { (void)fputc('\\', out_file); } (void)fputc(chr, out_file); } else { (void)fputc('\\', out_file); switch (chr) { case '\n': (void)fputc('n', out_file); break; case '\t': (void)fputc('t', out_file); break; default: (void)fprintf(out_file, "%03o", chr); } } } (void)fputc(quote, out_file); }