/* %Z%%M% %I% %E% */ /* * Copyright (c) 1991-2006 by Wayne C. Gramlich. * All rights reserved. */ /* * This file is used to output error messages with a file name and * line number. */ #ifndef FLAGS_DEFS_H #include "flags_defs.h" #endif #ifndef HEAP_EXPORTS_H #include "heap_exports.h" #endif #ifndef INT_EXPORTS_H #include "int_exports.h" #endif #ifndef LIBC_EXPORTS_H #include "libc_exports.h" #endif #ifndef LINT_H #include "lint.h" #endif #ifndef MSG_DEFS_H #include "msg_defs.h" #endif #ifndef OUT_EXPORTS_H #include "out_exports.h" #endif #ifndef STR_EXPORTS_H #include "str_exports.h" #endif #ifndef UNIX_ASSERT_H #include "unix_assert.h" #endif #ifndef UNIX_STDIO_H #include "unix_stdio.h" #endif #ifndef UNIX_UNISTD_H #include "unix_unistd.h" #endif #ifndef VECTOR_EXPORTS_H #include "vector_exports.h" #endif LOCAL int msg_int_compare(int, int, int); /* * msg_count_get(Msg) * This routine will return the number of error messages output. */ int msg_count_get( Msg msg) { return msg->count; } /* * msg_create(in_file, heap) * This routine will create and return a new Msg object for outputing * error messages for "flags->in_file" allocated from "heap". */ Msg msg_create( Flags flags, Heap heap) { char buffer[2000]; Flags_file in_file; Msg msg; char working_dir[2000]; assert(getcwd(working_dir, sizeof(working_dir)) != (Str)0); in_file = flags->in_file; msg = heap_allocate(heap, Msg); msg->count = 0; msg->error_file = stderr; if (strequal(in_file->path, working_dir)) { (void)sprintf(buffer, "%s%s", in_file->base, in_file->suffix); msg->file_name = strdupl(buffer, heap); } else { msg->file_name = in_file->full; } msg->flags = flags; msg->position_split = -1; msg->positions = vec_create(int, heap); return msg; } /* * msg_int_compare(int1, int2, zilch) * This routine will return <0, ==0, >0 depending upon whether "int1" * is less than, equal to, or greater than 0. */ /* ARGSUSED */ LOCAL int msg_int_compare( int int1, int int2, int zilch) { return int_compare(int1, int2); } /* * msg_line_append(msg, position) * This routine will append "position" to the position table inside of * "msg". */ void msg_line_append( Msg msg, int position) { vec_append(int, msg->positions, position); } /* * msg_line_get(msg, position) * This routine will return the line number associated with "position". */ int msg_line_get( Msg msg, int position) { return vec_search_binary(int, msg->positions, position, msg_int_compare, 0) + 1; } /* * msg_out(msg, position, format, arg1, ..., argN) * This routine will output "arg1" through "argN" as an error message * using "format". "position" is used to compute line number. */ void msg_out( Msg msg, int position, Str format, ...) { va_list args; int line_number; Stdio error_file; int temp; error_file = msg->error_file; va_start(args, format); line_number = vec_search_binary(int, msg->positions, position, msg_int_compare, 0) + 1; if ((msg->position_split >= 0) && (position >= msg->position_split)) { temp = vec_search_binary(int, msg->positions, msg->position_split, msg_int_compare, 0) + 1; out(error_file, "%\", line %d: ", msg->flags->gen_file->full, line_number - temp); } else { out(error_file, "%\", line %d: ", msg->file_name, line_number); } out_format(error_file, format, args); out(error_file, "\n"); msg->count++; va_end(args); } /* * msg_trace(msg, position, format, arg1, ..., argN) * This routine will output "arg1" through "argN" as a trace message * using "format". "position" is used to compute line number. */ void msg_trace( Msg msg, int position, Str format, ...) { va_list args; int line_number; Stdio error_file; int temp; error_file = msg->error_file; va_start(args, format); line_number = vec_search_binary(int, msg->positions, position, msg_int_compare, 0) + 1; if ((msg->position_split >= 0) && (position >= msg->position_split)) { temp = vec_search_binary(int, msg->positions, msg->position_split, msg_int_compare, 0) + 1; out(error_file, "%\", line %d: ", msg->flags->gen_file->full, line_number - temp); } else { out(error_file, "%\", line %d: ", msg->file_name, line_number); } out_format(error_file, format, args); out(error_file, "\n"); va_end(args); }