~ubuntu-branches/ubuntu/natty/curl/natty-proposed

« back to all changes in this revision

Viewing changes to lib/mprintf.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Schuldei
  • Date: 2009-05-24 21:12:19 UTC
  • mfrom: (1.1.12 upstream)
  • mto: (3.3.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 39.
  • Revision ID: james.westby@ubuntu.com-20090524211219-7jgcwuhl04ixuqsm
Tags: upstream-7.19.5
ImportĀ upstreamĀ versionĀ 7.19.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/****************************************************************************
2
 
 *
3
 
 * $Id: mprintf.c,v 1.61 2007-11-20 10:03:33 bagder Exp $
4
 
 *
5
 
 *************************************************************************
6
 
 *
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.
10
 
 *
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
/***************************************************************************
 
2
 *                                  _   _ ____  _
 
3
 *  Project                     ___| | | |  _ \| |
 
4
 *                             / __| | | | |_) | |
 
5
 *                            | (__| |_| |  _ <| |___
 
6
 *                             \___|\___/|_| \_\_____|
 
7
 *
 
8
 * Copyright (C) 1999 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
 
9
 *
 
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.
 
13
 *
 
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.
 
17
 *
 
18
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 
19
 * KIND, either express or implied.
 
20
 *
 
21
 * $Id: mprintf.c,v 1.81 2009-04-21 11:46:17 yangtse Exp $
15
22
 *
16
23
 * Purpose:
17
24
 *  A merge of Bjorn Reese's format() function and Daniel's dsprintf()
29
36
 * page at http://daniel.haxx.se/trio/
30
37
 */
31
38
 
32
 
 
33
39
#include "setup.h"
34
40
#include <stdio.h>
35
41
#include <stdlib.h>
43
49
 
44
50
#include <curl/mprintf.h>
45
51
 
 
52
#include "curl_memory.h"
 
53
/* The last #include file should be: */
 
54
#include "memdebug.h"
 
55
 
46
56
#ifndef SIZEOF_LONG_DOUBLE
47
57
#define SIZEOF_LONG_DOUBLE 0
48
58
#endif
49
59
 
 
60
/*
 
61
 * If SIZEOF_SIZE_T has not been defined, default to the size of long.
 
62
 */
 
63
 
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
53
 
#endif
54
 
 
55
 
#ifdef DPRINTF_DEBUG
56
 
#define HAVE_LONGLONG
57
 
#define LONG_LONG long long
58
 
#define ENABLE_64BIT
59
 
#endif
60
 
 
61
 
#include "memory.h"
62
 
/* The last #include file should be: */
63
 
#include "memdebug.h"
 
65
#  define SIZEOF_SIZE_T CURL_SIZEOF_LONG
 
66
#endif
 
67
 
 
68
#ifdef HAVE_LONGLONG
 
69
#  define LONG_LONG_TYPE long long
 
70
#  define HAVE_LONG_LONG_TYPE
 
71
#else
 
72
#  if defined(_MSC_VER) && (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
 
73
#    define LONG_LONG_TYPE __int64
 
74
#    define HAVE_LONG_LONG_TYPE
 
75
#  else
 
76
#    undef LONG_LONG_TYPE
 
77
#    undef HAVE_LONG_LONG_TYPE
 
78
#  endif
 
79
#endif
 
80
 
 
81
/*
 
82
 * Max integer data types that mprintf.c is capable
 
83
 */
 
84
 
 
85
#ifdef HAVE_LONG_LONG_TYPE
 
86
#  define mp_intmax_t LONG_LONG_TYPE
 
87
#  define mp_uintmax_t unsigned LONG_LONG_TYPE
 
88
#else
 
89
#  define mp_intmax_t long
 
90
#  define mp_uintmax_t unsigned long
 
91
#endif
64
92
 
65
93
#define BUFFSIZE 256 /* buffer for long-to-str and float-to-str calcs */
66
94
#define MAX_PARAMETERS 128 /* lame static limit */
67
95
 
68
 
#undef TRUE
69
 
#undef FALSE
70
 
#undef BOOL
71
 
#ifdef __cplusplus
72
 
# define TRUE true
73
 
# define FALSE false
74
 
# define BOOL bool
75
 
#else
76
 
# define TRUE  ((char)(1 == 1))
77
 
# define FALSE ((char)(0 == 1))
78
 
# define BOOL char
79
 
#endif
80
 
 
81
96
#ifdef __AMIGA__
82
97
# undef FORMAT_INT
83
98
#endif
143
158
  union {
144
159
    char *str;
145
160
    void *ptr;
146
 
    long num;
147
 
#ifdef ENABLE_64BIT
148
 
    LONG_LONG lnum;
149
 
#endif
 
161
    union {
 
162
      mp_intmax_t as_signed;
 
163
      mp_uintmax_t as_unsigned;
 
164
    } num;
150
165
    double dnum;
151
166
  } data;
152
167
} va_stack_t;
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
165
 
                   the complete data */
 
179
  int fail;     /* (!= 0) if an alloc has failed and thus
 
180
                   the output is not the complete data */
166
181
};
167
182
 
168
 
int curl_msprintf(char *buffer, const char *format, ...);
169
 
 
170
183
static long dprintf_DollarString(char *input, char **end)
171
184
{
172
185
  int number=0;
182
195
  return 0;
183
196
}
184
197
 
185
 
static BOOL dprintf_IsQualifierNoDollar(char c)
 
198
static int dprintf_IsQualifierNoDollar(char c)
186
199
{
187
200
  switch (c) {
188
201
  case '-': case '+': case ' ': case '#': case '.':
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':
193
 
    return TRUE;
 
206
    return 1; /* true */
194
207
  default:
195
 
    return FALSE;
 
208
    return 0; /* false */
196
209
  }
197
210
}
198
211
 
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)
201
214
{
202
215
  int i;
203
 
  char buffer[128];
 
216
  char buffer[256];
204
217
  int bit;
205
218
  int flags;
206
219
 
219
232
    case FORMAT_INT:
220
233
      type = "int";
221
234
      break;
 
235
    case FORMAT_INTPTR:
 
236
      type = "intptr";
 
237
      break;
222
238
    case FORMAT_LONG:
223
239
      type = "long";
224
240
      break;
396
412
        case 'z':
397
413
          /* the code below generates a warning if -Wunreachable-code is
398
414
             used */
399
 
#if SIZEOF_SIZE_T>4
 
415
#if (SIZEOF_SIZE_T > CURL_SIZEOF_LONG)
400
416
          flags |= FLAGS_LONGLONG;
401
417
#else
402
418
          flags |= FLAGS_LONG;
403
419
#endif
404
420
          break;
405
421
        case 'O':
406
 
#if SIZEOF_CURL_OFF_T > 4
 
422
#if (CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG)
407
423
          flags |= FLAGS_LONGLONG;
408
424
#else
409
425
          flags |= FLAGS_LONG;
538
554
        /* Width/precision arguments must be read before the main argument
539
555
         * they are attached to
540
556
         */
541
 
        vto[i + 1].data.num = va_arg(arglist, int);
 
557
        vto[i + 1].data.num.as_signed = (mp_intmax_t)va_arg(arglist, int);
542
558
      }
543
559
 
544
560
    switch (vto[i].type)
554
570
        break;
555
571
 
556
572
      case FORMAT_INT:
557
 
#ifdef ENABLE_64BIT
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);
560
580
        else
561
581
#endif
562
 
          if(vto[i].flags & FLAGS_LONG)
563
 
            vto[i].data.num = va_arg(arglist, long);
564
 
        else
565
 
          vto[i].data.num = va_arg(arglist, int);
 
582
        {
 
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);
 
592
          else
 
593
            vto[i].data.num.as_signed =
 
594
              (mp_intmax_t)va_arg(arglist, int);
 
595
        }
566
596
        break;
567
597
 
568
598
      case FORMAT_DOUBLE:
622
652
  f = (char *)format;
623
653
  while(*f != '\0') {
624
654
    /* Format spec modifiers.  */
625
 
    char alt;
 
655
    int is_alt;
626
656
 
627
657
    /* Width of a field.  */
628
658
    long width;
631
661
    long prec;
632
662
 
633
663
    /* Decimal integer is negative.  */
634
 
    char is_neg;
 
664
    int is_neg;
635
665
 
636
666
    /* Base of a number to be written.  */
637
667
    long base;
638
668
 
639
669
    /* Integral values to be written.  */
640
 
#ifdef ENABLE_64BIT
641
 
    unsigned LONG_LONG num;
642
 
#else
643
 
    unsigned long num;
644
 
#endif
645
 
    long signed_num;
 
670
    mp_uintmax_t num;
 
671
 
 
672
    /* Used to convert negative in positive.  */
 
673
    mp_intmax_t signed_num;
646
674
 
647
675
    if(*f != '%') {
648
676
      /* This isn't a format spec, so write everything out until the next one
681
709
 
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;
685
713
    else
686
714
      width = p->width;
687
715
 
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 */
693
721
    }
696
724
    else
697
725
      prec = -1;
698
726
 
699
 
    alt = (char)((p->flags & FLAGS_ALT)?TRUE:FALSE);
 
727
    is_alt = (p->flags & FLAGS_ALT) ? 1 : 0;
700
728
 
701
729
    switch (p->type) {
702
730
    case FORMAT_INT:
703
 
      num = p->data.num;
 
731
      num = p->data.num.as_unsigned;
704
732
      if(p->flags & FLAGS_CHAR) {
705
733
        /* Character.  */
706
734
        if(!(p->flags & FLAGS_LEFT))
733
761
      /* Decimal integer.  */
734
762
      base = 10;
735
763
 
736
 
#ifdef ENABLE_64BIT
737
 
      if(p->flags & FLAGS_LONGLONG) {
738
 
        /* long long */
739
 
        is_neg = (char)(p->data.lnum < 0);
740
 
        num = is_neg ? (- p->data.lnum) : p->data.lnum;
741
 
      }
742
 
      else
743
 
#endif
744
 
      {
745
 
        signed_num = (long) num;
746
 
        is_neg = (char)(signed_num < 0);
747
 
        num = is_neg ? (- signed_num) : signed_num;
748
 
      }
 
764
      is_neg = (p->data.num.as_signed < (mp_intmax_t)0) ? 1 : 0;
 
765
      if(is_neg) {
 
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;
 
771
      }
 
772
 
749
773
      goto number;
750
774
 
751
775
      unsigned_number:
771
795
        width -= (long)(workend - w);
772
796
        prec -= (long)(workend - w);
773
797
 
774
 
        if(alt && base == 8 && prec <= 0) {
 
798
        if(is_alt && base == 8 && prec <= 0) {
775
799
          *w-- = '0';
776
800
          --width;
777
801
        }
782
806
            *w-- = '0';
783
807
        }
784
808
 
785
 
        if(alt && base == 16)
 
809
        if(is_alt && base == 16)
786
810
          width -= 2;
787
811
 
788
812
        if(is_neg || (p->flags & FLAGS_SHOWSIGN) || (p->flags & FLAGS_SPACE))
799
823
        else if(p->flags & FLAGS_SPACE)
800
824
          OUTCHAR(' ');
801
825
 
802
 
        if(alt && base == 16) {
 
826
        if(is_alt && base == 16) {
803
827
          OUTCHAR('0');
804
828
          if(p->flags & FLAGS_UPPER)
805
829
            OUTCHAR('X');
877
901
          /* If the pointer is not NULL, write it as a %#x spec.  */
878
902
          base = 16;
879
903
          digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
880
 
          alt = 1;
 
904
          is_alt = 1;
881
905
          num = (size_t) ptr;
882
906
          is_neg = 0;
883
907
          goto number;
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;
915
939
 
916
940
        prec = -1;
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;
921
945
 
922
946
        if(p->flags & FLAGS_LEFT)
923
947
          strcat(formatbuf, "-");
965
989
 
966
990
    case FORMAT_INTPTR:
967
991
      /* Answer the count of characters written.  */
968
 
#ifdef ENABLE_64BIT
 
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;
971
995
      else
972
996
#endif
973
997
        if(p->flags & FLAGS_LONG)
1042
1066
  unsigned char outc = (unsigned char)output;
1043
1067
 
1044
1068
  if(!infop->buffer) {
1045
 
    infop->buffer=(char *)malloc(32);
 
1069
    infop->buffer = malloc(32);
1046
1070
    if(!infop->buffer) {
1047
 
      infop->fail = TRUE;
 
1071
      infop->fail = 1;
1048
1072
      return -1; /* fail */
1049
1073
    }
1050
1074
    infop->alloc = 32;
1053
1077
  else if(infop->len+1 >= infop->alloc) {
1054
1078
    char *newptr;
1055
1079
 
1056
 
    newptr = (char *)realloc(infop->buffer, infop->alloc*2);
 
1080
    newptr = realloc(infop->buffer, infop->alloc*2);
1057
1081
 
1058
1082
    if(!newptr) {
1059
 
      infop->fail = TRUE;
1060
 
      return -1;
 
1083
      infop->fail = 1;
 
1084
      return -1; /* fail */
1061
1085
    }
1062
1086
    infop->buffer = newptr;
1063
1087
    infop->alloc *= 2;
1079
1103
  info.buffer = NULL;
1080
1104
  info.len = 0;
1081
1105
  info.alloc = 0;
1082
 
  info.fail = FALSE;
 
1106
  info.fail = 0;
1083
1107
 
1084
1108
  va_start(ap_save, format);
1085
1109
  retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
1105
1129
  info.buffer = NULL;
1106
1130
  info.len = 0;
1107
1131
  info.alloc = 0;
1108
 
  info.fail = FALSE;
 
1132
  info.fail = 0;
1109
1133
 
1110
1134
  retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
1111
1135
  if((-1 == retcode) || info.fail) {
1186
1210
{
1187
1211
  char buffer[129];
1188
1212
  char *ptr;
1189
 
#ifdef ENABLE_64BIT
1190
 
  long long one=99;
1191
 
  long long two=100;
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);
1194
1218
#endif
1195
1219