1 |
/* |
2 |
* ASCEND Printf Substitutes |
3 |
* by Mark Thomas |
4 |
* Created: 27.May.1997 |
5 |
* Version: $Revision: 1.6 $ |
6 |
* Version control file: $RCSfile: ascPrint.c,v $ |
7 |
* Date last modified: $Date: 1997/10/29 13:08:49 $ |
8 |
* Last modified by: $Author: mthomas $ |
9 |
* |
10 |
* This file is part of the ASCEND utilities. |
11 |
* |
12 |
* Copyright 1997, Carnegie Mellon University |
13 |
* |
14 |
* The ASCEND utilities is free software; you can redistribute |
15 |
* it and/or modify it under the terms of the GNU General Public License as |
16 |
* published by the Free Software Foundation; either version 2 of the |
17 |
* License, or (at your option) any later version. |
18 |
* |
19 |
* The ASCEND utilities is distributed in hope that it will be |
20 |
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
21 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
22 |
* General Public License for more details. |
23 |
* |
24 |
* You should have received a copy of the GNU General Public License |
25 |
* along with the program; if not, write to the Free Software Foundation, |
26 |
* Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named |
27 |
* COPYING. COPYING is found in ../compiler. |
28 |
*/ |
29 |
|
30 |
/* ChangeLog |
31 |
* |
32 |
* 10/13/2005 Added Asc_PrintHasVTable() so user can tell if a vtable |
33 |
* has already been registered. (J.D. St.Clair) |
34 |
*/ |
35 |
#include <stdlib.h> |
36 |
#include <stdarg.h> |
37 |
#include <stdio.h> |
38 |
#include "ascConfig.h" |
39 |
#include "ascPrint.h" |
40 |
|
41 |
/* <..> path is required here for the autotools build to be happy */ |
42 |
#include <utilities/config.h> |
43 |
|
44 |
static struct Asc_PrintVTable *g_Asc_printVtables = NULL; |
45 |
|
46 |
#define PRINT_BUFFER_SIZE 16380 |
47 |
|
48 |
int Asc_PrintPushVTable(struct Asc_PrintVTable *vtable) |
49 |
{ |
50 |
if ((vtable == NULL) || |
51 |
(vtable->name == NULL) || |
52 |
(vtable->print == NULL) || |
53 |
(vtable->fflush == NULL) || |
54 |
(vtable->next != NULL)) { |
55 |
return 1; |
56 |
} |
57 |
/* push it on the stack */ |
58 |
vtable->next = g_Asc_printVtables; |
59 |
g_Asc_printVtables = vtable; |
60 |
return 0; |
61 |
} |
62 |
|
63 |
struct Asc_PrintVTable *Asc_PrintRemoveVTable(CONST char *name) |
64 |
{ |
65 |
struct Asc_PrintVTable *prev; |
66 |
struct Asc_PrintVTable *vt; |
67 |
|
68 |
/* skip notables cases */ |
69 |
if ((g_Asc_printVtables == NULL) || (NULL == name)) { |
70 |
return NULL; |
71 |
} |
72 |
/* LIFO is easy */ |
73 |
vt = g_Asc_printVtables; |
74 |
if ( strcmp(vt->name,name) == 0 ) { |
75 |
g_Asc_printVtables = vt->next; |
76 |
return vt; |
77 |
} |
78 |
/* middle chain is worse */ |
79 |
prev = g_Asc_printVtables; |
80 |
vt = prev->next; |
81 |
while (vt != NULL) { |
82 |
if ( strcmp(vt->name,name) == 0 ) { |
83 |
prev->next = vt->next; |
84 |
return vt; |
85 |
} |
86 |
vt = vt->next; |
87 |
prev = prev->next; |
88 |
} |
89 |
return NULL; |
90 |
} |
91 |
|
92 |
int Asc_PrintHasVTable(CONST char *name) |
93 |
{ |
94 |
struct Asc_PrintVTable *vt; |
95 |
|
96 |
if ((g_Asc_printVtables == NULL) || |
97 |
(NULL == name)) { |
98 |
return FALSE; |
99 |
} |
100 |
vt = g_Asc_printVtables; |
101 |
while (vt != NULL) { |
102 |
if (strcmp(vt->name, name) == 0) { |
103 |
return TRUE; |
104 |
} |
105 |
vt = vt->next; |
106 |
} |
107 |
return FALSE; |
108 |
} |
109 |
|
110 |
|
111 |
/* |
112 |
* int Asc_Printf(format, variable_number_args) |
113 |
* CONST char *format; |
114 |
* variable_number_args; |
115 |
* |
116 |
* Using the sprintf-style format string `format', print the |
117 |
* `variable_number_args' to an approximation of stdout. |
118 |
* |
119 |
* This function just initializes the variable_number_args into a |
120 |
* va_list, and then calls AscPrint to actually do the work. |
121 |
*/ |
122 |
int Asc_Printf(CONST char *format, ...) |
123 |
{ |
124 |
va_list args; /* the variable number of arguments */ |
125 |
int result = 0; /* the result of the call to AscPrint; our return value */ |
126 |
|
127 |
struct Asc_PrintVTable * vt = g_Asc_printVtables; |
128 |
while (vt != NULL) { |
129 |
/* create the va_list */ |
130 |
va_start( args, format ); |
131 |
result = vt->print( stdout, format, args ); |
132 |
/* cleanup */ |
133 |
va_end( args ); |
134 |
vt = vt->next; |
135 |
} |
136 |
/* only the result of the last printer makes it out */ |
137 |
return result; |
138 |
} |
139 |
|
140 |
|
141 |
/* |
142 |
* int Asc_FPrintf(fp, format, variable_number_args) |
143 |
* FILE *fp; |
144 |
* CONST char *format; |
145 |
* variable_number_args; |
146 |
* |
147 |
* Using the sprintf-style format string `format', print the |
148 |
* `variable_number_args' to the file pointer `fp'. |
149 |
* |
150 |
* This function just initializes the variable_number_args into a |
151 |
* va_list, and then calls AscPrint to actually do the work. |
152 |
*/ |
153 |
int Asc_FPrintf(FILE *fp, CONST char *format, ...) |
154 |
{ |
155 |
va_list args; /* the variable number of arguments */ |
156 |
int result=0; /* the result of the call to AscPrint; our return value */ |
157 |
|
158 |
struct Asc_PrintVTable * vt = g_Asc_printVtables; |
159 |
while (vt != NULL) { |
160 |
/* create the va_list */ |
161 |
va_start( args, format ); |
162 |
result = vt->print( fp, format, args ); |
163 |
/* cleanup and return */ |
164 |
va_end( args ); |
165 |
vt = vt->next; |
166 |
} |
167 |
/* only the result of the last printer makes it out */ |
168 |
return result; |
169 |
} |
170 |
|
171 |
/** |
172 |
Var-arg version of the above, used by error.h |
173 |
*/ |
174 |
int Asc_VFPrintf(FILE *fp, CONST char *format, va_list args){ |
175 |
int result=0; /* the result of the call to AscPrint; our return value */ |
176 |
|
177 |
struct Asc_PrintVTable * vt; |
178 |
for(vt = g_Asc_printVtables; vt != NULL; vt = vt->next) { |
179 |
result = vt->print(fp, format, args); |
180 |
} |
181 |
return result; |
182 |
} |
183 |
|
184 |
/* |
185 |
* int Asc_FFlush(fileptr) |
186 |
* FILE *fileptr; |
187 |
* |
188 |
* Flush output to the file pointed to by the file pointer `fileptr'; |
189 |
* return 0 for success and EOF for failure. |
190 |
* |
191 |
* This is needed for consistency with Asc_FPrintf() and Asc_Printf(). |
192 |
*/ |
193 |
int Asc_FFlush( FILE *fileptr ) |
194 |
{ |
195 |
int result = 0; |
196 |
struct Asc_PrintVTable * vt = g_Asc_printVtables; |
197 |
while (vt != NULL) { |
198 |
result = vt->fflush(fileptr); |
199 |
vt = vt->next; |
200 |
} |
201 |
/* only the result of the last printer makes it out */ |
202 |
return result; |
203 |
} |
204 |
|
205 |
|
206 |
/* |
207 |
* int Asc_FPutc( c, fileptr ); |
208 |
* int c; |
209 |
* FILE *fileptr; |
210 |
* |
211 |
* Print the character `c' to the output file pointed to by the |
212 |
* file pointer `fileptr'; return 0 for success and EOF for failure. |
213 |
* |
214 |
* This is needed for consistency with Asc_FPrintf() and Asc_Printf(). |
215 |
*/ |
216 |
int Asc_FPutc( int c, FILE *fileptr ) |
217 |
{ |
218 |
/* |
219 |
* Call vtable list for output to stdout and stderr, or the real putc |
220 |
* for output to other file handles |
221 |
*/ |
222 |
if(( fileptr == stdout ) || ( fileptr == stderr )) { |
223 |
return Asc_FPrintf( fileptr, "%c", c ); |
224 |
} else { |
225 |
return fputc( c, fileptr ); |
226 |
} |
227 |
} |
228 |
|
229 |
|
230 |
/* |
231 |
* int Asc_Putchar( c ); |
232 |
* int c; |
233 |
* |
234 |
* Print the character `c' to `stdout'; return 0 for success and |
235 |
* EOF for failure. |
236 |
* |
237 |
* This is needed for consistency with Asc_FPrintf() and Asc_Printf(). |
238 |
*/ |
239 |
int Asc_Putchar( int c ) |
240 |
{ |
241 |
return Asc_Printf( "%c", c ); |
242 |
} |
243 |
|
244 |
#ifdef ASC_XTERM_COLORS |
245 |
static int color_test(){ |
246 |
static int use_xterm_color = 0; |
247 |
char *term; |
248 |
if(!use_xterm_color){ |
249 |
term = getenv("TERM"); |
250 |
if(term!=NULL){ |
251 |
if(strcmp(term,"msys")==0 || strcmp(term,"xterm")==0){ |
252 |
/* fprintf(stderr,"\n\n\nCOLOR CODES \033[1mWILL\033[0m BE USED\n\n\n"); */ |
253 |
use_xterm_color=1; |
254 |
}else{ |
255 |
use_xterm_color=-1; |
256 |
Asc_FPrintf(stderr,"\n\n\n----------------------------------\nCOLOR CODES WILL NOT BE USED\n\n\n"); |
257 |
} |
258 |
}else{ |
259 |
/*fprintf(stderr,"\n\n\n----------------------------------\nCOLOR CODES WILL NOT BE USED (NO ENV VAR 'TERM')\n\n\n");*/ |
260 |
use_xterm_color=-1; |
261 |
} |
262 |
|
263 |
# ifdef WIN32 |
264 |
/** @TODO see http://msdn2.microsoft.com/en-us/library/ms682088.aspx */ |
265 |
# if 0 |
266 |
term = getenv("CLIENTNAME"); |
267 |
if(term!=NULL){ |
268 |
if(strcmp(term,"Console")==0){ |
269 |
use_xterm_color=1; |
270 |
/* windows command prompt is OK as well */ |
271 |
} |
272 |
} |
273 |
# endif |
274 |
# endif |
275 |
|
276 |
}/*else{ |
277 |
Asc_FPrintf(stderr,"color=%d",use_xterm_color); |
278 |
}*/ |
279 |
return use_xterm_color; |
280 |
} |
281 |
#endif /*ASC_XTERM_COLORS*/ |
282 |
|
283 |
/** |
284 |
Little routine to aid output of XTERM colour codes where supported. |
285 |
Not very efficient, so use sparingly. |
286 |
*/ |
287 |
int color_on(FILE *f, const char *colorcode){ |
288 |
#ifdef ASC_XTERM_COLORS |
289 |
int use_color = color_test(); |
290 |
|
291 |
if(colorcode!=NULL && use_color==1){ |
292 |
return fprintf(f,"\033[%sm",colorcode); |
293 |
} |
294 |
#else |
295 |
(void)f; (void)colorcode; |
296 |
#endif |
297 |
return 0; |
298 |
} |
299 |
|
300 |
/** |
301 |
Little routine to aid output of XTERM colour codes where supported. |
302 |
Not very efficient, so use sparingly. |
303 |
*/ |
304 |
int color_off(FILE *f){ |
305 |
#ifdef ASC_XTERM_COLORS |
306 |
int use_color = color_test(); |
307 |
if(use_color==1){ |
308 |
return fprintf(f,"\033[0m"); |
309 |
} |
310 |
|
311 |
#else |
312 |
(void)f; |
313 |
#endif |
314 |
return 0; |
315 |
} |