2 * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
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:
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.
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.
25 * #if _SGIAPI && _NO_ANSIMODE
26 * extern int vsnprintf(char *, ssize_t, const char *, char *);
42 * Shamelessly snarfed from sane...
43 * which shamelessly snarfed from LPR
44 * which probably shamelessly snarfed from....
46 * Moved comments to end so I can actually read the code.. cleaned out useless
50 #define VA_LOCAL_DECL va_list ap
51 #define VA_START(f) va_start(ap, f)
52 #define VA_SHIFT(v,t) ; /* no-op for ANSI */
53 #define VA_END va_end(ap)
56 * dopr(): poor man's version of doprintf
59 static void dopr(char *buffer, const char *format, va_list args);
60 static void fmtstr(char *value, int ljust, int len, int zpad,
62 static void fmtnum(long value, int base, int dosign, int ljust, int len,
63 int zpad, int precision);
64 static void fmtdouble(int fmt, double value, int ljust, int len,
65 int zpad, int precision);
66 static void dostr(char *);
68 static void dopr_outch(int c);
70 int visible_control = 1;
73 Evsnprintf(char *str, size_t count, const char *fmt, va_list args)
76 end = str + count - 1;
87 Esnprintf(char *str, size_t count, const char *fmt, ...)
103 VA_SHIFT(str, char *);
105 VA_SHIFT(count, size_t);
106 VA_SHIFT(fmt, char *);
108 (void)Evsnprintf(str, count, fmt, ap);
110 return (strlen(str));
114 dopr(char *buffer, const char *format, va_list args)
128 while ((ch = *format++))
133 ljust = len = zpad = 0;
141 dostr("**end of format**");
151 len = va_arg(args, int);
154 case '0': /* set zero padding if len not set */
155 if (len == 0 && set_precision == 0)
168 precision = precision * 10 + ch - '0';
172 len = len * 10 + ch - '0';
180 /*fmtnum(value,base,dosign,ljust,len, zpad, precision) */
183 value = va_arg(args, long);
187 value = va_arg(args, int);
189 fmtnum(value, 10, 0, ljust, len, zpad, precision);
193 /*fmtnum(value,base,dosign,ljust,len, zpad, precision) */
196 value = va_arg(args, long);
200 value = va_arg(args, int);
202 fmtnum(value, 8, 0, ljust, len, zpad, precision);
209 value = va_arg(args, long);
213 value = va_arg(args, int);
215 fmtnum(value, 10, 1, ljust, len, zpad, precision);
220 value = va_arg(args, long);
224 value = va_arg(args, int);
226 fmtnum(value, 16, 0, ljust, len, zpad, precision);
231 value = va_arg(args, long);
235 value = va_arg(args, int);
237 fmtnum(value, -16, 0, ljust, len, zpad, precision);
240 strvalue = va_arg(args, char *);
242 fmtstr(strvalue, ljust, len, zpad, precision);
245 ch = va_arg(args, int);
249 int vsb = visible_control;
254 fmtstr(b, ljust, len, zpad, precision);
255 visible_control = vsb;
260 dval = va_arg(args, double);
262 fmtdouble(ch, dval, ljust, len, zpad, precision);
281 * Format '%[-]len[.precision]s'
282 * - = left justify (ljust)
283 * len = minimum length
284 * precision = numbers of chars in string to use
287 fmtstr(char *value, int ljust, int len, int zpad, int precision)
289 int padlen, strlen, i, c; /* amount to pad */
302 /* cheap strlen so you do not have library call */
303 for (strlen = 0; (c = value[strlen]); ++strlen)
305 if (visible_control && iscntrl(c) && !isspace(c))
311 padlen = len - strlen;
321 /* output characters */
322 for (i = 0; (c = value[i]); ++i)
324 if (visible_control && iscntrl(c) && !isspace(c))
327 c = ('@' | (c & 0x1F));
339 fmtnum(long value, int base, int dosign, int ljust, int len, int zpad,
343 unsigned long uvalue;
346 int padlen = 0; /* amount to pad */
350 /* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n",
351 * value, base, dosign, ljust, len, zpad )); */
369 (caps ? "0123456789ABCDEF" : "0123456789abcdef")[uvalue %
371 uvalue = (uvalue / (unsigned)base);
375 padlen = len - place;
380 /* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n",
381 * convert,place,signvalue,padlen)); */
382 if (zpad && padlen > 0)
386 dopr_outch(signvalue);
402 dopr_outch(signvalue);
404 dopr_outch(convert[--place]);
413 fmtdouble(int fmt, double value, int ljust, int len, int zpad, int precision)
422 if (len > (int)sizeof(convert) - 10)
424 len = (int)sizeof(convert) - 10;
426 if (precision > (int)sizeof(convert) - 10)
428 precision = (int)sizeof(convert) - 10;
437 sprintf(fmtstr + strlen(fmtstr), "%d", len);
441 sprintf(fmtstr + strlen(fmtstr), ".%d", precision);
446 sprintf(convert, fmtstr, value);
460 if (end == 0 || output < end)
466 /**************************************************************
468 * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
469 * A bombproof version of doprnt (dopr) included.
470 * Sigh. This sort of thing is always nasty do deal with. Note that
471 * the version here does not include floating point...
473 * plp_snprintf() is used instead of sprintf() as it does limit checks
474 * for string length. This covers a nasty loophole.
476 * The other functions are there to prevent NULL pointers from
477 * causing nast effects.
478 **************************************************************/
480 /***************************************************************************
481 * LPRng - An Extended Print Spooler System
483 * Copyright 1988-1997, Patrick Powell, San Diego, CA
485 * See below for conditions of use.
487 ***************************************************************************
489 * PURPOSE: LPRng version of printf - absolutely bombproof (hopefully!)
490 **************************************************************************/
493 * The "Artistic License"
497 * The intent of this document is to state the conditions under which a
498 * Package may be copied, such that the Copyright Holder maintains some
499 * semblance of artistic control over the development of the package,
500 * while giving the users of the package the right to use and distribute
501 * the Package in a more-or-less customary fashion, plus the right to make
502 * reasonable modifications.
506 * "Package" refers to the collection of files distributed by the
507 * Copyright Holder, and derivatives of that collection of files
508 * created through textual modification.
510 * "Standard Version" refers to such a Package if it has not been
511 * modified, or has been modified in accordance with the wishes
512 * of the Copyright Holder as specified below.
514 * "Copyright Holder" is whoever is named in the copyright or
515 * copyrights for the package.
517 * "You" is you, if you are thinking about copying or distributing
520 * "Reasonable copying fee" is whatever you can justify on the
521 * basis of media cost, duplication charges, time of people involved,
522 * and so on. (You will not be required to justify it to the
523 * Copyright Holder, but only to the computing community at large
524 * as a market that must bear the fee.)
526 * "Freely Available" means that no fee is charged for the item
527 * itself, though there may be fees involved in handling the item.
528 * It also means that recipients of the item may redistribute it
529 * under the same conditions they received it.
531 * 1. You may make and give away verbatim copies of the source form of the
532 * Standard Version of this Package without restriction, provided that you
533 * duplicate all of the original copyright notices and associated disclaimers.
535 * 2. You may apply bug fixes, portability fixes and other modifications
536 * derived from the Public Domain or from the Copyright Holder. A Package
537 * modified in such a way shall still be considered the Standard Version.
539 * 3. You may otherwise modify your copy of this Package in any way, provided
540 * that you insert a prominent notice in each changed file stating how and
541 * when you changed that file, and provided that you do at least ONE of the
544 * a) place your modifications in the Public Domain or otherwise make them
545 * Freely Available, such as by posting said modifications to Usenet or
546 * an equivalent medium, or placing the modifications on a major archive
547 * site such as uunet.uu.net, or by allowing the Copyright Holder to include
548 * your modifications in the Standard Version of the Package.
550 * b) use the modified Package only within your corporation or organization.
552 * c) rename any non-standard executables so the names do not conflict
553 * with standard executables, which must also be provided, and provide
554 * a separate manual page for each non-standard executable that clearly
555 * documents how it differs from the Standard Version.
557 * d) make other distribution arrangements with the Copyright Holder.
559 * 4. You may distribute the programs of this Package in object code or
560 * executable form, provided that you do at least ONE of the following:
562 * a) distribute a Standard Version of the executables and library files,
563 * together with instructions (in the manual page or equivalent) on where
564 * to get the Standard Version.
566 * b) accompany the distribution with the machine-readable source of
567 * the Package with your modifications.
569 * c) give non-standard executables non-standard names, and clearly
570 * document the differences in manual pages (or equivalent), together
571 * with instructions on where to get the Standard Version.
573 * d) make other distribution arrangements with the Copyright Holder.
575 * 5. You may charge a reasonable copying fee for any distribution of this
576 * Package. You may charge any fee you choose for support of this
577 * Package. You may not charge a fee for this Package itself. However,
578 * you may distribute this Package in aggregate with other (possibly
579 * commercial) programs as part of a larger (possibly commercial) software
580 * distribution provided that you do not advertise this Package as a
581 * product of your own.
583 * 6. The name of the Copyright Holder may not be used to endorse or promote
584 * products derived from this software without specific prior written permission.
586 * 7. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
587 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
588 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.