📄 parse_opts.c
字号:
/* * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * Further, this software is distributed without any warranty that it is * free of the rightful claim of any third person regarding infringement * or the like. Any license provided herein, whether implied or * otherwise, applies only to this software file. Patent licenses, if * any, provided herein do not apply to combinations of this program with * other software, or any other product whatsoever. * * You should have received a copy of the GNU General Public License along * with this program; if not, write the Free Software Foundation, Inc., 59 * Temple Place - Suite 330, Boston MA 02111-1307, USA. * * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, * Mountain View, CA 94043, or: * * http://www.sgi.com * * For further information regarding this notice, see: * * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ *//* $Id: parse_opts.c,v 1.2 2000/09/06 14:21:52 duda Exp $ *//********************************************************** * * OS Testing - Silicon Graphics, Inc. * * FUNCTION NAME : parse_opts * * FUNCTION TITLE : parse standard & user options for system call tests * * SYNOPSIS: * #include "usctest.h" * * char *parse_opts(ac, av, user_optarr, uhf) * int ac; * char **av; * option_t user_optarr[]; * void (*uhf)(); * * AUTHOR : William Roske/Richard Logan * * INITIAL RELEASE : UNICOS 7.0 * * DESCRIPTION * The parse_opts library routine takes that argc and argv parameters * recevied by main() and an array of structures defining user options. * It parses the command line setting flag and argument locations * associated with the options. It uses getopt to do the actual cmd line * parsing. uhf() is a function to print user define help * * This module contains the functions usc_global_setup_hook and * usc_test_looping, which are called by marcos defined in usctest.h. * * RETURN VALUE * parse_opts returns a pointer to an error message if an error occurs. * This pointer is (char *)NULL if parsing is successful. * *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/#include <errno.h>#include <stdlib.h>#include <string.h>#include <sys/param.h>#include <sys/signal.h>#include <sys/types.h>#include <unistd.h>#include <sys/time.h>#ifdef __CYGWIN__#include <getopt.h>#endif#if UNIT_TEST#include <time.h>#endif /* UNIT_TEST */#include "test.h"#define _USC_LIB_ 1 /* indicates we are the library to the usctest.h include */#include "usctest.h"#ifndef USC_COPIES#define USC_COPIES "USC_COPIES"#endif#ifndef UNIT_TEST#define UNIT_TEST 0#endif#ifndef DEBUG#define DEBUG 0#endif/* The timing information block. */struct tblock tblock={0,((long) -1)>>1,0,0};/* Define flags and args for standard options */int STD_FUNCTIONAL_TEST=1, /* flag indicating to do functional testing code */ STD_TIMING_ON=0, /* flag indicating to print timing stats */ STD_PAUSE=0, /* flag indicating to pause before actual start, */ /* for contention mode */ STD_INFINITE=0, /* flag indciating to loop forever */ STD_LOOP_COUNT=1, /* number of iterations */ STD_COPIES=1, /* number of copies */ STD_ERRNO_LOG=0; /* flag indicating to do errno logging */float STD_LOOP_DURATION=0.0, /* duration value in fractional seconds */ STD_LOOP_DELAY=0.0; /* loop delay value in fractional seconds */char **STD_opt_arr = NULL; /* array of option strings */int STD_nopts=0, /* number of elements in STD_opt_arr */ STD_argind=1; /* argv index to next argv element */ /* (first argument) */ /* To getopt users, it is like optind *//* * The following variables are to support system testing additions. */static int STD_TP_barrier=0; /* flag to do barrier in TEST_PAUSE */ /* 2 - wait_barrier(), 3 - set_barrier(), * - barrier() */static int STD_LP_barrier=0; /* flag to do barrier in TEST_LOOPING */ /* 2 - wait_barrier(), 3 - set_barrier(), * - barrier() */static int STD_TP_shmem_sz=0; /* shmalloc this many words per pe in TEST_PAUSE */static int STD_LD_shmem=0; /* flag to do shmem_puts and shmem_gets during delay */static int STD_LP_shmem=0; /* flag to do shmem_puts and gets during TEST_LOOPING */static int STD_LD_recfun=0; /* do recressive function calls in loop delay */static int STD_LP_recfun=0; /* do recressive function calls in TEST_LOOPING */static int STD_TP_sbrk=0; /* do sbrk in TEST_PAUSE */static int STD_LP_sbrk=0; /* do sbrk in TEST_LOOPING */static char *STD_start_break=0; /* original sbrk size */static int Debug=0;struct std_option_t { const char *optstr; const char *help; char *flag; char **arg;} std_options[] = { { "c:", " -c n Run n copies concurrently\n", NULL, NULL}, { "e" , " -e Turn on errno logging\n", NULL, NULL}, { "f" , " -f Turn off functional testing\n", NULL, NULL}, { "h" , " -h Show this help screen\n", NULL, NULL}, { "i:", " -i n Execute test n times\n", NULL, NULL}, { "I:", " -I x Execute test for x seconds\n", NULL, NULL}, { "p" , " -p Pause for SIGUSR1 before starting\n", NULL, NULL}, { "P:", " -P x Pause for x seconds between iterations\n", NULL, NULL}, { "t" , " -t Turn on syscall timing\n", NULL, NULL}, {NULL, NULL, NULL, NULL}};void print_help(void (*user_help)());/* * Structure for usc_recressive_func argument */struct usc_bigstack_t { char space[4096];};static struct usc_bigstack_t *STD_bigstack=NULL;/* * Counter of errnos returned (-e option). Indexed by errno. * Make the array USC_MAX_ERRNO long. That is the first Fortran * Lib errno. No syscall should return an errno that high. */int STD_ERRNO_LIST[USC_MAX_ERRNO];/* define the string length for Mesg and Mesg2 strings */#define STRLEN 2048static char Mesg2[STRLEN]; /* holds possible return string */static void usc_recressive_func();/* * Define bits for options that might have env variable default */#define OPT_iteration 01#define OPT_nofunccheck 02#define OPT_duration 04#define OPT_delay 010#define OPT_copies 020/********************************************************************** * parse_opts: **********************************************************************/const char *parse_opts(int ac, char **av, option_t *user_optarr, void (*uhf)()){ int found; /* flag to indicate that an option specified was */ /* found in the user's list */ int k; /* scratch integer for returns and short time usage */ float ftmp; /* tmp float for parsing env variables */ char *ptr; /* used in getting env variables */ int options=0; /* no options specified */ int optstrlen, i; char *optionstr; int opt; /* return of getopt */ /* * If not the first time this function is called, release the old STD_opt_arr * vector. */ if ( STD_opt_arr != NULL ) { free(STD_opt_arr); STD_opt_arr=NULL; } /* Calculate how much space we need for the option string */ optstrlen = 0; for (i = 0; std_options[i].optstr; ++i) optstrlen += strlen(std_options[i].optstr); if (user_optarr) for (i = 0; user_optarr[i].option; ++i) { if (strlen(user_optarr[i].option) > 2) return "parse_opts: ERROR - Only short options are allowed"; optstrlen += strlen(user_optarr[i].option); } optstrlen += 1; /* Create the option string for getopt */ optionstr = (char *)malloc(optstrlen); if (!optionstr) return "parse_opts: ERROR - Could not allocate memory for optionstr"; optionstr[0] = '\0'; for (i = 0; std_options[i].optstr; ++i) strcat(optionstr, std_options[i].optstr); if (user_optarr) for (i = 0; user_optarr[i].option; ++i) /* only add the option if it wasn't there already */ if (strchr(optionstr, user_optarr[i].option[0]) == NULL) strcat(optionstr, user_optarr[i].option);#if DEBUG > 1 printf("STD_nopts = %d\n", STD_nopts);#endif /* * Loop through av parsing options. */ while ( (opt = getopt(ac, av, optionstr)) > 0) { STD_argind = optind;#if DEBUG > 0 printf("parse_opts: getopt returned '%c'\n", opt);#endif switch (opt) { case '?': /* Unknown option */ return "Unknown option"; break; case ':': /* Missing Arg */ return "Missing argument"; break; case 'i': /* Iterations */ options |= OPT_iteration; STD_LOOP_COUNT = atoi(optarg); if (STD_LOOP_COUNT == 0) STD_INFINITE = 1; break; case 'P': /* Delay between iterations */ options |= OPT_delay; STD_LOOP_DELAY = atof(optarg); break; case 'I': /* Time duration */ options |= OPT_duration; STD_LOOP_DURATION = atof(optarg); if ( STD_LOOP_DURATION == 0.0 ) STD_INFINITE=1; break; case 'c': /* Copies */ options |= OPT_copies; STD_COPIES = atoi(optarg); break; case 'f': /* Functional testing */ STD_FUNCTIONAL_TEST = 0; break; case 'p': /* Pause for SIGUSR1 */ STD_PAUSE = 1; break; case 't': /* syscall timing */ STD_TIMING_ON = 1; break; case 'e': /* errno loggin */ STD_ERRNO_LOG = 1; break; case 'h': /* Help */ print_help(uhf); exit(0); break; default: /* Check all the user specified options */ found=0; for(i = 0; user_optarr[i].option; ++i) { if (opt == user_optarr[i].option[0]) { /* Yup, This is a user option, set the flag and look for argument */ if ( user_optarr[i].flag ) { *user_optarr[i].flag=1; } found++; /* save the argument at the user's location */ if ( user_optarr[i].option[strlen(user_optarr[i].option)-1] == ':' ) { *user_optarr[i].arg=optarg; } break; /* option found - break out of the for loop */ } } /* This condition "should never happen". SO CHECK FOR IT!!!! */ if ( ! found ) { sprintf(Mesg2, "parse_opts: ERROR - option:\"%c\" NOT FOUND... INTERNAL ERROR", opt); return(Mesg2); } } } /* end of while */ STD_argind = optind; /* * Turn on debug */ if ( (ptr=getenv("USC_DEBUG")) != NULL ) { Debug=1; printf("env USC_DEBUG is defined, turning on debug\n"); } if ( (ptr=getenv("USC_VERBOSE")) != NULL ) { Debug=1; printf("env USC_VERBOSE is defined, turning on debug\n"); } /* * If the USC_ITERATION_ENV environmental variable is set to * a number, use that number as iteration count (same as -c option). * The -c option with arg will be used even if this env var is set. */ if ( !(options & OPT_iteration) && (ptr=getenv(USC_ITERATION_ENV)) != NULL ) { if ( sscanf(ptr, "%i", &k) == 1) { if ( k == 0 ) { /* if arg is 0, set infinite loop flag */ STD_INFINITE=1; if ( Debug ) printf("Using env %s, set STD_INFINITE to 1\n", USC_ITERATION_ENV); } else { /* else, set the loop count to the arguement */ STD_LOOP_COUNT=k; if ( Debug ) printf("Using env %s, set STD_LOOP_COUNT to %d\n", USC_ITERATION_ENV, k); } } } /* * If the USC_NO_FUNC_CHECK environmental variable is set, we'll * unset the STD_FUNCTIONAL_TEST variable. */ if ( !(options & OPT_nofunccheck) && (ptr=getenv(USC_NO_FUNC_CHECK)) != NULL ) { STD_FUNCTIONAL_TEST=0; /* Turn off functional testing */ if ( Debug ) printf("Using env %s, set STD_FUNCTIONAL_TEST to 0\n", USC_NO_FUNC_CHECK); } /* * If the USC_LOOP_WALLTIME environmental variable is set, * use that number as duration (same as -I option). * The -I option with arg will be used even if this env var is set. */ if ( !(options & OPT_duration) && (ptr=getenv(USC_LOOP_WALLTIME)) != NULL ) { if ( sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0 ) { STD_LOOP_DURATION=ftmp; if ( Debug ) printf("Using env %s, set STD_LOOP_DURATION to %f\n", USC_LOOP_WALLTIME, ftmp); if ( STD_LOOP_DURATION == 0.0 ) { /* if arg is 0, set infinite loop flag */ STD_INFINITE=1; if ( Debug ) printf("Using env %s, set STD_INFINITE to 1\n", USC_LOOP_WALLTIME); } } } if ( !(options & OPT_duration) && (ptr=getenv("USC_DURATION")) != NULL ) { if ( sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0 ) { STD_LOOP_DURATION=ftmp; if ( Debug ) printf("Using env USC_DURATION, set STD_LOOP_DURATION to %f\n", ftmp); if ( STD_LOOP_DURATION == 0.0 ) { /* if arg is 0, set infinite loop flag */ STD_INFINITE=1; if ( Debug ) printf("Using env USC_DURATION, set STD_INFINITE to 1\n"); } } } /* * If the USC_LOOP_DELAY environmental variable is set, * use that number as delay in factional seconds (same as -P option). * The -P option with arg will be used even if this env var is set. */ if ( !(options & OPT_delay) && (ptr=getenv(USC_LOOP_DELAY)) != NULL ) { if ( sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0 ) { STD_LOOP_DELAY=ftmp; if ( Debug ) printf("Using env %s, set STD_LOOP_DELAY = %f\n", USC_LOOP_DELAY, ftmp); } } /* * If the USC_COPIES environmental variable is set, * use that number as copies (same as -c option). * The -c option with arg will be used even if this env var is set. */ if ( !(options & OPT_copies) && (ptr=getenv(USC_COPIES)) != NULL ) { if ( sscanf(ptr, "%d", &STD_COPIES) == 1 && STD_COPIES >= 0 ) { if ( Debug ) printf("Using env %s, set STD_COPIES = %d\n", USC_COPIES, STD_COPIES); } } /* * The following are special system testing envs to turn on special * hooks in the code.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -