ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/applications/nanoparticleBuilder/nanorodBuilderCmd.cpp
Revision: 1798
Committed: Thu Sep 13 14:10:11 2012 UTC (12 years, 7 months ago) by gezelter
File size: 33087 byte(s)
Log Message:
Merged trunk changes into the development branch

File Contents

# User Rev Content
1 kstocke1 1701 /*
2     File autogenerated by gengetopt version 2.22.4
3     generated with the following command:
4     gengetopt -i nanorodBuilder.ggo -F nanorodBuilderCmd -u
5    
6     The developers of gengetopt consider the fixed text that goes in all
7     gengetopt output files to be in the public domain:
8     we make no copyright claims on it.
9     */
10    
11     /* If we use autoconf. */
12     #ifdef HAVE_CONFIG_H
13     #include "config.h"
14     #endif
15    
16     #include <stdio.h>
17     #include <stdlib.h>
18     #include <string.h>
19    
20     #ifndef FIX_UNUSED
21     #define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */
22     #endif
23    
24 gezelter 1798 #ifdef WIN32
25     #include "utils/wingetopt.h"
26     #else
27 kstocke1 1701 #include <getopt.h>
28 gezelter 1798 #endif
29 kstocke1 1701
30     #include "nanorodBuilderCmd.h"
31    
32     const char *gengetopt_args_info_purpose = "Builds spherically-capped random or core-shell nanorods and outputs an OpenMD \nstartup file";
33    
34     const char *gengetopt_args_info_usage = "Usage: nanorodBuilder [OPTIONS]... [FILES]...";
35    
36     const char *gengetopt_args_info_description = "";
37    
38     const char *gengetopt_args_info_help[] = {
39     " -h, --help Print help and exit",
40     " -V, --version Print version and exit",
41     " -o, --output=STRING Output file name",
42     " --latticeConstant=DOUBLE Lattice spacing in Angstroms for cubic lattice.",
43     " --radius=DOUBLE Nanorod radius in Angstroms",
44     " --length=DOUBLE Nanorod length in Angstroms",
45     " --shellRadius=DOUBLE Radius containing within it only molecules of a \n specific component. Specified for each \n component > 1 in the template file.",
46     " --molFraction=DOUBLE Builds a multi-component random alloy \n nanoparticle. A mole Fraction must be \n specified for each component > 1 in the \n template file.",
47     " --vacancyPercent=DOUBLE Percentage of atoms to remove from within \n vacancy range",
48     " --vacancyInnerRadius=DOUBLE\n Radius arround core-shell where vacancies \n should be located.",
49     " --vacancyOuterRadius=DOUBLE\n Radius arround core-shell where vacancies \n should be located.",
50     0
51     };
52    
53     typedef enum {ARG_NO
54     , ARG_STRING
55     , ARG_DOUBLE
56     } cmdline_parser_arg_type;
57    
58     static
59     void clear_given (struct gengetopt_args_info *args_info);
60     static
61     void clear_args (struct gengetopt_args_info *args_info);
62    
63     static int
64     cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args_info,
65     struct cmdline_parser_params *params, const char *additional_error);
66    
67     static int
68     cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error);
69    
70     static char *
71     gengetopt_strdup (const char *s);
72    
73     static
74     void clear_given (struct gengetopt_args_info *args_info)
75     {
76     args_info->help_given = 0 ;
77     args_info->version_given = 0 ;
78     args_info->output_given = 0 ;
79     args_info->latticeConstant_given = 0 ;
80     args_info->radius_given = 0 ;
81     args_info->length_given = 0 ;
82     args_info->shellRadius_given = 0 ;
83     args_info->molFraction_given = 0 ;
84     args_info->vacancyPercent_given = 0 ;
85     args_info->vacancyInnerRadius_given = 0 ;
86     args_info->vacancyOuterRadius_given = 0 ;
87     }
88    
89     static
90     void clear_args (struct gengetopt_args_info *args_info)
91     {
92     FIX_UNUSED (args_info);
93     args_info->output_arg = NULL;
94     args_info->output_orig = NULL;
95     args_info->latticeConstant_orig = NULL;
96     args_info->radius_orig = NULL;
97     args_info->length_orig = NULL;
98     args_info->shellRadius_arg = NULL;
99     args_info->shellRadius_orig = NULL;
100     args_info->molFraction_arg = NULL;
101     args_info->molFraction_orig = NULL;
102     args_info->vacancyPercent_orig = NULL;
103     args_info->vacancyInnerRadius_orig = NULL;
104     args_info->vacancyOuterRadius_orig = NULL;
105    
106     }
107    
108     static
109     void init_args_info(struct gengetopt_args_info *args_info)
110     {
111    
112    
113     args_info->help_help = gengetopt_args_info_help[0] ;
114     args_info->version_help = gengetopt_args_info_help[1] ;
115     args_info->output_help = gengetopt_args_info_help[2] ;
116     args_info->latticeConstant_help = gengetopt_args_info_help[3] ;
117     args_info->radius_help = gengetopt_args_info_help[4] ;
118     args_info->length_help = gengetopt_args_info_help[5] ;
119     args_info->shellRadius_help = gengetopt_args_info_help[6] ;
120     args_info->shellRadius_min = 0;
121     args_info->shellRadius_max = 0;
122     args_info->molFraction_help = gengetopt_args_info_help[7] ;
123     args_info->molFraction_min = 0;
124     args_info->molFraction_max = 0;
125     args_info->vacancyPercent_help = gengetopt_args_info_help[8] ;
126     args_info->vacancyInnerRadius_help = gengetopt_args_info_help[9] ;
127     args_info->vacancyOuterRadius_help = gengetopt_args_info_help[10] ;
128    
129     }
130    
131     void
132     cmdline_parser_print_version (void)
133     {
134     printf ("%s %s\n",
135     (strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : CMDLINE_PARSER_PACKAGE),
136     CMDLINE_PARSER_VERSION);
137     }
138    
139     static void print_help_common(void) {
140     cmdline_parser_print_version ();
141    
142     if (strlen(gengetopt_args_info_purpose) > 0)
143     printf("\n%s\n", gengetopt_args_info_purpose);
144    
145     if (strlen(gengetopt_args_info_usage) > 0)
146     printf("\n%s\n", gengetopt_args_info_usage);
147    
148     printf("\n");
149    
150     if (strlen(gengetopt_args_info_description) > 0)
151     printf("%s\n\n", gengetopt_args_info_description);
152     }
153    
154     void
155     cmdline_parser_print_help (void)
156     {
157     int i = 0;
158     print_help_common();
159     while (gengetopt_args_info_help[i])
160     printf("%s\n", gengetopt_args_info_help[i++]);
161     }
162    
163     void
164     cmdline_parser_init (struct gengetopt_args_info *args_info)
165     {
166     clear_given (args_info);
167     clear_args (args_info);
168     init_args_info (args_info);
169    
170     args_info->inputs = 0;
171     args_info->inputs_num = 0;
172     }
173    
174     void
175     cmdline_parser_params_init(struct cmdline_parser_params *params)
176     {
177     if (params)
178     {
179     params->override = 0;
180     params->initialize = 1;
181     params->check_required = 1;
182     params->check_ambiguity = 0;
183     params->print_errors = 1;
184     }
185     }
186    
187     struct cmdline_parser_params *
188     cmdline_parser_params_create(void)
189     {
190     struct cmdline_parser_params *params =
191     (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params));
192     cmdline_parser_params_init(params);
193     return params;
194     }
195    
196     static void
197     free_string_field (char **s)
198     {
199     if (*s)
200     {
201     free (*s);
202     *s = 0;
203     }
204     }
205    
206     /** @brief generic value variable */
207     union generic_value {
208     double double_arg;
209     char *string_arg;
210     const char *default_string_arg;
211     };
212    
213     /** @brief holds temporary values for multiple options */
214     struct generic_list
215     {
216     union generic_value arg;
217     char *orig;
218     struct generic_list *next;
219     };
220    
221     /**
222     * @brief add a node at the head of the list
223     */
224     static void add_node(struct generic_list **list) {
225     struct generic_list *new_node = (struct generic_list *) malloc (sizeof (struct generic_list));
226     new_node->next = *list;
227     *list = new_node;
228     new_node->arg.string_arg = 0;
229     new_node->orig = 0;
230     }
231    
232     /**
233     * The passed arg parameter is NOT set to 0 from this function
234     */
235     static void
236     free_multiple_field(unsigned int len, void *arg, char ***orig)
237     {
238     unsigned int i;
239     if (arg) {
240     for (i = 0; i < len; ++i)
241     {
242     free_string_field(&((*orig)[i]));
243     }
244    
245     free (arg);
246     free (*orig);
247     *orig = 0;
248     }
249     }
250    
251    
252     static void
253     cmdline_parser_release (struct gengetopt_args_info *args_info)
254     {
255     unsigned int i;
256     free_string_field (&(args_info->output_arg));
257     free_string_field (&(args_info->output_orig));
258     free_string_field (&(args_info->latticeConstant_orig));
259     free_string_field (&(args_info->radius_orig));
260     free_string_field (&(args_info->length_orig));
261     free_multiple_field (args_info->shellRadius_given, (void *)(args_info->shellRadius_arg), &(args_info->shellRadius_orig));
262     args_info->shellRadius_arg = 0;
263     free_multiple_field (args_info->molFraction_given, (void *)(args_info->molFraction_arg), &(args_info->molFraction_orig));
264     args_info->molFraction_arg = 0;
265     free_string_field (&(args_info->vacancyPercent_orig));
266     free_string_field (&(args_info->vacancyInnerRadius_orig));
267     free_string_field (&(args_info->vacancyOuterRadius_orig));
268    
269    
270     for (i = 0; i < args_info->inputs_num; ++i)
271     free (args_info->inputs [i]);
272    
273     if (args_info->inputs_num)
274     free (args_info->inputs);
275    
276     clear_given (args_info);
277     }
278    
279    
280     static void
281     write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[])
282     {
283     FIX_UNUSED (values);
284     if (arg) {
285     fprintf(outfile, "%s=\"%s\"\n", opt, arg);
286     } else {
287     fprintf(outfile, "%s\n", opt);
288     }
289     }
290    
291     static void
292     write_multiple_into_file(FILE *outfile, int len, const char *opt, char **arg, const char *values[])
293     {
294     int i;
295    
296     for (i = 0; i < len; ++i)
297     write_into_file(outfile, opt, (arg ? arg[i] : 0), values);
298     }
299    
300     int
301     cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info)
302     {
303     int i = 0;
304    
305     if (!outfile)
306     {
307     fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE);
308     return EXIT_FAILURE;
309     }
310    
311     if (args_info->help_given)
312     write_into_file(outfile, "help", 0, 0 );
313     if (args_info->version_given)
314     write_into_file(outfile, "version", 0, 0 );
315     if (args_info->output_given)
316     write_into_file(outfile, "output", args_info->output_orig, 0);
317     if (args_info->latticeConstant_given)
318     write_into_file(outfile, "latticeConstant", args_info->latticeConstant_orig, 0);
319     if (args_info->radius_given)
320     write_into_file(outfile, "radius", args_info->radius_orig, 0);
321     if (args_info->length_given)
322     write_into_file(outfile, "length", args_info->length_orig, 0);
323     write_multiple_into_file(outfile, args_info->shellRadius_given, "shellRadius", args_info->shellRadius_orig, 0);
324     write_multiple_into_file(outfile, args_info->molFraction_given, "molFraction", args_info->molFraction_orig, 0);
325     if (args_info->vacancyPercent_given)
326     write_into_file(outfile, "vacancyPercent", args_info->vacancyPercent_orig, 0);
327     if (args_info->vacancyInnerRadius_given)
328     write_into_file(outfile, "vacancyInnerRadius", args_info->vacancyInnerRadius_orig, 0);
329     if (args_info->vacancyOuterRadius_given)
330     write_into_file(outfile, "vacancyOuterRadius", args_info->vacancyOuterRadius_orig, 0);
331    
332    
333     i = EXIT_SUCCESS;
334     return i;
335     }
336    
337     int
338     cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info)
339     {
340     FILE *outfile;
341     int i = 0;
342    
343     outfile = fopen(filename, "w");
344    
345     if (!outfile)
346     {
347     fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename);
348     return EXIT_FAILURE;
349     }
350    
351     i = cmdline_parser_dump(outfile, args_info);
352     fclose (outfile);
353    
354     return i;
355     }
356    
357     void
358     cmdline_parser_free (struct gengetopt_args_info *args_info)
359     {
360     cmdline_parser_release (args_info);
361     }
362    
363     /** @brief replacement of strdup, which is not standard */
364     char *
365     gengetopt_strdup (const char *s)
366     {
367     char *result = 0;
368     if (!s)
369     return result;
370    
371     result = (char*)malloc(strlen(s) + 1);
372     if (result == (char*)0)
373     return (char*)0;
374     strcpy(result, s);
375     return result;
376     }
377    
378     static char *
379     get_multiple_arg_token(const char *arg)
380     {
381     const char *tok;
382     char *ret;
383     size_t len, num_of_escape, i, j;
384    
385     if (!arg)
386     return 0;
387    
388     tok = strchr (arg, ',');
389     num_of_escape = 0;
390    
391     /* make sure it is not escaped */
392     while (tok)
393     {
394     if (*(tok-1) == '\\')
395     {
396     /* find the next one */
397     tok = strchr (tok+1, ',');
398     ++num_of_escape;
399     }
400     else
401     break;
402     }
403    
404     if (tok)
405     len = (size_t)(tok - arg + 1);
406     else
407     len = strlen (arg) + 1;
408    
409     len -= num_of_escape;
410    
411     ret = (char *) malloc (len);
412    
413     i = 0;
414     j = 0;
415     while (arg[i] && (j < len-1))
416     {
417     if (arg[i] == '\\' &&
418     arg[ i + 1 ] &&
419     arg[ i + 1 ] == ',')
420     ++i;
421    
422     ret[j++] = arg[i++];
423     }
424    
425     ret[len-1] = '\0';
426    
427     return ret;
428     }
429    
430     static const char *
431     get_multiple_arg_token_next(const char *arg)
432     {
433     const char *tok;
434    
435     if (!arg)
436     return 0;
437    
438     tok = strchr (arg, ',');
439    
440     /* make sure it is not escaped */
441     while (tok)
442     {
443     if (*(tok-1) == '\\')
444     {
445     /* find the next one */
446     tok = strchr (tok+1, ',');
447     }
448     else
449     break;
450     }
451    
452     if (! tok || strlen(tok) == 1)
453     return 0;
454    
455     return tok+1;
456     }
457    
458     static int
459     check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, unsigned int min, unsigned int max, const char *option_desc);
460    
461     int
462     check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, unsigned int min, unsigned int max, const char *option_desc)
463     {
464     int error = 0;
465    
466     if (option_given && (min > 0 || max > 0))
467     {
468     if (min > 0 && max > 0)
469     {
470     if (min == max)
471     {
472     /* specific occurrences */
473     if (option_given != (unsigned int) min)
474     {
475     fprintf (stderr, "%s: %s option occurrences must be %d\n",
476     prog_name, option_desc, min);
477     error = 1;
478     }
479     }
480     else if (option_given < (unsigned int) min
481     || option_given > (unsigned int) max)
482     {
483     /* range occurrences */
484     fprintf (stderr, "%s: %s option occurrences must be between %d and %d\n",
485     prog_name, option_desc, min, max);
486     error = 1;
487     }
488     }
489     else if (min > 0)
490     {
491     /* at least check */
492     if (option_given < min)
493     {
494     fprintf (stderr, "%s: %s option occurrences must be at least %d\n",
495     prog_name, option_desc, min);
496     error = 1;
497     }
498     }
499     else if (max > 0)
500     {
501     /* at most check */
502     if (option_given > max)
503     {
504     fprintf (stderr, "%s: %s option occurrences must be at most %d\n",
505     prog_name, option_desc, max);
506     error = 1;
507     }
508     }
509     }
510    
511     return error;
512     }
513     int
514     cmdline_parser (int argc, char **argv, struct gengetopt_args_info *args_info)
515     {
516     return cmdline_parser2 (argc, argv, args_info, 0, 1, 1);
517     }
518    
519     int
520     cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info,
521     struct cmdline_parser_params *params)
522     {
523     int result;
524     result = cmdline_parser_internal (argc, argv, args_info, params, 0);
525    
526     if (result == EXIT_FAILURE)
527     {
528     cmdline_parser_free (args_info);
529     exit (EXIT_FAILURE);
530     }
531    
532     return result;
533     }
534    
535     int
536     cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required)
537     {
538     int result;
539     struct cmdline_parser_params params;
540    
541     params.override = override;
542     params.initialize = initialize;
543     params.check_required = check_required;
544     params.check_ambiguity = 0;
545     params.print_errors = 1;
546    
547     result = cmdline_parser_internal (argc, argv, args_info, &params, 0);
548    
549     if (result == EXIT_FAILURE)
550     {
551     cmdline_parser_free (args_info);
552     exit (EXIT_FAILURE);
553     }
554    
555     return result;
556     }
557    
558     int
559     cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name)
560     {
561     int result = EXIT_SUCCESS;
562    
563     if (cmdline_parser_required2(args_info, prog_name, 0) > 0)
564     result = EXIT_FAILURE;
565    
566     if (result == EXIT_FAILURE)
567     {
568     cmdline_parser_free (args_info);
569     exit (EXIT_FAILURE);
570     }
571    
572     return result;
573     }
574    
575     int
576     cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error)
577     {
578     int error = 0;
579     FIX_UNUSED (additional_error);
580    
581     /* checks for required options */
582     if (! args_info->output_given)
583     {
584     fprintf (stderr, "%s: '--output' ('-o') option required%s\n", prog_name, (additional_error ? additional_error : ""));
585     error = 1;
586     }
587    
588     if (! args_info->latticeConstant_given)
589     {
590     fprintf (stderr, "%s: '--latticeConstant' option required%s\n", prog_name, (additional_error ? additional_error : ""));
591     error = 1;
592     }
593    
594     if (! args_info->radius_given)
595     {
596     fprintf (stderr, "%s: '--radius' option required%s\n", prog_name, (additional_error ? additional_error : ""));
597     error = 1;
598     }
599    
600     if (! args_info->length_given)
601     {
602     fprintf (stderr, "%s: '--length' option required%s\n", prog_name, (additional_error ? additional_error : ""));
603     error = 1;
604     }
605    
606     if (check_multiple_option_occurrences(prog_name, args_info->shellRadius_given, args_info->shellRadius_min, args_info->shellRadius_max, "'--shellRadius'"))
607     error = 1;
608    
609     if (check_multiple_option_occurrences(prog_name, args_info->molFraction_given, args_info->molFraction_min, args_info->molFraction_max, "'--molFraction'"))
610     error = 1;
611    
612    
613     /* checks for dependences among options */
614    
615     return error;
616     }
617    
618    
619     static char *package_name = 0;
620    
621     /**
622     * @brief updates an option
623     * @param field the generic pointer to the field to update
624     * @param orig_field the pointer to the orig field
625     * @param field_given the pointer to the number of occurrence of this option
626     * @param prev_given the pointer to the number of occurrence already seen
627     * @param value the argument for this option (if null no arg was specified)
628     * @param possible_values the possible values for this option (if specified)
629     * @param default_value the default value (in case the option only accepts fixed values)
630     * @param arg_type the type of this option
631     * @param check_ambiguity @see cmdline_parser_params.check_ambiguity
632     * @param override @see cmdline_parser_params.override
633     * @param no_free whether to free a possible previous value
634     * @param multiple_option whether this is a multiple option
635     * @param long_opt the corresponding long option
636     * @param short_opt the corresponding short option (or '-' if none)
637     * @param additional_error possible further error specification
638     */
639     static
640     int update_arg(void *field, char **orig_field,
641     unsigned int *field_given, unsigned int *prev_given,
642     char *value, const char *possible_values[],
643     const char *default_value,
644     cmdline_parser_arg_type arg_type,
645     int check_ambiguity, int override,
646     int no_free, int multiple_option,
647     const char *long_opt, char short_opt,
648     const char *additional_error)
649     {
650     char *stop_char = 0;
651     const char *val = value;
652     int found;
653     char **string_field;
654     FIX_UNUSED (field);
655    
656     stop_char = 0;
657     found = 0;
658    
659     if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given)))
660     {
661     if (short_opt != '-')
662     fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n",
663     package_name, long_opt, short_opt,
664     (additional_error ? additional_error : ""));
665     else
666     fprintf (stderr, "%s: `--%s' option given more than once%s\n",
667     package_name, long_opt,
668     (additional_error ? additional_error : ""));
669     return 1; /* failure */
670     }
671    
672     FIX_UNUSED (default_value);
673    
674     if (field_given && *field_given && ! override)
675     return 0;
676     if (prev_given)
677     (*prev_given)++;
678     if (field_given)
679     (*field_given)++;
680     if (possible_values)
681     val = possible_values[found];
682    
683     switch(arg_type) {
684     case ARG_DOUBLE:
685     if (val) *((double *)field) = strtod (val, &stop_char);
686     break;
687     case ARG_STRING:
688     if (val) {
689     string_field = (char **)field;
690     if (!no_free && *string_field)
691     free (*string_field); /* free previous string */
692     *string_field = gengetopt_strdup (val);
693     }
694     break;
695     default:
696     break;
697     };
698    
699     /* check numeric conversion */
700     switch(arg_type) {
701     case ARG_DOUBLE:
702     if (val && !(stop_char && *stop_char == '\0')) {
703     fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val);
704     return 1; /* failure */
705     }
706     break;
707     default:
708     ;
709     };
710    
711     /* store the original value */
712     switch(arg_type) {
713     case ARG_NO:
714     break;
715     default:
716     if (value && orig_field) {
717     if (no_free) {
718     *orig_field = value;
719     } else {
720     if (*orig_field)
721     free (*orig_field); /* free previous string */
722     *orig_field = gengetopt_strdup (value);
723     }
724     }
725     };
726    
727     return 0; /* OK */
728     }
729    
730     /**
731     * @brief store information about a multiple option in a temporary list
732     * @param list where to (temporarily) store multiple options
733     */
734     static
735     int update_multiple_arg_temp(struct generic_list **list,
736     unsigned int *prev_given, const char *val,
737     const char *possible_values[], const char *default_value,
738     cmdline_parser_arg_type arg_type,
739     const char *long_opt, char short_opt,
740     const char *additional_error)
741     {
742     /* store single arguments */
743     char *multi_token;
744     const char *multi_next;
745    
746     if (arg_type == ARG_NO) {
747     (*prev_given)++;
748     return 0; /* OK */
749     }
750    
751     multi_token = get_multiple_arg_token(val);
752     multi_next = get_multiple_arg_token_next (val);
753    
754     while (1)
755     {
756     add_node (list);
757     if (update_arg((void *)&((*list)->arg), &((*list)->orig), 0,
758     prev_given, multi_token, possible_values, default_value,
759     arg_type, 0, 1, 1, 1, long_opt, short_opt, additional_error)) {
760     if (multi_token) free(multi_token);
761     return 1; /* failure */
762     }
763    
764     if (multi_next)
765     {
766     multi_token = get_multiple_arg_token(multi_next);
767     multi_next = get_multiple_arg_token_next (multi_next);
768     }
769     else
770     break;
771     }
772    
773     return 0; /* OK */
774     }
775    
776     /**
777     * @brief free the passed list (including possible string argument)
778     */
779     static
780     void free_list(struct generic_list *list, short string_arg)
781     {
782     if (list) {
783     struct generic_list *tmp;
784     while (list)
785     {
786     tmp = list;
787     if (string_arg && list->arg.string_arg)
788     free (list->arg.string_arg);
789     if (list->orig)
790     free (list->orig);
791     list = list->next;
792     free (tmp);
793     }
794     }
795     }
796    
797     /**
798     * @brief updates a multiple option starting from the passed list
799     */
800     static
801     void update_multiple_arg(void *field, char ***orig_field,
802     unsigned int field_given, unsigned int prev_given, union generic_value *default_value,
803     cmdline_parser_arg_type arg_type,
804     struct generic_list *list)
805     {
806     int i;
807     struct generic_list *tmp;
808    
809     if (prev_given && list) {
810     *orig_field = (char **) realloc (*orig_field, (field_given + prev_given) * sizeof (char *));
811    
812     switch(arg_type) {
813     case ARG_DOUBLE:
814     *((double **)field) = (double *)realloc (*((double **)field), (field_given + prev_given) * sizeof (double)); break;
815     case ARG_STRING:
816     *((char ***)field) = (char **)realloc (*((char ***)field), (field_given + prev_given) * sizeof (char *)); break;
817     default:
818     break;
819     };
820    
821     for (i = (prev_given - 1); i >= 0; --i)
822     {
823     tmp = list;
824    
825     switch(arg_type) {
826     case ARG_DOUBLE:
827     (*((double **)field))[i + field_given] = tmp->arg.double_arg; break;
828     case ARG_STRING:
829     (*((char ***)field))[i + field_given] = tmp->arg.string_arg; break;
830     default:
831     break;
832     }
833     (*orig_field) [i + field_given] = list->orig;
834     list = list->next;
835     free (tmp);
836     }
837     } else { /* set the default value */
838     if (default_value && ! field_given) {
839     switch(arg_type) {
840     case ARG_DOUBLE:
841     if (! *((double **)field)) {
842     *((double **)field) = (double *)malloc (sizeof (double));
843     (*((double **)field))[0] = default_value->double_arg;
844     }
845     break;
846     case ARG_STRING:
847     if (! *((char ***)field)) {
848     *((char ***)field) = (char **)malloc (sizeof (char *));
849     (*((char ***)field))[0] = gengetopt_strdup(default_value->string_arg);
850     }
851     break;
852     default: break;
853     }
854     if (!(*orig_field)) {
855     *orig_field = (char **) malloc (sizeof (char *));
856     (*orig_field)[0] = 0;
857     }
858     }
859     }
860     }
861    
862     int
863     cmdline_parser_internal (
864     int argc, char **argv, struct gengetopt_args_info *args_info,
865     struct cmdline_parser_params *params, const char *additional_error)
866     {
867     int c; /* Character of the parsed option. */
868    
869     struct generic_list * shellRadius_list = NULL;
870     struct generic_list * molFraction_list = NULL;
871     int error = 0;
872     struct gengetopt_args_info local_args_info;
873    
874     int override;
875     int initialize;
876     int check_required;
877     int check_ambiguity;
878    
879     package_name = argv[0];
880    
881     override = params->override;
882     initialize = params->initialize;
883     check_required = params->check_required;
884     check_ambiguity = params->check_ambiguity;
885    
886     if (initialize)
887     cmdline_parser_init (args_info);
888    
889     cmdline_parser_init (&local_args_info);
890    
891     optarg = 0;
892     optind = 0;
893     opterr = params->print_errors;
894     optopt = '?';
895    
896     while (1)
897     {
898     int option_index = 0;
899    
900     static struct option long_options[] = {
901     { "help", 0, NULL, 'h' },
902     { "version", 0, NULL, 'V' },
903     { "output", 1, NULL, 'o' },
904     { "latticeConstant", 1, NULL, 0 },
905     { "radius", 1, NULL, 0 },
906     { "length", 1, NULL, 0 },
907     { "shellRadius", 1, NULL, 0 },
908     { "molFraction", 1, NULL, 0 },
909     { "vacancyPercent", 1, NULL, 0 },
910     { "vacancyInnerRadius", 1, NULL, 0 },
911     { "vacancyOuterRadius", 1, NULL, 0 },
912     { 0, 0, 0, 0 }
913     };
914    
915     c = getopt_long (argc, argv, "hVo:", long_options, &option_index);
916    
917     if (c == -1) break; /* Exit from `while (1)' loop. */
918    
919     switch (c)
920     {
921     case 'h': /* Print help and exit. */
922     cmdline_parser_print_help ();
923     cmdline_parser_free (&local_args_info);
924     exit (EXIT_SUCCESS);
925    
926     case 'V': /* Print version and exit. */
927     cmdline_parser_print_version ();
928     cmdline_parser_free (&local_args_info);
929     exit (EXIT_SUCCESS);
930    
931     case 'o': /* Output file name. */
932    
933    
934     if (update_arg( (void *)&(args_info->output_arg),
935     &(args_info->output_orig), &(args_info->output_given),
936     &(local_args_info.output_given), optarg, 0, 0, ARG_STRING,
937     check_ambiguity, override, 0, 0,
938     "output", 'o',
939     additional_error))
940     goto failure;
941    
942     break;
943    
944     case 0: /* Long option with no short option */
945     /* Lattice spacing in Angstroms for cubic lattice.. */
946     if (strcmp (long_options[option_index].name, "latticeConstant") == 0)
947     {
948    
949    
950     if (update_arg( (void *)&(args_info->latticeConstant_arg),
951     &(args_info->latticeConstant_orig), &(args_info->latticeConstant_given),
952     &(local_args_info.latticeConstant_given), optarg, 0, 0, ARG_DOUBLE,
953     check_ambiguity, override, 0, 0,
954     "latticeConstant", '-',
955     additional_error))
956     goto failure;
957    
958     }
959     /* Nanorod radius in Angstroms. */
960     else if (strcmp (long_options[option_index].name, "radius") == 0)
961     {
962    
963    
964     if (update_arg( (void *)&(args_info->radius_arg),
965     &(args_info->radius_orig), &(args_info->radius_given),
966     &(local_args_info.radius_given), optarg, 0, 0, ARG_DOUBLE,
967     check_ambiguity, override, 0, 0,
968     "radius", '-',
969     additional_error))
970     goto failure;
971    
972     }
973     /* Nanorod length in Angstroms. */
974     else if (strcmp (long_options[option_index].name, "length") == 0)
975     {
976    
977    
978     if (update_arg( (void *)&(args_info->length_arg),
979     &(args_info->length_orig), &(args_info->length_given),
980     &(local_args_info.length_given), optarg, 0, 0, ARG_DOUBLE,
981     check_ambiguity, override, 0, 0,
982     "length", '-',
983     additional_error))
984     goto failure;
985    
986     }
987     /* Radius containing within it only molecules of a specific component. Specified for each component > 1 in the template file.. */
988     else if (strcmp (long_options[option_index].name, "shellRadius") == 0)
989     {
990    
991     if (update_multiple_arg_temp(&shellRadius_list,
992     &(local_args_info.shellRadius_given), optarg, 0, 0, ARG_DOUBLE,
993     "shellRadius", '-',
994     additional_error))
995     goto failure;
996    
997     }
998     /* Builds a multi-component random alloy nanoparticle. A mole Fraction must be specified for each component > 1 in the template file.. */
999     else if (strcmp (long_options[option_index].name, "molFraction") == 0)
1000     {
1001    
1002     if (update_multiple_arg_temp(&molFraction_list,
1003     &(local_args_info.molFraction_given), optarg, 0, 0, ARG_DOUBLE,
1004     "molFraction", '-',
1005     additional_error))
1006     goto failure;
1007    
1008     }
1009     /* Percentage of atoms to remove from within vacancy range. */
1010     else if (strcmp (long_options[option_index].name, "vacancyPercent") == 0)
1011     {
1012    
1013    
1014     if (update_arg( (void *)&(args_info->vacancyPercent_arg),
1015     &(args_info->vacancyPercent_orig), &(args_info->vacancyPercent_given),
1016     &(local_args_info.vacancyPercent_given), optarg, 0, 0, ARG_DOUBLE,
1017     check_ambiguity, override, 0, 0,
1018     "vacancyPercent", '-',
1019     additional_error))
1020     goto failure;
1021    
1022     }
1023     /* Radius arround core-shell where vacancies should be located.. */
1024     else if (strcmp (long_options[option_index].name, "vacancyInnerRadius") == 0)
1025     {
1026    
1027    
1028     if (update_arg( (void *)&(args_info->vacancyInnerRadius_arg),
1029     &(args_info->vacancyInnerRadius_orig), &(args_info->vacancyInnerRadius_given),
1030     &(local_args_info.vacancyInnerRadius_given), optarg, 0, 0, ARG_DOUBLE,
1031     check_ambiguity, override, 0, 0,
1032     "vacancyInnerRadius", '-',
1033     additional_error))
1034     goto failure;
1035    
1036     }
1037     /* Radius arround core-shell where vacancies should be located.. */
1038     else if (strcmp (long_options[option_index].name, "vacancyOuterRadius") == 0)
1039     {
1040    
1041    
1042     if (update_arg( (void *)&(args_info->vacancyOuterRadius_arg),
1043     &(args_info->vacancyOuterRadius_orig), &(args_info->vacancyOuterRadius_given),
1044     &(local_args_info.vacancyOuterRadius_given), optarg, 0, 0, ARG_DOUBLE,
1045     check_ambiguity, override, 0, 0,
1046     "vacancyOuterRadius", '-',
1047     additional_error))
1048     goto failure;
1049    
1050     }
1051    
1052     break;
1053     case '?': /* Invalid option. */
1054     /* `getopt_long' already printed an error message. */
1055     goto failure;
1056    
1057     default: /* bug: option not considered. */
1058     fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : ""));
1059     abort ();
1060     } /* switch */
1061     } /* while */
1062    
1063    
1064     update_multiple_arg((void *)&(args_info->shellRadius_arg),
1065     &(args_info->shellRadius_orig), args_info->shellRadius_given,
1066     local_args_info.shellRadius_given, 0,
1067     ARG_DOUBLE, shellRadius_list);
1068     update_multiple_arg((void *)&(args_info->molFraction_arg),
1069     &(args_info->molFraction_orig), args_info->molFraction_given,
1070     local_args_info.molFraction_given, 0,
1071     ARG_DOUBLE, molFraction_list);
1072    
1073     args_info->shellRadius_given += local_args_info.shellRadius_given;
1074     local_args_info.shellRadius_given = 0;
1075     args_info->molFraction_given += local_args_info.molFraction_given;
1076     local_args_info.molFraction_given = 0;
1077    
1078     if (check_required)
1079     {
1080     error += cmdline_parser_required2 (args_info, argv[0], additional_error);
1081     }
1082    
1083     cmdline_parser_release (&local_args_info);
1084    
1085     if ( error )
1086     return (EXIT_FAILURE);
1087    
1088     if (optind < argc)
1089     {
1090     int i = 0 ;
1091     int found_prog_name = 0;
1092     /* whether program name, i.e., argv[0], is in the remaining args
1093     (this may happen with some implementations of getopt,
1094     but surely not with the one included by gengetopt) */
1095    
1096     i = optind;
1097     while (i < argc)
1098     if (argv[i++] == argv[0]) {
1099     found_prog_name = 1;
1100     break;
1101     }
1102     i = 0;
1103    
1104     args_info->inputs_num = argc - optind - found_prog_name;
1105     args_info->inputs =
1106     (char **)(malloc ((args_info->inputs_num)*sizeof(char *))) ;
1107     while (optind < argc)
1108     if (argv[optind++] != argv[0])
1109     args_info->inputs[ i++ ] = gengetopt_strdup (argv[optind-1]) ;
1110     }
1111    
1112     return 0;
1113    
1114     failure:
1115     free_list (shellRadius_list, 0 );
1116     free_list (molFraction_list, 0 );
1117    
1118     cmdline_parser_release (&local_args_info);
1119     return (EXIT_FAILURE);
1120     }