Variable Argumets


C

Chul Min Kim

Hi,

I'm writing logging functions.
I want to use them within my demon program.
I'm working on Solaris 7, Sun Sparc Machine.

Here are source code.
------------------------------------------------------------
// log.c
// 2005.03
// Kim Chul Min <[email protected]>

// header files
#include <stdio.h> // freopen()
#include <unistd.h> // access()
#include <string.h> // memset()
#include <strings.h> // strcpy()
#include <varargs.h> // va_*
#include <errno.h>

#include "common.h"

// global
char logfile[MAX_PATH_SZ];
int loglevel = DBGLVL_WARNING;
char *logmode = "a";
char tmbuf[40];

// extern
extern int errno;

// function declarations


int make_logfile(char *path, char *mode)
{
if ( freopen(path, mode, stderr) == NULL ) {
// PRINT ERROR
printf("freopen fail=%d(%s)\n", errno, strerror(errno));
return JOB_FAIL;
}

return JOB_OK;
}

void logmsg(va_alist)
va_dcl
{
int mylevel;
va_list args;
char *fmt;

va_start(args);

mylevel = va_arg(args, int);
if (mylevel < loglevel) {
return;
}
if ( access(logfile, F_OK) ) {
make_logfile(logfile, logmode);
}
fmt = va_arg(args, char *);
vfprintf(stderr, fmt, args);
fflush(stderr);
va_end(ap);
return;
}

char *timestamp(void)
{
time_t timeval;
struct tm *tm;

timeval = time(NULL);
tm = (struct tm *)localtime(&timeval);
strftime(tmbuf, 35, "%Y %b %d %X", tm);

return tmbuf;
}

#ifdef _TEST_
int main(int ac, char **av)
{

if (ac < 2) {
puts("***************************************");
puts("** [USAGE] **");
puts("** $ PGM LOG_FILENAME **");
puts("***************************************");
return 1;
}

memset(logfile, NULL, MAX_PATH_SZ);
strcpy(logfile, av[1]);

printf("logfile = [%s]\n", logfile);

if ( make_logfile(logfile, "a") != JOB_OK ) {
printf("make_logfile() fail.\n");
return 1;
}

logmsg(DBGLVL_WARNING, "[%s] warning logmsg...\n", timestamp());
logmsg(DBGLVL_ERROR, "[%s] error logmsg...\n", timestamp());
logmsg(DBGLVL_FATAL, "[%s] fatal logmsg...\n", timestamp());
logmsg(DBGLVL_ABSOLUTE, "[%s] absolute logmsg...\n", timestamp());

return 0;
}
#endif
------------------------------------------------------------

Here are compile messages.
------------------------------------------------------------
VIS_DEV[yfirst]:/home/yfirst/bear/src/lib> cc -xCC -v -Xa -D_TEST_ -I../h -c log.c
"log.c", line 98: warning: argument mismatch: 3 args passed, 1 expected
"log.c", line 99: warning: argument mismatch: 3 args passed, 1 expected
"log.c", line 100: warning: argument mismatch: 3 args passed, 1 expected
"log.c", line 101: warning: argument mismatch: 3 args passed, 1 expected
------------------------------------------------------------

My questions are (1) why I got a argument mismatch warning messages
during compile and how can I fix it, (2) I found that above source
code is old K&R style. I want to write them with ANSI C Style
if it is possible on Solaris 7. I cannot find "stdargs.h" file in /usr/include

I mean ANSI C Style variable arguments coding like:

#include <stdargs.h>
void Logmsg(char *Format, ...)
{

}


Thank you for your valuable time.
Kim
Seoul, Korea
 
Ad

Advertisements

E

Eric Sosman

Chul said:
Hi,

I'm writing logging functions.
I want to use them within my demon program.
I'm working on Solaris 7, Sun Sparc Machine.

Here are source code.
------------------------------------------------------------
// log.c
// 2005.03
// Kim Chul Min <[email protected]>

// header files
#include <stdio.h> // freopen()
#include <unistd.h> // access()

Not a Standard C header, but we'll forgive you.
#include <string.h> // memset()
#include <strings.h> // strcpy()

#include <varargs.h> // va_*

Ugh, barf, vomit, and this is the root of your problem.
The pre-Standard <varargs.h> mechanism has been obsolete for
almost sixteen years; it was replaced by said:
#include <errno.h>

#include "common.h"

// global
char logfile[MAX_PATH_SZ];
int loglevel = DBGLVL_WARNING;
char *logmode = "a";
char tmbuf[40];

// extern
extern int errno;

UGH! BARF! VOMIT! You have already included <errno.h>,
and this line attempts to re-declare what <errno.h> already
declared for you! This is wrong, R-O-N-G, wrong! Do *NOT*
try to write "free-hand" declarations of Standard library
components; use the Standard headers and *only* the Standard
headers. It is possible (although stupid) to write your own
declarations -- but in this case your declaration is R-O-N-G.
[...]
void logmsg(va_alist)
va_dcl
{

This is the root of your problem. You are trying to use
the pre-Standard <varargs.h> mechanism, but you ought to be
using the Standard <stdarg.h> facility, which is somewhat
different. I can tell you're trying to do the right thing
because you say
> I cannot find "stdargs.h" file in /usr/include

.... and the reason you cannot find "stdargs.h" is because the
correct name of the header is <stdarg.h> -- angle brackets
instead of quotation marks, and only one "s". Switch to
<stdarg.h>, change the logmsg() function to match, and you'll
have solved your problem. (Or your "immediate problem;" there
is no end to fixing code ...)

Disclaimer: I sometimes post from a sun.com address but
I do not speak for Sun Microsystems, not even to people who
mention "Solaris" in their questions.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top