Example #1
0
static int 
checkargs (int argc, char **argv, bool_t *double_resolution, bool_t *panel,
	   int *fps, char **image_name, fiasco_d_options_t **options)
/*
 *  Check validness of command line parameters and of the parameter files.
 *
 *  Return value.
 *	index in argv of the first argv-element that is not an option.
 *
 *  Side effects:
 *	'double_resolution', 'panel', 'fps', 'image_name' and 'options'
 *      are modified.
 */
{
   int optind;				/* last processed commandline param */

   optind = parseargs (params, argc, argv,
		       "Decode FIASCO-FILEs and write frame(s) to disk.",
		       "With no FIASCO-FILE, or if FIASCO-FILE is -, "
		       "read standard input.\n"
		       "Environment:\n"
		       "FIASCO_DATA   Search path for automata files. "
		       "Default: ./\n"
		       "FIASCO_IMAGES Save path for image files. "
		       "Default: ./", " [FIASCO-FILE]...",
		       FIASCO_SHARE, "system.fiascorc", ".fiascorc");

   *image_name        =   (char *)   parameter_value (params, "output");
   *double_resolution = *((bool_t *) parameter_value (params, "double"));
   *panel             = *((bool_t *) parameter_value (params, "panel"));
   *fps		      = *((int *)    parameter_value (params, "framerate"));

   /*
    *  Additional options ... (have to be set with the fiasco_set_... methods)
    */
   *options = fiasco_d_options_new ();

   {
      int n = *((int *) parameter_value (params, "smoothing"));
      
      if (!fiasco_d_options_set_smoothing (*options, max (-1, n)))
	 error (fiasco_get_error_message ());
   }

   {
      int n = *((int *) parameter_value (params, "magnify"));
      
      if (!fiasco_d_options_set_magnification (*options, n))
	 error (fiasco_get_error_message ());
   }
   
   {
      bool_t n = *((bool_t *) parameter_value (params, "fast"));
      
      if (!fiasco_d_options_set_4_2_0_format (*options, n > 0 ? YES : NO))
	 error (fiasco_get_error_message ());
   }

   return optind;
}
Example #2
0
static void 
checkargs (int argc, char **argv, char const ***image_template,
           char **wfa_name, float *quality, fiasco_c_options_t **options)
/*
 *  Check validness of command line parameters and of the parameter files.
 *
 *  Return value:
 *  1 on success
 *  0 otherwise
 *  
 *
 *  Side effects:
 *  'image_template', 'wfa_name', 'quality' and 'options' are set.
 */
{
    int   optind;            /* last processed commandline param */
    char *image_name;            /* filename given by option '--input_name' */
    int   i;             /* counter */
   
    optind = parseargs (params, argc, argv,
                        "Compress raw PPM/PGM image FILEs to a FIASCO file.",
                        "With no image FILE, or if FILE is -, "
                        "read standard input.\n"
                        "FILE must be either a filename"
                        " or an image template of the form:\n"
                        "`prefix[start-end{+,-}step]suffix'\n"
                        "e.g., img0[12-01-1].pgm is substituted by"
                        " img012.pgm ... img001.pgm\n\n"
                        "Environment:\n"
                        "FIASCO_DATA   Search and save path for FIASCO files. "
                        "Default: ./\n"
                        "FIASCO_IMAGES Search path for image files. "
                        "Default: ./", " [FILE]...",
                        FIASCO_SHARE, "system.fiascorc", ".fiascorc");

    /*
     *  Default options ...
     */
    image_name = (char *) parameter_value (params, "image-name"); 
    *wfa_name  = (char *) parameter_value (params, "output-name");
    for (;;)
    {
        *quality = * (float *) parameter_value (params, "quality");
        if (*quality > 100)
            fprintf (stderr, "Typical range of quality: (0,100].\n"
                     "Expect some trouble on slow machines.\n");
        if (*quality > 0)
            break;
        ask_and_set (params, "quality",
                     "Please enter coding quality 'q' ('q' > 0): ");
    }
   
    if (optind < argc)           /* Additional command line param */
    {
        if (image_name)
            error ("Multiple image_template arguments."
                   "\nOption --input-name %s already specified!", image_name);

        *image_template = calloc (argc - optind + 1, sizeof (char *));
        if (!*image_template)
            error ("Out of memory.");
        for (i = 0; optind < argc; i++, optind++)
            (*image_template) [i] = argv [optind];
        (*image_template) [i] = NULL;
    }
    else                 /* option -i image_name */
    {
        *image_template = calloc (2, sizeof (char *));
        if (!*image_template)
            error ("Out of memory.");
        (*image_template) [0] = image_name;
        (*image_template) [1] = NULL;
    }
    /*
     *  Additional options ... (have to be set with the fiasco_set_... methods)
     */
    {
        *options = fiasco_c_options_new ();
      
        {
            char *pattern = (char *) parameter_value (params, "pattern");

            if (!fiasco_c_options_set_frame_pattern (*options, pattern))
                error (fiasco_get_error_message ());
        }

        {
            char *basis = (char *) parameter_value (params, "basis-name");
     
            if (!fiasco_c_options_set_basisfile (*options, basis))
                error (fiasco_get_error_message ());
        }

        {
            int   n = * (int *) parameter_value (params, "chroma-dictionary");
            float q = * (float *) parameter_value (params, "chroma-qfactor");
      
            if (!fiasco_c_options_set_chroma_quality (*options, q, MAX(0, n)))
                error (fiasco_get_error_message ());
        }
      
        {
            int n = *((int *) parameter_value (params, "smooth"));
     
            if (!fiasco_c_options_set_smoothing (*options, MAX(0, n)))
                error (fiasco_get_error_message ());
        }
      
        {
            int n = * (int *) parameter_value (params, "progress-meter");
            fiasco_progress_e type = (n < 0) ? 
                FIASCO_PROGRESS_NONE : (fiasco_progress_e) n;
      
            if (!fiasco_c_options_set_progress_meter (*options, type))
                error (fiasco_get_error_message ());
        }
      
        {
            char *t = (char *) parameter_value (params, "title");
     
            if (strlen (t) > 0 && !fiasco_c_options_set_title (*options, t))
                error (fiasco_get_error_message ());
        }
      
        {
            char *c = (char *) parameter_value (params, "comment");

            if (strlen (c) > 0 && !fiasco_c_options_set_comment (*options, c))
                error (fiasco_get_error_message ());
        }
      
        {
            fiasco_tiling_e method = FIASCO_TILING_VARIANCE_DSC;
            int   e  = * (int *) parameter_value (params, "tiling-exponent");
            char *m  = (char *) parameter_value (params, "tiling-method");

            if (strcaseeq (m, "desc-variance"))
                method = FIASCO_TILING_VARIANCE_DSC;
            else if (strcaseeq (m, "asc-variance"))
                method = FIASCO_TILING_VARIANCE_ASC;
            else if (strcaseeq (m, "asc-spiral"))
                method = FIASCO_TILING_SPIRAL_ASC;
            else if (strcaseeq (m, "dsc-spiral"))
                method = FIASCO_TILING_SPIRAL_DSC;
            else
                error (_("Invalid tiling method `%s' specified."), m);

            if (!fiasco_c_options_set_tiling (*options, method, MAX(0, e)))
                error (fiasco_get_error_message ());
        }
      
        {
            int M/*  = * (int *) parameter_value (params, "max-level") */;
            int m/*  = * (int *) parameter_value (params, "min-level") */;
            int N/*  = * (int *) parameter_value (params, "max-elements") */;
            int D = * (int *) parameter_value (params, "dictionary-size");
            int o = * (int *) parameter_value (params, "optimize");

            if (o <= 0)
            {
                o = 0;
                M = 10;
                m = 6;
                N = 3;
            }
            else
            {
                o -= 1;
                M = 12;
                m = 4;
                N = 5;
            }
     
            if (!fiasco_c_options_set_optimizations (*options, m, M, N,
                                                     MAX(0, D), o))
                error (fiasco_get_error_message ());
        }
        {
            int M = * (int *) parameter_value (params, "max-level");
            int m = * (int *) parameter_value (params, "min-level");
            int p = * (int *) parameter_value (params, "prediction");
     
            if (!fiasco_c_options_set_prediction (*options,
                                                  p, MAX(0, m), MAX(0, M)))
                error (fiasco_get_error_message ());
        }
        {
            float r    = * (float *)parameter_value(params, "rpf-range");
            float dc_r = * (float *)parameter_value(params, "dc-rpf-range");
            int   m    = * (int *)  parameter_value(params, "rpf-mantissa");
            int   dc_m = * (int *)  parameter_value(params, "dc-rpf-mantissa");
            fiasco_rpf_range_e range, dc_range;
     
            if (r < 1)
                range = FIASCO_RPF_RANGE_0_75;
            else if (r < 1.5)
                range = FIASCO_RPF_RANGE_1_00;
            else if (r < 2.0)
                range = FIASCO_RPF_RANGE_1_50;
            else
                range = FIASCO_RPF_RANGE_2_00;
        
            if (dc_r < 1)
                dc_range = FIASCO_RPF_RANGE_0_75;
            else if (dc_r < 1.5)
                dc_range = FIASCO_RPF_RANGE_1_00;
            else if (dc_r < 2.0)
                dc_range = FIASCO_RPF_RANGE_1_50;
            else
                dc_range = FIASCO_RPF_RANGE_2_00;
        
            if (!fiasco_c_options_set_quantization (*options,
                                                    MAX(0, m), range,
                                                    MAX(0, dc_m), dc_range))
                error (fiasco_get_error_message ());
        }

        if (fiasco_get_verbosity () == FIASCO_ULTIMATE_VERBOSITY)
            write_parameters (params, stderr);
    }
}   
Example #3
0
void add_error_element(ERRORVAL *errcon, NAMELIST_TEXT *nltext, LINE_LIST *beamline)
{
    long n_items, n_added, i_start, firstIndexInGroup;
    ELEMENT_LIST *context;
    double sMin = -DBL_MAX, sMax = DBL_MAX;
    
    log_entry("add_error_element");

    if ((n_items = errcon->n_items)==0) {
        if (errcon->new_data_read)
            bombElegant("improper sequencing of error specifications and tracking", NULL);
        errcon->new_data_read = 1;
        }

    /* process namelist text */
    set_namelist_processing_flags(STICKY_NAMELIST_DEFAULTS);
    set_print_namelist_flags(0);
    if (processNamelist(&error, nltext)==NAMELIST_ERROR)
      bombElegant(NULL, NULL);
    if (name==NULL) {
      if (!element_type)
        bombElegant("element name missing in error namelist", NULL);
      SDDS_CopyString(&name, "*");
    }
    if (echoNamelists) print_namelist(stdout, &error);

    /* check for valid input and copy to errcon arrays */
    if (item==NULL)
        bombElegant("item name missing in error namelist", NULL);
    if (match_string(type, known_error_type, N_ERROR_TYPES, 0)<0)
        bombElegant("unknown error type specified", NULL);
    if (bind_number<0)
        bombElegant("bind_number < 0", NULL);
    if (!additive && fractional)
        bombElegant("fractional errors must be additive", NULL);

    context = NULL;
    n_added = 0;
    i_start = n_items;

    context = NULL;
    if (after && strlen(after)) {
      if (!(context=find_element(after, &context, &(beamline->elem)))) {
        fprintf(stdout, "Element %s not found in beamline.\n", after);
        exitElegant(1);
      }
      sMin = context->end_pos;
      if (find_element(after, &context, &(beamline->elem))) {
        fprintf(stdout, "Element %s found in beamline more than once.\n", after);
        exitElegant(1);
      }
      fprintf(stdout, "%s found at s = %le m\n", after, sMin);
      fflush(stdout);
    }
    context = NULL;
    if (before && strlen(before)) {
      if (!(context=find_element(before, &context, &(beamline->elem)))) {
        fprintf(stdout, "Element %s not found in beamline.\n", before);
        exitElegant(1);
      }
      sMax = context->end_pos;
      if (find_element(before, &context, &(beamline->elem))) {
        fprintf(stdout, "Element %s found in beamline more than once.\n", after);
        exitElegant(1);
      }
      fprintf(stdout, "%s found at s = %le m\n", before, sMax);
      fflush(stdout);
    }
    if (after && before && sMin>sMax) {
      fprintf(stdout, "Element %s is not upstream of %s!\n",
              before, after);
      exitElegant(1);
    }
    if (element_type && has_wildcards(element_type) && strchr(element_type, '-'))
      element_type = expand_ranges(element_type);
    if (has_wildcards(name)) {
        if (strchr(name, '-'))
            name = expand_ranges(name);
        str_toupper(name);
        firstIndexInGroup = -1;
        while ((context=wfind_element(name, &context, &(beamline->elem)))) {
            if (element_type && 
                !wild_match(entity_name[context->type], element_type))
              continue;
            if (exclude &&
                wild_match(context->name, exclude))
              continue;
            if (i_start!=n_items && duplicate_name(errcon->name+i_start, n_items-i_start, context->name))
                continue;
            if ((sMin>=0 && context->end_pos<sMin) ||
                (sMax>=0 && context->end_pos>sMax)) 
              continue;
            errcon->name              = trealloc(errcon->name, sizeof(*errcon->name)*(n_items+1));
            errcon->item              = trealloc(errcon->item, sizeof(*errcon->item)*(n_items+1));
            errcon->quan_name         = trealloc(errcon->quan_name, sizeof(*errcon->quan_name)*(n_items+1));
            errcon->quan_final_index  
              = trealloc(errcon->quan_final_index, sizeof(*errcon->quan_final_index)*(n_items+1));
            errcon->quan_unit         = trealloc(errcon->quan_unit, sizeof(*errcon->quan_unit)*(n_items+1));
            errcon->error_level       = trealloc(errcon->error_level, sizeof(*errcon->error_level)*(n_items+1));
            errcon->error_cutoff      = trealloc(errcon->error_cutoff, sizeof(*errcon->error_cutoff)*(n_items+1));
            errcon->error_type        = trealloc(errcon->error_type, sizeof(*errcon->error_type)*(n_items+1));
            errcon->elem_type         = trealloc(errcon->elem_type, sizeof(*errcon->elem_type)*(n_items+1));
            errcon->error_value       = trealloc(errcon->error_value, sizeof(*errcon->error_value)*(n_items+1));
            errcon->unperturbed_value = trealloc(errcon->unperturbed_value, sizeof(*errcon->unperturbed_value)*(n_items+1));
            errcon->param_number      = trealloc(errcon->param_number, sizeof(*errcon->param_number)*(n_items+1));
            errcon->bind_number       = trealloc(errcon->bind_number, sizeof(*errcon->bind_number)*(n_items+1));
            errcon->flags             = trealloc(errcon->flags, sizeof(*errcon->flags)*(n_items+1));
            errcon->sMin             = trealloc(errcon->sMin, sizeof(*errcon->sMin)*(n_items+1));
            errcon->sMax             = trealloc(errcon->sMax, sizeof(*errcon->sMax)*(n_items+1));
            errcon->boundTo          = trealloc(errcon->boundTo, sizeof(*errcon->boundTo)*(n_items+1));

            cp_str(errcon->item+n_items, str_toupper(item));
            cp_str(errcon->name+n_items, context->name);
            errcon->error_level[n_items] = amplitude*error_factor;
            errcon->error_cutoff[n_items] = cutoff;
            errcon->error_type[n_items] = match_string(type, known_error_type, N_ERROR_TYPES, 0);
            errcon->quan_name[n_items] = tmalloc(sizeof(char*)*(strlen(context->name)+strlen(item)+4));
            errcon->quan_final_index[n_items] = -1;
            sprintf(errcon->quan_name[n_items], "d%s.%s", context->name, item);
            errcon->flags[n_items]  = (fractional?FRACTIONAL_ERRORS:0);
            errcon->flags[n_items] += (bind==0?0:(bind==-1?ANTIBIND_ERRORS:BIND_ERRORS));
            errcon->flags[n_items] += (post_correction?POST_CORRECTION:PRE_CORRECTION);
            errcon->flags[n_items] += (additive?0:NONADDITIVE_ERRORS);
            errcon->bind_number[n_items] = bind_number;
            /* boundTo must be -1 when there is no cross-name binding or when this element is the
             * first of a series 
             */
            errcon->boundTo[n_items] = bind_across_names?firstIndexInGroup:-1;
/*
            if (errcon->boundTo[n_items]!=-1)
              fprintf(stdout, "%s bound to %s\n", 
                      errcon->name[n_items], errcon->name[errcon->boundTo[n_items]]);
*/
            errcon->sMin[n_items] = sMin;
            errcon->sMax[n_items] = sMax;
            errcon->elem_type[n_items] = context->type;

            if ((errcon->param_number[n_items] = confirm_parameter(item, context->type))<0) {
                fprintf(stdout, "error: cannot vary %s--no such parameter for %s (wildcard name: %s)\n",item, context->name, name);
                fflush(stdout);
                exitElegant(1);
                }
            cp_str(&errcon->quan_unit[n_items], 
                errcon->flags[n_items]&FRACTIONAL_ERRORS?"fr":
                entity_description[errcon->elem_type[n_items]].parameter[errcon->param_number[n_items]].unit
                );
            errcon->unperturbed_value[n_items] 
                = parameter_value(errcon->name[n_items], errcon->elem_type[n_items], errcon->param_number[n_items],
                            beamline);
            if (errcon->unperturbed_value[n_items]==0 && errcon->flags[n_items]&FRACTIONAL_ERRORS)
                fprintf(stdout, "***\7\7\7 warning: you've specified fractional errors for %s.%s, but the unperturbed value is zero.\nThis may be an error.\n", 
                    errcon->name[n_items], errcon->item[n_items]);
                fflush(stdout);
            if (duplicate_name(errcon->quan_name, n_items, errcon->quan_name[n_items]))
                fprintf(stdout, "***\7\7\7 warning: you've specified errors for %s.%s more than once!\n",
                    errcon->name[n_items], errcon->item[n_items]);
                fflush(stdout);
            errcon->n_items = ++n_items;
            n_added++;
            if (firstIndexInGroup==-1)
              firstIndexInGroup = n_items-1;
            }
        }
    else {
        str_toupper(name);
        if (!(context=find_element(name, &context, &(beamline->elem)))) {
            fprintf(stdout, "error: cannot add errors to element %s--not in beamline\n", name);
            fflush(stdout);
            exitElegant(1);
            }
        errcon->name              = trealloc(errcon->name, sizeof(*errcon->name)*(n_items+1));
        errcon->item              = trealloc(errcon->item, sizeof(*errcon->item)*(n_items+1));
        errcon->quan_name         = trealloc(errcon->quan_name, sizeof(*errcon->quan_name)*(n_items+1));
        errcon->quan_final_index  
          = trealloc(errcon->quan_final_index, sizeof(*errcon->quan_final_index)*(n_items+1));
        errcon->quan_unit         = trealloc(errcon->quan_unit, sizeof(*errcon->quan_unit)*(n_items+1));
        errcon->error_level       = trealloc(errcon->error_level, sizeof(*errcon->error_level)*(n_items+1));
        errcon->error_cutoff      = trealloc(errcon->error_cutoff, sizeof(*errcon->error_cutoff)*(n_items+1));
        errcon->error_type        = trealloc(errcon->error_type, sizeof(*errcon->error_type)*(n_items+1));
        errcon->elem_type         = trealloc(errcon->elem_type, sizeof(*errcon->elem_type)*(n_items+1));
        errcon->error_value       = trealloc(errcon->error_value, sizeof(*errcon->error_value)*(n_items+1));
        errcon->unperturbed_value = trealloc(errcon->unperturbed_value, sizeof(*errcon->unperturbed_value)*(n_items+1));
        errcon->param_number      = trealloc(errcon->param_number, sizeof(*errcon->param_number)*(n_items+1));
        errcon->bind_number       = trealloc(errcon->bind_number, sizeof(*errcon->bind_number)*(n_items+1));
        errcon->flags             = trealloc(errcon->flags, sizeof(*errcon->flags)*(n_items+1));
        errcon->sMin             = trealloc(errcon->sMin, sizeof(*errcon->sMin)*(n_items+1));
        errcon->sMax             = trealloc(errcon->sMax, sizeof(*errcon->sMax)*(n_items+1));
        errcon->boundTo          = trealloc(errcon->boundTo, sizeof(*errcon->boundTo)*(n_items+1));

        cp_str(errcon->item+n_items, str_toupper(item));
        cp_str(errcon->name+n_items, context->name);
        errcon->error_level[n_items] = amplitude;
        errcon->error_cutoff[n_items] = cutoff;
        errcon->error_type[n_items] = match_string(type, known_error_type, N_ERROR_TYPES, 0);
        errcon->quan_name[n_items] = tmalloc(sizeof(char*)*(strlen(context->name)+strlen(item)+4));
        sprintf(errcon->quan_name[n_items], "d%s.%s", context->name, item);
        errcon->flags[n_items]  = (fractional?FRACTIONAL_ERRORS:0);
        errcon->flags[n_items] += (bind==0?0:(bind==-1?ANTIBIND_ERRORS:BIND_ERRORS));
        errcon->flags[n_items] += (post_correction?POST_CORRECTION:PRE_CORRECTION);
        errcon->flags[n_items] += (additive?0:NONADDITIVE_ERRORS);
        errcon->bind_number[n_items] = bind_number;
        errcon->sMin[n_items] = sMin;
        errcon->sMax[n_items] = sMax;
        errcon->boundTo[n_items] = -1;  /* not used when there are no wildcards */

        errcon->elem_type[n_items] = context->type;
        if ((errcon->param_number[n_items] = confirm_parameter(item, context->type))<0) {
            fprintf(stdout, "error: cannot vary %s--no such parameter for %s\n",item, name);
            fflush(stdout);
            exitElegant(1);
            }
        cp_str(&errcon->quan_unit[n_items], 
            errcon->flags[n_items]&FRACTIONAL_ERRORS?"fr":
            entity_description[errcon->elem_type[n_items]].parameter[errcon->param_number[n_items]].unit
            );
        errcon->unperturbed_value[n_items] 
            = parameter_value(errcon->name[n_items], errcon->elem_type[n_items], errcon->param_number[n_items],
                        beamline);
        if (errcon->unperturbed_value[n_items]==0 && errcon->flags[n_items]&FRACTIONAL_ERRORS)
            fprintf(stdout, "***\7\7\7 warning: you've specified fractional errors for %s.%s, but the unperturbed value is zero.\nThis may be an error.\n", 
                errcon->name[n_items], errcon->item[n_items]);
            fflush(stdout);

        if (duplicate_name(errcon->quan_name, n_items, errcon->quan_name[n_items]))
            fprintf(stdout, "***\7\7\7 warning: you've specified errors for %s.%s more than once!\n",
                errcon->name[n_items], errcon->item[n_items]);
            fflush(stdout);
        errcon->n_items = ++n_items;
        n_added++;
        }

    if (!n_added && !allow_missing_elements) {
        fprintf(stdout, "error: no match for name %s\n", name);
        fflush(stdout);
        exitElegant(1);
        }
    log_exit("add_error_element");
    }
Example #4
0
int
parseargs (param_t *usr_params, 
           int argc, char **argv, 
           const char *synopsis,
           const char *comment, 
           const char *non_opt_string, 
           const char *path,
           const char *sys_file_name, 
           const char *usr_file_name)
/*
 *  Perform the command line parsing.
 *  List of allowed parameters is given by 'usr_params'.
 *  Command line and number of parameters are given by 'argv' and 'argc'.
 *  'synopsis' contains a brief description of the program and
 *  'comment' may contain some additional advice.
 *  Initialization order of parameters:
 *	1.) Default values given by the param_t struct
 *	2.) System parameter-file ('path'/'sys_file_name')
 *	3.) User parameter-file ($HOME/'usr_file_name')
 *	4.) Command line parameters
 *	5.) Parameter-file forced by option -f (--config-file)
 *
 *  Return value:
 *	index in ARGV of the first ARGV-element that is not an option.
 *
 *  Side effects:
 *	the elements of ARGV are permuted
 *      usr_params [].value is modified 
 */
{
   extern int optind;			/* index in ARGV of the 1st element
					   that is not an option */
   bool_t     detailed_help = NO;	/* NO if all parameters can be modified
					   with short options too */
   unsigned   n1;			/* number of user parameters */
   unsigned   n2;			/* number of system parameters */
   bool_t     read_config_file = NO;	/* will override command line */
   param_t    *params;			/* array of user and system params */
   param_t    *sys_params;		/* array of system parameters */
   param_t    detailed_sys_params [] =  /* detailed system parameters */
   {
      {"version", NULL, 'v', PFLAG, {0}, NULL,
       "Print program version number, then exit."},
      {"verbose", "NUM", 'V', PINT, {0}, "1",
       "Set level of verbosity to `%s'."},
      {"config", "FILE", 'f', PSTR, {0}, NULL,
       "Load `%s' to initialize parameters."},
      {"info", NULL, 'h', PFLAG, {0}, NULL,
       "Print brief help, then exit."},
      {"help", NULL, 'H', PFLAG, {0}, NULL,
       "Print detailed help, then exit."},
      {NULL, NULL, 0, PSTR, {0}, NULL, NULL }
   };
   param_t    short_sys_params [] =	/* short system parameters */
   {
      {"version", NULL, 'v', PFLAG, {0}, NULL,
       "Print program version number, then exit."},
      {"verbose", "NUM", 'V', PINT, {0}, "1",
       "Set level of verbosity to `%s'."},
      {"config", "FILE", 'f', PSTR, {0}, NULL,
       "Load `%s' to initialize parameters."},
      {"help", NULL, 'h', PFLAG, {0}, NULL,
       "Print this help, then exit."},
      {NULL, NULL, 0, PSTR, {0}, NULL, NULL }
   };
   char *sys_path;			/* path to system config file */

   sys_path = calloc (strlen (path) + strlen (sys_file_name) + 2,
		      sizeof (char));
   if (!sys_path)
      error ("Out of memory.");
   sprintf (sys_path, "%s/%s", path, sys_file_name);

   /*
    *  Set parameters defaults
    */
   {
       param_t *p;
      
       for (p = usr_params; p->name != NULL; p++)
       {
           set_parameter (p, p->default_value);
           if (p->optchar == '\0')
               detailed_help = YES;
       }

      sys_params = detailed_help ? detailed_sys_params : short_sys_params;
      
      for (p = sys_params; p->name != NULL; p++)
          set_parameter (p, p->default_value);
   }
   /*
    *  Append system command line option to user parameters
    */
   for (n1 = 0; usr_params [n1].name != NULL; n1++)
      ;
   for (n2 = 0; sys_params [n2].name != NULL; n2++)
      ;
   params = calloc (n1 + n2 + 1, sizeof (param_t));
   if (!params)
      error ("Out of memory.");

   memcpy (params, usr_params, n1 * sizeof (param_t));
   memcpy (params + n1, sys_params, (n2 + 1) * sizeof (param_t));
   /*
    *  Try to open the system resource file 'path'/'sys_file_name'
    */
   {
      FILE *parameter_file = open_file (sys_path, NULL, READ_ACCESS);
      if (parameter_file == NULL)
/*
	 warning ("No system resource file found.");
*/ {}
      else
      {
	 read_parameter_file (params, parameter_file);
	 fclose (parameter_file);
      }
   }
   /*
    *  Try to read user resource file $HOME/'usr_file_name'
    */
   {
      FILE *parameter_file = open_file (usr_file_name, "HOME", READ_ACCESS);
      if (parameter_file != NULL)
      {
	 read_parameter_file (params, parameter_file);
	 fclose (parameter_file);
      }
   }
   /*
    *  Parse command line options
    */
   {
      extern char   *optarg;		/* argument of current option */
      struct option *long_options;	/* array of long options */
      int	     option_index = 0;
      char	     optstr [MAXSTRLEN]; /* string containing the legitimate
					    option characters */
      int	     optchar;		/* found option character */

      /*
       *  Build short option string for getopt_long (). 
       */
      {
	 param_t *p;			/* counter */
	 char	 *ptr_optstr;		/* pointer to position in string */
	 
	 ptr_optstr = optstr;
	 for (p = params; p->name != NULL; p++)
	    if (p->optchar != '\0')
	    {
	       *ptr_optstr++ = p->optchar;
	       if (p->type == POSTR)
	       {
		  *ptr_optstr++ = ':';
		  *ptr_optstr++ = ':';
	       }
	       else if (p->type != PFLAG)
		  *ptr_optstr++ = ':';
	    }
	 *ptr_optstr = '\0';
      }
      
      /*
       *  Build long option string for getopt_long (). 
       */
      {
	 int i;
	 
	 long_options = calloc (n1 + n2 + 1, sizeof (struct option));
	 if (!long_options)
	    error ("Out of memory.");
	 for (i = 0; params [i].name != NULL; i++)
	 {
	    long_options [i].name    = params [i].name;
	    switch (params [i].type)
	    {
	       case PFLAG:
		  long_options [i].has_arg = 0;
		  break;
	       case POSTR:
		  long_options [i].has_arg = 2;
		  break;
	       case PINT:
	       case PSTR:
	       case PFLOAT:
	       default:
		  long_options [i].has_arg = 1;
		  break;
	    }
	    long_options [i].has_arg = params [i].type != PFLAG;
	    long_options [i].flag    = NULL;
	    long_options [i].val     = 0;
	 }
      }
      
      /*
       *  Parse comand line
       */
      while ((optchar = getopt_long (argc, argv, optstr, long_options,
				     &option_index)) != EOF)
      {
	 int param_index = -1;
	 
	 switch (optchar)
	 {
	    case 0:
	       param_index = option_index;
	       break;
	    case ':':
	       if (detailed_help)
		  fprintf (stderr,
			   "Try `%s -h' or `%s --help' for "
			   "more information.\n",
			   argv [0], argv [0]);
	       else
		  fprintf (stderr, "Try `%s --help' for more information.\n",
			   argv [0]);
	       exit (2);
	       break;
	    case '?':
	       if (detailed_help)
		  fprintf (stderr,
			   "Try `%s -h' or `%s --help' "
			   "for more information.\n",
			   argv [0], argv [0]);
	       else
		  fprintf (stderr, "Try `%s --help' for more information.\n",
			   argv [0]);
	       exit (2);
	       break;
	    default:
	       {
		  int i;
		  
		  for (i = 0; params [i].name != NULL; i++)
		     if (params [i].optchar == optchar)
		     {
			param_index = i;
			break;
		     }
	       }
	 }
	 /*
	  *  Check for system options
	  */
	 if (param_index >= 0)
	 {
	    set_parameter (params + param_index, optarg ? optarg : "");
	    if (streq (params [param_index].name, "help"))
	       usage (params, argv [0], synopsis, comment, non_opt_string,
		      YES, sys_path, usr_file_name);
	    else if (streq (params [param_index].name, "info"))
	       usage (params, argv [0], synopsis, comment, non_opt_string,
		      NO, sys_path, usr_file_name);
	    else if (streq (params [param_index].name, "version"))
	    {
	       fprintf (stderr, "%s " VERSION "\n", argv [0]);
	       exit (2);
	    }
	    else if (streq (params [param_index].name, "verbose"))
	       fiasco_set_verbosity (
               * (fiasco_verbosity_e *) parameter_value (params,
                                                         "verbose"));
	    else if (streq (params [param_index].name, "config"))
	       read_config_file = YES;
	    param_index = -1;		/* clear index flag */
	 }
      }

      free (long_options);
   }
   
   /*
    *  Read config-file if specified by option -f
    */
   if (read_config_file)
   {
      char *filename;

      if ((filename = (char *) parameter_value (params, "config")) != NULL)
      {
	 FILE *parameter_file;		/* input file */
	 
	 warning ("Options set in file `%s' will override"
		  " command line options.", filename);
	 parameter_file = open_file (filename, NULL, READ_ACCESS);
	 if (parameter_file != NULL)
	 {
	    read_parameter_file (params, parameter_file);
	    fclose (parameter_file);
	 }
	 else
	    file_error (filename);
      }
      else
	 error ("Invalid config filename.");
   }

   memcpy (usr_params, params, n1 * sizeof (param_t)); /* fill user struct */
   free (sys_path);
   
   return optind;
}