1 /*
2  * Copyright (C) 1997-2004, Michael Jennings
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to
6  * deal in the Software without restriction, including without limitation the
7  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8  * sell copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies of the Software, its documentation and marketing & publicity
13  * materials, and acknowledgment shall be given in the documentation, materials
14  * and software packages that this Software was used.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 
24 /**
25  * @file msgs.c
26  * Diagnostic message routines.
27  *
28  * This file contains routines related to the display of warning and
29  * error messages to the end user.
30  *
31  * @author Michael Jennings <mej@eterm.org>
32  * $Revision: 1.11 $
33  * $Date: 2004/07/23 21:38:39 $
34  */
35 
36 static const char __attribute__((unused)) cvs_ident[] = "$Id: msgs.c,v 1.11 2004/07/23 21:38:39 mej Exp $";
37 
38 #ifdef HAVE_CONFIG_H
39 # include <config.h>
40 #endif
41 
42 #include "libast_internal.h"
43 
44 /**
45  * Program name.
46  *
47  * The client program name as shown in warning/error messages.  It is
48  * also used in the config file parser for magic number checking and
49  * some built-in functions.  This variable must be set using the
50  * libast_set_program_name() function.
51  */
52 spif_charptr_t libast_program_name = SPIF_CAST(charptr) PACKAGE;
53 /**
54  * Program version.
55  *
56  * The version of the client program as shown in warning/error
57  * messages.  It is also used in the config file parser for magic
58  * number checking and some built-in functions.  This variable must be
59  * set using the libast_set_program_version() function.
60  */
61 spif_charptr_t libast_program_version = SPIF_CAST(charptr) VERSION;
62 
63 /**
64  * Sets the program name.
65  *
66  * This function is provided for safe and sane setting of the
67  * #libast_program_name variable.  Setting it directly should be
68  * avoided.
69  *
70  * @param progname The name of the client program as it should be
71  *                 displayed in warning/error messages.
72  * @see libast_program_name
73  */
74 void
libast_set_program_name(const char * progname)75 libast_set_program_name(const char *progname)
76 {
77     if (libast_program_name) {
78         if (!strcmp(SPIF_CAST_C(char *) libast_program_name, progname)) {
79             return;
80         }
81         if (strcmp(SPIF_CAST_C(char *) libast_program_name, PACKAGE)) {
82             FREE(libast_program_name);
83         }
84     }
85     if (progname) {
86         libast_program_name = SPIF_CAST(charptr) STRDUP(progname);
87     } else {
88         libast_program_name = SPIF_CAST(charptr) PACKAGE;
89     }
90 }
91 
92 /**
93  * Sets the program version.
94  *
95  * This function is provided for safe and sane setting of the
96  * #libast_program_version variable.  Setting it directly should be
97  * avoided.
98  *
99  * @param progversion The version of the client program as it should
100  *                    appear in config file magic numbers and such.
101  * @see libast_program_version
102  */
103 void
libast_set_program_version(const char * progversion)104 libast_set_program_version(const char *progversion)
105 {
106     if (libast_program_version) {
107         if (!strcmp(SPIF_CAST_C(char *) libast_program_version, progversion)) {
108             return;
109         }
110         if (strcmp(SPIF_CAST_C(char *) libast_program_version, VERSION)) {
111             FREE(libast_program_version);
112         }
113     }
114     if (progversion) {
115         libast_program_version = SPIF_CAST(charptr) STRDUP(progversion);
116     } else {
117         libast_program_version = SPIF_CAST(charptr) VERSION;
118     }
119 }
120 
121 /**
122  * Prints debugging output.
123  *
124  * This function is the guts behing the D_*() and DPRINTF() families of
125  * macros.  Debugging output is sent to LIBAST_DEBUG_FD which is
126  * flushed after each line in case of crash.
127  *
128  * @param format The printf-style format string.
129  * @param ...    Zero or more parameters as required by the @a format
130  *               string.
131  * @return       The total number of characters printed.
132  *
133  * @see LIBAST_DEBUG_FD, DPRINTF()
134  * @ingroup DOXGRP_DEBUG
135  */
136 int
libast_dprintf(const char * format,...)137 libast_dprintf(const char *format, ...)
138 {
139     va_list args;
140     int n;
141 
142     ASSERT_RVAL(!SPIF_PTR_ISNULL(format), SPIF_CAST_C(int) -1);
143     REQUIRE_RVAL(libast_program_name != NULL, 0);
144     va_start(args, format);
145     n = vfprintf(LIBAST_DEBUG_FD, format, args);
146     va_end(args);
147     fflush(LIBAST_DEBUG_FD);
148     return (n);
149 }
150 
151 /**
152  * Prints a non-terminal error message.
153  *
154  * This function displays a non-fatal error condition in the format
155  * "<prog>:  Error:  <msg>".  Trailing newlines must be supplied by
156  * the caller.
157  *
158  * @param fmt The printf-style format string.
159  * @param ... Zero or more parameters as required by the @a fmt
160  *            string.
161  * @return    The total number of characters printed.
162  *
163  * @see libast_program_name
164  */
165 void
libast_print_error(const char * fmt,...)166 libast_print_error(const char *fmt, ...)
167 {
168     va_list arg_ptr;
169 
170     ASSERT(!SPIF_PTR_ISNULL(fmt));
171     REQUIRE(libast_program_name != NULL);
172     va_start(arg_ptr, fmt);
173     fprintf(stderr, "%s:  Error:  ", libast_program_name);
174     vfprintf(stderr, fmt, arg_ptr);
175     va_end(arg_ptr);
176 }
177 
178 /**
179  * Prints a warning message.
180  *
181  * This function displays a warning message in the format
182  * "<prog>:  Warning:  <msg>".  Trailing newlines must be supplied by
183  * the caller.
184  *
185  * @param fmt The printf-style format string.
186  * @param ... Zero or more parameters as required by the @a fmt
187  *            string.
188  * @return    The total number of characters printed.
189  *
190  * @see libast_program_name
191  */
192 void
libast_print_warning(const char * fmt,...)193 libast_print_warning(const char *fmt, ...)
194 {
195     va_list arg_ptr;
196 
197     ASSERT(!SPIF_PTR_ISNULL(fmt));
198     REQUIRE(libast_program_name != NULL);
199     va_start(arg_ptr, fmt);
200     fprintf(stderr, "%s:  Warning:  ", libast_program_name);
201     vfprintf(stderr, fmt, arg_ptr);
202     va_end(arg_ptr);
203 }
204 
205 /**
206  * Prints a terminal error message.
207  *
208  * This function displays a fatal error condition in the format
209  * "<prog>:  FATAL:  <msg>".  Trailing newlines must be supplied by
210  * the caller.  The program exits after the message is displayed.
211  *
212  * @param fmt The printf-style format string.
213  * @param ... Zero or more parameters as required by the @a fmt
214  *            string.
215  * @return    Does not return.
216  *
217  * @see libast_program_name
218  */
219 void
libast_fatal_error(const char * fmt,...)220 libast_fatal_error(const char *fmt, ...)
221 {
222     va_list arg_ptr;
223 
224     ASSERT(!SPIF_PTR_ISNULL(fmt));
225     if (libast_program_name != NULL) {
226         va_start(arg_ptr, fmt);
227         fprintf(stderr, "%s:  FATAL:  ", libast_program_name);
228         vfprintf(stderr, fmt, arg_ptr);
229         va_end(arg_ptr);
230     }
231     exit(-1);
232 }
233