| 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 |
#include <stdlib.h> |
| 31 |
#include <stdarg.h> |
| 32 |
#include "utilities/ascConfig.h" |
| 33 |
static struct Asc_PrintVTable *g_Asc_printVtables = NULL; |
| 34 |
/* |
| 35 |
* Only compile this file if we are using Asc_Printf() |
| 36 |
*/ |
| 37 |
#if PRINTF == Asc_PrintF |
| 38 |
|
| 39 |
|
| 40 |
#include "utilities/ascPrint.h" |
| 41 |
|
| 42 |
|
| 43 |
#define PRINT_BUFFER_SIZE 16380 |
| 44 |
|
| 45 |
int Asc_PrintPushVTable(struct Asc_PrintVTable *vtable) |
| 46 |
{ |
| 47 |
if ( vtable == NULL || |
| 48 |
vtable->name == NULL || |
| 49 |
vtable->print == NULL || |
| 50 |
vtable->fflush == NULL |
| 51 |
) { |
| 52 |
return 1; |
| 53 |
} |
| 54 |
/* push it on the stack */ |
| 55 |
assert(vtable->next == NULL); |
| 56 |
vtable->next = g_Asc_printVtables; |
| 57 |
g_Asc_printVtables = vtable; |
| 58 |
return 0; |
| 59 |
} |
| 60 |
|
| 61 |
struct Asc_PrintVTable * Asc_PrintRemoveVTable(CONST char *name) |
| 62 |
{ |
| 63 |
struct Asc_PrintVTable * prev; |
| 64 |
struct Asc_PrintVTable * vt; |
| 65 |
|
| 66 |
/* skip notables case */ |
| 67 |
if (g_Asc_printVtables == NULL) { |
| 68 |
return NULL; |
| 69 |
} |
| 70 |
/* LIFO is easy */ |
| 71 |
vt = g_Asc_printVtables; |
| 72 |
if ( strcmp(vt->name,name) == 0 ) { |
| 73 |
g_Asc_printVtables = vt->next; |
| 74 |
return vt; |
| 75 |
} |
| 76 |
/* middle chain is worse */ |
| 77 |
prev = g_Asc_printVtables; |
| 78 |
vt = prev->next; |
| 79 |
while (vt != NULL) { |
| 80 |
if ( strcmp(vt->name,name) == 0 ) { |
| 81 |
prev->next = vt->next; |
| 82 |
return vt; |
| 83 |
} |
| 84 |
vt = vt->next; |
| 85 |
prev = prev->next; |
| 86 |
} |
| 87 |
return NULL; |
| 88 |
|
| 89 |
} |
| 90 |
|
| 91 |
/* |
| 92 |
* int Asc_Printf(format, variable_number_args) |
| 93 |
* CONST char *format; |
| 94 |
* variable_number_args; |
| 95 |
* |
| 96 |
* Using the sprintf-style format string `format', print the |
| 97 |
* `variable_number_args' to an approximation of stdout. |
| 98 |
* |
| 99 |
* This function just initializes the variable_number_args into a |
| 100 |
* va_list, and then calls AscPrint to actually do the work. |
| 101 |
*/ |
| 102 |
int Asc_Printf(CONST char *format, ...) |
| 103 |
{ |
| 104 |
va_list args; /* the variable number of arguments */ |
| 105 |
int result = 0; /* the result of the call to AscPrint; our return value */ |
| 106 |
|
| 107 |
struct Asc_PrintVTable * vt = g_Asc_printVtables; |
| 108 |
while (vt != NULL) { |
| 109 |
/* create the va_list */ |
| 110 |
va_start( args, format ); |
| 111 |
result = vt->print( stdout, format, args ); |
| 112 |
/* cleanup */ |
| 113 |
va_end( args ); |
| 114 |
vt = vt->next; |
| 115 |
} |
| 116 |
/* only the result of the last printer makes it out */ |
| 117 |
return result; |
| 118 |
} |
| 119 |
|
| 120 |
|
| 121 |
/* |
| 122 |
* int Asc_FPrintf(fp, format, variable_number_args) |
| 123 |
* FILE *fp; |
| 124 |
* CONST char *format; |
| 125 |
* variable_number_args; |
| 126 |
* |
| 127 |
* Using the sprintf-style format string `format', print the |
| 128 |
* `variable_number_args' to the file pointer `fp'. |
| 129 |
* |
| 130 |
* This function just initializes the variable_number_args into a |
| 131 |
* va_list, and then calls AscPrint to actually do the work. |
| 132 |
*/ |
| 133 |
int Asc_FPrintf(FILE *fp, CONST char *format, ...) |
| 134 |
{ |
| 135 |
va_list args; /* the variable number of arguments */ |
| 136 |
int result=0; /* the result of the call to AscPrint; our return value */ |
| 137 |
|
| 138 |
struct Asc_PrintVTable * vt = g_Asc_printVtables; |
| 139 |
while (vt != NULL) { |
| 140 |
/* create the va_list */ |
| 141 |
va_start( args, format ); |
| 142 |
result = vt->print( fp, format, args ); |
| 143 |
/* cleanup and return */ |
| 144 |
va_end( args ); |
| 145 |
vt = vt->next; |
| 146 |
} |
| 147 |
/* only the result of the last printer makes it out */ |
| 148 |
return result; |
| 149 |
} |
| 150 |
|
| 151 |
|
| 152 |
/* |
| 153 |
* int Asc_FFlush(fileptr) |
| 154 |
* FILE *fileptr; |
| 155 |
* |
| 156 |
* Flush output to the file pointed to by the file pointer `fileptr'; |
| 157 |
* return 0 for success and EOF for failure. |
| 158 |
* |
| 159 |
* This is needed for consistency with Asc_FPrintf() and Asc_Printf(). |
| 160 |
*/ |
| 161 |
int Asc_FFlush( FILE *fileptr ) |
| 162 |
{ |
| 163 |
int result = 0; |
| 164 |
struct Asc_PrintVTable * vt = g_Asc_printVtables; |
| 165 |
while (vt != NULL) { |
| 166 |
result = vt->fflush(fileptr); |
| 167 |
vt = vt->next; |
| 168 |
} |
| 169 |
/* only the result of the last printer makes it out */ |
| 170 |
return result; |
| 171 |
} |
| 172 |
|
| 173 |
|
| 174 |
/* |
| 175 |
* int Asc_FPutc( c, fileptr ); |
| 176 |
* int c; |
| 177 |
* FILE *fileptr; |
| 178 |
* |
| 179 |
* Print the character `c' to the output file pointed to by the |
| 180 |
* file pointer `fileptr'; return 0 for success and EOF for failure. |
| 181 |
* |
| 182 |
* This is needed for consistency with Asc_FPrintf() and Asc_Printf(). |
| 183 |
*/ |
| 184 |
int Asc_FPutc( int c, FILE *fileptr ) |
| 185 |
{ |
| 186 |
/* |
| 187 |
* Call vtable list for output to stdout and stderr, or the real putc |
| 188 |
* for output to other file handles |
| 189 |
*/ |
| 190 |
if(( fileptr == stdout ) || ( fileptr == stderr )) { |
| 191 |
return Asc_FPrintf( fileptr, "%c", c ); |
| 192 |
} else { |
| 193 |
return fputc( c, fileptr ); |
| 194 |
} |
| 195 |
} |
| 196 |
|
| 197 |
|
| 198 |
/* |
| 199 |
* int Asc_Putchar( c ); |
| 200 |
* int c; |
| 201 |
* |
| 202 |
* Print the character `c' to `stdout'; return 0 for success and |
| 203 |
* EOF for failure. |
| 204 |
* |
| 205 |
* This is needed for consistency with Asc_FPrintf() and Asc_Printf(). |
| 206 |
*/ |
| 207 |
int Asc_Putchar( int c ) |
| 208 |
{ |
| 209 |
return Asc_Printf( "%c", c ); |
| 210 |
} |
| 211 |
|
| 212 |
#endif /* PRINTF == Asc_Printf */ |