~ubuntu-branches/ubuntu/maverick/avr-libc/maverick

« back to all changes in this revision

Viewing changes to libc/stdio/vsnprintf_p.c

  • Committer: Bazaar Package Importer
  • Author(s): Hakan Ardo
  • Date: 2007-08-09 11:28:01 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070809112801-ps7wognnynio9kz7
Tags: 1:1.4.6-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
  POSSIBILITY OF SUCH DAMAGE.
28
28
*/
29
29
 
30
 
/* $Id: vsnprintf_p.c,v 1.1 2003/11/12 20:50:03 joerg_wunsch Exp $ */
 
30
/* $Id: vsnprintf_p.c,v 1.1.8.1 2007/03/25 14:33:03 dmix Exp $ */
31
31
 
32
32
#include <limits.h>
33
33
#include <stdarg.h>
34
34
#include <stdio.h>
35
35
 
36
 
#include "stdio_private.h"
37
 
 
38
36
int
39
37
vsnprintf_P(char *s, size_t n, const char *fmt, va_list ap)
40
38
{
43
41
 
44
42
        f.flags = __SWR | __SSTR | __SPGM;
45
43
        f.buf = s;
46
 
        if (n > (size_t)INT_MAX)
47
 
                f.size = INT_MAX;
48
 
        else
49
 
                f.size = (int)n - 1;
 
44
        /* Restrict max output length to 32767, as snprintf() return
 
45
           signed int. The fputc() function uses a signed comparison
 
46
           between estimated len and f.size field. So we can write a
 
47
           negative value into f.size in the case of n was 0. Note,
 
48
           that f.size will be a max number of nonzero symbols. */
 
49
        if ((int)n < 0)
 
50
                n = (unsigned)INT_MAX + 1;              /* 32768 */
 
51
        f.size = n - 1;                         /* -1,0,...32767 */
 
52
 
50
53
        i = vfprintf(&f, fmt, ap);
51
 
        s[i < f.size? i: f.size] = 0;
 
54
 
 
55
        /* We use f.size (not 'n') as this is more effective: two 'ld'
 
56
           instructions vs. two 'push+pop' and 'movw'.  */
 
57
        if (f.size >= 0)
 
58
                s[f.len < f.size ? f.len : f.size] = 0;
52
59
 
53
60
        return i;
54
61
}