Hey guys: Here is what I have so far of the string_nprintf function. As of now it only handles C string backslash escape sequences and regular chars from the format string. My primary concern is whether I am using BUFFER_immobile_FLAG the correct way to protect myself from GC. I also dont know if the syntax I am using to convert the format string is correct (It seems like it should be). adding in the rest is only a matter of time if this method works {btw, I appologize for not submitting a complete function but I was concerned that I might be running down the wrong road and wanted to check }
also I think encoding_lookup() should accept an argument of "native". Roman
Index: string.c =================================================================== RCS file: /cvs/public/parrot/string.c,v retrieving revision 1.67 diff -u -d -r1.67 string.c --- string.c 9 Apr 2002 03:51:45 -0000 1.67 +++ string.c 10 Apr 2002 22:19:27 -0000 @@ -801,7 +801,148 @@ NULL, 0, NULL); } +/*=for api string_nprintf + * print formated output of len + * chars/glyphs to dest, allocating + * new string if dest is NULL, and + * mimicking sprintf if len == 0. + */ + + +STRING* +string_nprintf(struct Parrot_Interp *interpreter, STRING* dest, UINTVAL len, const +char *format, ...) +{ + va_list ap; + va_start(ap, format); + + if(!dest) + dest = string_make(interpreter, NULL, len, NULL, 0, NULL); + + return (string_vnprintf(interpreter, dest, len, format, ap)); +} + +/* for previous function */ +STRING* +string_vnprintf(struct Parrot_Interp *interpreter, STRING* dest, UINTVAL len, const +char *format, va_list ap) +{ + STRING *b_trans; + STRING *temp_str; + STRING** destp; + + INTVAL grow_total; + + unsigned char sprintf_emu, transcode; + char c, *cp; + + transcode = 0; + sprintf_emu = (len ? 0 : 1); + grow_total = (sprintf_emu ? 0 : len); + + destp = &dest; + cp = &c; + + temp_str = string_make(interpreter, NULL, 0, dest->encoding, +BUFFER_immobile_FLAG, dest->type); + + /* test for native */ + if(dest->encoding != encoding_lookup("singlebyte")) + transcode = 1; + + for (; *format ; ++format) { + /* print reg reg chars */ + if (*format != '\\' && *format != '%') { + if (sprintf_emu) + ++grow_total; + if (sprintf_emu || (len-- != 0)) { + b_trans = string_make(interpreter, format, 1, NULL, + BUFFER_immobile_FLAG, NULL); + (void)string_concat(interpreter, temp_str, b_trans, transcode); + string_destroy(b_trans); + } + } + else if (*(format++) == '\\') { + if (sprintf_emu) + ++grow_total; + if (*format == 'n') { + c = '\n'; + if (sprintf_emu || (len-- != 0)) { + b_trans = string_make(interpreter, cp, 1, NULL, + BUFFER_immobile_FLAG, NULL); + (void)string_concat(interpreter, temp_str, b_trans, + transcode); + string_destroy(b_trans); + } + } + else if (*format == '\\') { + c = '\\'; + if (sprintf_emu || (len-- != 0)) { + b_trans = string_make(interpreter, cp, 1, NULL, + BUFFER_immobile_FLAG, NULL); + (void)string_concat(interpreter, temp_str, b_trans, + transcode); + string_destroy(b_trans); + } + } + else if (*format == 'r') { + c = '\r'; + if (sprintf_emu || (len-- != 0)) { + b_trans = string_make(interpreter, cp, 1, NULL, + BUFFER_immobile_FLAG, NULL); + (void)string_concat(interpreter, temp_str, b_trans, + transcode); + string_destroy(b_trans); + } + } + else if (*format == 'a') { + c = '\a'; + if (sprintf_emu || (len-- != 0)) { + b_trans = string_make(interpreter, cp, 1, NULL, + BUFFER_immobile_FLAG, NULL); + (void)string_concat(interpreter, temp_str, b_trans, + transcode); + string_destroy(b_trans); + } + } + else if (*format == 't') { + c = '\t'; + if (sprintf_emu || (len-- != 0)) { + b_trans = string_make(interpreter, cp, 1, NULL, + BUFFER_immobile_FLAG, NULL); + (void)string_concat(interpreter, temp_str, b_trans, + transcode); + string_destroy(b_trans); + } + } + else if (*format == '\'') { + c = '\''; + if (sprintf_emu || (len-- != 0)) { + b_trans = string_make(interpreter, cp, 1, NULL, + BUFFER_immobile_FLAG, NULL); + (void)string_concat(interpreter, temp_str, b_trans, + transcode); + string_destroy(b_trans); + } + } + else if (*format == '\"') { + c = '\"'; + if (sprintf_emu || (len-- != 0)) { + b_trans = string_make(interpreter, cp, 1, NULL, + BUFFER_immobile_FLAG, NULL); + (void)string_concat(interpreter, temp_str, b_trans, + transcode); + string_destroy(b_trans); + } + } + } + } + string_grow(interpreter, dest, grow_total); + + dest = string_substr(interpreter, temp_str, 0, grow_total, destp); + + return dest; +} + + /* * Local variables: * c-indentation-style: bsd