home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c
- Path: sparky!uunet!snorkelwacker.mit.edu!thunder.mcrcim.mcgill.edu!sobeco!ozrout!stirling
- From: stirling@ozrout.uucp (Stirling Westrup)
- Subject: Re: (Help) dynamic use of sprintf ?
- Organization: Andre P. Ozrout
- Date: Fri, 24 Jul 1992 16:45:18 GMT
- Message-ID: <1992Jul24.164518.27683@ozrout.uucp>
- References: <1992Jul21.201712.20985@BitBlocks.COM>
- Lines: 116
-
- bvs@BitBlocks.COM (Bakul Shah) writes:
- >
- >I have a vfprintf like function, called `vfnprintf' that takes a
- >_function pointer_ instead of a FILE *. vfnprintf calls this
- >function, possibly multiple times, to drain already formatted
- >characters. _You_ supply the function. Here is an example use.
-
- [Some code deleted...]
-
- > /* typedef for a function ptr */
- > typedef int (*_vfn_t)(void * st, const char * string, unsigned int count);
- >
- > int vfnprintf(_vfn_t fn, void * st, const char * format, va_list args);
-
- [More code deleted...]
-
- > int snprintf(char * str, int size, const char * fmt, ...) {
- > int count;
- > va_list args;
- > struct snstate snstate;
- > snstate.size = size;
- > snstate.offset = 0;
- > snstate.buffer = str;
- >
- > va_start(args, fmt);
- > count = vfnprintf((_vfn_t)sndrain, &snstate, fmt, args);
- > va_end(args);
- > return count;
- > }
- >
-
- The above aproach is very similar to the one I took when I needed to
- provide flexible handling of format strings (even to the fact that I also
- did not bother with the floating point formats). There is one major
- difference between our ways of doing things. My function (called 'fmt')
- accepts two void pointers, and returns a void pointer. The intent was to
- allow for a printf-type function to return something other than an integer
- count. For instance, my implementation of saprintf returns a pointer to
- the newly allocated string. This does make for some added complexity for
- simple cases like the above though, and I'm not entirely sure its worth it.
-
- The basic idea is that one of the void pointers passed to the function is
- for state information, and the other is for some sort of accumulating
- result. The ancillary function (called 'sndrain' in the above code)
- would use the result from the previous invocation of itself to compute the
- result for this invocation. This may be clearer if I include the
- definition of snprintf from my own library. I think most of the types
- should be clear from context, except perhaps for Nat which is an unsigned
- int. Oh, the Vpl... stuff is just an alias for the va_... stuff from ANSI.
- I use my own names due to certain bugs I've had to work around in various
- compilers.
-
-
- Struct StrLen StrLen;
-
- Struct StrLen /* String/Length pair for snput */
- { Char *str; /* string to write into */
- Nat len; /* max characters to put in string */
- };
-
- Static Void *snput /* put a chunk of text into a string */
- ( Const Char *txt, /* pointer to thte *
- Nat len, /* length of the text */
- Void *ctx, /* context (StrLen pointer) */
- Void *rsl /* result (pointer to a character counter) */
- )
- { Register Struct StrLen sl = x; /* recover type of StrLen pointer */
- Register Nat idx = 0; /* We need an index, why not a reg? */
- Nat *num = rsl; /* recover type of counter pointer */
-
- while( len && sl->len ) /* while text, and a place for it... */
- {
- *(sl->str++) = txt[idx++]; /* Copy a char into the string */
- len--; /* one less char to copy */
- sl->len--; /* one less space ithe string */
- }
- *(sl->str) = 0; /* null terminate the string */
- (*num) += idx; /* and bump counter by chars moved */
- return rsl; /* return our result pointer */
- }
-
- /*
- snprintf - printf'er to a string, with size maximum
- Takes a pointer to a buffer, the size of the buffer (including space for the
- trailing 0), a printf format string, and a variable parameter list.
- The function stores the formatted string in the buffer, or as much as will
- fit. The buffer will be null tminated.
- The function returns the number of characters actually stored.
- */
-
- Nat snprintf
- ( Char *buf,
- Nat len,
- Const Char *str,
- ...
- )
- { StrLen sl;
- Nat num = 0;
- Vpl args;
-
- if( !buf || len < 2 )
- return 0;
- sl.str = buf;
- sl.len = len-1;
- vplBeg(args,str);
- fmt(snput, &sl, &num, str, args);
- vplEnd(args);
- return num;
- }
-
-
- --
- || BUNGEE SIDEWAYS! o )))
- || /-- ///
- |P~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\_ \\\ __ -_
- || stirling@ozrout.uucp ((( (_)T(_)
-