putmsg() replacement

Normally all Metamorph 3 API output goes to stderr or a disk file. But, depending on your application, this may not be desirable. You may wish to send all messages to a special alternate window under a graphical environment or process the messages as they occur and take immediate action based on the type of message. You may also want to filter the messages so that only errors and warnings get displayed. Whatever your reason, putmsg() may be replaced.

Since putmsg() takes a variable number of arguments it must be written using varargs or the ANSI stdarg, if you prefer (see your 'C' manual). Only the varargs method will be documented here. The core is the same either way; the only variation is how you go about getting the function arguments.

There are three arguments that are always present. The first argument is a message number of type (int). The second argument is a function name of type (char *). The third argument is a htpf() format string of type (char *). htpf() is a Thunderstone function similar to printf(), but with extended flags and codes: the fmt argument should always be printed with an htpf()-family function and not printf()-family because some messages may utilize these extended flags and codes. Any remaining arguments are as required by the htpf() format string.

putmsg() returns whether there was an error outputting the message or not. A return of 0 means there was not an error. A return of non-0 means there was an error.

All of the macros needed for putmsg() are in the header "mmsg.h". "api3.h" automatically #include's "mmsg.h". If you put putmsg() in its own source file just use "mmsg.h". If you put putmsg() in the same file as Metamorph API calls or call the API from putmsg() use "api3.h".


** This implementation will *ONLY* output errors(MERR) and
** warnings(MWARN).
** It will output "ERROR:" or "WARNING:" instead of a message number.
** It will always send its output to stderr.
** Function names will not be printed.

#include <stdio.h>
#include <varargs.h>        /* for variable argument list handling */
#include "mmsg.h"                                   /* or "api3.h" */
#include "cgi.h"                        /* for htvfpf()  prototype */

putmsg(va_alist)                    /* args: msgn,funcname,fmt,... */
va_dcl       /* no semicolon allowed! - just the way varargs works */
va_list args;       /* for variable argument list handling         */
int        n;       /* the message number (may be -1)              */
char     *fn;       /* the function name (may be NULL)             */
char    *fmt;       /* the htpf type format string (may be NULL) */
int level;                               /* message hundreds level */

                                        /* get the fixed arguments */
   va_start(args);      /* initialize variable argument list usage */
   n  =va_arg(args,int   );                      /* message number */
   fn =va_arg(args,char *);                      /* function name  */
   fmt=va_arg(args,char *);                      /* htpf format    */

   if(n>=0){                          /* is there a message number */
      level=n-(n%100);           /* clear the tens and ones places */
                                 /* to get the hundreds level      */
      if(level==MERR || level==MWARN){ /* only do error or warning */
         if(level==MERR) fputs("ERROR: "  ,stderr);
         else            fputs("WARNING: ",stderr);
         if(fmt!=(char *)NULL){           /* is there message text */
            htvfpf(stderr,fmt,args);  /* print the message content */
                                      /* using the varargs version */
                                      /* of htpf(): htvfpf()       */
         fputc('\n',stderr);                 /* print the new line */
   va_end(args);         /* terminate variable argument list usage */
   return(0);                                         /* return OK */

The putmsg() extensions need not be replaced if you are not going to use them because the API does not use them. If you do use any extensions you must also replace the ones that you use to avoid linker clashes.


apimmsg.c, mmsg.h

Copyright © Thunderstone Software     Last updated: May 19 2023
Copyright © 2023 Thunderstone Software LLC. All rights reserved.