chiark / gitweb /
NFC and NFKC support
[disorder] / lib / snprintf.c
1 /*
2  * This file is part of DisOrder
3  * Copyright (C) 2004 Richard Kettlewell
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18  * USA
19  */
20
21 #define NO_MEMORY_ALLOCATION
22 /* because used from log.c */
23
24 #include <config.h>
25 #include "types.h"
26
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdarg.h>
30 #include <stddef.h>
31
32 #include "printf.h"
33 #include "sink.h"
34
35 struct fixedstr_sink {
36   struct sink s;
37   char *buffer;
38   int nbytes;
39   size_t size;
40 };
41
42 static int fixedstr_write(struct sink *f, const void *buffer, int nbytes) {
43   struct fixedstr_sink *s = (struct fixedstr_sink *)f;
44   int count;
45
46   if((size_t)s->nbytes < s->size) {
47     if((size_t)nbytes > s->size - s->nbytes)
48       count = s->size - s->nbytes;
49     else
50       count = nbytes;
51     memcpy(s->buffer + s->nbytes, buffer, count);
52   }
53   s->nbytes += nbytes;
54   return 0;
55 }
56
57 int byte_vsnprintf(char buffer[],
58                    size_t bufsize,
59                    const char *fmt,
60                    va_list ap) {
61   struct fixedstr_sink s;
62   int n, m;
63
64   /* We have to make a sink directly here, since we can't safely do memory
65    * allocation here (we might be formatting the error message from a failed
66    * memory allocation) */
67   s.s.write = fixedstr_write;
68   s.buffer = buffer;
69   s.nbytes = 0;
70   s.size = bufsize;
71   n = byte_vsinkprintf(&s.s, fmt, ap);
72   if(bufsize) {
73     /* add the null terminator (even if the printf failed) */
74     m = s.nbytes;
75     if((size_t)m >= bufsize) m = bufsize - 1;
76     buffer[m] = 0;
77   }
78   return n;
79 }
80
81 int byte_snprintf(char buffer[], size_t bufsize, const char *fmt, ...) {
82   int n;
83   va_list ap;
84
85   va_start(ap, fmt);
86   n = byte_vsnprintf(buffer, bufsize, fmt, ap);
87   va_end(ap);
88   return n;
89 }
90
91 /*
92 Local Variables:
93 c-basic-offset:2
94 comment-column:40
95 End:
96 */