1 /* @(#)jssnprintf.c 1.14 17/08/03 Copyright 1985, 1995-2017 J. Schilling */
2 /*
3 * Copyright (c) 1985, 1995-2017 J. Schilling
4 */
5 /*
6 * The contents of this file are subject to the terms of the
7 * Common Development and Distribution License, Version 1.0 only
8 * (the "License"). You may not use this file except in compliance
9 * with the License.
10 *
11 * See the file CDDL.Schily.txt in this distribution for details.
12 * A copy of the CDDL is also available via the Internet at
13 * http://www.opensource.org/licenses/cddl1.txt
14 *
15 * When distributing Covered Code, include this CDDL HEADER in each
16 * file and include the License file CDDL.Schily.txt from this distribution.
17 */
18
19 #include <schily/mconfig.h>
20 #include <schily/unistd.h> /* include <sys/types.h> try to get size_t */
21 #include <schily/stdio.h> /* Try again for size_t */
22 #include <schily/stdlib.h> /* Try again for size_t */
23 #include <schily/varargs.h>
24 #include <schily/standard.h>
25 #include <schily/schily.h>
26
27 EXPORT int js_snprintf __PR((char *, size_t maxcnt, const char *, ...));
28
29 typedef struct {
30 char *ptr;
31 int count;
32 } *BUF, _BUF;
33
34 #ifdef PROTOTYPES
35 static void
_cput(char c,void * l)36 _cput(char c, void *l)
37 #else
38 static void
39 _cput(c, l)
40 char c;
41 void *l;
42 #endif
43 {
44 register BUF bp = (BUF)l;
45
46 if (--bp->count > 0) {
47 *bp->ptr++ = c;
48 } else {
49 /*
50 * Make sure that there will never be a negative overflow.
51 */
52 bp->count++;
53 }
54 }
55
56 /* VARARGS2 */
57 #ifdef PROTOTYPES
58 EXPORT int
js_snprintf(char * buf,size_t maxcnt,const char * form,...)59 js_snprintf(char *buf, size_t maxcnt, const char *form, ...)
60 #else
61 EXPORT int
62 js_snprintf(buf, maxcnt, form, va_alist)
63 char *buf;
64 unsigned maxcnt;
65 char *form;
66 va_dcl
67 #endif
68 {
69 va_list args;
70 int cnt;
71 _BUF bb;
72
73 bb.ptr = buf;
74 bb.count = maxcnt;
75
76 #ifdef PROTOTYPES
77 va_start(args, form);
78 #else
79 va_start(args);
80 #endif
81 cnt = format(_cput, &bb, form, args);
82 va_end(args);
83 if (maxcnt > 0)
84 *(bb.ptr) = '\0';
85 if (bb.count < 0)
86 return (-1);
87
88 return (cnt);
89 }
90