]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
utf8: add VM_sprintf support
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 25 Dec 2009 08:49:38 +0000 (08:49 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 25 Dec 2009 08:49:38 +0000 (08:49 +0000)
now sprintf("%#10s", s) pads to 10 bytes, and sprintf("%10s", s) pads to 10 characters, if utf8 is enabled

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9685 d7cf8633-e32d-0410-b094-e92efae38249

prvm_cmds.c
utf8lib.c
utf8lib.h

index 1e67092920b24ee2b63816238377cda83df4fc30..702d8a82f9d253f21f41aabc729cd6f6a8e2447e 100644 (file)
@@ -5860,7 +5860,8 @@ nolength:
                                if(o < end - 1)
                                {
                                        f = &formatbuf[1];
-                                       if(flags & PRINTF_ALTERNATE) *f++ = '#';
+                                       if(*s != 's' && *s != 'c')
+                                               if(flags & PRINTF_ALTERNATE) *f++ = '#';
                                        if(flags & PRINTF_ZEROPAD) *f++ = '0';
                                        if(flags & PRINTF_LEFT) *f++ = '-';
                                        if(flags & PRINTF_SPACEPOSITIVE) *f++ = ' ';
@@ -5870,19 +5871,44 @@ nolength:
                                        *f++ = '*';
                                        *f++ = *s;
                                        *f++ = 0;
+
+                                       if(width < 0)
+                                               width = 0;
+
                                        switch(*s)
                                        {
                                                case 'd': case 'i':
                                                        o += dpsnprintf(o, end - o, formatbuf, width, precision, (isfloat ? (int) GETARG_FLOAT(thisarg) : (int) GETARG_INT(thisarg)));
                                                        break;
-                                               case 'o': case 'u': case 'x': case 'X': case 'c': 
+                                               case 'o': case 'u': case 'x': case 'X':
                                                        o += dpsnprintf(o, end - o, formatbuf, width, precision, (isfloat ? (unsigned int) GETARG_FLOAT(thisarg) : (unsigned int) GETARG_INT(thisarg)));
                                                        break;
                                                case 'e': case 'E': case 'f': case 'F': case 'g': case 'G':
+                                                       if(precision < 0)
+                                                               precision = 6;
                                                        o += dpsnprintf(o, end - o, formatbuf, width, precision, (isfloat ? (double) GETARG_FLOAT(thisarg) : (double) GETARG_INT(thisarg)));
                                                        break;
+                                               case 'c':
+                                                       if(precision < 0)
+                                                               precision = end - o - 1;
+                                                       if(flags & PRINTF_ALTERNATE)
+                                                               o += dpsnprintf(o, end - o, formatbuf, width, precision, (isfloat ? (unsigned int) GETARG_FLOAT(thisarg) : (unsigned int) GETARG_INT(thisarg)));
+                                                       else
+                                                       {
+                                                               unsigned int c = (isfloat ? (unsigned int) GETARG_FLOAT(thisarg) : (unsigned int) GETARG_INT(thisarg));
+                                                               const char *buf = u8_encodech(c, NULL);
+                                                               if(!buf)
+                                                                       buf = "";
+                                                               o += u8_strpad(o, end - o, buf, (flags & PRINTF_LEFT) != 0, width, precision);
+                                                       }
+                                                       break;
                                                case 's':
-                                                       o += dpsnprintf(o, end - o, formatbuf, width, precision, GETARG_STRING(thisarg));
+                                                       if(precision < 0)
+                                                               precision = end - o - 1;
+                                                       if(flags & PRINTF_ALTERNATE)
+                                                               o += dpsnprintf(o, end - o, formatbuf, width, precision, GETARG_STRING(thisarg));
+                                                       else
+                                                               o += u8_strpad(o, end - o, GETARG_STRING(thisarg), (flags & PRINTF_LEFT) != 0, width, precision);
                                                        break;
                                                default:
                                                        VM_Warning("VM_sprintf: invalid directive in %s: %s\n", PRVM_NAME, s0);
index bc3ce39a615c3558f1470590c6b4be43d31e5063..b1749c128f2bd3b0f670916e377170ecf9755d20 100644 (file)
--- a/utf8lib.c
+++ b/utf8lib.c
@@ -694,3 +694,30 @@ u8_COM_StringLengthNoColors(const char *s, size_t size_s, qboolean *valid)
        }
        // never get here
 }
+
+/** Pads a utf-8 string
+ * @param out     The target buffer the utf-8 string is written to.
+ * @param outsize The size of the target buffer, including the final NUL
+ * @param in      The input utf-8 buffer
+ * @param leftalign Left align the output string (by default right alignment is done)
+ * @param minwidth The minimum output width
+ * @param maxwidth The maximum output width
+ * @return        The number of bytes written, not including the terminating \0
+ */
+size_t u8_strpad(char *out, size_t outsize, const char *in, qboolean leftalign, size_t minwidth, size_t maxwidth)
+{
+       if(!utf8_enable.integer)
+       {
+               return dpsnprintf(out, outsize, "%*.*s", leftalign ? -(int) minwidth : (int) minwidth, (int) maxwidth, in);
+       }
+       else
+       {
+               size_t l = u8_bytelen(in, maxwidth);
+               size_t actual_width = u8_strnlen(in, l);
+               int pad = (actual_width >= minwidth) ? 0 : (minwidth - actual_width);
+               int prec = l;
+               int lpad = leftalign ? 0 : pad;
+               int rpad = leftalign ? pad : 0;
+               return dpsnprintf(out, outsize, "%*s%.*s%*s", lpad, "", prec, in, rpad, "");
+       }
+}
index 4c04cfab9c9eaba5b7dc994898d6b23e5879715f..f918ed792f01cddd15b6297e6aef6037c3e8b00d 100644 (file)
--- a/utf8lib.h
+++ b/utf8lib.h
@@ -44,4 +44,6 @@ size_t u8_COM_StringLengthNoColors(const char *s, size_t size_s, qboolean *valid
 // returns a static buffer, use this for inlining
 char  *u8_encodech(Uchar ch, size_t*);
 
+size_t u8_strpad(char *out, size_t outsize, const char *in, qboolean leftalign, size_t minwidth, size_t maxwidth);
+
 #endif // UTF8LIB_H__