ftp.nice.ch/pub/next/unix/developer/pcn.2.0.s.tar.gz#/src/runtime/args.c

This is args.c in view mode; [Download] [Up]

/*
 * PCN Abstract Machine Emulator
 * Authors:     Steve Tuecke and Ian Foster
 *              Argonne National Laboratory
 *
 * Please see the DISCLAIMER file in the top level directory of the
 * distribution regarding the provisions under which this software
 * is distributed.
 *
 * args.c - Command line argument parsing routines.
 */

#include "pcn.h"

static	void	match_arg();
static	int	parse_args();
static	void	argdesc_usage();

#ifdef PCN_HOST

/*
 *  int _p_read_args(int argc, char *argv[])
 *
 * Read in the command line arguments, and set the appropriate global
 * variables based on the arguments.
 *
 * Return a new argc for the number of arguments that should go to
 * the user procedure.
 */
int _p_read_args(argc, argv)
int argc;
char *argv[];
{
    static int_t need_help = 0;
    int unknown_argc;
    char **unknown_argv;
    argdesc_t *sr_argdesc;
    int sr_n_argdesc;
    int i;
    
#ifdef DEBUG    
    static int_t global_dl = -1;
    static int_t em_dl = -1;
    static int_t gc_dl = -1;
    static int_t par_dl = -1;
#ifdef PARALLEL
    static int_t n_global_dl = -1;
    static int_t n_em_dl = -1;
    static int_t n_gc_dl = -1;
    static int_t n_par_dl = -1;
#endif /* PARALLEL */
#endif /* DEBUG */

    static argdesc_t argdesc[] = {
	BOOL_ARG("h", &need_help,
		 "show help message"),
	STRING_ARG("bm", _p_boot_mod,
		   "PCN boot module"),
	STRING_ARG("bp", _p_boot_proc,
		   "PCN boot procedure"),
	STRING_ARG("mm", _p_main_mod,
		   "PCN main module"),
	STRING_ARG("mp", _p_main_proc,
		   "PCN main procedure"),
	INTEGER_ARG("heap_size", &_p_heap_size,
		    "initial heap size (cells)"),
	INTEGER_ARG("heap_inc_proximity", &_p_heap_inc_proximity,
		    "increase heap when this close to full (cells)"),
	INTEGER_ARG("heap_increment", &_p_heap_increment,
		    "increase heap by this much when heap fills up (cells)"),
	INTEGER_ARG("heap_free_after_gc", &_p_heap_free_after_gc,
		    "use this much free heap space after a gc (cells)"),
	INTEGER_ARG("heap_lowat", &_p_heap_lowat,
		    "heap low water mark -- shrink to this (cells)"),
	INTEGER_ARG("heap_hiwat", &_p_heap_hiwat,
		    "heap high water mark -- grow at most to this (cells)"),
	INTEGER_ARG("gc_slack", &_p_gc_slack,
		    "gc slack at top of heap (cells)"),
	INTEGER_ARG("irt_size", &_p_irt_size,
		    "initial IRT size (>0 means # entries, <0 means multiply this with the number of nodes)"),
	INTEGER_ARG("irt_increment", &_p_irt_increment,
		    "IRT increment size (>0 means # entries, <0 means multiply this with the number of nodes)"),
	INTEGER_ARG("gsq_interval", &_p_gsq_interval,
		    "Global suspension queue Reschedule Interval (in reductions)"),
	INTEGER_ARG("vt_debug_level", &_p_vt_debug_level,
		    "Debug level to pass to the VT runtime system (integer >=0)"),
	BOOL_ARG("signal", &_p_no_signal_handlers,
		 "Turn off all signal handlers in the runtime system"),
#ifdef GAUGE
	BOOL_ARG("gauge", &_p_gauge,
		 "Run with Gauge profiling turned on"),
	STRING_ARG("gauge_file", _p_gauge_file,
		   "Use this as the name of the Gauge output file (default==profile.cnt)"),
	STRING_ARG("tmp_dir", _p_tmp_dir,
		   "Directory in which to put temporary file (default==/tmp)"),
#endif /* GAUGE */

#ifdef UPSHOT
	BOOL_ARG("upshot", &_p_upshot,
		 "Run with Upshot logging turned on"),
	STRING_ARG("upshot_file", _p_upshot_file,
		   "Use this as the name of the Upshot output file (default==log)"),
	INTEGER_ARG("upshot_log_size", &_p_upshot_log_size,
		    "Size of the upshot log buffer (integer >=0)"),
#endif /* UPSHOT */	
	
#ifdef PDB	
	BOOL_ARG("pdb", &_pdb_enter_immediately,
		 "Enter PDB immediately upon startup"),
	BOOL_ARG("gc_after_foreign", &_pdb_gc_after_foreign,
		 "Call the garbage collector after every foreign call.  (To help track down array bounds violations in foreign code.)"),
#endif /* PDB */	
#ifdef DYNAMIC_PAM_LOADING    
	STRING_ARG("load", _p_initial_load_pam_files,
		   "PAM files to automatically load upon startup"),
#endif /* DYNAMIC_PAM_LOADING */
#ifdef DEBUG
	INTEGER_ARG("d", &global_dl,
		    "global debug level"),
	INTEGER_ARG("g", &gc_dl,
		    "garbage collector debug level (overrides global level),"),
	INTEGER_ARG("e", &em_dl,
		    "emulator debug level (overrides global level),"),
	INTEGER_ARG("p", &par_dl,
		    "parallel code debug level (overrides global level),"),
	INTEGER_ARG("r", &_p_start_em_debug,
		    "start emulator debugging after this many reductions"),
#endif /* DEBUG */
#ifdef PARALLEL
	BOOL_ARG("log", &_p_use_logfile,
		 "use log files for node output"),
#ifdef DEBUG
	INTEGER_ARG("nd", &n_global_dl,
		    "global debug level on nodes"),
	INTEGER_ARG("ng", &n_gc_dl,
		    "garbage collector debug level on nodes"),
	INTEGER_ARG("ne", &n_em_dl,
		    "emulator debug level on nodes"),
	INTEGER_ARG("np", &n_par_dl,
		    "parallel code debug level on nodes"),
	INTEGER_ARG("nr", &_p_n_start_em_debug,
		    "start emulator debugging after this many reductions on nodes"),
	INTEGER_ARG("node", &_p_debug_node,
		    "only apply debug levels to this node (-1 = all)"),
#endif /* DEBUG */
#endif /* PARALLEL */
};
    static int n_argdesc = sizeof(argdesc) / sizeof(argdesc[0]);
    int rc;
    int pcn_argc, new_argc;
    char **pcn_argv;


#if defined(PARALLEL) && defined(DEBUG)    
    _p_n_start_em_debug = -1;
    _p_debug_node = -1;
#endif
    
#ifdef PARALLEL
    _p_sr_get_argdesc(argc, argv, &sr_argdesc, &sr_n_argdesc);
#else
    sr_argdesc = (argdesc_t *) 0;
    sr_n_argdesc = 0;
#endif

    /*
     * Find the first "-pcn" argument.  All arguments after it should
     * be passed to parse_args()
     */
    for (i = 0; i < argc && strcmp(argv[i],"-pcn") != 0; i++)
	;
    if (i < argc)
    {
	pcn_argc = argc - i;
	pcn_argv = &(argv[i]);
	new_argc = argc - pcn_argc;
    }
    else
    {
	pcn_argc = 1;
	pcn_argv = argv;
	new_argc = argc;
    }
    
    rc = parse_args(pcn_argc, pcn_argv,
		       argdesc, n_argdesc,
		       sr_argdesc, sr_n_argdesc,
		       &unknown_argc, &unknown_argv);
    if (!rc || need_help || unknown_argc != 0)
    {
	_p_print_banner();
	printf("Usage: %s [<user_arguments>] [-pcn <pcn_runtime_arguments>]\n", argv[0]);
	argdesc_usage(stdout, argdesc, n_argdesc, sr_argdesc, sr_n_argdesc);
	exit(1);
    }

#ifdef DEBUG
    if (global_dl >= 0)
	_p_global_dl = global_dl;

    if (em_dl >= 0)
	_p_em_dl = em_dl;
    else if (global_dl >= 0)
	_p_em_dl = global_dl;
    
    if (gc_dl >= 0)
	_p_gc_dl = gc_dl;
    else if (global_dl >= 0)
	_p_gc_dl = global_dl;
    
    if (par_dl >= 0)
	_p_par_dl = par_dl;
    else if (global_dl >= 0)
	_p_par_dl = global_dl;

    
#ifdef PARALLEL
    if (n_global_dl >= 0)
	_p_n_global_dl = n_global_dl;
    else if (global_dl >= 0)
	_p_n_global_dl = n_global_dl = global_dl;

    if (n_em_dl >= 0)
	_p_n_em_dl = n_em_dl;
    else if (em_dl >= 0)
	_p_n_em_dl = em_dl;
    else if (n_global_dl >= 0)
	_p_n_em_dl = n_global_dl;
    
    if (n_gc_dl >= 0)
	_p_n_gc_dl = n_gc_dl;
    else if (gc_dl >= 0)
	_p_n_gc_dl = gc_dl;
    else if (n_global_dl >= 0)
	_p_n_gc_dl = n_global_dl;
    
    if (n_par_dl >= 0)
	_p_n_par_dl = n_par_dl;
    else if (par_dl >= 0)
	_p_n_par_dl = par_dl;
    else if (n_global_dl >= 0)
	_p_n_par_dl = n_global_dl;
    
    if (_p_n_start_em_debug < 0)
	_p_n_start_em_debug = _p_start_em_debug;
    
#endif /* PARALLEL */    
#endif /* DEBUG */

    return (new_argc);
} /* _p_read_args() */



static int parse_args(argc, argv, argdesc1, nargs1,
		      argdesc2, nargs2, newargc, newargv)
int argc;
char **argv;
argdesc_t *argdesc1, *argdesc2;
int nargs1, nargs2;
int *newargc;
char ***newargv;
{
    int i, arg;
    int found, error;

    *newargc = argc - 1;
    *newargv = argv + 1;

    for (i = 1; i < argc; i++)
    {
	if (*argv[i] == '-')
	{
	    for (arg = 0, found= 0, error=0; !found && arg < nargs1; arg++)
	    {
		match_arg(argc, argv, &i, argdesc1, arg, &found, &error);
		if (error)
		{
		    return 0;
		}
	    }

	    for (arg = 0, error=0; !found && arg < nargs2; arg++)
	    {
		match_arg(argc, argv, &i, argdesc2, arg, &found, &error);
		if (error)
		{
		    return 0;
		}
	    }
	    if (!found)
	    {
		    return 0;
	    }
	}
	else
	{
	    break;
	}
    }
    *newargc = argc - i;
    *newargv = argv + i;

    return 1;
} /* parse_args */


static void match_arg(argc, argv, i, argdesc, arg, foundp, errorp)
int argc;
char **argv;
int *i;
argdesc_t *argdesc;
int arg;
int *foundp;
int *errorp;
{
    if (strcmp(argv[*i] + 1, argdesc[arg].flag) == 0)
    {
	switch (argdesc[arg].argtype)
	{
	case ARGTYPE_STRING:
	    if (++(*i) < argc)
	    {
		strcpy(argdesc[arg].argval, argv[*i]);
		*foundp = 1;
	    }
	    else
		*errorp = 1;
	    break;
	    
	case ARGTYPE_INTEGER:
	    if (++(*i) < argc)
	    {
		*((int_t *) argdesc[arg].argval) = atoi(argv[*i]);
		*foundp = 1;
	    }
	    else
		*errorp = 1;
	    
	    break;
	    
	case ARGTYPE_NONE:
	    *((int_t *) argdesc[arg].argval) = 1;
	    *foundp = 1;
	    break;

	default:
	    *errorp = 1;
	    break;
	    
	}
    }
} /* match_arg() */


static void argdesc_usage(fp, argdesc, nargs, argdesc2, nargs2)
FILE *fp;
argdesc_t *argdesc, *argdesc2;
int nargs, nargs2;
{
    int i, j;
    int mlen, len, spaces;
    static char *types[] = {"", "<string>", "<integer>", "", "<string>"};
    static int lengths[] = {0, 8, 9, 0, 8};

    for (mlen = 0, i = 0; i < nargs; i++)
    {
	len = lengths[argdesc[i].argtype] + strlen (argdesc[i].flag);
	if (len > 100)
	    printf("bogus len=%d\n", len);
	if (len > mlen)
	    mlen = len;
    }
    for (i = 0; i < nargs2; i++)
    {
	len = lengths[argdesc2[i].argtype] + strlen (argdesc2[i].flag);
	if (len > mlen)
	    mlen = len;
    }

    len = mlen + 5;

    for (i = 0; i < nargs; i++)
    {
	fprintf(fp, "\t-%s %s", argdesc[i].flag, types[argdesc[i].argtype]);
	spaces = len - (strlen(argdesc[i].flag) + lengths[argdesc[i].argtype]);
	for (j = 0; j < spaces; j++)
	{
	    fprintf(fp, " ");
	}
	fprintf(fp, "%s\n", argdesc[i].usage);
    }
    for (i = 0; i < nargs2; i++)
    {
	fprintf(fp, "\t-%s %s", argdesc2[i].flag, types[argdesc2[i].argtype]);
	spaces = len - (strlen(argdesc2[i].flag) + lengths[argdesc2[i].argtype]);
	for (j = 0; j < spaces; j++)
	{
	    fprintf(fp, " ");
	}
	fprintf(fp, "%s\n", argdesc2[i].usage);
    }
} /* argdesc_usage() */

#endif /* PCN_HOST */

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.