[RHS] ''15Nov2004'' A sprintf-like command that returns a Tcl_Obj. I use it to do things like: Tcl_ListObjAppendElement(interp, bcListObj, RHS_MakeStringObj("The offset: %d", pcOffset)); I'm sure there's places in the code that would run into problems when not using gcc, but thats all I use. If people want to improve this, that would be fantastic. Now, for the actual code... // This is coded specifically for glibc Tcl_Obj * RHS_MakeStringObj(const char *fmt, ...) { /* Guess we need no more than 100 bytes. */ int n, size = 100; char *p; Tcl_Obj *retObj; va_list ap; if ((p = Tcl_Alloc (size)) == NULL) return (Tcl_Obj *)NULL; while (1) { /* Try to print in the allocated space. */ va_start(ap, fmt); n = vsnprintf (p, size, fmt, ap); va_end(ap); /* If that worked, return the string. */ if (n > -1 && n < size) { retObj = Tcl_NewStringObj(p, strlen(p)); Tcl_Free(p); return retObj; } /* Else try again with more space. */ if (n > -1) /* glibc 2.1 */ size = n+1; /* precisely what is needed */ else /* glibc 2.0 */ size *= 2; /* twice the old size */ if ((p = Tcl_Realloc (p, size)) == NULL) { return (Tcl_Obj *)NULL; } } } [RHS] It appears that the microsoft compiler uses the name '''_vsnprintf''' rather than '''vsnprintf'''. So, if you're using MSVC, you may need to change the name. From chat: In fact, on BSD it looks like you need stdio.h and stdarg.h [MAK] Since you mention gcc, I suggest: #ifndef __GNUC__ # define __attribute__(x) #endif Tcl_Obj * RHS_MakeStringObj(const char *fmt, ...) __attribute__((format(printf, 1, 2)))) ... This tells gcc that the form of the arguments is the same as a printf and that it should check to make sure that the number of arguments and their types are appropriate given the format string, and issue errors/warnings if not, just as if you mess up a printf() call. (Btw, that's great. It would be cool to TIP that into the core and use it for [http://sourceforge.net/tracker/index.php?func=detail&aid=572392&group_id=10894&atid=360894].) [RHS] ''16Nov2004'' Having been thinking about what it would take to add such a thing into the core, what I have found leads me to believe that the best option is to write code that calculates the size the string needed to store the results of a printf type input. With that, it would be possible to write the above code simple by just calculating the size needed, malloc'ing it, and using ''sprintf'' to write to it... then creating the Tcl_Obj from that string. This would free us from having to use ''nvsprintf'', which is not particularly portable. I'll put some free time (what little I have, as I just bought a house) into writing such a beast. If anyone already has such code and is willing to release it under the Tcl license, that would simplify things :) [MAK] I'd imagine you could use Tcl_FormatObjCmd() as a starting point. [RHS] Tcl_FormatObjCmd() handles a bit more than I had planned on implementing. Specifically, it handles XPG3 positional arguments, which I hadn't planned on handling (as far as I can tell, they'd be a royal pain do deal with using varargs). There's a couple simple implementations of "take format string and values and figure out the length" out there, and I was planning on going that route. ---- [Category Dev. Tools]