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 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 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