[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

19991203: dcwtch



After tring to set up dcwtch, I found that there is no way to
specify the spcwatch.tbl station table using the standard
"-s" dc option.

The ww_crnr routine calls clo_findstn to obtain the watch box corners,
and clo_findstn in turn relies on clo_rdstn to load the spcwatch.tbl
file (as defined as the ANCHOR file type in clocmn.h). My problem here is
that clo_rdstn relies on the standard table search path from GEMTBL/stns
in order to find the table- and ignores any input from the "-s" 
option. Without GEMTBL being explicitly set, the program core dumps.
In general, all the other dc style decoders can be driven with
commandline options so that they have not required all the GEMPAK variables 
to exist in the LDM environment. I guess the point here is whether or not
this is expected behavior for a dc style decoder.

A simple work around which benefits all the decoders is to add a
optarg case in dc_init which allows environmental variables to
be set for the decoder environment from the command line. This also
eliminates the need for long path names in -p and -s arguments.
Several decoders I have, like dcgrib, use multiple tables files-
and it greatly simplifies execution from the LDM point of view
to have "-e GEMTBL=/home/nawips/gempak/tables".

I will attatch a copy of my dc_init which solves my above problem
in case you think a -e flag is useful.

The basic outline:

In dcinit.c, define an enironmental variable list:

typedef struct envlist{
   char *env;
   struct envlist *next;
   }envlist;

and define list pointers in the dc_init routine:
envlist *envhead=NULL,*envobj;

In the optarg section, create the environmental variable
list. This allows multiple "-e PARM-value" definitions.
Since putenv requires that the string become part of the
environment, you do not want to use a single char*.

                case 'e':
                        envobj = (envlist *)malloc(sizeof(envlist));
                        envobj->env = malloc(strlen(optarg)+1);
                        strcpy(envobj->env,optarg);A
                        envobj->env[strlen(optarg)] = '\0';
                        envobj->next = envhead;
                        envhead = envobj;
                        break;

The after the decoder log is opened:
        envobj = envhead;
        while(envobj != NULL)
           {
           if(putenv(envobj->env) != 0)
              {
              printf(errstr,"Can't set environmental variable [%s]\0",
                 envobj->env);
              sprintf(errgrp,"DCINIT\0");
              dc_wclg ( 0, errgrp, 1, errstr, &ier);
              }
           envobj = envobj->next;
           }

Steve Chiswell 
Unidata User Support



#define DCCMN_GLOBAL
#include "dccmn.h"
#include "undscr.h"

typedef struct envlist{
   char *env;
   struct envlist *next;
   }envlist;

void
dc_init ( prgnam, argc, argv, numexp, parms, num, iret )
        char    *prgnam;
        int     argc;
        char    **argv;
        int     numexp;
        char    parms[][DCMXLN];
        int     *num;
        int     *iret;

/************************************************************************
 * dc_init                                                              *
 *                                                                      *
 * This routine initializes the bridge and decoder parameters and       *
 * processes the command line options.                                  *
 *                                                                      *
 * dc_init ( prgnam, argc, argv, numexp, parms, num, iret )             *
 *                                                                      *
 * Input parameters:                                                    *
 *      *prgnam         char            Program name                    *
 *      argc            int             Number of command line args     *
 *      **argv          char            Command line arguments          *
 *      numexp          int             Number of expected parameters   *
 *                                                                      *
 * Output parameters:                                                   *
 *      parms[][DCMXLN] char            Parameters found on command line*
 *      *num            int             Number of parameters found      *
 *      *iret           int             Return code                     *
 *                                         0 = normal return            *
 *                                       -11 = no command line args     *
 *                                                                      *
 **                                                                     *
 * Log:                                                                 *
 * A. Chang/EAi          5/95                                           *
 * S. Jacobs/NMC         7/95   Update and clean up                     *
 * S. Jacobs/NCEP        6/96   Updated documentation; Changed atoi to  *
 *                              cst_numb; Removed the +3 return code;   *
 *                              Changed ldfd to a FILE stream - fplog   *
 * S. Jacobs/NCEP        7/96   Reorganized the source code             *
 * K. Tyle/GSC           7/96   NT_HELP --> IP_HELP                     *
 * S. Jacobs/NCEP        7/96   Removed log file open                   *
 * K. Tyle/GSC           1/97   Added calls to IN_BDTA and ER_STAT;     *
 *                              changed numerr in startup dc_wclg call  *
 * K. Tyle/GSC           1/97   Use iflg in call to ER_STAT             *
 * D. Kidwell/NCEP       9/97   Added version number to help option     *
 * I. Durham/GSC         5/98   Changed underscore decl. to an include  *
 ***********************************************************************/

{
        int     ch, i, errflg, ier, ierr;
        int     pagflg = G_FALSE;
        int     iflg   = G_TRUE;

/*
**      These variables are used for logging errors and notices.
*/
        char    ldmlog[5], tdclog[DCMXLN], prglc[DCMXLN];
        int     logmask = (LOG_MASK(LOG_ERR) | LOG_MASK(LOG_NOTICE)) ;
        int     loglev, numerr, logflg, ibuf;
        char    errgrp[9], errstr[DCMXLN];

/*
**      These variables are used by getopt. Unset the error reporting.
*/
        char            optver[20];
        extern char     *optarg;
        extern int      optind, optopt, opterr;

/*      environmental variables must be allocated. They become
        part of the environment */
        envlist *envhead=NULL,*envobj;
/*---------------------------------------------------------------------*/
        *iret = 0;

/*
**      Set the process ID for log messages.
*/
        ipid = (int) getpid ();

/*
**      Initialize the bulletin counter.
*/
        nbull = 0;

/*
**      Save the program name as a global variable.
*/
        strcpy ( cprgnm, prgnam );

/*
**      Set up the signal handlers.
*/
        dc_sgnl ( );
    
/*
**      Get and process the command line options.
**
**      Set the default values for parsing the command line.
*/
        strcpy ( curtim, "SYSTEM" );
        cst_uclc ( cprgnm, tdclog, &ier );
        strcat ( tdclog, ".log" );
        logflg    = G_FALSE;
        ldmlog[0] = CHNULL;
        itmout    = DCDFTM;
        irltim    = G_TRUE;
        txtflg    = G_TRUE;
        ivrblv    = 0;
        prmfil[0] = CHNULL;
        stntbl[0] = CHNULL;
        iadstn    = IMISSD;
        maxtim    = IMISSD;
        nhours    = IMISSD;

/*
**      Get the valid options from the command line.
**      The valid options are:
**              -v      Set the level of verbosity for the logs
**              -c      Set the "current" time
**              -b      Number of hours to decode prior to "current" time
**              -d      Set the decoder log file name
**              -t      Set the interval for the time out
**              -p      Set the parameter packing table
**              -s      Set the station table
**              -a      Set the number of additional stations
**              -m      Set the max number of times
**              -n      Set a flag to NOT save the text data
**              -h      Print the help file, then exit the program
*/
        opterr = 1;
        errflg = 0;
        while ( ( ch = getopt ( argc, argv,
                                "v:c:b:d:t:p:s:a:m:e:nh" ) ) != EOF ) {
            switch ( ch ) {
                case 'v':
                        cst_numb ( optarg, &ivrblv, &ier );
                        if  ( ivrblv < 0 )  ivrblv = 0;
                        break;
                case 'c':
                        strcpy ( curtim, optarg );
                        irltim = G_FALSE;
                        break;
                case 'b':
                        cst_numb ( optarg, &nhours, &ier );
                        break;
                case 'd':
                        strcpy ( tdclog, optarg );
                        logflg = G_TRUE;
                        break;
                case 't':
                        cst_numb ( optarg, &itmout, &ier );
                        if  ( itmout < 1 )  itmout = DCDFTM;
                        break;
                case 'p':
                        strcpy ( prmfil, optarg );
                        break;
                case 's':
                        strcpy ( stntbl, optarg );
                        break;
                case 'e':
                        envobj = (envlist *)malloc(sizeof(envlist));
                        envobj->env = malloc(strlen(optarg)+1);
                        strcpy(envobj->env,optarg);
                        envobj->env[strlen(optarg)] = '\0';
                        envobj->next = envhead;
                        envhead = envobj;
                        break;
                case 'a':
                        cst_numb ( optarg, &iadstn, &ier );
                        break;
                case 'm':
                        cst_numb ( optarg, &maxtim, &ier );
                        break;
                case 'n':
                        txtflg = G_FALSE;
                        break;
                case 'h':
                        ip_help ( cprgnm, &pagflg, &ier,
                                  strlen(cprgnm) );
                        strcpy ( cprgnm, "DECODE" );
                        ip_help ( cprgnm, &pagflg, &ier,
                                  strlen(cprgnm) );
                        ss_vers ( optver, &ier,
                                  sizeof (optver) );
                        printf ( ">%s<\n", optver );
                        exit ( 0 );
                        break;
                case '?':
                        errflg++;
                        break;
            }
        }

/*
**      Initialize GEMPAK and set error reporting parameters.
*/
        in_bdta ( &ier );
        ibuf = 1;
        er_stat ( &ivrblv, &ibuf, &iflg, &ier );
/*
**      Open and initialize the ldm log.
**
**      If the program is being used to decode an archive file, send
**      all LDM messages to STDERR.
*/
        if  ( ! irltim )  strcpy ( ldmlog, "-" );
        setulogmask ( logmask );
        ierr = openulog ( prgnam, (LOG_CONS|LOG_PID), LOG_LOCAL0,
                          ldmlog );
        unotice ( "Starting Up" );

/*
**      Open the decoder log.
**
**      If the processing is in real-time add the directory to the 
**      file name.
*/
        if  ( !logflg && irltim )
        {
            strcpy ( dcdlog, "logs/" );
            strcat ( dcdlog, tdclog );
        }
        else
        {
            strcpy ( dcdlog, tdclog );
        }

/*
**      Send a start up message to the decoder log.
*/
        dc_wclg ( 0, "DC", 3, " ", &ier );

        envobj = envhead;
        while(envobj != NULL)
           {
           if(putenv(envobj->env) != 0)
              {
              printf(errstr,"Can't set environmental variable [%s]\0",
                 envobj->env);
              sprintf(errgrp,"DCINIT\0");
              dc_wclg ( 0, errgrp, 1, errstr, &ier);
              }
           envobj = envobj->next;
           }
/*
**      Adjust argc and argv by the option index.
*/
        argc -= optind;
        argv += optind;

/*
**      Initialize the output string array.
*/
        for ( i = 0; i < numexp; i++ )
            strcpy ( parms[i], " " );

/*
**      Get the decoder specific parameters.
*/
        *num = argc;

        if  ( *num == 0 )
        {
/*
**          If there are no parameters write a message and return
**          with an error.
*/
            *iret = -11;
            dc_wclg ( 0, "DC", *iret, " ", &ier );
        }
        else
        {
/*
**          Otherwise, set the parameters to be returned.
*/
            for ( i = 0; i < *num; i++ )
                if  ( i < numexp )  strcpy ( parms[i], argv[i] );
        }
}