473,786 Members | 2,451 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Howto pass va_list to another va func

I have a C program, where I control the error behavior according to context:
/* some error handlers */
static void on_error_log (MYSQL *mysql, const char *msg, ...);
....
static void on_error_exit (MYSQL *mysql, const char *msg, ...);

/* the error function */
static void (*error_fatal) (MYSQL *mysql, const char *msg, ...) =
on_error_log;
i.e. on the fly I can change which handler error_fatal() uses, sometimes I
want to call exit(), other times just log error and continue etc.
So far, no problem, but then I wanted a trace function and decided to reuse
the on_error_log() function, since the trace function didn't need the MYSQL
context, a simplified interface could be used:
static void log_err(const char *msg, ...);
Now comes the problem, how to make log_err() call on_err_log(), clearly my
first try didn't work:
$ cat test_argp.c
/*
Demonstrate the problem of calling variable argument
function, from another va function.
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <assert.h>

#define LOG_FILE_NAME "test.log"

static void on_error_log(co nst char *msg, ...)
{
va_list argp;
FILE *log;

assert(msg != NULL);

log = fopen(LOG_FILE_ NAME, "a");
if (log == NULL)
{
perror(LOG_FILE _NAME);
exit(EXIT_FAILU RE);
}

if ( msg != NULL)
{
va_start(argp, msg);
(void) vfprintf(log, msg, argp);
va_end(argp);
}

fclose(log);
}

static void log_err(const char *msg, ...)
{
va_list argp;

assert(msg != NULL);

va_start(argp, msg);
on_error_log(NU LL, msg, argp);
va_end(argp);
}

int main(void)
{
const char *string = "Test string";

log_err("Log test.... string");
log_err("Log test.... string");

log_err("string = '%s'\n", string);
log_err("string = '%s'\n", string);

return EXIT_SUCCESS;
}

$ gcc -ansi -W -Wall -pedantic -g test_argp.c
$ ./a.out
a.out: test_argp.c:18: on_error_log: Assertion `msg != ((void *)0)' failed.
Aborted
$ gdb a.out
(gdb) r
Starting program: /****/***/***/******/a.out
a.out: test_argp.c:18: on_error_log: Assertion `msg != ((void *)0)' failed.

Program received signal SIGABRT, Aborted.
0xffffe410 in __kernel_vsysca ll ()
(gdb) bt
#0 0xffffe410 in __kernel_vsysca ll ()
#1 0xb7e51770 in raise () from /lib/tls/i686/cmov/libc.so.6
#2 0xb7e52ef3 in abort () from /lib/tls/i686/cmov/libc.so.6
#3 0xb7e4adbb in __assert_fail () from /lib/tls/i686/cmov/libc.so.6
#4 0x080484b4 in on_error_log (msg=0x0) at test_argp.c:18
#5 0x0804856b in log_err (msg=0x80486f7 "Log test.... string") at
test_argp.c:44
#6 0x08048591 in main () at test_argp.c:52
(gdb)
so the assert() bomb out on the first logerr() call. Unless I'm missing some
trivial point here, could someone explain how to do this, and why the above
code fail.

--
Tor <torust [at] online [dot] no>

Apr 25 '07 #1
4 19248
Tor Rustad wrote:
on_error_log(NU LL, msg, argp);
Grrrrrrrrrrr...

on_error_log(ms g, argp);
--
Tor <torust [at] online [dot] no>

Apr 25 '07 #2
Tor Rustad wrote On 04/25/07 15:41,:
I have a C program, where I control the error behavior according to context:
/* some error handlers */
static void on_error_log (MYSQL *mysql, const char *msg, ...);
...
static void on_error_exit (MYSQL *mysql, const char *msg, ...);

/* the error function */
static void (*error_fatal) (MYSQL *mysql, const char *msg, ...) =
on_error_log;
i.e. on the fly I can change which handler error_fatal() uses, sometimes I
want to call exit(), other times just log error and continue etc.
So far, no problem, but then I wanted a trace function and decided to reuse
the on_error_log() function, since the trace function didn't need the MYSQL
context, a simplified interface could be used:
static void log_err(const char *msg, ...);
Now comes the problem, how to make log_err() call on_err_log(), clearly my
first try didn't work:
[...]
You were about half way home, but only half. The idea
is to put the "guts" of the operation in a function that
takes a fixed argument list, one of which is a va_list.
Then you also write one or more wrappers that take "..."
arguments, initialize a va_list, call the "guts" function,
and clean up the va_list. See Question 15.12 in the FAQ
at <http://www.c-faq.com/>.

--
Er*********@sun .com
Apr 25 '07 #3
Tor Rustad wrote, On 25/04/07 20:49:
Tor Rustad wrote:
>on_error_log(N ULL, msg, argp);

Grrrrrrrrrrr...

on_error_log(ms g, argp);
Also you have to make on_error_log take a va_list rather than being
varidac (ending in a ...). If you want to be able to call it both ways,
something like:

void von_error_log(c har *msg, va_list args)
{
/* do the work */
}

void on_error_log(ch ar *msg, ...)
{
va_list args;
va_start(args,m sg);
von_error_log(m sg,args);
va_end(args);
}
--
Flash Gordon
Apr 25 '07 #4
Eric Sosman wrote:
Tor Rustad wrote On 04/25/07 15:41,:
[...]
>>
Now comes the problem, how to make log_err() call on_err_log(), clearly
my first try didn't work:

You were about half way home, but only half. The idea
is to put the "guts" of the operation in a function that
takes a fixed argument list, one of which is a va_list.
Then you also write one or more wrappers that take "..."
arguments, initialize a va_list, call the "guts" function,
and clean up the va_list. See Question 15.12 in the FAQ
at <http://www.c-faq.com/>.
For some reason I must have forgot 15.12, thanks a lot!

Here, is the modified test code, which indeed worked as expected:
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <assert.h>

#define LOG_FILE_NAME "test.log"

static void verror_log(cons t char *msg, va_list argp)
{
FILE *log;

assert(msg != NULL);

log = fopen(LOG_FILE_ NAME, "a");
if (log == NULL)
{
perror(LOG_FILE _NAME);
exit(EXIT_FAILU RE);
}

if ( msg != NULL)
{
(void) vfprintf(log, msg, argp);
}

fclose(log);
}

static void on_error_log(co nst char *msg, ...)
{
va_list argp;

assert(msg != NULL);

va_start(argp, msg);
verror_log(msg, argp);
va_end(argp);
}

static void log_err(const char *msg, ...)
{
va_list argp;

assert(msg != NULL);

va_start(argp, msg);
verror_log(msg, argp);
va_end(argp);
}

int main(void)
{
const char *string = "Test string";

on_error_log("L og test.... string\n");
log_err("Log test.... string\n");

on_error_log("s tring = '%s'\n", string);
log_err("string = '%s'\n", string);

return EXIT_SUCCESS;
}

--
Tor <torust [at] online [dot] no>

Apr 25 '07 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
2820
by: Renie83 | last post by:
Hi I really am going crazy! I'm using VBScript, ASP, and SQL My page reminds me of a shopping cart but looking at shopping cart examples has not helped! What I have is a page that brings in products ordered by a certain company. Along with those values, I'm creating a text box at the end of each record that a user may or may not enter in an estimated delivery date. If the user does enter in a date I want that row of data submitted to a...
2
2218
by: Timmins | last post by:
I have a date in a frame/page that i want to pass to another page. I can succefully pass a static value, i just can't pass a value from a text box. I tried to make everything public. I believe that Me. may only refer to the page that is orginating the action. But how do I pass the text box. Can we assume since I can pass the static value, that the issue is how I grab the textbox value the Error i get is Object reference not set to an...
10
1688
by: Steven Blair | last post by:
Hi, Quick overview of the problem: public bool Something( out DataSet ds ) { bool ret=false; try {
0
1767
by: Wilhelm Pieper | last post by:
Hello, I want to setup a webservice. But before lauching the client webpage I'd like to fill up the clients menu with data from the server. So I created a reference inside the client project to the server project. When the server application is started an arrayList (public static) is filled as shown inside the debugger. When I start the client page it can acces an arraylist inside the server classes but this list is still empty - so I...
6
3509
by: Wijaya Edward | last post by:
Hi, How can I pass Array, Hash, and a plain variable in to a function at the same time. I come from Perl. Where as you probably know it is done like this: sub myfunc {
1
9476
by: skillzero | last post by:
Is there a portable way to pass a va_list as a parameter to another function taking a variable argument list? I have a function that takes a printf-like format string and I'd like to use something like %V to pass in another format string and a va_list to allow nesting. It happens to work on my compiler, but I wasn't sure if it's portable to use va_list's as parameters to a variable argument function because va_list isn't always just a...
2
2109
by: Alexander Eisenhuth | last post by:
Hallo Alltogether, I've searched in this mailing list, but it seems to me that there is no general approach to pass exceptions from one thread to another. I think most application do a unique way of handling "unhandled exceptions", at least they (should) try to log them. The following discussion seems to me most valuable (Sorry for the long URL, I don't know a way of shorter)
0
1249
by: fiveheads | last post by:
Hi guy, I'm Javascript beginner... Recently thinking to have a code, which can read a list of servers from EXCEL (XLS) file and search these servers from network and then pass the results into another excel fle. Any expert can help me.... \\%%i.domain.com\HKEY_LOCAL_MACHINE\SOFTWARE\Fireware Systems\Galaxy\Platform Information\%%i.domain.com\servers" /v "sCSCLIENTNAME Currently i have a version using dos command to grep info as per...
1
1842
by: amitjain123 | last post by:
Hello Friends, I have list box and grid view on screen. on selection of list box item, value of selected item gets added into grid view through java script. Now I want to generate the XML string of values from grid view, and pass the xml string to another screen as Session value. How Can we do this? I had tried but I have faced following problem.
0
10360
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10108
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8988
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7510
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6744
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5397
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5532
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4064
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3668
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.