Hi all,

I'm a terrible lurker, so apologies for my first post being a bug
report. I should say up front that I'm very grateful that you folks
have made mspgcc, it's made our project much more pleasant than it
would have been if we were stuck on Windows with some proprietary
tools. BTW we're using the USB FET under Linux, and working well apart
from lack of working backtrace. Anyway here goes:

The printf functions all call vuprintf. If you use the %s format with
an argument string longer than 128 chars, it's truncated. It comes
down to this line in vuprintf:

   signed char size = 0;       /* size of converted field or string */

So this works as expected:

   snprintf(buf, sizeof(buf), "%s", "Hello world");

and this fails:

   snprintf(buf, sizeof(buf), "%s",
       "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"    // 50 chars
       "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"    // 50 chars
       "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"    // 50 chars
   );

because 50 + 50 + 50 = 150 > 128.

Ok, not exactly front page news, but I thought I'd report it in case
this saves someone 10 mins of headscratching. The patch attached might
be a bit heavy-handed, I just changed the relevant-looking 'signed
char's to 'signed int'. Works for me, but someone who knows more
should check and test before a fix is committed.

Cheers,

- Ben.
Index: vuprintf.c
===================================================================
RCS file: /home/cvs/Projects/neuro/software/source/framework/vuprintf.c,v
retrieving revision 1.1
diff -u -r1.1 vuprintf.c
--- vuprintf.c  26 Sep 2006 05:16:59 -0000      1.1
+++ vuprintf.c  26 Sep 2006 05:33:37 -0000
@@ -119,7 +119,7 @@
 #define PAD_SP(x) __write_pad(' ',x)
 #define PAD_0(x) __write_pad('0',x)
 
-static int __write_pad(char c, signed char howmany)
+static int __write_pad(char c, signed int howmany)
 {
     for(;howmany>0;howmany--)
     {
@@ -165,21 +165,21 @@
     register char *cp; /* handy char pointer (short term usage) */
     const char *fmark; /* for remembering a place in fmt */
     register unsigned char flags;      /* flags as above */
-    signed char width;         /* width from format (%8d), or 0 */
-    signed char prec;          /* precision from format (%.3d), or -1 */
+    signed int width;          /* width from format (%8d), or 0 */
+    signed int prec;           /* precision from format (%.3d), or -1 */
     char sign;                         /* sign prefix (' ', '+', '-', or \0) */
     unsigned long _ulong=0;    /* integer arguments %[diouxX] */
 #define OCT 8
 #define DEC 10
 #define HEX 16
     unsigned char base;                /* base for [diouxX] conversion */
-    signed char dprec;         /* a copy of prec if [diouxX], 0 otherwise */
-    signed char dpad;                  /* extra 0 padding needed for integers 
*/
-    signed char fieldsz;               /* field size expanded by sign, dpad 
etc */
+    signed int dprec;          /* a copy of prec if [diouxX], 0 otherwise */
+    signed int dpad;                   /* extra 0 padding needed for integers 
*/
+    signed int fieldsz;                /* field size expanded by sign, dpad 
etc */
     /* The initialization of 'size' is to suppress a warning that
        'size' might be used unitialized.  It seems gcc can't
        quite grok this spaghetti code ... */
-    signed char size = 0;              /* size of converted field or string */
+    signed int size = 0;               /* size of converted field or string */
     char buf[BUF];             /* space for %c, %[diouxX], %[eEfgG] */
     char ox[2];                        /* space for 0x hex-prefix */
     

Reply via email to