1
/****************************************************************************
3
* $Id: mprintf.c,v 1.61 2007-11-20 10:03:33 bagder Exp $
5
*************************************************************************
7
* Permission to use, copy, modify, and distribute this software for any
8
* purpose with or without fee is hereby granted, provided that the above
9
* copyright notice and this permission notice appear in all copies.
11
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13
* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14
* CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
1
/***************************************************************************
3
* Project ___| | | | _ \| |
5
* | (__| |_| | _ <| |___
6
* \___|\___/|_| \_\_____|
8
* Copyright (C) 1999 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
10
* This software is licensed as described in the file COPYING, which
11
* you should have received as part of this distribution. The terms
12
* are also available at http://curl.haxx.se/docs/copyright.html.
14
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
15
* copies of the Software, and permit persons to whom the Software is
16
* furnished to do so, under the terms of the COPYING file.
18
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
* KIND, either express or implied.
21
* $Id: mprintf.c,v 1.81 2009-04-21 11:46:17 yangtse Exp $
17
24
* A merge of Bjorn Reese's format() function and Daniel's dsprintf()
44
50
#include <curl/mprintf.h>
52
#include "curl_memory.h"
53
/* The last #include file should be: */
46
56
#ifndef SIZEOF_LONG_DOUBLE
47
57
#define SIZEOF_LONG_DOUBLE 0
61
* If SIZEOF_SIZE_T has not been defined, default to the size of long.
50
64
#ifndef SIZEOF_SIZE_T
51
/* default to 4 bytes for size_t unless defined in the config.h */
52
#define SIZEOF_SIZE_T 4
57
#define LONG_LONG long long
62
/* The last #include file should be: */
65
# define SIZEOF_SIZE_T CURL_SIZEOF_LONG
69
# define LONG_LONG_TYPE long long
70
# define HAVE_LONG_LONG_TYPE
72
# if defined(_MSC_VER) && (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
73
# define LONG_LONG_TYPE __int64
74
# define HAVE_LONG_LONG_TYPE
76
# undef LONG_LONG_TYPE
77
# undef HAVE_LONG_LONG_TYPE
82
* Max integer data types that mprintf.c is capable
85
#ifdef HAVE_LONG_LONG_TYPE
86
# define mp_intmax_t LONG_LONG_TYPE
87
# define mp_uintmax_t unsigned LONG_LONG_TYPE
89
# define mp_intmax_t long
90
# define mp_uintmax_t unsigned long
65
93
#define BUFFSIZE 256 /* buffer for long-to-str and float-to-str calcs */
66
94
#define MAX_PARAMETERS 128 /* lame static limit */
76
# define TRUE ((char)(1 == 1))
77
# define FALSE ((char)(0 == 1))
161
176
char *buffer; /* allocated buffer */
162
177
size_t len; /* length of string */
163
178
size_t alloc; /* length of alloc */
164
bool fail; /* TRUE if an alloc has failed and thus the output is not
179
int fail; /* (!= 0) if an alloc has failed and thus
180
the output is not the complete data */
168
int curl_msprintf(char *buffer, const char *format, ...);
170
183
static long dprintf_DollarString(char *input, char **end)
190
203
case '5': case '6': case '7': case '8': case '9':
191
204
case 'h': case 'l': case 'L': case 'z': case 'q':
192
205
case '*': case 'O':
208
return 0; /* false */
199
212
#ifdef DPRINTF_DEBUG2
200
int dprintf_Pass1Report(va_stack_t *vto, int max)
213
static void dprintf_Pass1Report(va_stack_t *vto, int max)
558
if(vto[i].flags & FLAGS_LONGLONG)
559
vto[i].data.lnum = va_arg(arglist, LONG_LONG);
573
#ifdef HAVE_LONG_LONG_TYPE
574
if((vto[i].flags & FLAGS_LONGLONG) && (vto[i].flags & FLAGS_UNSIGNED))
575
vto[i].data.num.as_unsigned =
576
(mp_uintmax_t)va_arg(arglist, mp_uintmax_t);
577
else if(vto[i].flags & FLAGS_LONGLONG)
578
vto[i].data.num.as_signed =
579
(mp_intmax_t)va_arg(arglist, mp_intmax_t);
562
if(vto[i].flags & FLAGS_LONG)
563
vto[i].data.num = va_arg(arglist, long);
565
vto[i].data.num = va_arg(arglist, int);
583
if((vto[i].flags & FLAGS_LONG) && (vto[i].flags & FLAGS_UNSIGNED))
584
vto[i].data.num.as_unsigned =
585
(mp_uintmax_t)va_arg(arglist, unsigned long);
586
else if(vto[i].flags & FLAGS_LONG)
587
vto[i].data.num.as_signed =
588
(mp_intmax_t)va_arg(arglist, long);
589
else if(vto[i].flags & FLAGS_UNSIGNED)
590
vto[i].data.num.as_unsigned =
591
(mp_uintmax_t)va_arg(arglist, unsigned int);
593
vto[i].data.num.as_signed =
594
(mp_intmax_t)va_arg(arglist, int);
568
598
case FORMAT_DOUBLE:
633
663
/* Decimal integer is negative. */
636
666
/* Base of a number to be written. */
639
669
/* Integral values to be written. */
641
unsigned LONG_LONG num;
672
/* Used to convert negative in positive. */
673
mp_intmax_t signed_num;
648
676
/* This isn't a format spec, so write everything out until the next one
682
710
/* pick up the specified width */
683
711
if(p->flags & FLAGS_WIDTHPARAM)
684
width = vto[p->width].data.num;
712
width = (long)vto[p->width].data.num.as_signed;
686
714
width = p->width;
688
716
/* pick up the specified precision */
689
717
if(p->flags & FLAGS_PRECPARAM) {
690
prec = vto[p->precision].data.num;
718
prec = (long)vto[p->precision].data.num.as_signed;
691
719
param_num++; /* since the precision is extraced from a parameter, we
692
720
must skip that to get to the next one properly */
699
alt = (char)((p->flags & FLAGS_ALT)?TRUE:FALSE);
727
is_alt = (p->flags & FLAGS_ALT) ? 1 : 0;
701
729
switch (p->type) {
731
num = p->data.num.as_unsigned;
704
732
if(p->flags & FLAGS_CHAR) {
706
734
if(!(p->flags & FLAGS_LEFT))
733
761
/* Decimal integer. */
737
if(p->flags & FLAGS_LONGLONG) {
739
is_neg = (char)(p->data.lnum < 0);
740
num = is_neg ? (- p->data.lnum) : p->data.lnum;
745
signed_num = (long) num;
746
is_neg = (char)(signed_num < 0);
747
num = is_neg ? (- signed_num) : signed_num;
764
is_neg = (p->data.num.as_signed < (mp_intmax_t)0) ? 1 : 0;
766
/* signed_num might fail to hold absolute negative minimum by 1 */
767
signed_num = p->data.num.as_signed + (mp_intmax_t)1;
768
signed_num = -signed_num;
769
num = (mp_uintmax_t)signed_num;
770
num += (mp_uintmax_t)1;
911
935
if(p->flags & FLAGS_WIDTH)
912
936
width = p->width;
913
937
else if(p->flags & FLAGS_WIDTHPARAM)
914
width = vto[p->width].data.num;
938
width = (long)vto[p->width].data.num.as_signed;
917
941
if(p->flags & FLAGS_PREC)
918
942
prec = p->precision;
919
943
else if(p->flags & FLAGS_PRECPARAM)
920
prec = vto[p->precision].data.num;
944
prec = (long)vto[p->precision].data.num.as_signed;
922
946
if(p->flags & FLAGS_LEFT)
923
947
strcat(formatbuf, "-");
966
990
case FORMAT_INTPTR:
967
991
/* Answer the count of characters written. */
992
#ifdef HAVE_LONG_LONG_TYPE
969
993
if(p->flags & FLAGS_LONGLONG)
970
*(LONG_LONG *) p->data.ptr = (LONG_LONG)done;
994
*(LONG_LONG_TYPE *) p->data.ptr = (LONG_LONG_TYPE)done;
973
997
if(p->flags & FLAGS_LONG)
1187
1211
char buffer[129];
1192
long long test = 0x1000000000LL;
1213
#ifdef HAVE_LONG_LONG_TYPE
1214
LONG_LONG_TYPE one=99;
1215
LONG_LONG_TYPE two=100;
1216
LONG_LONG_TYPE test = 0x1000000000LL;
1193
1217
curl_mprintf("%lld %lld %lld\n", one, two, test);