Changeset 3215 for trunk/src/kmk/kmkbuiltin/printf.c
- Timestamp:
- Mar 31, 2018, 12:01:55 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/kmkbuiltin/printf.c
r3192 r3215 50 50 * Header Files * 51 51 *********************************************************************************************************************************/ 52 #define FAKES_NO_GETOPT_H /* bird */ 52 53 #if !defined(KMK_BUILTIN_STANDALONE) && !defined(BUILTIN) && !defined(SHELL) 53 54 # include "../makeint.h" … … 70 71 #include <string.h> 71 72 #include <unistd.h> 72 #include "getopt .h"73 #include "getopt_r.h" 73 74 #ifdef __sun__ 74 75 # include "solfakes.h" … … 139 140 { 140 141 PKMKBUILTINCTX pCtx; 142 /* former globals */ 141 143 size_t b_length; 142 144 char *b_fmt; … … 146 148 char *g_o; 147 149 #endif 150 /* former function level statics in common_printf(); both need freeing. */ 151 char *a, *t; 152 153 /* former function level statics in conv_expand(); needs freeing. */ 154 char *conv_str; 155 148 156 /* Buffer the output because windows doesn't do line buffering of stdout. */ 149 157 size_t g_cchBuf; … … 167 175 * Internal Functions * 168 176 *********************************************************************************************************************************/ 169 static int common_printf(PPRINTFINSTANCE pThis, int argc, char *argv[]); 177 static int common_printf(PPRINTFINSTANCE pThis, char *argv[], PKMKBUILTINCTX pCtx); 178 static int common_printf_inner(PPRINTFINSTANCE pThis, char *argv[]); 170 179 static void conv_escape_str(PPRINTFINSTANCE, char *, void (*)(PPRINTFINSTANCE, int)); 171 180 static char *conv_escape(PPRINTFINSTANCE, char *, char *); 172 static c har *conv_expand(const char *);181 static const char *conv_expand(PPRINTFINSTANCE, const char *); 173 182 static int getchr(PPRINTFINSTANCE); 174 183 static double getdouble(PPRINTFINSTANCE); … … 191 200 int kmk_builtin_printf(int argc, char **argv, char **envp, PKMKBUILTINCTX pCtx) 192 201 { 202 PRINTFINSTANCE This; 203 struct getopt_state_r gos; 193 204 int ch; 194 PRINTFINSTANCE This; 195 This.pCtx = pCtx; 196 This.b_length = 0; 197 This.b_fmt = NULL; 198 This.rval = 0; 199 This.gargv = NULL; 200 #ifndef KMK_BUILTIN_STANDALONE 201 This.g_o = NULL; 202 #endif 203 This.g_cchBuf = 0; 204 205 /* kmk: reset getopt, set progname and reset buffer. */ 206 opterr = 1; 207 optarg = NULL; 208 optopt = 0; 209 optind = 0; /* init */ 210 211 while ((ch = getopt_long(argc, argv, "", long_options, NULL)) != -1) { 205 206 getopt_initialize_r(&gos, argc, argv, "", long_options, envp, pCtx); 207 while ((ch = getopt_long_r(&gos, NULL)) != -1) { 212 208 switch (ch) { 213 209 case 261: … … 221 217 } 222 218 } 223 argc -= optind;224 argv += optind;219 argc -= gos.optind; 220 argv += gos.optind; 225 221 226 222 if (argc < 1) 227 223 return usage(pCtx, 1); 228 return common_printf(&This, argc, argv); 224 225 #ifndef KMK_BUILTIN_STANDALONE 226 This.g_o = NULL; 227 #endif 228 return common_printf(&This, argv, pCtx); 229 229 } 230 230 … … 249 249 fatal(NILF, strlen(funcname) + INTSTR_LENGTH, _("$(%s): no format string\n"), funcname); 250 250 251 This.pCtx = NULL;252 This.b_length = 0;253 This.b_fmt = NULL;254 This.rval = 0;255 This.gargv = NULL;256 This.g_cchBuf = 0;257 251 This.g_o = o; 258 259 rc = common_printf(&This, argc, argv); 252 rc = common_printf(&This, argv, NULL); 260 253 o = This.g_o; 261 254 … … 266 259 #endif /* KMK_BUILTIN_STANDALONE */ 267 260 268 static int common_printf(PPRINTFINSTANCE pThis, int argc, char *argv[]) 261 static int common_printf(PPRINTFINSTANCE pThis, char *argv[], PKMKBUILTINCTX pCtx) 262 { 263 int rc; 264 265 /* Init all but g_o. */ 266 pThis->pCtx = pCtx; 267 pThis->b_length = 0; 268 pThis->b_fmt = NULL; 269 pThis->rval = 0; 270 pThis->gargv = NULL; 271 pThis->g_cchBuf = 0; 272 pThis->a = NULL; 273 pThis->t = NULL; 274 pThis->conv_str = NULL; 275 276 rc = common_printf_inner(pThis, argv); 277 278 /* Cleanup allocations. */ 279 if (pThis->a) { 280 free(pThis->a); 281 pThis->a = NULL; 282 } 283 if (pThis->t) { 284 free(pThis->t); 285 pThis->t = NULL; 286 } 287 if (pThis->conv_str) { 288 free(pThis->conv_str); 289 pThis->conv_str = NULL; 290 } 291 return rc; 292 } 293 294 static int common_printf_inner(PPRINTFINSTANCE pThis, char *argv[]) 269 295 { 270 296 char *fmt, *start; … … 275 301 char longbuf[64]; 276 302 277 /* kmk: reinitialize globals */278 pThis->b_length = 0;279 pThis->b_fmt = NULL;280 pThis->rval = 0;281 pThis->gargv = NULL;282 pThis->g_cchBuf = 0;283 303 format = *argv; 284 304 pThis->gargv = ++argv; … … 338 358 339 359 case 'B': { 340 const char *p = conv_expand( getstr(pThis));360 const char *p = conv_expand(pThis, getstr(pThis)); 341 361 *fmt = 's'; 342 362 PF(start, p); … … 347 367 * but the string we generate might have 348 368 * embedded nulls. */ 349 static char *a, *t;350 369 char *cp = getstr(pThis); 351 370 /* Free on entry in case shell longjumped out */ 352 if (a != NULL) 353 free(a); 354 a = NULL; 355 if (t != NULL) 356 free(t); 357 t = NULL; 371 if (pThis->a != NULL) { 372 free(pThis->a); 373 pThis->a = NULL; 374 } 375 if (pThis->t != NULL) { 376 free(pThis->t); 377 pThis->t = NULL; 378 } 358 379 /* Count number of bytes we want to output */ 359 380 pThis->b_length = 0; 360 381 conv_escape_str(pThis, cp, b_count); 361 t = malloc(pThis->b_length + 1);362 if ( t == NULL)382 pThis->t = malloc(pThis->b_length + 1); 383 if (pThis->t == NULL) 363 384 break; 364 memset( t, 'x', pThis->b_length);365 t[pThis->b_length] = 0;385 memset(pThis->t, 'x', pThis->b_length); 386 pThis->t[pThis->b_length] = 0; 366 387 /* Get printf to calculate the lengths */ 367 388 *fmt = 's'; 368 APF(& a, start,t);369 pThis->b_fmt = a;389 APF(&pThis->a, start, pThis->t); 390 pThis->b_fmt = pThis->a; 370 391 /* Output leading spaces and data bytes */ 371 392 conv_escape_str(pThis, cp, b_output); … … 710 731 /* expand a string so that everything is printable */ 711 732 712 static char * 713 conv_expand(const char *str) 714 { 715 static char *conv_str; 716 static char no_memory[] = "<no memory>"; 733 static const char * 734 conv_expand(PPRINTFINSTANCE pThis, const char *str) 735 { 736 static const char no_memory[] = "<no memory>"; 717 737 char *cp; 718 738 int ch; 719 739 720 if ( conv_str)721 free( conv_str);740 if (pThis->conv_str) 741 free(pThis->conv_str); 722 742 /* get a buffer that is definitely large enough.... */ 723 conv_str= malloc(4 * strlen(str) + 1);724 if (!c onv_str)743 pThis->conv_str = cp = malloc(4 * strlen(str) + 1); 744 if (!cp) 725 745 return no_memory; 726 cp = conv_str;727 746 728 747 while ((ch = *(const unsigned char *)str++) != '\0') { … … 771 790 772 791 *cp = 0; 773 return conv_str;792 return pThis->conv_str; 774 793 } 775 794
Note:
See TracChangeset
for help on using the changeset viewer.