Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Redefine fprintf for debugging purposes

Reply
Thread Tools

Redefine fprintf for debugging purposes

 
 
stdazi@gmail.com
Guest
Posts: n/a
 
      07-25-2007
On Jul 23, 10:23 am, Prayag Narula <(E-Mail Removed)> wrote:
> Hi,


> all the output that is going to the stdout should be logged in a
> file.

/* .... */
fclose(stdout);
stdout = fopen("....", "w+");
/* ... error checking ... */

What about something like this ?

 
Reply With Quote
 
 
 
 
Ben Bacarisse
Guest
Posts: n/a
 
      07-25-2007
Prayag Narula <(E-Mail Removed)> writes:

> So basically, this is what I did.
>
> <debug.h>
> #ifndef __DEBUG_H__
> #define __DEBUG_H__


You are liable to run into name problems. Implementations are allowed
to define __DEBUG_H__ at their leisure. I think the usual "best
practice" is to use H_DEBUG.

>
> #define fprintf(fp,...) my_fprintf(fp, __VA_ARGS__)
>
> #endif
>
> </debug.h>
>
>
>
> <debug.c>
>
>
> #include <stdio.h>
> #include<string.h>
> #include <stdarg.h>
> #include "debug.h"
>
> int my_fprintf(FILE *fo, ...)
> {
> va_list ap;
> va_start(ap,fo);
> FILE *fp;
> char *buffer;
> buffer = va_arg(ap,char*);
> fp = fopen("log","a");
>
> //printf("%s %d",buffer,strlen(buffer));
>
> if(fo == stdout || fo == stderr)
> {
> fp = fopen("log","a");
> if (fp == NULL)
> return(-1);
> if(fwrite(buffer,sizeof(char),strlen(buffer),fp)> 0)


I don't see the value of using variable argument lists if you just
print the format string (i.e. one argument).

IMO your best bet is to:

(1) re-write all the debugging call to make them call a new function
of your own with no FILE *. It will be a pain the first time, but you
will have freed yourself from having rather inflexible fprintfs all
over the place.

(2) write this debug function to use vfprintf either to stdout,
stderr, a log file or all (or none) of them under the control of some
other variables. (These can be global, or you can pass a pointer to a
debug state structure if you are worried about that.)

You will avoid the need for variable argument macros this way, too.

--
Ben.
 
Reply With Quote
 
 
 
 
Mark Bluemel
Guest
Posts: n/a
 
      07-25-2007
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> On Jul 23, 10:23 am, Prayag Narula <(E-Mail Removed)> wrote:
>
>>Hi,

>
>
>>all the output that is going to the stdout should be logged in a
>>file.

>
> /* .... */
> fclose(stdout);
> stdout = fopen("....", "w+");
> /* ... error checking ... */
>
> What about something like this ?


Nope - stdout may not be an lvalue...

freopen() may be appropriate, I guess.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      07-26-2007
Mark Bluemel <(E-Mail Removed)> writes:
> (E-Mail Removed) wrote:
>> On Jul 23, 10:23 am, Prayag Narula <(E-Mail Removed)> wrote:
>>
>>>Hi,

>>
>>>all the output that is going to the stdout should be logged in a
>>>file.

>> /* .... */
>> fclose(stdout);
>> stdout = fopen("....", "w+");
>> /* ... error checking ... */
>> What about something like this ?

>
> Nope - stdout may not be an lvalue...


Meaning that stdout isn't necessarily an lvalue. (A reasonable, but
incorrect, parsing of your statement is that stdout is not allowed to
be an lvalue.)

And even if stdout happens to be an lvalue, assigning a value to it
may not necessarily work.

> freopen() may be appropriate, I guess.


--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Prayag Narula
Guest
Posts: n/a
 
      07-31-2007
On Jul 25, 9:53 pm, Mark Bluemel <(E-Mail Removed)> wrote:
> (E-Mail Removed) wrote:
> > On Jul 23, 10:23 am, Prayag Narula <(E-Mail Removed)> wrote:

>
> >>Hi,

>
> >>all the output that is going to the stdout should be logged in a
> >>file.

>
> > /* .... */
> > fclose(stdout);
> > stdout = fopen("....", "w+");
> > /* ... error checking ... */

>
> > What about something like this ?

>
> Nope - stdout may not be an lvalue...
>
> freopen() may be appropriate, I guess.


Works!! Thanks a lot!!

 
Reply With Quote
 
Manish Tomar
Guest
Posts: n/a
 
      08-05-2007
>
> #define fprintf(x,y) my_fprintf_1(x,y)
> #define fprintf(x,y,z) my_fprintf_2(x,y,z)
> ...


I dont think this works... I tried in gcc and it gave redefinition
error..

 
Reply With Quote
 
David Thompson
Guest
Posts: n/a
 
      08-26-2007
On Wed, 25 Jul 2007 01:44:14 -0700, Prayag Narula
<(E-Mail Removed)> wrote:

> #define fprintf(fp,...) my_fprintf(fp, __VA_ARGS__)


> int my_fprintf(FILE *fo, ...)
> {
> va_list ap;
> va_start(ap,fo);


Minor: va_start() counts as code, and having code before declarations
within a block is not standard in C90, although it is supported as an
extension in several popular compilers and is standard in C99.

> FILE *fp;
> char *buffer;
> buffer = va_arg(ap,char*);
> fp = fopen("log","a");
>
> //printf("%s %d",buffer,strlen(buffer));
>
> if(fo == stdout || fo == stderr)
> {
> fp = fopen("log","a");
> if (fp == NULL)
> return(-1);
> if(fwrite(buffer,sizeof(char),strlen(buffer),fp)> 0)
> return(strlen(buffer));


This will only print the format string, not any converted data that it
calls for, which means the only valid invocations are with exactly two
arguments (fp and str) and you don't need variadic. If you really want
fprintf functionality, use vfprintf, or sprintf or better snprintf
(also a common extension in C90, standard in C99) plus fwrite.

> }
> else
> {
> return (-1);


From your description elsethread I thought you do want to
allow/support output to files other than stdout/err, you just don't
want the redirection to apply to those other files.

> Works in gcc but doesn't work in the embedded IDE. I guess, the
> embedded compiler does not support variable arguments macro. Though it
> definitely supports variable argument functions.
>

vararg functions have been standard since C90, which is almost
universally implemented (modulo bugs), and were fairly common even
before standardization. variadic macros are new in C99, not yet widely
implemented, and were/are not common outside of C99 and gcc.

> Though I am still testing.
>
> Anyways, another option that I can think of is
>
> #define fprintf(x,y) my_fprintf_1(x,y)
> #define fprintf(x,y,z) my_fprintf_2(x,y,z)
> ...
> and so on. A dirty way of doing this. What do you guys think ?
>

That can't work at all; Cpp allows only one definition for a macro.

What does work is
#define fprintf0(f,s), my_fprintf_0(f,s)
#define fprintf1(f,s,a) my_fprintf_1(f,s,a)
#define fprintf2(f,s,a,b) my_fprintf_2(f,s,a,b)
(where I count the number of variable/data args only) but this
requires changing each invocation, which you wanted to avoid.

Using an 'object-like' (nonparameterized) macro instead can work:

#undef fprintf
#define fprintf my_fprintf

void my_fprintf (FILE * f, /*restrict*/ const char * s, ...)
/* note signature EXACTLY SAME as real fprintf() */
{ blah blah blah }

and then usage as fprintf (fp, "foo", x, y, z) just expands to
my_fprintf (fp, "foo", x, y, z) and your function can do its thing.

Caveat: this is officially not supported by the standard -- overriding
any standard-library feature is not -- but it is likely to work on all
real implementations, at least as long as you do it only for source
i.e. NOT before #include'ing system or even third-party headers. And
of course it only applies to calls within code you write or modify and
compile, not within any object libraries that you call.

- formerly david.thompson1 || achar(64) || worldnet.att.net
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to print SRE_Pattern (regexp object) text for debugging purposes? dmtr Python 3 06-17-2010 11:16 PM
Tree View for Non-Navigational Purposes =?Utf-8?B?ZGF2ZS5kb2xhbg==?= ASP .Net 2 03-20-2006 02:27 AM
I need to make me a specification list for outsourcing purposes, please help.. Edwin Knoppert ASP .Net 3 01-27-2006 02:11 PM
PBR for load sharing purposes paranic Cisco 2 11-02-2005 02:37 PM
Validators at cross purposes? Ken McAndrew ASP .Net 2 01-06-2004 05:13 PM



Advertisments