Hi All, I've been experimenting with the printf function and the usage of va_list but I'm not sure if I understand it right. int printf(const char *format, ...) /* Our main entry */ { va_list ap; int nr_of_chars; va_start(ap, format); /* Variable argument begin */ nr_of_chars = _formatted_write(format, put_one_char, (void *) 0, ap); va_end(ap); /* Variable argument end */ return nr_of_chars; /* According to ANSI */ } this is a copy of the printf. Does nr_of_chars actually contain the number of chars formatted??? Because I don't see anything else but 1. I'de like to use the va_list stuff for other serial related stuff so it would be realy cool if nr_of_chars would contain the number of formatted bytes. thanks Martijn Broens
printf function
Started by ●April 1, 2003
Reply by ●April 1, 20032003-04-01
usage of > va_list but I'm not sure if I understand it right. Yu may want to check http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.10.html for details. /Roland
Reply by ●April 2, 20032003-04-02
> I've been experimenting with the printf
function and the usage of
> va_list but I'm not sure if I understand it right.
>
> int printf(const char *format, ...) /* Our main entry
> */
> {
> va_list ap;
> int nr_of_chars;
>
> va_start(ap, format); /* Variable argument begin */
> nr_of_chars = _formatted_write(format, put_one_char, (void *) 0, ap);
> va_end(ap); /* Variable argument end */
> return nr_of_chars; /* According to ANSI */
> }
>
> this is a copy of the printf. Does nr_of_chars actually contain the
> number of chars formatted??? Because I don't see anything else but 1.
>
> I'de like to use the va_list stuff for other serial related stuff so
it
> would be realy cool if nr_of_chars would contain the number of formatted
> bytes.
Yes, printf returns the number of bytes that has been printed.
For example, you can compiler and run the following program, and play
around with the format string (%x, %d etc.):
/---------------------
| #include <stdio.h>
|
| int main()
| {
| int x = printf("Hello %d!\n", -1);
| printf("%d\n", x);
| }
\---------------------
You might want to be interested in the "vprintf" function. This is a
quite unknown cousin to printf that accepts only two parameters, one
format string and a va_list. This can be used inside other functions
that themselves have "..." arguments. (All printf-related functions
have v-cousins like "vsprintf".) For example:
/---------------------
| #include <stdio.h>
| #include <stdarg.h>
|
| void foo(int x, ...)
| {
| va_list args;
| char const * fmt = 0;
|
| va_start(args, x);
|
| switch(x)
| {
| case 1: fmt = "%d\n"; break;
| case 2: fmt = "%d:%d\n"; break;
| case 3: fmt = "%d:%d:%d\n"; break;
| case 4: fmt = "%d:%d:%d:%d\n"; break;
| }
|
| if (fmt != 0)
| {
| vprintf(fmt, args);
| }
|
| va_end(args);
| }
|
| int main()
| {
| foo(1, 10);
| foo(2, 4711, 17);
| foo(3, 123, 456, 789);
| foo(4, 1, 2, 4, 8);
| }
\---------------------
-- Anders
Reply by ●April 4, 20032003-04-04
Hi Anders, Thanks for the reply, i still don't know why nr_of_chars in my file doesn't contain the actual number of bytes formatted. The problem with vprintf is that you need to know how many bytes you've got, and that just what I want to get rid of. One of my wishes would be to create a printf look a like function that send's a stream to the uarts or parallel busses. thanks Martijn Broens -----Oorspronkelijk bericht----- Van: Anders Lindgren [mailto:andersl@ande...] Verzonden: woensdag 2 april 2003 11:57 Aan: msp430@msp4... Onderwerp: Re: [msp430] printf function > I've been experimenting with the printf function and the usage of > va_list but I'm not sure if I understand it right. > > int printf(const char *format, ...) /* Our main entry > */ > { > va_list ap; > int nr_of_chars; > > va_start(ap, format); /* Variable argument begin */ > nr_of_chars = _formatted_write(format, put_one_char, (void *) 0, ap); > va_end(ap); /* Variable argument end */ > return nr_of_chars; /* According to ANSI */ > } > > this is a copy of the printf. Does nr_of_chars actually contain the > number of chars formatted??? Because I don't see anything else but 1. > > I'de like to use the va_list stuff for other serial related stuff so it > would be realy cool if nr_of_chars would contain the number of formatted > bytes. Yes, printf returns the number of bytes that has been printed. For example, you can compiler and run the following program, and play around with the format string (%x, %d etc.): /--------------------- | #include <stdio.h> | | int main() | { | int x = printf("Hello %d!\n", -1); | printf("%d\n", x); | } \--------------------- You might want to be interested in the "vprintf" function. This is a quite unknown cousin to printf that accepts only two parameters, one format string and a va_list. This can be used inside other functions that themselves have "..." arguments. (All printf-related functions have v-cousins like "vsprintf".) For example: /--------------------- | #include <stdio.h> | #include <stdarg.h> | | void foo(int x, ...) | { | va_list args; | char const * fmt = 0; | | va_start(args, x); | | switch(x) | { | case 1: fmt = "%d\n"; break; | case 2: fmt = "%d:%d\n"; break; | case 3: fmt = "%d:%d:%d\n"; break; | case 4: fmt = "%d:%d:%d:%d\n"; break; | } | | if (fmt != 0) | { | vprintf(fmt, args); | } | | va_end(args); | } | | int main() | { | foo(1, 10); | foo(2, 4711, 17); | foo(3, 123, 456, 789); | foo(4, 1, 2, 4, 8); | } \--------------------- -- Anders <http://rd.yahoo.com/M$6920.2960106.4328965.1728375/D=egroupweb/S05 005378:HM/A13703/R=0/*http:/www.gotomypc.com/u/tr/yh/cpm/grp/300_06F/ g22lp?Target=mm/g22lp.tmpl> <http://us.adserver.yahoo.com/l?M$6920.2960106.4328965.1728375/D=egrou pmail/S=:HM/A13703/randb5225343> . ">http://docs.yahoo.com/info/terms/> Terms of Service.
Reply by ●April 4, 20032003-04-04
Hi Martijn, > Thanks for the reply, i still don't know why nr_of_chars in my file > doesn't contain the actual number of bytes formatted. The problem with > vprintf is that you need to know how many bytes you've got, and that > just what I want to get rid of. Strange, what version of the tools are you using? (It seems to run correctly in IAR 2.10A.) > One of my wishes would be to create a printf look a like function that > send's a stream to the uarts or parallel busses. There are two ways of doing this. The first is to use "vsprintf", print to a string and then copy the output to the uart. For example: /--- | #include <stdio.h> | #include <stdarg.h> | | /* Assuming that you have this somewhere. */ | void uart_send(char); | | void uart_printf(char const * fmt, ...) | { | va_list args; | int i, len; | char buf[256]; | | va_start(args, fmt); | | len = vsprintf(buf, fmt, args); | | /* | * If your "vsprintf" returns the wrong length then you can uncomment the | * line below. | */ | | /* len = strlen(buf); */ | | for (i = 0; i < len; ++i) | { | uart_send(buf[i]); | } | | va_end(args); | } \--- The other approach is to replace one of the underlying library low-level output routines with a routine that sends the output to a uart. The advantage is that using this method all output can be redirected a uart. How this is done depends on the tools you are using and (for some tools) the library you are using. For the IAR tools version 1 you can replace "putchar". The same goes for version 2 if you are using the "CLib library". The following code will send all output to the uart, regardless of how it is generated. /--- | #include <stdio.h> | | int putchar(int x) | { | uart_send(x); | return x; | } | | int main() | { | printf("Hello\n"); | } \--- In version 2 of the tools there is also another library, the "DLib library". This library support file-systems so the overriding mechanisms are slightly more complicated. You can either override "__write" or "__writechar" (but not "putchar"!!), depending on if you would like to transmit a whole bunch of characters or just one at the time. (If overhead is required for each transmission then it might be much more efficient to transmit a buffer.) In addition the library support several open files so if you override a small number of functions: "__open", "__close", "__read" etc. then you can send data to different hardware units, or you can use them to implement a memory file system. All higher level functions like "fprintf" use the functions I mentioned above. -- Anders
Reply by ●April 4, 20032003-04-04
How many people can be running 2.10 of the IAR tools? Despite paying huge sums to IAR for the privilege I have not been sent an official copy. The only way I got hold of it was to e-mail the support office and ask where it was - almost a month after IAR announced its release. I was given the download URL. My app is some 150 source files and 50K of compiled code. Porting it was not too difficult but I have abandoned the development under 2.10 because I hate the IAR editor and attempting to use an external one involves repeatedly changing the edit mode from internal to external and back again. It is too painful. Ian >From: Anders Lindgren <andersl@ande...> >Reply-To: msp430@msp4... >To: msp430@msp4... >Subject: Re: [msp430] printf function >Date: Fri, 4 Apr 2003 10:31:00 +0200 (MEST) > > >Hi Martijn, > > > Thanks for the reply, i still don't know why nr_of_chars in my file > > doesn't contain the actual number of bytes formatted. The problem with > > vprintf is that you need to know how many bytes you've got, and that > > just what I want to get rid of. > >Strange, what version of the tools are you using? (It seems to run >correctly in IAR 2.10A.) > > > > One of my wishes would be to create a printf look a like function that > > send's a stream to the uarts or parallel busses. > >There are two ways of doing this. > >The first is to use "vsprintf", print to a string and then copy the >output to the uart. For example: > >/--- >| #include <stdio.h> >| #include <stdarg.h> >| >| /* Assuming that you have this somewhere. */ >| void uart_send(char); >| >| void uart_printf(char const * fmt, ...) >| { >| va_list args; >| int i, len; >| char buf[256]; >| >| va_start(args, fmt); >| >| len = vsprintf(buf, fmt, args); >| >| /* >| * If your "vsprintf" returns the wrong length then you can uncomment >the >| * line below. >| */ >| >| /* len = strlen(buf); */ >| >| for (i = 0; i < len; ++i) >| { >| uart_send(buf[i]); >| } >| >| va_end(args); >| } >\--- > > >The other approach is to replace one of the underlying library >low-level output routines with a routine that sends the output to a >uart. The advantage is that using this method all output can be >redirected a uart. > >How this is done depends on the tools you are using and (for some >tools) the library you are using. For the IAR tools version 1 you can >replace "putchar". The same goes for version 2 if you are using the >"CLib library". The following code will send all output to the uart, >regardless of how it is generated. > >/--- >| #include <stdio.h> >| >| int putchar(int x) >| { >| uart_send(x); >| return x; >| } >| >| int main() >| { >| printf("Hello\n"); >| } >\--- > > >In version 2 of the tools there is also another library, the "DLib >library". This library support file-systems so the overriding >mechanisms are slightly more complicated. You can either override >"__write" or "__writechar" (but not "putchar"!!), depending on if you >would like to transmit a whole bunch of characters or just one at the >time. (If overhead is required for each transmission then it might be >much more efficient to transmit a buffer.) > >In addition the library support several open files so if you override >a small number of functions: "__open", "__close", "__read" etc. then >you can send data to different hardware units, or you can use them to >implement a memory file system. All higher level functions like >"fprintf" use the functions I mentioned above. > > -- Anders _________________________________________________________________ Use MSN Messenger to send music and pics to your friends http://www.msn.co.uk/messenger
Reply by ●April 7, 20032003-04-07
hi Anders, I was able to use printf available in IAR code limited version, to print debug messages to 2x16 LCD. had to recompile the source and link it to the library module. have't traced the history of your discussion on this thread to understand if you have already done the above. -vasu --- In msp430@msp4..., Anders Lindgren <andersl@i...> wrote: > > Hi Martijn, > > > Thanks for the reply, i still don't know why nr_of_chars in my file > > doesn't contain the actual number of bytes formatted. The problem with > > vprintf is that you need to know how many bytes you've got, and that > > just what I want to get rid of. > > Strange, what version of the tools are you using? (It seems to run > correctly in IAR 2.10A.) > > > > One of my wishes would be to create a printf look a like function that > > send's a stream to the uarts or parallel busses. > > There are two ways of doing this. > > The first is to use "vsprintf", print to a string and then copy the > output to the uart. For example: > > /--- > | #include <stdio.h> > | #include <stdarg.h> > | > | /* Assuming that you have this somewhere. */ > | void uart_send(char); > | > | void uart_printf(char const * fmt, ...) > | { > | va_list args; > | int i, len; > | char buf[256]; > | > | va_start(args, fmt); > | > | len = vsprintf(buf, fmt, args); > | > | /* > | * If your "vsprintf" returns the wrong length then you can uncomment the > | * line below. > | */ > | > | /* len = strlen(buf); */ > | > | for (i = 0; i < len; ++i) > | { > | uart_send(buf[i]); > | } > | > | va_end(args); > | } > \--- > > > The other approach is to replace one of the underlying library > low-level output routines with a routine that sends the output to a > uart. The advantage is that using this method all output can be > redirected a uart. > > How this is done depends on the tools you are using and (for some > tools) the library you are using. For the IAR tools version 1 you can > replace "putchar". The same goes for version 2 if you are using the > "CLib library". The following code will send all output to the uart, > regardless of how it is generated. > > /--- > | #include <stdio.h> > | > | int putchar(int x) > | { > | uart_send(x); > | return x; > | } > | > | int main() > | { > | printf("Hello\n"); > | } > \--- > > > In version 2 of the tools there is also another library, the "DLib > library". This library support file-systems so the overriding > mechanisms are slightly more complicated. You can either override > "__write" or "__writechar" (but not "putchar"!!), depending on if you > would like to transmit a whole bunch of characters or just one at the > time. (If overhead is required for each transmission then it might be > much more efficient to transmit a buffer.) > > In addition the library support several open files so if you override > a small number of functions: "__open", "__close", "__read" etc. then > you can send data to different hardware units, or you can use them to > implement a memory file system. All higher level functions like > "fprintf" use the functions I mentioned above. > > -- Anders