ReactOS  r76032
format.c
Go to the documentation of this file.
1 /* @(#)format.c 1.62 17/08/03 Copyright 1985-2017 J. Schilling */
2 /*
3  * format
4  * common code for printf fprintf & sprintf
5  *
6  * allows recursive printf with "%r", used in:
7  * error, comerr, comerrno, errmsg, errmsgno and the like
8  *
9  * Copyright (c) 1985-2017 J. Schilling
10  */
11 /*
12  * The contents of this file are subject to the terms of the
13  * Common Development and Distribution License, Version 1.0 only
14  * (the "License"). You may not use this file except in compliance
15  * with the License.
16  *
17  * See the file CDDL.Schily.txt in this distribution for details.
18  * A copy of the CDDL is also available via the Internet at
19  * http://www.opensource.org/licenses/cddl1.txt
20  *
21  * When distributing Covered Code, include this CDDL HEADER in each
22  * file and include the License file CDDL.Schily.txt from this distribution.
23  */
24 
25 #include <schily/mconfig.h>
26 #include <schily/varargs.h>
27 #include <schily/string.h>
28 #include <schily/stdlib.h>
29 #ifdef DEBUG
30 #include <schily/unistd.h>
31 #endif
32 #if !defined(HAVE_STDLIB_H) || !defined(HAVE_GCVT)
33 extern char *gcvt __PR((double, int, char *));
34 #endif
35 #include <schily/standard.h>
36 #include <schily/utypes.h>
37 #include <schily/schily.h>
38 
39 /*
40  * As Llong is currently a 'best effort' long long, we usually need to
41  * include long long print formats.
42  * This may go away, if we implement maxint_t formats.
43  */
44 #ifndef USE_LONGLONG
45 #define USE_LONGLONG
46 #endif
47 
48 #ifdef NO_LONGLONG
49 #undef USE_LONGLONG
50 #endif
51 
52 #ifndef USE_NL_ARGS
53 #define USE_NL_ARGS
54 #endif
55 
56 #ifdef NO_NL_ARGS
57 #undef USE_NL_ARGS
58 #endif
59 
60 /*
61  * Avoid to keep copies of the variable arg list in case that
62  * format() was compiled without including NL support for
63  * argument reordering.
64  */
65 #ifdef USE_NL_ARGS
66 #define args fargs.ap /* Use working copy */
67 #else
68 #define args oargs /* Directly use format() arg */
69 #endif
70 
71 /*
72  * We may need to decide whether we should check whether all
73  * flags occur according to the standard which is either directly past:
74  * "%" or directly past "%n$".
75  *
76  * This however may make printf() slower in some cases.
77  */
78 #ifdef USE_CHECKFLAG
79 #define CHECKFLAG() if (fa.flags & GOTSTAR) goto flagerror
80 #else
81 #define CHECKFLAG()
82 #endif
83 
84 #ifdef NO_USER_XCVT
85  /*
86  * We cannot define our own gcvt() so we need to use a
87  * local name instead.
88  */
89 #ifndef HAVE_GCVT
90 # define gcvt js_gcvt
91 EXPORT char *gcvt __PR((double value, int ndigit, char *buf));
92 #endif
93 #endif
94 
95 /*
96  * Some CPU's (e.g. PDP-11) cannot do logical shifts.
97  * They use rotate instead. Masking the low bits before,
98  * makes rotate work too.
99  */
100 #define allmask(t) ((unsigned t)~((unsigned t)0))
101 #define lowmask(t, x) ((unsigned t)~((unsigned t)((1 << (x))-1)))
102 #define rshiftmask(t, s)((allmask(t) & lowmask(t, s)) >> (s))
103 
104 #define CHARMASK makemask(char)
105 #define SHORTMASK makemask(short)
106 #define INTMASK makemask(int)
107 #define LONGMASK makemask(long)
108 
109 #ifdef DIVLBYS
110 extern long divlbys();
111 extern long modlbys();
112 #else
113 #define divlbys(val, base) ((val)/(base))
114 #define modlbys(val, base) ((val)%(base))
115 #endif
116 
117 /*
118  * We use macros here to avoid the need to link to the international
119  * character routines.
120  * We don't need internationalization for our purpose.
121  */
122 #define is_dig(c) (((c) >= '0') && ((c) <= '9'))
123 #define is_cap(c) ((c) >= 'A' && (c) <= 'Z')
124 #define to_cap(c) (is_cap(c) ? c : c - 'a' + 'A')
125 #define cap_ty(c) (is_cap(c) ? 'L' : 'I')
126 
127 #ifdef HAVE_LONGLONG
128 typedef union {
129  Ullong ll;
130  Ulong l[2];
131  char c[8];
132 } quad_u;
133 #endif
134 
135 typedef struct f_args {
136 #ifdef FORMAT_BUFFER
137 #define BFSIZ 256
138  char *ptr; /* Current ptr in buf */
139  int cnt; /* Free char count in buf */
140 #else
141  void (*outf)__PR((char, void *)); /* Func from format(fun, arg) */
142 #endif
143  void *farg; /* Arg from format (fun, arg) */
144  int minusflag; /* Fieldwidth is negative */
145  int flags; /* General flags (+-#) */
146  int fldwidth; /* Field width as in %3d */
147  int signific; /* Significant chars as in %.4d */
148  int lzero; /* Left '0' pad flag */
149  char *buf; /* Out print buffer */
150  char *bufp; /* Write ptr into buffer */
151  char fillc; /* Left fill char (' ' or '0') */
152  char *prefix; /* Prefix to print before buf */
153  int prefixlen; /* Len of prefix ('+','-','0x') */
154 #ifdef FORMAT_BUFFER
155  /* rarely used members last: */
156  char iobuf[BFSIZ]; /* buffer for stdio */
157  FILE *fp; /* FILE * for fprformat() */
158  int err; /* FILE * I/O error */
159 #endif
160 } f_args;
161 
162 #define MINUSFLG 1 /* '-' flag */
163 #define PLUSFLG 2 /* '+' flag */
164 #define SPACEFLG 4 /* ' ' flag */
165 #define HASHFLG 8 /* '#' flag */
166 #define APOFLG 16 /* '\'' flag */
167 #define GOTDOT 32 /* '.' found */
168 #define GOTSTAR 64 /* '*' found */
169 
170 #define FMT_ARGMAX 30 /* Number of fast args */
171 
172 LOCAL void prnum __PR((Ulong, unsigned, f_args *));
173 LOCAL void prdnum __PR((Ulong, f_args *));
174 LOCAL void pronum __PR((Ulong, f_args *));
175 LOCAL void prxnum __PR((Ulong, f_args *));
176 LOCAL void prXnum __PR((Ulong, f_args *));
177 #ifdef USE_LONGLONG
178 LOCAL void prlnum __PR((Ullong, unsigned, f_args *));
179 LOCAL void prldnum __PR((Ullong, f_args *));
180 LOCAL void prlonum __PR((Ullong, f_args *));
181 LOCAL void prlxnum __PR((Ullong, f_args *));
182 LOCAL void prlXnum __PR((Ullong, f_args *));
183 #endif
184 LOCAL int prbuf __PR((const char *, f_args *));
185 LOCAL int prc __PR((char, f_args *));
186 LOCAL int prstring __PR((const char *, f_args *));
187 #ifdef DEBUG
188 LOCAL void dbg_print __PR((char *fmt, int a, int b, int c, int d, int e, int f, int g, int h, int i));
189 #endif
190 
191 #ifdef USE_NL_ARGS
192 #ifndef FORMAT_FUNC_NAME
193 #define FORMAT_IMPL
194 EXPORT void _fmtarglist __PR((const char *fmt, va_lists_t, va_lists_t arglist[]));
195 EXPORT void _fmtgetarg __PR((const char *fmt, int num, va_lists_t *));
196 #else
197 extern void _fmtarglist __PR((const char *fmt, va_lists_t, va_lists_t arglist[]));
198 extern void _fmtgetarg __PR((const char *fmt, int num, va_lists_t *));
199 #endif
200 #endif
201 
202 #ifdef FORMAT_BUFFER
203 LOCAL char xflsbuf __PR((int c, f_args *ap));
204 
205 LOCAL char
206 xflsbuf(c, ap)
207  int c;
208  f_args *ap;
209 {
210  *ap->ptr++ = c;
211  if (filewrite((FILE *)ap->fp, ap->iobuf, ap->ptr - ap->iobuf) < 0)
212  ap->err = 1;
213 
214  ap->cnt = BFSIZ;
215  ap->ptr = ap->iobuf;
216  return (c);
217 }
218 
219 #undef ofun
220 #define ofun(c, xp) (--((f_args *)xp)->cnt <= 0 ? \
221  xflsbuf(c, (f_args *)xp) : \
222  (*(((f_args *)xp)->ptr)++ = (c)))
223 
224 #endif
225 
226 #ifndef FORMAT_FUNC_NAME
227 #define FORMAT_FUNC_NAME format
228 #define FORMAT_FUNC_PARM
229 
230 #define FORMAT_FUNC_PROTO_DECL void (*fun)(char, void *),
231 #define FORMAT_FUNC_KR_DECL register void (*fun)();
232 #define FORMAT_FUNC_KR_ARGS fun,
233 
234 #define ofun(c, fp) (*fun)(c, fp)
235 #endif
236 
237 #ifdef FORMAT_BUFFER
238 #define FARG ((void *)((UIntptr_t)farg|1))
239 #else
240 #define FARG farg
241 #endif
242 
243 #ifdef PROTOTYPES
244 EXPORT int
246  void *farg,
247  const char *fmt,
248  va_list oargs)
249 #else
250 EXPORT int
251 FORMAT_FUNC_NAME(FORMAT_FUNC_KR_ARGS farg, fmt, oargs)
253  register void *farg;
254  register char *fmt;
255  va_list oargs;
256 #endif
257 {
258 #ifdef FORMAT_LOW_MEM
259  char buf[512];
260 #else
261  char buf[8192];
262 #endif
263  const char *sfmt;
264  register int unsflag;
265  register long val;
266  register char type;
267  register char mode;
268  register char c;
269  int count;
270  int num;
271  int i;
272  short sh;
273  const char *str;
274  double dval;
275 #ifdef USE_LONGLONG
277 #endif
279  char *rfmt;
281 #ifdef USE_NL_ARGS
282  va_lists_t fargs; /* Used to get arguments */
283  va_lists_t sargs; /* Saved argument state */
284  va_lists_t arglist[FMT_ARGMAX+1]; /* List of fast args */
285  const char *ofmt = fmt; /* Saved original format */
286  BOOL didlist = FALSE; /* Need to scan arguments */
287 #endif
288 
289 #ifdef FORMAT_BUFFER
290  if (((UIntptr_t)farg & 1) == 0) { /* Called externally */
291  fa.cnt = BFSIZ;
292  fa.ptr = fa.iobuf;
293  fa.fp = (FILE *)farg;
294  fa.err = 0;
295  farg = fa.farg = &fa;
296  } else { /* recursion */
297  farg = (void *)((UIntptr_t)farg & ~1);
298  }
299 #endif
300 #ifdef FORMAT_FUNC_PARM
301  fa.outf = fun;
302 #endif
303  fa.farg = farg;
304  count = 0;
305 
306 #ifdef USE_NL_ARGS
307  va_copy(sargs.ap, oargs); /* Keep a copy in sargs */
308  fargs = sargs; /* Make a working copy */
309 #endif
310 
311  /*
312  * Main loop over the format string.
313  * Increment and check for end of string is made here.
314  */
315  for (; *fmt != '\0'; fmt++) {
316  c = *fmt;
317  while (c != '%') {
318  if (c == '\0')
319  goto out;
320  ofun(c, farg);
321  c = *(++fmt);
322  count++;
323  }
324 
325  /*
326  * We reached a '%' sign.
327  */
328  buf[0] = '\0';
329  fa.buf = fa.bufp = buf;
330  fa.minusflag = 0;
331  fa.flags = 0;
332  fa.fldwidth = 0;
333  fa.signific = -1;
334  fa.lzero = 0;
335  fa.fillc = ' ';
336  fa.prefixlen = 0;
337  sfmt = fmt;
338  unsflag = FALSE;
339  type = '\0';
340  mode = '\0';
341  /*
342  * %<flags>f.s<length-mod><conversion-spec>
343  * %<flags>*.*<length-mod><conversion-spec>
344  * %n$<flags>f.s<length-mod><conversion-spec>
345  * %n$<flags>*n$.*n$<length-mod><conversion-spec>
346  */
347  newflag:
348  switch (*(++fmt)) {
349 
350  case '+':
351  CHECKFLAG();
352  fa.flags |= PLUSFLG;
353  goto newflag;
354 
355  case '-':
356  CHECKFLAG();
357  fa.minusflag++;
358  fa.flags |= MINUSFLG;
359  goto newflag;
360 
361  case ' ':
362  CHECKFLAG();
363  /*
364  * If the space and the + flag are present,
365  * the space flag will be ignored.
366  */
367  fa.flags |= SPACEFLG;
368  goto newflag;
369 
370  case '#':
371  CHECKFLAG();
372  fa.flags |= HASHFLG;
373  goto newflag;
374 
375  case '\'':
376  CHECKFLAG();
377  fa.flags |= APOFLG;
378  goto newflag;
379 
380  case '.':
381  fa.flags |= GOTDOT;
382  fa.signific = 0;
383  goto newflag;
384 
385  case '*':
386  fa.flags |= GOTSTAR;
387 #ifdef USE_NL_ARGS
388  if (is_dig(fmt[1])) { /* *n$ */
389  fmt++; /* Eat up '*' */
390  goto dodig;
391  }
392 #endif
393  if (!(fa.flags & GOTDOT)) {
394  fa.fldwidth = va_arg(args, int);
395  /*
396  * A negative fieldwith is a minus flag with a
397  * positive fieldwidth.
398  */
399  if (fa.fldwidth < 0) {
400  fa.fldwidth = -fa.fldwidth;
401  fa.minusflag = 1;
402  }
403  } else {
404  /*
405  * A negative significance (precision) is taken
406  * as if the precision and '.' were omitted.
407  */
408  fa.signific = va_arg(args, int);
409  if (fa.signific < 0)
410  fa.signific = -1;
411  }
412  goto newflag;
413 
414  case '0':
415  /*
416  * '0' may be a flag.
417  */
418  if (!(fa.flags & (GOTDOT | GOTSTAR | MINUSFLG)))
419  fa.fillc = '0';
420  /* FALLTHRU */
421  case '1': case '2': case '3': case '4':
422  case '5': case '6': case '7': case '8': case '9':
423 #ifdef USE_NL_ARGS
424  dodig:
425 #endif
426  num = *fmt++ - '0';
427  while (c = *fmt, is_dig(c)) {
428  num *= 10;
429  num += c - '0';
430  fmt++;
431  }
432 #ifdef USE_NL_ARGS
433  if (c == '$')
434  goto doarglist;
435 #endif
436  fmt--; /* backup to last digit */
437  if (!(fa.flags & GOTDOT))
438  fa.fldwidth = num;
439  else
440  fa.signific = num;
441  goto newflag;
442 
443 #ifdef USE_NL_ARGS
444  doarglist:
445  {
446  va_lists_t tmp; /* Temporary arg state */
447  if (num <= 0) /* Illegal arg offset */
448  goto newflag; /* Continue after '$' */
449  if (!didlist) { /* Need to init arglist */
450  _fmtarglist(ofmt, sargs, arglist);
451  didlist = TRUE;
452  }
453  if (num <= FMT_ARGMAX) {
454  tmp = arglist[num-1];
455  } else {
456  tmp = arglist[FMT_ARGMAX-1];
457  _fmtgetarg(ofmt, num, &tmp);
458  }
459  if (!(fa.flags & GOTSTAR)) {
460  fargs = tmp;
461  } else {
462  if (!(fa.flags & GOTDOT)) {
463  fa.fldwidth = va_arg(tmp.ap, int);
464  /*
465  * A negative fieldwith is a minus flag
466  * with a positive fieldwidth.
467  */
468  if (fa.fldwidth < 0) {
469  fa.fldwidth = -fa.fldwidth;
470  fa.minusflag = 1;
471  }
472  } else {
473  /*
474  * A negative significance (precision)
475  * is taken as if the precision and '.'
476  * were omitted.
477  */
478  fa.signific = va_arg(tmp.ap, int);
479  if (fa.signific < 0)
480  fa.signific = -1;
481  }
482  }
483  goto newflag;
484  }
485 #endif
486 
487 #ifdef USE_CHECKFLAG
488  flagerror:
489  fmt = ++sfmt; /* Don't print '%' */
490  continue;
491 #endif
492  }
493 
494  if (strchr("UCSIL", *fmt)) {
495  /*
496  * Enhancements to K&R and ANSI:
497  *
498  * got a type specifyer
499  *
500  * XXX 'S' in C99 is %ls, 'S' should become 'H'
501  */
502  if (*fmt == 'U') {
503  fmt++;
504  unsflag = TRUE;
505  }
506  if (!strchr("CSILZODX", *fmt)) {
507  /*
508  * Got only 'U'nsigned specifyer,
509  * use default type and mode.
510  */
511  type = 'I';
512  mode = 'D';
513  fmt--;
514  } else if (!strchr("CSIL", *fmt)) {
515  /*
516  * no type, use default
517  */
518  type = 'I';
519  mode = *fmt;
520  } else {
521  /*
522  * got CSIL type
523  */
524  type = *fmt++;
525  if (!strchr("ZODX", mode = *fmt)) {
526  /*
527  * Check long double "Le", "Lf" or "Lg"
528  */
529  if (type == 'L' &&
530  (mode == 'e' ||
531  mode == 'f' ||
532  mode == 'g'))
533  goto checkfmt;
534  fmt--;
535  mode = 'D'; /* default mode */
536  }
537  }
538  } else {
539  checkfmt:
540  switch (*fmt) {
541 
542  case 'h':
543  if (!type)
544  type = 'H'; /* convert to short type */
545  goto getmode;
546 
547  case 'l':
548  if (!type)
549  type = 'L'; /* convert to long type */
550  goto getmode;
551 
552  case 'j':
553  if (!type)
554  type = 'J'; /* convert to intmax_t type */
555  goto getmode;
556 
557  case 'z': /* size_t */
558 #if SIZEOF_SIZE_T == SIZEOF_INT
559  if (!type)
560  type = 'I'; /* convert to int type */
561 #else
562 #if SIZEOF_SIZE_T == SIZEOF_LONG_INT
563  if (!type)
564  type = 'L'; /* convert to long type */
565 #else
566 #if SIZEOF_SIZE_T == SIZEOF_LLONG
567  if (!type)
568  type = 'Q'; /* convert to long long type */
569 #else
570 error sizeof (size_t) is unknown
571 #endif
572 #endif
573 #endif
574  goto getmode;
575 
576  case 't': /* ptrdiff_t */
577 #if SIZEOF_PTRDIFF_T == SIZEOF_INT
578  if (!type)
579  type = 'I'; /* convert to int type */
580 #else
581 #if SIZEOF_PTRDIFF_T == SIZEOF_LONG_INT
582  if (!type)
583  type = 'L'; /* convert to long type */
584 #else
585 #if SIZEOF_PTRDIFF_T == SIZEOF_LLONG
586  if (!type)
587  type = 'Q'; /* convert to long long type */
588 #else
589 error sizeof (ptrdiff_t) is unknown
590 #endif
591 #endif
592 #endif
593  /*
594  * XXX Future length modifiers:
595  * XXX 'L' with double: long double
596  */
597 
598  getmode:
599  if (!strchr("udioxXn", *(++fmt))) {
600  /*
601  * %hhd -> char in decimal
602  */
603  if (type == 'H' && *fmt == 'h') {
604  type = 'C';
605  goto getmode;
606  }
607 #ifdef USE_LONGLONG
608  if (type == 'L' && *fmt == 'l') {
609  type = 'Q';
610  goto getmode;
611  }
612 #endif
613  fmt--;
614  mode = 'D';
615  } else { /* One of "udioxXn": */
616  mode = *fmt;
617  if (mode == 'n')
618  goto gotn;
619  if (mode != 'x')
620  mode = to_cap(mode);
621  if (mode == 'U')
622  unsflag = TRUE;
623  else if (mode == 'I') /* XXX */
624  mode = 'D';
625  }
626  break;
627  case 'x':
628  mode = 'x';
629  goto havemode;
630  case 'X':
631  mode = 'X';
632  type = 'I';
633  goto havemode;
634  case 'u':
635  unsflag = TRUE;
636  /*
637  * XXX Need to remove uppercase letters for 'long'
638  * XXX in future for POSIX/C99 compliance.
639  */
640  /* FALLTHRU */
641  case 'o': case 'O':
642  case 'd': case 'D':
643  case 'i': case 'I':
644  case 'Z':
645  mode = to_cap(*fmt);
646  havemode:
647  if (!type)
648  type = cap_ty(*fmt);
649 #ifdef DEBUG
650  dbg_print("*fmt: '%c' mode: '%c' type: '%c'\n",
651  *fmt, mode, type);
652 #endif
653  if (mode == 'I') /* XXX kann entfallen */
654  mode = 'D'; /* wenn besseres uflg */
655  break;
656  case 'p':
657  mode = 'P';
658  type = 'L';
659  break;
660 
661  case '%':
662  count += prc('%', &fa);
663  continue;
664  case ' ':
665  count += prbuf("", &fa);
666  continue;
667  case 'c':
668  c = va_arg(args, int);
669  count += prc(c, &fa);
670  continue;
671  case 's':
672  str = va_arg(args, char *);
673  count += prstring(str, &fa);
674  continue;
675  case 'b':
676  str = va_arg(args, char *);
677  fa.signific = va_arg(args, int);
678  count += prstring(str, &fa);
679  continue;
680 
681 #ifndef NO_FLOATINGPOINT
682  case 'e':
683  if (fa.signific == -1)
684  fa.signific = 6;
685  if (type == 'L') {
686 #ifdef HAVE_LONGDOUBLE
687  long double ldval = va_arg(args, long double);
688 
689 #if (defined(HAVE_QECVT) || defined(HAVE__LDECVT))
690  qftoes(buf, ldval, 0, fa.signific);
691  count += prbuf(buf, &fa);
692  continue;
693 #else
694  dval = ldval;
695 #endif
696 #endif
697  }
698  dval = va_arg(args, double);
699  ftoes(buf, dval, 0, fa.signific);
700  count += prbuf(buf, &fa);
701  continue;
702  case 'f':
703  if (fa.signific == -1)
704  fa.signific = 6;
705  if (type == 'L') {
706 #ifdef HAVE_LONGDOUBLE
707  long double ldval = va_arg(args, long double);
708 
709 #if (defined(HAVE_QFCVT) || defined(HAVE__LDFCVT))
710  qftofs(buf, ldval, 0, fa.signific);
711  count += prbuf(buf, &fa);
712  continue;
713 #else
714  dval = ldval;
715 #endif
716 #endif
717  }
718  dval = va_arg(args, double);
719  ftofs(buf, dval, 0, fa.signific);
720  count += prbuf(buf, &fa);
721  continue;
722  case 'g':
723  if (fa.signific == -1)
724  fa.signific = 6;
725  if (fa.signific == 0)
726  fa.signific = 1;
727  if (type == 'L') {
728 #ifdef HAVE_LONGDOUBLE
729  long double ldval = va_arg(args, long double);
730 
731 #if (defined(HAVE_QGCVT) || defined(HAVE__LDGCVT))
732 
733 #ifdef HAVE__LDGCVT
734 #define qgcvt(ld, n, b) _ldgcvt(*(long_double *)&ld, n, b)
735 #endif
736  (void) qgcvt(ldval, fa.signific, buf);
737  count += prbuf(buf, &fa);
738  continue;
739 #else
740  dval = ldval;
741 #endif
742 #endif
743  }
744  dval = va_arg(args, double);
745  (void) gcvt(dval, fa.signific, buf);
746  count += prbuf(buf, &fa);
747  continue;
748 #else
749 # ifdef USE_FLOATINGARGS
750  case 'e':
751  case 'f':
752  case 'g':
753  dval = va_arg(args, double);
754  continue;
755 # endif
756 #endif
757 
758  case 'r': /* recursive printf */
759  case 'R': /* recursive printf */
760  rfmt = va_arg(args, char *);
761  /*
762  * I don't know any portable way to get an arbitrary
763  * C object from a var arg list so I use a
764  * system-specific routine __va_arg_list() that knows
765  * if 'va_list' is an array. You will not be able to
766  * assign the value of __va_arg_list() but it works
767  * to be used as an argument of a function.
768  * It is a requirement for recursive printf to be able
769  * to use this function argument. If your system
770  * defines va_list to be an array you need to know this
771  * via autoconf or another mechanism.
772  * It would be nice to have something like
773  * __va_arg_list() in stdarg.h
774  */
776  FARG, rfmt, __va_arg_list(args));
777  continue;
778 
779  gotn:
780  case 'n':
781  switch (type) {
782 
783  case 'C': {
784  signed char *cp = va_arg(args, signed char *);
785 
786  *cp = count;
787  }
788  continue;
789  case 'H': {
790  short *sp = va_arg(args, short *);
791 
792  *sp = count;
793  }
794  continue;
795  case 'L': {
796  long *lp = va_arg(args, long *);
797 
798  *lp = count;
799  }
800  continue;
801 #ifdef USE_LONGLONG
802  case 'J': /* For now Intmax_t is Llong */
803  case 'Q': {
804  Llong *qp = va_arg(args, Llong *);
805 
806  *qp = count;
807  }
808  continue;
809 #endif
810  default: {
811  int *ip = va_arg(args, int *);
812 
813  *ip = count;
814  }
815  continue;
816  }
817 
818  default: /* Unknown '%' format */
819  sfmt++; /* Dont't print '%' */
820  count += fmt - sfmt;
821  while (sfmt < fmt)
822  ofun(*(sfmt++), farg);
823  if (*fmt == '\0') {
824  fmt--;
825  continue;
826  } else {
827  ofun(*fmt, farg);
828  count++;
829  continue;
830  }
831  }
832  }
833  /*
834  * print numbers:
835  * first prepare type 'C'har, s'H'ort, 'I'nt, or 'L'ong
836  * or 'Q'ad and 'J'==maxint_t
837  */
838  switch (type) {
839 
840  case 'C':
841  c = va_arg(args, int);
842  val = c; /* extend sign here */
843  if (unsflag || mode != 'D')
844 #ifdef DO_MASK
845  val &= CHARMASK;
846 #else
847  val = (unsigned char)val;
848 #endif
849  break;
850  case 'H':
851  case 'S': /* XXX remove 'S' in future */
852  sh = va_arg(args, int);
853  val = sh; /* extend sign here */
854  if (unsflag || mode != 'D')
855 #ifdef DO_MASK
856  val &= SHORTMASK;
857 #else
858  val = (unsigned short)val;
859 #endif
860  break;
861  case 'I':
862  default:
863  i = va_arg(args, int);
864  val = i; /* extend sign here */
865  if (unsflag || mode != 'D')
866 #ifdef DO_MASK
867  val &= INTMASK;
868 #else
869  val = (unsigned int)val;
870 #endif
871  break;
872  case 'P':
873  case 'L':
874  val = va_arg(args, long);
875  break;
876 #ifdef USE_LONGLONG
877  case 'J': /* For now Intmax_t is Llong */
878  type = 'Q'; /* use 'Q' for processing */
879  case 'Q':
880  llval = va_arg(args, Llong);
881  val = llval != 0;
882  break;
883 #endif
884  }
885 
886  /*
887  * Final print out, take care of mode:
888  * mode is one of: 'O'ctal, 'D'ecimal, or he'X'
889  * oder 'Z'weierdarstellung.
890  */
891  fa.bufp = &buf[sizeof (buf)-1];
892  *--fa.bufp = '\0';
893 
894  if (val == 0 && mode != 'D') {
895  printzero:
896  /*
897  * Printing '0' with fieldwidth 0 results in no chars.
898  */
899  fa.lzero = -1;
900  if (fa.signific >= 0)
901  fa.fillc = ' ';
902  count += prstring("0", &fa);
903  continue;
904  } else switch (mode) {
905 
906  case 'D':
907 #ifdef USE_LONGLONG
908  if (type == 'Q') {
909  if (!unsflag && llval < 0) {
910  fa.prefix = "-";
911  fa.prefixlen = 1;
912  llval = -llval;
913  } else if (fa.flags & PLUSFLG) {
914  fa.prefix = "+";
915  fa.prefixlen = 1;
916  } else if (fa.flags & SPACEFLG) {
917  fa.prefix = " ";
918  fa.prefixlen = 1;
919  }
920  if (llval == 0)
921  goto printzero;
922  goto prunsigned;
923  }
924 #endif
925  if (!unsflag && val < 0) {
926  fa.prefix = "-";
927  fa.prefixlen = 1;
928  val = -val;
929  } else if (fa.flags & PLUSFLG) {
930  fa.prefix = "+";
931  fa.prefixlen = 1;
932  } else if (fa.flags & SPACEFLG) {
933  fa.prefix = " ";
934  fa.prefixlen = 1;
935  }
936  if (val == 0)
937  goto printzero;
938  /* FALLTHRU */
939  case 'U':
940  /* output a long unsigned decimal number */
941 #ifdef USE_LONGLONG
942  prunsigned:
943  if (type == 'Q')
944  prldnum(llval, &fa);
945  else
946 #endif
947  prdnum(val, &fa);
948  break;
949  case 'O':
950  /* output a long octal number */
951  if (fa.flags & HASHFLG) {
952  fa.prefix = "0";
953  fa.prefixlen = 1;
954  }
955 #ifdef USE_LONGLONG
956  if (type == 'Q') {
957  prlonum(llval, &fa);
958  } else
959 #endif
960  {
961  pronum(val & 07, &fa);
962  if ((res = (val>>3) & rshiftmask(long, 3)) != 0)
963  pronum(res, &fa);
964  }
965  break;
966  case 'p':
967  case 'x':
968  /* output a hex long */
969  if (fa.flags & HASHFLG) {
970  fa.prefix = "0x";
971  fa.prefixlen = 2;
972  }
973 #ifdef USE_LONGLONG
974  if (type == 'Q')
975  prlxnum(llval, &fa);
976  else
977 #endif
978  {
979  prxnum(val & 0xF, &fa);
980  if ((res = (val>>4) & rshiftmask(long, 4)) != 0)
981  prxnum(res, &fa);
982  }
983  break;
984  case 'P':
985  case 'X':
986  /* output a hex long */
987  if (fa.flags & HASHFLG) {
988  fa.prefix = "0X";
989  fa.prefixlen = 2;
990  }
991 #ifdef USE_LONGLONG
992  if (type == 'Q')
993  prlXnum(llval, &fa);
994  else
995 #endif
996  {
997  prXnum(val & 0xF, &fa);
998  if ((res = (val>>4) & rshiftmask(long, 4)) != 0)
999  prXnum(res, &fa);
1000  }
1001  break;
1002  case 'Z':
1003  /* output a binary long */
1004 #ifdef USE_LONGLONG
1005  if (type == 'Q')
1006  prlnum(llval, 2, &fa);
1007  else
1008 #endif
1009  {
1010  prnum(val & 0x1, 2, &fa);
1011  if ((res = (val>>1) & rshiftmask(long, 1)) != 0)
1012  prnum(res, 2, &fa);
1013  }
1014  }
1015  fa.lzero = -1;
1016  /*
1017  * If a precision (fielwidth) is specified
1018  * on diouXx conversions, the '0' flag is ignored.
1019  */
1020  if (fa.signific >= 0)
1021  fa.fillc = ' ';
1022  count += prbuf(fa.bufp, &fa);
1023  }
1024 out:
1025 #ifdef FORMAT_BUFFER
1026  if (farg == &fa) { /* Top level call, flush buffer */
1027  if (fa.err)
1028  return (EOF);
1029  if ((fa.ptr != fa.iobuf) &&
1030  (filewrite(fa.fp, fa.iobuf, fa.ptr - fa.iobuf) < 0))
1031  return (EOF);
1032  }
1033 #endif
1034  return (count);
1035 }
1036 
1037 /*
1038  * Routines to print (not negative) numbers in an arbitrary base
1039  */
1040 LOCAL unsigned char dtab[] = "0123456789abcdef";
1041 LOCAL unsigned char udtab[] = "0123456789ABCDEF";
1042 
1043 LOCAL void
1044 prnum(val, base, fa)
1045  register Ulong val;
1046  register unsigned base;
1047  f_args *fa;
1048 {
1049  register char *p = fa->bufp;
1050 
1051  do {
1052  *--p = dtab[modlbys(val, base)];
1053  val = divlbys(val, base);
1054  } while (val > 0);
1055 
1056  fa->bufp = p;
1057 }
1058 
1059 LOCAL void
1060 prdnum(val, fa)
1061  register Ulong val;
1062  f_args *fa;
1063 {
1064  register char *p = fa->bufp;
1065 
1066  do {
1067  *--p = dtab[modlbys(val, (unsigned)10)];
1068  val = divlbys(val, (unsigned)10);
1069  } while (val > 0);
1070 
1071  fa->bufp = p;
1072 }
1073 
1074 /*
1075  * We may need to use division here too (PDP-11, non two's complement ...)
1076  */
1077 LOCAL void
1078 pronum(val, fa)
1079  register Ulong val;
1080  f_args *fa;
1081 {
1082  register char *p = fa->bufp;
1083 
1084  do {
1085  *--p = dtab[val & 7];
1086  val >>= 3;
1087  } while (val > 0);
1088 
1089  fa->bufp = p;
1090 }
1091 
1092 LOCAL void
1093 prxnum(val, fa)
1094  register Ulong val;
1095  f_args *fa;
1096 {
1097  register char *p = fa->bufp;
1098 
1099  do {
1100  *--p = dtab[val & 15];
1101  val >>= 4;
1102  } while (val > 0);
1103 
1104  fa->bufp = p;
1105 }
1106 
1107 LOCAL void
1108 prXnum(val, fa)
1109  register Ulong val;
1110  f_args *fa;
1111 {
1112  register char *p = fa->bufp;
1113 
1114  do {
1115  *--p = udtab[val & 15];
1116  val >>= 4;
1117  } while (val > 0);
1118 
1119  fa->bufp = p;
1120 }
1121 
1122 #ifdef USE_LONGLONG
1123 LOCAL void
1124 prlnum(val, base, fa)
1125  register Ullong val;
1126  register unsigned base;
1127  f_args *fa;
1128 {
1129  register char *p = fa->bufp;
1130 
1131  do {
1132  *--p = dtab[modlbys(val, base)];
1133  val = divlbys(val, base);
1134  } while (val > 0);
1135 
1136  fa->bufp = p;
1137 }
1138 
1139 LOCAL void
1140 prldnum(val, fa)
1141  register Ullong val;
1142  f_args *fa;
1143 {
1144  register char *p = fa->bufp;
1145 
1146  do {
1147  *--p = dtab[val % (unsigned)10];
1148  val = val / (unsigned)10;
1149  } while (val > 0);
1150 
1151  fa->bufp = p;
1152 }
1153 
1154 LOCAL void
1155 prlonum(val, fa)
1156  register Ullong val;
1157  f_args *fa;
1158 {
1159  register char *p = fa->bufp;
1160 
1161  do {
1162  *--p = dtab[val & 7];
1163  val >>= 3;
1164  } while (val > 0);
1165 
1166  fa->bufp = p;
1167 }
1168 
1169 LOCAL void
1170 prlxnum(val, fa)
1171  register Ullong val;
1172  f_args *fa;
1173 {
1174  register char *p = fa->bufp;
1175 
1176  do {
1177  *--p = dtab[val & 15];
1178  val >>= 4;
1179  } while (val > 0);
1180 
1181  fa->bufp = p;
1182 }
1183 
1184 LOCAL void
1185 prlXnum(val, fa)
1186  register Ullong val;
1187  f_args *fa;
1188 {
1189  register char *p = fa->bufp;
1190 
1191  do {
1192  *--p = udtab[val & 15];
1193  val >>= 4;
1194  } while (val > 0);
1195 
1196  fa->bufp = p;
1197 }
1198 
1199 #endif
1200 
1201 /*
1202  * Final buffer print out routine.
1203  */
1204 LOCAL int
1205 prbuf(s, fa)
1206  register const char *s;
1207  f_args *fa;
1208 {
1209  register int diff;
1210  register int rfillc;
1211  register void *arg = fa->farg;
1212 #ifdef FORMAT_FUNC_PARM
1213  register void (*fun) __PR((char, void *)) = fa->outf;
1214 #endif
1215  register int count;
1216  register int lzero = 0;
1217 
1218  count = strlen(s);
1219 
1220  /*
1221  * lzero becomes the number of left fill chars needed to reach signific
1222  */
1223  if (fa->lzero < 0 && count < fa->signific)
1224  lzero = fa->signific - count;
1225  count += lzero + fa->prefixlen;
1226  diff = fa->fldwidth - count;
1227  if (diff > 0)
1228  count += diff;
1229 
1230  if (fa->prefixlen && fa->fillc != ' ') {
1231  while (*fa->prefix != '\0')
1232  ofun(*fa->prefix++, arg);
1233  }
1234  if (!fa->minusflag) {
1235  rfillc = fa->fillc;
1236  while (--diff >= 0)
1237  ofun(rfillc, arg);
1238  }
1239  if (fa->prefixlen && fa->fillc == ' ') {
1240  while (*fa->prefix != '\0')
1241  ofun(*fa->prefix++, arg);
1242  }
1243  if (lzero > 0) {
1244  rfillc = '0';
1245  while (--lzero >= 0)
1246  ofun(rfillc, arg);
1247  }
1248  while (*s != '\0')
1249  ofun(*s++, arg);
1250  if (fa->minusflag) {
1251  rfillc = ' ';
1252  while (--diff >= 0)
1253  ofun(rfillc, arg);
1254  }
1255  return (count);
1256 }
1257 
1258 /*
1259  * Print out one char, allowing prc('\0')
1260  * Similar to prbuf()
1261  */
1262 #ifdef PROTOTYPES
1263 
1264 LOCAL int
1265 prc(char c, f_args *fa)
1266 
1267 #else
1268 
1269 LOCAL int
1270 prc(c, fa)
1271  char c;
1272  f_args *fa;
1273 #endif
1274 {
1275  register int diff;
1276  register int rfillc;
1277  register void *arg = fa->farg;
1278 #ifdef FORMAT_FUNC_PARM
1279  register void (*fun) __PR((char, void *)) = fa->outf;
1280 #endif
1281  register int count;
1282 
1283  count = 1;
1284  diff = fa->fldwidth - 1;
1285  if (diff > 0)
1286  count += diff;
1287 
1288  if (!fa->minusflag) {
1289  rfillc = fa->fillc;
1290  while (--diff >= 0)
1291  ofun(rfillc, arg);
1292  }
1293  ofun(c, arg);
1294  if (fa->minusflag) {
1295  rfillc = ' ';
1296  while (--diff >= 0)
1297  ofun(rfillc, arg);
1298  }
1299  return (count);
1300 }
1301 
1302 /*
1303  * String output routine.
1304  * If fa->signific is >= 0, it uses only fa->signific chars.
1305  * If fa->signific is 0, print no characters.
1306  */
1307 LOCAL int
1309  register const char *s;
1310  f_args *fa;
1311 {
1312  register char *bp;
1313  register int signific;
1314 
1315  if (s == NULL)
1316  return (prbuf("(NULL POINTER)", fa));
1317 
1318  if (fa->signific < 0)
1319  return (prbuf(s, fa));
1320 
1321  bp = fa->buf;
1322  signific = fa->signific;
1323 
1324  while (--signific >= 0 && *s != '\0')
1325  *bp++ = *s++;
1326  *bp = '\0';
1327 
1328  return (prbuf(fa->buf, fa));
1329 }
1330 
1331 #ifdef DEBUG
1332 LOCAL void
1333 dbg_print(fmt, a, b, c, d, e, f, g, h, i)
1334 char *fmt;
1335 {
1336  char ff[1024];
1337 
1338  sprintf(ff, fmt, a, b, c, d, e, f, g, h, i);
1339  write(STDERR_FILENO, ff, strlen(ff));
1340 }
1341 #endif
1342 
1343 #ifdef USE_NL_ARGS
1344 #ifdef FORMAT_IMPL
1345 /*
1346  * The following code is shared between format() and fprformat().
1347  */
1348 
1349 /*
1350  * Format argument types.
1351  * As "char" and "short" type arguments are fetched as "int"
1352  * we start with size "int" and ignore the 'h' modifier when
1353  * parsing sizes.
1354  */
1355 #define AT_NONE 0
1356 #define AT_INT 1
1357 #define AT_LONG 2
1358 #define AT_LONG_LONG 3
1359 #define AT_DOUBLE 4
1360 #define AT_LONG_DOUBLE 5
1361 #define AT_VOID_PTR 6
1362 #define AT_CHAR_PTR 7
1363 #define AT_SHORT_PTR 8
1364 #define AT_INT_PTR 9
1365 #define AT_LONG_PTR 10
1366 #define AT_LONG_LONG_PTR 11
1367 #define AT_R_FMT 12
1368 #define AT_R_VA_LIST 13
1369 #define AT_BOUNDS 14
1370 
1371 #define AF_NONE 0
1372 #define AF_LONG 1
1373 #define AF_LONG_LONG 2
1374 #define AF_LONG_DOUBLE 4
1375 #define AF_STAR 8
1376 
1377 static const char skips[] = "+- #'.$h1234567890";
1378 static const char *digits = &skips[8];
1379 
1380 /*
1381  * Parse the format string and store the first FMT_ARGMAX args in the arglist
1382  * parameter.
1383  *
1384  * This is done in two stages:
1385  * 1 parse the format string and store the types in argtypes[].
1386  * 2 use the type list in argtypes[], fetch the args in order and
1387  * store the related va_list state in arglist[]
1388  */
1389 EXPORT void
1390 _fmtarglist(fmt, fargs, arglist)
1391  const char *fmt;
1392  va_lists_t fargs;
1393  va_lists_t arglist[];
1394 {
1395  int i;
1396  int argindex;
1397  int maxindex;
1398  int thistype;
1399  int thisflag;
1400  int argtypes[FMT_ARGMAX+1];
1401 
1402  for (i = 0; i < FMT_ARGMAX; i++)
1403  argtypes[i] = AT_NONE;
1404 
1405  maxindex = -1;
1406  argindex = 0;
1407  while ((fmt = strchr(fmt, '%')) != NULL) {
1408  fmt++;
1409  i = strspn(fmt, digits);
1410  if (fmt[i] == '$') {
1411  int c;
1412 
1413  argindex = *fmt++ - '0';
1414  while (c = *fmt, is_dig(c)) {
1415  argindex *= 10;
1416  argindex += c - '0';
1417  fmt++;
1418  }
1419  argindex -= 1;
1420  }
1421  thistype = AT_NONE;
1422  thisflag = AF_NONE;
1423  newarg:
1424  fmt += strspn(fmt, skips);
1425  switch (*fmt++) {
1426 
1427  case '%': /* %% format no arg */
1428  continue;
1429 
1430  case 'l':
1431  if (thisflag & AF_LONG) {
1432  thisflag |= AF_LONG_LONG;
1433  } else {
1434  thisflag |= AF_LONG;
1435  }
1436  goto newarg;
1437  case 'j': /* intmax_t for now is long long */
1438  thisflag |= AF_LONG_LONG;
1439  goto newarg;
1440  case 'z': /* size_t */
1441 #if SIZEOF_SIZE_T == SIZEOF_INT
1442  if (thistype == AT_NONE)
1443  thistype = AT_INT;
1444 #else
1445 #if SIZEOF_SIZE_T == SIZEOF_LONG_INT
1446  if (thistype == AT_NONE)
1447  thistype = AT_LONG;
1448 #else
1449 #if SIZEOF_SIZE_T == SIZEOF_LLONG
1450  if (thistype == AT_NONE)
1451  thistype = AT_LONG_LONG;
1452 #else
1453 error sizeof (size_t) is unknown
1454 #endif
1455 #endif
1456 #endif
1457  goto newarg;
1458  case 't': /* ptrdiff_t */
1459 #if SIZEOF_PTRDIFF_T == SIZEOF_INT
1460  if (thistype == AT_NONE)
1461  thistype = AT_INT;
1462 #else
1463 #if SIZEOF_PTRDIFF_T == SIZEOF_LONG_INT
1464  if (thistype == AT_NONE)
1465  thistype = AT_LONG;
1466 #else
1467 #if SIZEOF_PTRDIFF_T == SIZEOF_LLONG
1468  if (thistype == AT_NONE)
1469  thistype = AT_LONG_LONG;
1470 #else
1471 error sizeof (ptrdiff_t) is unknown
1472 #endif
1473 #endif
1474 #endif
1475  goto newarg;
1476 #ifndef NO_UCSIL
1477  /*
1478  * Enhancements to K&R and ANSI:
1479  *
1480  * got a type specifyer
1481  *
1482  * XXX 'S' in C99 is %ls, 'S' should become 'H'
1483  */
1484  case 'U':
1485  if (!strchr("CSILZODX", *fmt)) {
1486  /*
1487  * Got only 'U'nsigned specifyer,
1488  * use default type and mode.
1489  */
1490  thistype = AT_INT;
1491  break;
1492  }
1493  if (!strchr("CSIL", *fmt)) {
1494  /*
1495  * Got 'U' and ZODX.
1496  * no type, use default
1497  */
1498  thistype = AT_INT;
1499  fmt++; /* Skip ZODX */
1500  break;
1501  }
1502  fmt++; /* Unsigned, skip 'U', get CSIL */
1503  /* FALLTHRU */
1504  case 'C':
1505  case 'S':
1506  case 'I':
1507  case 'L':
1508  fmt--; /* Undo fmt++ from switch() */
1509  {
1510  /*
1511  * got CSIL type
1512  */
1513  int type = *fmt++; /* Undo above fmt-- */
1514  int mode = *fmt;
1515  if (!strchr("ZODX", mode)) {
1516  /*
1517  * Check long double "Le", "Lf" or "Lg"
1518  */
1519  if (type == 'L' &&
1520  (mode == 'e' ||
1521  mode == 'f' ||
1522  mode == 'g')) {
1523  thisflag |= AF_LONG_DOUBLE;
1524  goto newarg;
1525  }
1526  } else {
1527  fmt++; /* Skip ZODX */
1528  }
1529  if (type == 'L')
1530  thistype = AT_LONG;
1531  else
1532  thistype = AT_INT;
1533  }
1534  break;
1535 #else
1536  case 'L':
1537  thisflag |= AF_LONG_DOUBLE;
1538  goto newarg;
1539 #endif
1540 
1541  case 'e':
1542  case 'E':
1543  case 'f':
1544  case 'F':
1545  case 'g':
1546  case 'G':
1547  if (thisflag & AF_LONG_DOUBLE)
1548  thistype = AT_LONG_DOUBLE;
1549  else
1550  thistype = AT_DOUBLE;
1551  break;
1552 
1553  case 'p':
1554  thistype = AT_VOID_PTR;
1555  break;
1556  case 's':
1557  thistype = AT_CHAR_PTR;
1558  break;
1559  case 'b':
1560  thistype = AT_BOUNDS;
1561  break;
1562  case 'n':
1563  if (thisflag & AF_LONG_LONG)
1564  thistype = AT_LONG_LONG_PTR;
1565  else if (thistype & AF_LONG)
1566  thistype = AT_LONG_PTR;
1567  else
1568  thistype = AT_INT_PTR;
1569  break;
1570  case 'r':
1571  thistype = AT_R_FMT;
1572  break;
1573  default:
1574  if (thistype == AT_NONE) {
1575  if (thisflag & AF_LONG_LONG)
1576  thistype = AT_LONG_LONG;
1577  else if (thistype & AF_LONG)
1578  thistype = AT_LONG;
1579  else
1580  thistype = AT_INT;
1581  }
1582  break;
1583 
1584  case '*':
1585  if (is_dig(*fmt)) {
1586  int c;
1587  int starindex;
1588 
1589  starindex = *fmt++ - '0';
1590  while (c = *fmt, is_dig(c)) {
1591  starindex *= 10;
1592  starindex += c - '0';
1593  fmt++;
1594  }
1595  starindex -= 1;
1596  if (starindex >= 0 && starindex < FMT_ARGMAX) {
1597  argtypes[starindex] = AT_INT;
1598  if (starindex > maxindex)
1599  maxindex = starindex;
1600  }
1601  goto newarg;
1602  }
1603  thistype = AT_INT;
1604  thisflag |= AF_STAR; /* Make sure to rescan for type */
1605  break;
1606  }
1607  if (argindex >= 0 && argindex < FMT_ARGMAX) {
1608  argtypes[argindex] = thistype;
1609  if (thistype == AT_R_FMT)
1610  argtypes[++argindex] = AT_R_VA_LIST;
1611  else if (thistype == AT_BOUNDS)
1612  argtypes[++argindex] = AT_INT;
1613 
1614  if (argindex > maxindex)
1615  maxindex = argindex;
1616  }
1617  ++argindex; /* Default to next arg in list */
1618  if (thisflag & AF_STAR) { /* Found '*', continue for type */
1619  thisflag &= ~AF_STAR;
1620  goto newarg;
1621  }
1622  }
1623 
1624  for (i = 0; i <= maxindex; i++) { /* Do not fetch more args than known */
1625  arglist[i] = fargs; /* Save state before fetching this */
1626 
1627  switch (argtypes[i]) {
1628 
1629  default:
1630  /* FALLTHRU */
1631  case AT_NONE: /* This matches '*' args */
1632  /* FALLTHRU */
1633  case AT_INT:
1634  (void) va_arg(fargs.ap, int);
1635  break;
1636  case AT_LONG:
1637  (void) va_arg(fargs.ap, long);
1638  break;
1639  case AT_LONG_LONG:
1640  (void) va_arg(fargs.ap, Llong);
1641  break;
1642  case AT_DOUBLE:
1643  (void) va_arg(fargs.ap, double);
1644  break;
1645  case AT_LONG_DOUBLE:
1646 #ifdef HAVE_LONGDOUBLE
1647  (void) va_arg(fargs.ap, long double);
1648 #endif
1649  break;
1650  case AT_VOID_PTR:
1651  (void) va_arg(fargs.ap, void *);
1652  break;
1653  case AT_CHAR_PTR:
1654  (void) va_arg(fargs.ap, char *);
1655  break;
1656  case AT_SHORT_PTR:
1657  (void) va_arg(fargs.ap, short *);
1658  break;
1659  case AT_INT_PTR:
1660  (void) va_arg(fargs.ap, int *);
1661  break;
1662  case AT_LONG_PTR:
1663  (void) va_arg(fargs.ap, long *);
1664  break;
1665  case AT_LONG_LONG_PTR:
1666  (void) va_arg(fargs.ap, Llong *);
1667  break;
1668  case AT_R_FMT:
1669  (void) va_arg(fargs.ap, char *);
1670  arglist[++i] = fargs;
1671  (void) __va_arg_list(fargs.ap);
1672  break;
1673  case AT_R_VA_LIST:
1674  break;
1675  case AT_BOUNDS:
1676  (void) va_arg(fargs.ap, char *);
1677  arglist[++i] = fargs;
1678  (void) va_arg(fargs.ap, int);
1679  break;
1680  }
1681  }
1682 }
1683 
1684 /*
1685  * In case that the format references an argument > FMT_ARGMAX, we use this
1686  * implementation. It is slow (n*n - where n is (argno - FMT_ARGMAX)).
1687  * Fortunately, it is most unlikely that there are more positional args than
1688  * the current FMT_ARGMAX definition of 30.
1689  */
1690 EXPORT void
1691 _fmtgetarg(fmt, num, fargs)
1692  const char *fmt;
1693  int num;
1694  va_lists_t *fargs;
1695 {
1696  const char *sfmt = fmt;
1697  int i;
1698 
1699  /*
1700  * Hacky preliminary support for all int type args bejond FMT_ARGMAX.
1701  */
1702  for (i = FMT_ARGMAX; i < num; i++)
1703  (void) va_arg((*fargs).ap, int);
1704 }
1705 #endif /* FORMAT_IMPL */
1706 #endif /* USE_NL_ARGS */
#define AF_NONE
Definition: format.c:1371
LOCAL void prXnum(Ulong val, f_args *fa)
Definition: format.c:1108
Definition: get.c:139
#define TRUE
Definition: types.h:120
LOCAL void prlonum(Ullong val, f_args *fa)
Definition: format.c:1155
register int unsflag
Definition: format.c:264
#define AT_LONG_PTR
Definition: format.c:1365
#define AT_INT
Definition: format.c:1356
long Llong
Definition: stdint.h:152
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
register char mode
Definition: format.c:267
void outf __PR((char, void *))
#define MINUSFLG
Definition: format.c:162
unsigned int UIntptr_t
Definition: stdint.h:368
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
#define SHORTMASK
Definition: format.c:105
char * buf
Definition: format.c:149
BOOL didlist
Definition: format.c:286
#define AF_LONG
Definition: format.c:1372
#define PLUSFLG
Definition: format.c:163
char * rfmt
Definition: format.c:279
LOCAL unsigned char dtab[]
Definition: format.c:1040
_Check_return_ _CRTIMP size_t __cdecl strspn(_In_z_ const char *_Str, _In_z_ const char *_Control)
int count
Definition: format.c:269
#define ofun(c, fp)
Definition: format.c:234
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define CHARMASK
Definition: format.c:104
#define CHECKFLAG()
Definition: format.c:81
int prefixlen
Definition: format.c:153
EXPORT ssize_t filewrite(FILE *f, void *vbuf, size_t len)
Definition: filewrite.c:71
Definition: match.c:390
const char * sfmt
Definition: format.c:257
EXPORT void _fmtgetarg(char *fmt, int num, va_lists_t *fargs) const
Definition: format.c:1691
Definition: format.c:135
#define cap_ty(c)
Definition: format.c:125
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define FORMAT_FUNC_KR_ARGS
Definition: format.c:232
unsigned long Ullong
Definition: stdint.h:153
#define AF_LONG_DOUBLE
Definition: format.c:1374
#define write
Definition: acwin.h:73
#define to_cap(c)
Definition: format.c:124
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:91
int signific
Definition: format.c:147
#define APOFLG
Definition: format.c:166
#define FALSE
Definition: types.h:117
va_lists_t fargs
Definition: format.c:282
LOCAL void prdnum(Ulong val, f_args *fa)
Definition: format.c:1060
#define AT_LONG_DOUBLE
Definition: format.c:1360
#define e
Definition: ke_i.h:82
EXPORT int ftoes(register char *s, MDOUBLE val, register int fieldwidth, register int ndigits)
Definition: fconv.c:209
static PVOID ptr
Definition: dispmode.c:30
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:47
LOCAL void prlnum(Ullong val, unsigned base, f_args *fa)
Definition: format.c:1124
smooth NULL
Definition: ftsmooth.c:557
unsigned char
Definition: typeof.h:27
int num
Definition: format.c:270
EXPORT int FORMAT_FUNC_KR_DECL register void * farg
Definition: format.c:253
char * va_list
Definition: acmsvcex.h:78
register char * fmt
Definition: format.c:254
#define LOCAL(type)
Definition: jmorecfg.h:289
r l[0]
Definition: byte_order.h:167
int flags
Definition: format.c:145
__kernel_size_t size_t
Definition: linux.h:237
int lzero
Definition: format.c:148
GLboolean GLboolean g
Definition: glext.h:6204
register char c
Definition: format.c:268
GLfloat f
Definition: glext.h:7540
#define const
Definition: zconf.h:230
Llong llval
Definition: format.c:276
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
LOCAL void prlXnum(Ullong val, f_args *fa)
Definition: format.c:1185
unsigned int BOOL
Definition: ntddk_ex.h:94
static const char skips[]
Definition: format.c:1377
LOCAL unsigned char udtab[]
Definition: format.c:1041
double dval
Definition: format.c:274
#define GOTDOT
Definition: format.c:167
#define d
Definition: ke_i.h:81
Definition: dhcpd.h:61
EXPORT void _fmtarglist(char *fmt, va_lists_t fargs, arglist) const
Definition: format.c:1390
const GLubyte * c
Definition: glext.h:8905
static FILE * out
Definition: regtests2xml.c:44
GLuint GLuint num
Definition: glext.h:9618
#define FORMAT_FUNC_NAME
Definition: format.c:227
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define SPACEFLG
Definition: format.c:164
char fillc
Definition: format.c:151
Definition: id3.c:18
LOCAL int prc(char c, f_args *fa)
Definition: format.c:1270
register char type
Definition: format.c:266
char * prefix
Definition: format.c:152
#define AF_LONG_LONG
Definition: format.c:1373
int minusflag
Definition: format.c:144
const char * ofmt
Definition: format.c:285
#define GOTSTAR
Definition: format.c:168
#define INTMASK
Definition: format.c:106
#define AT_CHAR_PTR
Definition: format.c:1362
#define FMT_ARGMAX
Definition: format.c:170
GLdouble s
Definition: gl.h:2039
Ulong res
Definition: format.c:278
#define AT_LONG
Definition: format.c:1357
#define err(...)
LOCAL void prxnum(Ulong val, f_args *fa)
Definition: format.c:1093
va_lists_t sargs
Definition: format.c:283
EXPORT int ftofs(register char *s, MDOUBLE val, register int fieldwidth, register int ndigits)
Definition: fconv.c:290
#define FORMAT_FUNC_PROTO_DECL
Definition: format.c:230
int fldwidth
Definition: format.c:146
short sh
Definition: format.c:272
const char * str
Definition: format.c:273
char *gcvt __PR((double, int, char *))
#define va_arg(ap, T)
Definition: acmsvcex.h:89
#define AT_R_FMT
Definition: format.c:1367
LOCAL void prldnum(Ullong val, f_args *fa)
Definition: format.c:1140
#define FARG
Definition: format.c:240
#define is_dig(c)
Definition: format.c:122
#define modlbys(val, base)
Definition: format.c:114
char * bufp
Definition: format.c:150
#define HASHFLG
Definition: format.c:165
LOCAL int prbuf(const char *s, f_args *fa)
Definition: format.c:1205
w ll
Definition: byte_order.h:166
#define AT_VOID_PTR
Definition: format.c:1361
va_copy(sargs.ap, oargs)
__kernel_ptrdiff_t ptrdiff_t
Definition: linux.h:247
#define AT_INT_PTR
Definition: format.c:1364
#define __va_arg_list(list)
Definition: varargs.h:123
#define rshiftmask(t, s)
Definition: format.c:102
char * strchr(const char *String, int ch)
Definition: utclib.c:501
LOCAL int prstring(const char *s, f_args *fa)
Definition: format.c:1308
#define AT_R_VA_LIST
Definition: format.c:1368
void * farg
Definition: format.c:143
static const char * digits
Definition: format.c:1378
#define EOF
Definition: stdio.h:24
POINT cp
Definition: magnifier.c:58
void int int ULONGLONG int va_list * ap
Definition: winesup.h:32
va_list oargs
Definition: format.c:255
#define AF_STAR
Definition: format.c:1375
int i
Definition: format.c:271
LOCAL void prlxnum(Ullong val, f_args *fa)
Definition: format.c:1170
static const WCHAR sp[]
Definition: suminfo.c:288
#define AT_LONG_LONG_PTR
Definition: format.c:1366
CONST PIXELFORMATDESCRIPTOR *typedef int
Definition: wingl.c:32
register long val
Definition: format.c:265
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
_CRTIMP char *__cdecl gcvt(_In_ double _Val, _In_ int _NumOfDigits, _Pre_notnull_ _Post_z_ char *_DstBuf)
unsigned long Ulong
Definition: utypes.h:42
#define AT_SHORT_PTR
Definition: format.c:1363
#define AT_LONG_LONG
Definition: format.c:1358
fa outf
Definition: format.c:301
#define AT_BOUNDS
Definition: format.c:1369
#define AT_DOUBLE
Definition: format.c:1359
va_list ap
Definition: varargs.h:133
Definition: dsound.c:958
LOCAL int checkfmt(char *fmt) const
Definition: getargs.c:1297
struct f_args f_args
LOCAL void pronum(Ulong val, f_args *fa)
Definition: format.c:1078
LOCAL void prnum(Ulong val, unsigned base, f_args *fa)
Definition: format.c:1044
#define STDERR_FILENO
Definition: syshdrs.h:90
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:29
#define AT_NONE
Definition: format.c:1355
va_lists_t arglist[FMT_ARGMAX+1]
Definition: format.c:284
f_args fa
Definition: format.c:280
#define FORMAT_FUNC_KR_DECL
Definition: format.c:231
#define divlbys(val, base)
Definition: format.c:113