]> Creatis software - clitk.git/blob - vv/tools_ggo/clitkRegionGrowing_ggo.c
Merge branch 'master' of git.creatis.insa-lyon.fr:clitk
[clitk.git] / vv / tools_ggo / clitkRegionGrowing_ggo.c
1 /*
2   File autogenerated by gengetopt version 2.22
3   generated with the following command:
4   /usr/local/bin/gengetopt --output-dir=/home/tbaudier/vv/vv_static/vv/vv_bin/segmentation --arg-struct-name=args_info_clitkRegionGrowing --func-name=cmdline_parser_clitkRegionGrowing --file-name=clitkRegionGrowing_ggo --unamed-opts --conf-parser --include-getopt 
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
21 #include "clitkRegionGrowing_ggo.h"
22
23 const char *args_info_clitkRegionGrowing_purpose = "Region growing from a seed point using various types of conditions to control \nthe growing";
24
25 const char *args_info_clitkRegionGrowing_usage = "Usage: clitkRegionGrowing [OPTIONS]... [FILES]...";
26
27 const char *args_info_clitkRegionGrowing_description = "";
28
29 const char *args_info_clitkRegionGrowing_help[] = {
30   "  -h, --help               Print help and exit",
31   "  -V, --version            Print version and exit",
32   "      --config=STRING      Config file",
33   "  -v, --verbose            Verbose  (default=off)",
34   "\nI/O:",
35   "  -i, --input=STRING       Input image filename",
36   "  -o, --output=STRING      Output image filename",
37   "\nParameters:",
38   "  -t, --type=INT           Region growing filter type: 0=threshold , \n                             1=neighborhood-threshold , 2=confidence , 3= \n                             locally-adaptive-threshold, 4= \n                             explosion-controlled-threshold  (default=`0')",
39   "  -l, --lower=DOUBLE       1,2,3,4: Lower threshold value  (default=`310')",
40   "  -u, --upper=DOUBLE       1,2,3,4: Upper threshold value  (default=`4000')",
41   "      --maxUpper=DOUBLE    4: Maximum upper threshold value  (default=`2000')",
42   "      --minLower=DOUBLE    4: Minimum lower threshold value  (default=`-1000')",
43   "      --step=DOUBLE        4: Threshold step size  (default=`64.0')",
44   "      --minStep=DOUBLE     4: Minimum threshold step size  (default=`1')",
45   "      --adaptLower         3,4: (locally) adapt lower thresholding  \n                             (default=off)",
46   "      --adaptUpper         3,4: (locally) adapt upper thresholding  \n                             (default=off)",
47   "  -m, --multiplier=DOUBLE  2-4: (2-3) accept if within mean+-mutiplier*SD, (4) \n                             explosion if size increases multiplier times  \n                             (default=`2.0')",
48   "  -s, --seed=INT           Seed index postion (in voxels)  (default=`0')",
49   "      --seedRadius=INT     Radius used for seed dilatation(in voxel)  \n                             (default=`0')",
50   "  -p, --pad=DOUBLE         The replace padding value  (default=`1.0')",
51   "  -r, --radius=INT         1-3: The radius of the neighborhood  (default=`1')",
52   "      --maxSD=DOUBLE       3: Limit to SD",
53   "      --full               4: use full connectivity (not implemented yet)  \n                             (default=off)",
54   "      --iter=INT           2: Iterations  (default=`5')",
55     0
56 };
57
58 typedef enum {ARG_NO
59   , ARG_FLAG
60   , ARG_STRING
61   , ARG_INT
62   , ARG_DOUBLE
63 } cmdline_parser_clitkRegionGrowing_arg_type;
64
65 static
66 void clear_given (struct args_info_clitkRegionGrowing *args_info);
67 static
68 void clear_args (struct args_info_clitkRegionGrowing *args_info);
69
70 static int
71 cmdline_parser_clitkRegionGrowing_internal (int argc, char * const *argv, struct args_info_clitkRegionGrowing *args_info,
72                         struct cmdline_parser_clitkRegionGrowing_params *params, const char *additional_error);
73
74 static int
75 cmdline_parser_clitkRegionGrowing_required2 (struct args_info_clitkRegionGrowing *args_info, const char *prog_name, const char *additional_error);
76 struct line_list
77 {
78   char * string_arg;
79   struct line_list * next;
80 };
81
82 static struct line_list *cmd_line_list = 0;
83 static struct line_list *cmd_line_list_tmp = 0;
84
85 static void
86 free_cmd_list(void)
87 {
88   /* free the list of a previous call */
89   if (cmd_line_list)
90     {
91       while (cmd_line_list) {
92         cmd_line_list_tmp = cmd_line_list;
93         cmd_line_list = cmd_line_list->next;
94         free (cmd_line_list_tmp->string_arg);
95         free (cmd_line_list_tmp);
96       }
97     }
98 }
99
100
101 static char *
102 gengetopt_strdup (const char *s);
103
104 static
105 void clear_given (struct args_info_clitkRegionGrowing *args_info)
106 {
107   args_info->help_given = 0 ;
108   args_info->version_given = 0 ;
109   args_info->config_given = 0 ;
110   args_info->verbose_given = 0 ;
111   args_info->input_given = 0 ;
112   args_info->output_given = 0 ;
113   args_info->type_given = 0 ;
114   args_info->lower_given = 0 ;
115   args_info->upper_given = 0 ;
116   args_info->maxUpper_given = 0 ;
117   args_info->minLower_given = 0 ;
118   args_info->step_given = 0 ;
119   args_info->minStep_given = 0 ;
120   args_info->adaptLower_given = 0 ;
121   args_info->adaptUpper_given = 0 ;
122   args_info->multiplier_given = 0 ;
123   args_info->seed_given = 0 ;
124   args_info->seedRadius_given = 0 ;
125   args_info->pad_given = 0 ;
126   args_info->radius_given = 0 ;
127   args_info->maxSD_given = 0 ;
128   args_info->full_given = 0 ;
129   args_info->iter_given = 0 ;
130 }
131
132 static
133 void clear_args (struct args_info_clitkRegionGrowing *args_info)
134 {
135   args_info->config_arg = NULL;
136   args_info->config_orig = NULL;
137   args_info->verbose_flag = 0;
138   args_info->input_arg = NULL;
139   args_info->input_orig = NULL;
140   args_info->output_arg = NULL;
141   args_info->output_orig = NULL;
142   args_info->type_arg = 0;
143   args_info->type_orig = NULL;
144   args_info->lower_arg = 310;
145   args_info->lower_orig = NULL;
146   args_info->upper_arg = 4000;
147   args_info->upper_orig = NULL;
148   args_info->maxUpper_arg = 2000;
149   args_info->maxUpper_orig = NULL;
150   args_info->minLower_arg = -1000;
151   args_info->minLower_orig = NULL;
152   args_info->step_arg = 64.0;
153   args_info->step_orig = NULL;
154   args_info->minStep_arg = 1;
155   args_info->minStep_orig = NULL;
156   args_info->adaptLower_flag = 0;
157   args_info->adaptUpper_flag = 0;
158   args_info->multiplier_arg = 2.0;
159   args_info->multiplier_orig = NULL;
160   args_info->seed_arg = NULL;
161   args_info->seed_orig = NULL;
162   args_info->seedRadius_arg = NULL;
163   args_info->seedRadius_orig = NULL;
164   args_info->pad_arg = 1.0;
165   args_info->pad_orig = NULL;
166   args_info->radius_arg = NULL;
167   args_info->radius_orig = NULL;
168   args_info->maxSD_orig = NULL;
169   args_info->full_flag = 0;
170   args_info->iter_arg = 5;
171   args_info->iter_orig = NULL;
172   
173 }
174
175 static
176 void init_args_info(struct args_info_clitkRegionGrowing *args_info)
177 {
178
179
180   args_info->help_help = args_info_clitkRegionGrowing_help[0] ;
181   args_info->version_help = args_info_clitkRegionGrowing_help[1] ;
182   args_info->config_help = args_info_clitkRegionGrowing_help[2] ;
183   args_info->verbose_help = args_info_clitkRegionGrowing_help[3] ;
184   args_info->input_help = args_info_clitkRegionGrowing_help[5] ;
185   args_info->output_help = args_info_clitkRegionGrowing_help[6] ;
186   args_info->type_help = args_info_clitkRegionGrowing_help[8] ;
187   args_info->lower_help = args_info_clitkRegionGrowing_help[9] ;
188   args_info->upper_help = args_info_clitkRegionGrowing_help[10] ;
189   args_info->maxUpper_help = args_info_clitkRegionGrowing_help[11] ;
190   args_info->minLower_help = args_info_clitkRegionGrowing_help[12] ;
191   args_info->step_help = args_info_clitkRegionGrowing_help[13] ;
192   args_info->minStep_help = args_info_clitkRegionGrowing_help[14] ;
193   args_info->adaptLower_help = args_info_clitkRegionGrowing_help[15] ;
194   args_info->adaptUpper_help = args_info_clitkRegionGrowing_help[16] ;
195   args_info->multiplier_help = args_info_clitkRegionGrowing_help[17] ;
196   args_info->seed_help = args_info_clitkRegionGrowing_help[18] ;
197   args_info->seed_min = -1;
198   args_info->seed_max = -1;
199   args_info->seedRadius_help = args_info_clitkRegionGrowing_help[19] ;
200   args_info->seedRadius_min = -1;
201   args_info->seedRadius_max = -1;
202   args_info->pad_help = args_info_clitkRegionGrowing_help[20] ;
203   args_info->radius_help = args_info_clitkRegionGrowing_help[21] ;
204   args_info->radius_min = -1;
205   args_info->radius_max = -1;
206   args_info->maxSD_help = args_info_clitkRegionGrowing_help[22] ;
207   args_info->full_help = args_info_clitkRegionGrowing_help[23] ;
208   args_info->iter_help = args_info_clitkRegionGrowing_help[24] ;
209   
210 }
211
212 void
213 cmdline_parser_clitkRegionGrowing_print_version (void)
214 {
215   printf ("%s %s\n", CMDLINE_PARSER_CLITKREGIONGROWING_PACKAGE, CMDLINE_PARSER_CLITKREGIONGROWING_VERSION);
216 }
217
218 static void print_help_common(void) {
219   cmdline_parser_clitkRegionGrowing_print_version ();
220
221   if (strlen(args_info_clitkRegionGrowing_purpose) > 0)
222     printf("\n%s\n", args_info_clitkRegionGrowing_purpose);
223
224   if (strlen(args_info_clitkRegionGrowing_usage) > 0)
225     printf("\n%s\n", args_info_clitkRegionGrowing_usage);
226
227   printf("\n");
228
229   if (strlen(args_info_clitkRegionGrowing_description) > 0)
230     printf("%s\n", args_info_clitkRegionGrowing_description);
231 }
232
233 void
234 cmdline_parser_clitkRegionGrowing_print_help (void)
235 {
236   int i = 0;
237   print_help_common();
238   while (args_info_clitkRegionGrowing_help[i])
239     printf("%s\n", args_info_clitkRegionGrowing_help[i++]);
240 }
241
242 void
243 cmdline_parser_clitkRegionGrowing_init (struct args_info_clitkRegionGrowing *args_info)
244 {
245   clear_given (args_info);
246   clear_args (args_info);
247   init_args_info (args_info);
248
249   args_info->inputs = NULL;
250   args_info->inputs_num = 0;
251 }
252
253 void
254 cmdline_parser_clitkRegionGrowing_params_init(struct cmdline_parser_clitkRegionGrowing_params *params)
255 {
256   if (params)
257     { 
258       params->override = 0;
259       params->initialize = 1;
260       params->check_required = 1;
261       params->check_ambiguity = 0;
262       params->print_errors = 1;
263     }
264 }
265
266 struct cmdline_parser_clitkRegionGrowing_params *
267 cmdline_parser_clitkRegionGrowing_params_create(void)
268 {
269   struct cmdline_parser_clitkRegionGrowing_params *params = 
270     (struct cmdline_parser_clitkRegionGrowing_params *)malloc(sizeof(struct cmdline_parser_clitkRegionGrowing_params));
271   cmdline_parser_clitkRegionGrowing_params_init(params);  
272   return params;
273 }
274
275 static void
276 free_string_field (char **s)
277 {
278   if (*s)
279     {
280       free (*s);
281       *s = 0;
282     }
283 }
284
285 /** @brief generic value variable */
286 union generic_value {
287     int int_arg;
288     double double_arg;
289     char *string_arg;
290 };
291
292 /** @brief holds temporary values for multiple options */
293 struct generic_list
294 {
295   union generic_value arg;
296   char *orig;
297   struct generic_list *next;
298 };
299
300 /**
301  * @brief add a node at the head of the list 
302  */
303 static void add_node(struct generic_list **list) {
304   struct generic_list *new_node = (struct generic_list *) malloc (sizeof (struct generic_list));
305   new_node->next = *list;
306   *list = new_node;
307   new_node->arg.string_arg = NULL;
308   new_node->orig = NULL;
309 }
310
311 static void
312 free_multiple_field(unsigned int len, void **arg, char ***orig)
313 {
314   unsigned int i;
315   if (*arg) {
316     for (i = 0; i < len; ++i)
317       {
318         free_string_field(&((*orig)[i]));
319       }
320
321     free (*arg);
322     *arg = 0;
323     free (*orig);
324     *orig = 0;
325   }
326 }
327
328
329 static void
330 cmdline_parser_clitkRegionGrowing_release (struct args_info_clitkRegionGrowing *args_info)
331 {
332   unsigned int i;
333   free_string_field (&(args_info->config_arg));
334   free_string_field (&(args_info->config_orig));
335   free_string_field (&(args_info->input_arg));
336   free_string_field (&(args_info->input_orig));
337   free_string_field (&(args_info->output_arg));
338   free_string_field (&(args_info->output_orig));
339   free_string_field (&(args_info->type_orig));
340   free_string_field (&(args_info->lower_orig));
341   free_string_field (&(args_info->upper_orig));
342   free_string_field (&(args_info->maxUpper_orig));
343   free_string_field (&(args_info->minLower_orig));
344   free_string_field (&(args_info->step_orig));
345   free_string_field (&(args_info->minStep_orig));
346   free_string_field (&(args_info->multiplier_orig));
347   free_multiple_field (args_info->seed_given, (void **)&(args_info->seed_arg), &(args_info->seed_orig));
348   free_multiple_field (args_info->seedRadius_given, (void **)&(args_info->seedRadius_arg), &(args_info->seedRadius_orig));
349   free_string_field (&(args_info->pad_orig));
350   free_multiple_field (args_info->radius_given, (void **)&(args_info->radius_arg), &(args_info->radius_orig));
351   free_string_field (&(args_info->maxSD_orig));
352   free_string_field (&(args_info->iter_orig));
353   
354   
355   for (i = 0; i < args_info->inputs_num; ++i)
356     free (args_info->inputs [i]);
357
358   if (args_info->inputs_num)
359     free (args_info->inputs);
360
361   clear_given (args_info);
362 }
363
364
365 static void
366 write_into_file(FILE *outfile, const char *opt, const char *arg, char *values[])
367 {
368   if (arg) {
369     fprintf(outfile, "%s=\"%s\"\n", opt, arg);
370   } else {
371     fprintf(outfile, "%s\n", opt);
372   }
373 }
374
375 static void
376 write_multiple_into_file(FILE *outfile, int len, const char *opt, char **arg, char *values[])
377 {
378   int i;
379   
380   for (i = 0; i < len; ++i)
381     write_into_file(outfile, opt, (arg ? arg[i] : 0), values);
382 }
383
384 int
385 cmdline_parser_clitkRegionGrowing_dump(FILE *outfile, struct args_info_clitkRegionGrowing *args_info)
386 {
387   int i = 0;
388
389   if (!outfile)
390     {
391       fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_CLITKREGIONGROWING_PACKAGE);
392       return EXIT_FAILURE;
393     }
394
395   if (args_info->help_given)
396     write_into_file(outfile, "help", 0, 0 );
397   if (args_info->version_given)
398     write_into_file(outfile, "version", 0, 0 );
399   if (args_info->config_given)
400     write_into_file(outfile, "config", args_info->config_orig, 0);
401   if (args_info->verbose_given)
402     write_into_file(outfile, "verbose", 0, 0 );
403   if (args_info->input_given)
404     write_into_file(outfile, "input", args_info->input_orig, 0);
405   if (args_info->output_given)
406     write_into_file(outfile, "output", args_info->output_orig, 0);
407   if (args_info->type_given)
408     write_into_file(outfile, "type", args_info->type_orig, 0);
409   if (args_info->lower_given)
410     write_into_file(outfile, "lower", args_info->lower_orig, 0);
411   if (args_info->upper_given)
412     write_into_file(outfile, "upper", args_info->upper_orig, 0);
413   if (args_info->maxUpper_given)
414     write_into_file(outfile, "maxUpper", args_info->maxUpper_orig, 0);
415   if (args_info->minLower_given)
416     write_into_file(outfile, "minLower", args_info->minLower_orig, 0);
417   if (args_info->step_given)
418     write_into_file(outfile, "step", args_info->step_orig, 0);
419   if (args_info->minStep_given)
420     write_into_file(outfile, "minStep", args_info->minStep_orig, 0);
421   if (args_info->adaptLower_given)
422     write_into_file(outfile, "adaptLower", 0, 0 );
423   if (args_info->adaptUpper_given)
424     write_into_file(outfile, "adaptUpper", 0, 0 );
425   if (args_info->multiplier_given)
426     write_into_file(outfile, "multiplier", args_info->multiplier_orig, 0);
427   write_multiple_into_file(outfile, args_info->seed_given, "seed", args_info->seed_orig, 0);
428   write_multiple_into_file(outfile, args_info->seedRadius_given, "seedRadius", args_info->seedRadius_orig, 0);
429   if (args_info->pad_given)
430     write_into_file(outfile, "pad", args_info->pad_orig, 0);
431   write_multiple_into_file(outfile, args_info->radius_given, "radius", args_info->radius_orig, 0);
432   if (args_info->maxSD_given)
433     write_into_file(outfile, "maxSD", args_info->maxSD_orig, 0);
434   if (args_info->full_given)
435     write_into_file(outfile, "full", 0, 0 );
436   if (args_info->iter_given)
437     write_into_file(outfile, "iter", args_info->iter_orig, 0);
438   
439
440   i = EXIT_SUCCESS;
441   return i;
442 }
443
444 int
445 cmdline_parser_clitkRegionGrowing_file_save(const char *filename, struct args_info_clitkRegionGrowing *args_info)
446 {
447   FILE *outfile;
448   int i = 0;
449
450   outfile = fopen(filename, "w");
451
452   if (!outfile)
453     {
454       fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_CLITKREGIONGROWING_PACKAGE, filename);
455       return EXIT_FAILURE;
456     }
457
458   i = cmdline_parser_clitkRegionGrowing_dump(outfile, args_info);
459   fclose (outfile);
460
461   return i;
462 }
463
464 void
465 cmdline_parser_clitkRegionGrowing_free (struct args_info_clitkRegionGrowing *args_info)
466 {
467   cmdline_parser_clitkRegionGrowing_release (args_info);
468 }
469
470 /** @brief replacement of strdup, which is not standard */
471 char *
472 gengetopt_strdup (const char *s)
473 {
474   char *result = NULL;
475   if (!s)
476     return result;
477
478   result = (char*)malloc(strlen(s) + 1);
479   if (result == (char*)0)
480     return (char*)0;
481   strcpy(result, s);
482   return result;
483 }
484
485 static char *
486 get_multiple_arg_token(const char *arg)
487 {
488   char *tok, *ret;
489   size_t len, num_of_escape, i, j;
490
491   if (!arg)
492     return NULL;
493
494   tok = strchr (arg, ',');
495   num_of_escape = 0;
496
497   /* make sure it is not escaped */
498   while (tok)
499     {
500       if (*(tok-1) == '\\')
501         {
502           /* find the next one */
503           tok = strchr (tok+1, ',');
504           ++num_of_escape;
505         }
506       else
507         break;
508     }
509
510   if (tok)
511     len = (size_t)(tok - arg + 1);
512   else
513     len = strlen (arg) + 1;
514
515   len -= num_of_escape;
516
517   ret = (char *) malloc (len);
518
519   i = 0;
520   j = 0;
521   while (arg[i] && (j < len-1))
522     {
523       if (arg[i] == '\\' && 
524           arg[ i + 1 ] && 
525           arg[ i + 1 ] == ',')
526         ++i;
527
528       ret[j++] = arg[i++];
529     }
530
531   ret[len-1] = '\0';
532
533   return ret;
534 }
535
536 static char *
537 get_multiple_arg_token_next(const char *arg)
538 {
539   char *tok;
540
541   if (!arg)
542     return NULL;
543
544   tok = strchr (arg, ',');
545
546   /* make sure it is not escaped */
547   while (tok)
548     {
549       if (*(tok-1) == '\\')
550         {
551           /* find the next one */
552           tok = strchr (tok+1, ',');
553         }
554       else
555         break;
556     }
557
558   if (! tok || strlen(tok) == 1)
559     return 0;
560
561   return tok+1;
562 }
563
564 static int
565 check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, int min, int max, const char *option_desc);
566
567 int
568 check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, int min, int max, const char *option_desc)
569 {
570   int error = 0;
571
572   if (option_given && ! (min < 0 && max < 0))
573     {
574       if (min >= 0 && max >= 0)
575         {
576           if (min == max)
577             {
578               /* specific occurrences */
579               if (option_given != min)
580                 {
581                   fprintf (stderr, "%s: %s option occurrences must be %d\n",
582                     prog_name, option_desc, min);
583                   error = 1;
584                 }
585             }
586           else if (option_given < min
587               || option_given > max)
588             {
589               /* range occurrences */
590               fprintf (stderr, "%s: %s option occurrences must be between %d and %d\n",
591                 prog_name, option_desc, min, max);
592               error = 1;
593             }
594         }
595       else if (min >= 0)
596         {
597           /* at least check */
598           if (option_given < min)
599             {
600               fprintf (stderr, "%s: %s option occurrences must be at least %d\n",
601                 prog_name, option_desc, min);
602               error = 1;
603             }
604         }
605       else if (max >= 0)
606         {
607           /* at most check */
608           if (option_given > max)
609             {
610               fprintf (stderr, "%s: %s option occurrences must be at most %d\n",
611                 prog_name, option_desc, max);
612               error = 1;
613             }
614         }
615     }
616     
617   return error;
618 }
619 int
620 cmdline_parser_clitkRegionGrowing (int argc, char * const *argv, struct args_info_clitkRegionGrowing *args_info)
621 {
622   return cmdline_parser_clitkRegionGrowing2 (argc, argv, args_info, 0, 1, 1);
623 }
624
625 int
626 cmdline_parser_clitkRegionGrowing_ext (int argc, char * const *argv, struct args_info_clitkRegionGrowing *args_info,
627                    struct cmdline_parser_clitkRegionGrowing_params *params)
628 {
629   int result;
630   result = cmdline_parser_clitkRegionGrowing_internal (argc, argv, args_info, params, NULL);
631
632   if (result == EXIT_FAILURE)
633     {
634       cmdline_parser_clitkRegionGrowing_free (args_info);
635       exit (EXIT_FAILURE);
636     }
637   
638   return result;
639 }
640
641 int
642 cmdline_parser_clitkRegionGrowing2 (int argc, char * const *argv, struct args_info_clitkRegionGrowing *args_info, int override, int initialize, int check_required)
643 {
644   int result;
645   struct cmdline_parser_clitkRegionGrowing_params params;
646   
647   params.override = override;
648   params.initialize = initialize;
649   params.check_required = check_required;
650   params.check_ambiguity = 0;
651   params.print_errors = 1;
652
653   result = cmdline_parser_clitkRegionGrowing_internal (argc, argv, args_info, &params, NULL);
654
655   if (result == EXIT_FAILURE)
656     {
657       cmdline_parser_clitkRegionGrowing_free (args_info);
658       exit (EXIT_FAILURE);
659     }
660   
661   return result;
662 }
663
664 int
665 cmdline_parser_clitkRegionGrowing_required (struct args_info_clitkRegionGrowing *args_info, const char *prog_name)
666 {
667   int result = EXIT_SUCCESS;
668
669   if (cmdline_parser_clitkRegionGrowing_required2(args_info, prog_name, NULL) > 0)
670     result = EXIT_FAILURE;
671
672   if (result == EXIT_FAILURE)
673     {
674       cmdline_parser_clitkRegionGrowing_free (args_info);
675       exit (EXIT_FAILURE);
676     }
677   
678   return result;
679 }
680
681 int
682 cmdline_parser_clitkRegionGrowing_required2 (struct args_info_clitkRegionGrowing *args_info, const char *prog_name, const char *additional_error)
683 {
684   int error = 0;
685
686   /* checks for required options */
687   if (! args_info->input_given)
688     {
689       fprintf (stderr, "%s: '--input' ('-i') option required%s\n", prog_name, (additional_error ? additional_error : ""));
690       error = 1;
691     }
692   
693   if (! args_info->output_given)
694     {
695       fprintf (stderr, "%s: '--output' ('-o') option required%s\n", prog_name, (additional_error ? additional_error : ""));
696       error = 1;
697     }
698   
699   if (check_multiple_option_occurrences(prog_name, args_info->seed_given, args_info->seed_min, args_info->seed_max, "'--seed' ('-s')"))
700      error = 1;
701   
702   if (check_multiple_option_occurrences(prog_name, args_info->seedRadius_given, args_info->seedRadius_min, args_info->seedRadius_max, "'--seedRadius'"))
703      error = 1;
704   
705   if (check_multiple_option_occurrences(prog_name, args_info->radius_given, args_info->radius_min, args_info->radius_max, "'--radius' ('-r')"))
706      error = 1;
707   
708   
709   /* checks for dependences among options */
710
711   return error;
712 }
713
714 /*
715  * Extracted from the glibc source tree, version 2.3.6
716  *
717  * Licensed under the GPL as per the whole glibc source tree.
718  *
719  * This file was modified so that getopt_long can be called
720  * many times without risking previous memory to be spoiled.
721  *
722  * Modified by Andre Noll and Lorenzo Bettini for use in
723  * GNU gengetopt generated files.
724  *
725  */
726
727 /* 
728  * we must include anything we need since this file is not thought to be
729  * inserted in a file already using getopt.h
730  *
731  * Lorenzo
732  */
733
734 struct option
735 {
736   const char *name;
737   /* has_arg can't be an enum because some compilers complain about
738      type mismatches in all the code that assumes it is an int.  */
739   int has_arg;
740   int *flag;
741   int val;
742 };
743
744 /* For communication from `getopt' to the caller.
745    When `getopt' finds an option that takes an argument,
746    the argument value is returned here.
747    Also, when `ordering' is RETURN_IN_ORDER,
748    each non-option ARGV-element is returned here.  */
749
750 static char *optarg;
751
752 /* Index in ARGV of the next element to be scanned.
753    This is used for communication to and from the caller
754    and for communication between successive calls to `getopt'.
755
756    On entry to `getopt', zero means this is the first call; initialize.
757
758    When `getopt' returns -1, this is the index of the first of the
759    non-option elements that the caller should itself scan.
760
761    Otherwise, `optind' communicates from one call to the next
762    how much of ARGV has been scanned so far.  */
763
764 static int optind;
765
766 /* Callers store zero here to inhibit the error message `getopt' prints
767    for unrecognized options.  */
768
769 static int opterr;
770
771 /* Set to an option character which was unrecognized.  */
772
773 static int optopt;
774
775 /* This version of `getopt' appears to the caller like standard Unix `getopt'
776    but it behaves differently for the user, since it allows the user
777    to intersperse the options with the other arguments.
778
779    As `getopt' works, it permutes the elements of ARGV so that,
780    when it is done, all the options precede everything else.  Thus
781    all application programs are extended to handle flexible argument order.
782 */
783 /*
784    If the field `flag' is not NULL, it points to a variable that is set
785    to the value given in the field `val' when the option is found, but
786    left unchanged if the option is not found.
787
788    To have a long-named option do something other than set an `int' to
789    a compiled-in constant, such as set a value from `custom_optarg', set the
790    option's `flag' field to zero and its `val' field to a nonzero
791    value (the equivalent single-letter option character, if there is
792    one).  For long options that have a zero `flag' field, `getopt'
793    returns the contents of the `val' field.  */
794
795 /* Names for the values of the `has_arg' field of `struct option'.  */
796 #ifndef no_argument
797 #define no_argument             0
798 #endif
799
800 #ifndef required_argument
801 #define required_argument       1
802 #endif
803
804 #ifndef optional_argument
805 #define optional_argument       2
806 #endif
807
808 struct custom_getopt_data {
809         /*
810          * These have exactly the same meaning as the corresponding global variables,
811          * except that they are used for the reentrant versions of getopt.
812          */
813         int custom_optind;
814         int custom_opterr;
815         int custom_optopt;
816         char *custom_optarg;
817
818         /* True if the internal members have been initialized.  */
819         int initialized;
820
821         /*
822          * The next char to be scanned in the option-element in which the last option
823          * character we returned was found.  This allows us to pick up the scan where
824          * we left off.  If this is zero, or a null string, it means resume the scan by
825          * advancing to the next ARGV-element.
826          */
827         char *nextchar;
828
829         /*
830          * Describe the part of ARGV that contains non-options that have been skipped.
831          * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is
832          * the index after the last of them.
833          */
834         int first_nonopt;
835         int last_nonopt;
836 };
837
838 /*
839  * the variables optarg, optind, opterr and optopt are renamed with
840  * the custom_ prefix so that they don't interfere with getopt ones.
841  *
842  * Moreover they're static so they are visible only from within the
843  * file where this very file will be included.
844  */
845
846 /*
847  * For communication from `custom_getopt' to the caller.  When `custom_getopt' finds an
848  * option that takes an argument, the argument value is returned here.
849  */
850 static char *custom_optarg;
851
852 /*
853  * Index in ARGV of the next element to be scanned.  This is used for
854  * communication to and from the caller and for communication between
855  * successive calls to `custom_getopt'.
856  *
857  * On entry to `custom_getopt', 1 means this is the first call; initialize.
858  *
859  * When `custom_getopt' returns -1, this is the index of the first of the non-option
860  * elements that the caller should itself scan.
861  *
862  * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV
863  * has been scanned so far.
864  *
865  * 1003.2 says this must be 1 before any call.
866  */
867 static int custom_optind = 1;
868
869 /*
870  * Callers store zero here to inhibit the error message for unrecognized
871  * options.
872  */
873 static int custom_opterr = 1;
874
875 /*
876  * Set to an option character which was unrecognized.  This must be initialized
877  * on some systems to avoid linking in the system's own getopt implementation.
878  */
879 static int custom_optopt = '?';
880
881 /*
882  * Exchange two adjacent subsequences of ARGV.  One subsequence is elements
883  * [first_nonopt,last_nonopt) which contains all the non-options that have been
884  * skipped so far.  The other is elements [last_nonopt,custom_optind), which contains
885  * all the options processed since those non-options were skipped.
886  * `first_nonopt' and `last_nonopt' are relocated so that they describe the new
887  * indices of the non-options in ARGV after they are moved.
888  */
889 static void exchange(char **argv, struct custom_getopt_data *d)
890 {
891         int bottom = d->first_nonopt;
892         int middle = d->last_nonopt;
893         int top = d->custom_optind;
894         char *tem;
895
896         /*
897          * Exchange the shorter segment with the far end of the longer segment.
898          * That puts the shorter segment into the right place.  It leaves the
899          * longer segment in the right place overall, but it consists of two
900          * parts that need to be swapped next.
901          */
902         while (top > middle && middle > bottom) {
903                 if (top - middle > middle - bottom) {
904                         /* Bottom segment is the short one.  */
905                         int len = middle - bottom;
906                         int i;
907
908                         /* Swap it with the top part of the top segment.  */
909                         for (i = 0; i < len; i++) {
910                                 tem = argv[bottom + i];
911                                 argv[bottom + i] =
912                                         argv[top - (middle - bottom) + i];
913                                 argv[top - (middle - bottom) + i] = tem;
914                         }
915                         /* Exclude the moved bottom segment from further swapping.  */
916                         top -= len;
917                 } else {
918                         /* Top segment is the short one.  */
919                         int len = top - middle;
920                         int i;
921
922                         /* Swap it with the bottom part of the bottom segment.  */
923                         for (i = 0; i < len; i++) {
924                                 tem = argv[bottom + i];
925                                 argv[bottom + i] = argv[middle + i];
926                                 argv[middle + i] = tem;
927                         }
928                         /* Exclude the moved top segment from further swapping.  */
929                         bottom += len;
930                 }
931         }
932         /* Update records for the slots the non-options now occupy.  */
933         d->first_nonopt += (d->custom_optind - d->last_nonopt);
934         d->last_nonopt = d->custom_optind;
935 }
936
937 /* Initialize the internal data when the first call is made.  */
938 static void custom_getopt_initialize(struct custom_getopt_data *d)
939 {
940         /*
941          * Start processing options with ARGV-element 1 (since ARGV-element 0
942          * is the program name); the sequence of previously skipped non-option
943          * ARGV-elements is empty.
944          */
945         d->first_nonopt = d->last_nonopt = d->custom_optind;
946         d->nextchar = NULL;
947         d->initialized = 1;
948 }
949
950 #define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\0')
951
952 /* return: zero: continue, nonzero: return given value to user */
953 static int shuffle_argv(int argc, char *const *argv,const struct option *longopts,
954         struct custom_getopt_data *d)
955 {
956         /*
957          * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been
958          * moved back by the user (who may also have changed the arguments).
959          */
960         if (d->last_nonopt > d->custom_optind)
961                 d->last_nonopt = d->custom_optind;
962         if (d->first_nonopt > d->custom_optind)
963                 d->first_nonopt = d->custom_optind;
964         /*
965          * If we have just processed some options following some
966          * non-options, exchange them so that the options come first.
967          */
968         if (d->first_nonopt != d->last_nonopt &&
969                         d->last_nonopt != d->custom_optind)
970                 exchange((char **) argv, d);
971         else if (d->last_nonopt != d->custom_optind)
972                 d->first_nonopt = d->custom_optind;
973         /*
974          * Skip any additional non-options and extend the range of
975          * non-options previously skipped.
976          */
977         while (d->custom_optind < argc && NONOPTION_P)
978                 d->custom_optind++;
979         d->last_nonopt = d->custom_optind;
980         /*
981          * The special ARGV-element `--' means premature end of options.  Skip
982          * it like a null option, then exchange with previous non-options as if
983          * it were an option, then skip everything else like a non-option.
984          */
985         if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], "--")) {
986                 d->custom_optind++;
987                 if (d->first_nonopt != d->last_nonopt
988                                 && d->last_nonopt != d->custom_optind)
989                         exchange((char **) argv, d);
990                 else if (d->first_nonopt == d->last_nonopt)
991                         d->first_nonopt = d->custom_optind;
992                 d->last_nonopt = argc;
993                 d->custom_optind = argc;
994         }
995         /*
996          * If we have done all the ARGV-elements, stop the scan and back over
997          * any non-options that we skipped and permuted.
998          */
999         if (d->custom_optind == argc) {
1000                 /*
1001                  * Set the next-arg-index to point at the non-options that we
1002                  * previously skipped, so the caller will digest them.
1003                  */
1004                 if (d->first_nonopt != d->last_nonopt)
1005                         d->custom_optind = d->first_nonopt;
1006                 return -1;
1007         }
1008         /*
1009          * If we have come to a non-option and did not permute it, either stop
1010          * the scan or describe it to the caller and pass it by.
1011          */
1012         if (NONOPTION_P) {
1013                 d->custom_optarg = argv[d->custom_optind++];
1014                 return 1;
1015         }
1016         /*
1017          * We have found another option-ARGV-element. Skip the initial
1018          * punctuation.
1019          */
1020         d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-'));
1021         return 0;
1022 }
1023
1024 /*
1025  * Check whether the ARGV-element is a long option.
1026  *
1027  * If there's a long option "fubar" and the ARGV-element is "-fu", consider
1028  * that an abbreviation of the long option, just like "--fu", and not "-f" with
1029  * arg "u".
1030  *
1031  * This distinction seems to be the most useful approach.
1032  *
1033  */
1034 static int check_long_opt(int argc, char *const *argv, const char *optstring,
1035                 const struct option *longopts, int *longind,
1036                 int print_errors, struct custom_getopt_data *d)
1037 {
1038         char *nameend;
1039         const struct option *p;
1040         const struct option *pfound = NULL;
1041         int exact = 0;
1042         int ambig = 0;
1043         int indfound = -1;
1044         int option_index;
1045
1046         for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++)
1047                 /* Do nothing.  */ ;
1048
1049         /* Test all long options for either exact match or abbreviated matches */
1050         for (p = longopts, option_index = 0; p->name; p++, option_index++)
1051                 if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) {
1052                         if ((unsigned int) (nameend - d->nextchar)
1053                                         == (unsigned int) strlen(p->name)) {
1054                                 /* Exact match found.  */
1055                                 pfound = p;
1056                                 indfound = option_index;
1057                                 exact = 1;
1058                                 break;
1059                         } else if (pfound == NULL) {
1060                                 /* First nonexact match found.  */
1061                                 pfound = p;
1062                                 indfound = option_index;
1063                         } else if (pfound->has_arg != p->has_arg
1064                                         || pfound->flag != p->flag
1065                                         || pfound->val != p->val)
1066                                 /* Second or later nonexact match found.  */
1067                                 ambig = 1;
1068                 }
1069         if (ambig && !exact) {
1070                 if (print_errors) {
1071                         fprintf(stderr,
1072                                 "%s: option `%s' is ambiguous\n",
1073                                 argv[0], argv[d->custom_optind]);
1074                 }
1075                 d->nextchar += strlen(d->nextchar);
1076                 d->custom_optind++;
1077                 d->custom_optopt = 0;
1078                 return '?';
1079         }
1080         if (pfound) {
1081                 option_index = indfound;
1082                 d->custom_optind++;
1083                 if (*nameend) {
1084                         if (pfound->has_arg != no_argument)
1085                                 d->custom_optarg = nameend + 1;
1086                         else {
1087                                 if (print_errors) {
1088                                         if (argv[d->custom_optind - 1][1] == '-') {
1089                                                 /* --option */
1090                                                 fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n",
1091                                                         argv[0], pfound->name);
1092                                         } else {
1093                                                 /* +option or -option */
1094                                                 fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n",
1095                                                         argv[0], argv[d->custom_optind - 1][0], pfound->name);
1096                                         }
1097
1098                                 }
1099                                 d->nextchar += strlen(d->nextchar);
1100                                 d->custom_optopt = pfound->val;
1101                                 return '?';
1102                         }
1103                 } else if (pfound->has_arg == required_argument) {
1104                         if (d->custom_optind < argc)
1105                                 d->custom_optarg = argv[d->custom_optind++];
1106                         else {
1107                                 if (print_errors) {
1108                                         fprintf(stderr,
1109                                                 "%s: option `%s' requires an argument\n",
1110                                                 argv[0],
1111                                                 argv[d->custom_optind - 1]);
1112                                 }
1113                                 d->nextchar += strlen(d->nextchar);
1114                                 d->custom_optopt = pfound->val;
1115                                 return optstring[0] == ':' ? ':' : '?';
1116                         }
1117                 }
1118                 d->nextchar += strlen(d->nextchar);
1119                 if (longind != NULL)
1120                         *longind = option_index;
1121                 if (pfound->flag) {
1122                         *(pfound->flag) = pfound->val;
1123                         return 0;
1124                 }
1125                 return pfound->val;
1126         }
1127         /*
1128          * Can't find it as a long option.  If this is not getopt_long_only, or
1129          * the option starts with '--' or is not a valid short option, then
1130          * it's an error.  Otherwise interpret it as a short option.
1131          */
1132         if (print_errors) {
1133                 if (argv[d->custom_optind][1] == '-') {
1134                         /* --option */
1135                         fprintf(stderr,
1136                                 "%s: unrecognized option `--%s'\n",
1137                                 argv[0], d->nextchar);
1138                 } else {
1139                         /* +option or -option */
1140                         fprintf(stderr,
1141                                 "%s: unrecognized option `%c%s'\n",
1142                                 argv[0], argv[d->custom_optind][0],
1143                                 d->nextchar);
1144                 }
1145         }
1146         d->nextchar = (char *) "";
1147         d->custom_optind++;
1148         d->custom_optopt = 0;
1149         return '?';
1150 }
1151
1152 static int check_short_opt(int argc, char *const *argv, const char *optstring,
1153                 int print_errors, struct custom_getopt_data *d)
1154 {
1155         char c = *d->nextchar++;
1156         char *temp = strchr(optstring, c);
1157
1158         /* Increment `custom_optind' when we start to process its last character.  */
1159         if (*d->nextchar == '\0')
1160                 ++d->custom_optind;
1161         if (!temp || c == ':') {
1162                 if (print_errors)
1163                         fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c);
1164
1165                 d->custom_optopt = c;
1166                 return '?';
1167         }
1168         if (temp[1] == ':') {
1169                 if (temp[2] == ':') {
1170                         /* This is an option that accepts an argument optionally.  */
1171                         if (*d->nextchar != '\0') {
1172                                 d->custom_optarg = d->nextchar;
1173                                 d->custom_optind++;
1174                         } else
1175                                 d->custom_optarg = NULL;
1176                         d->nextchar = NULL;
1177                 } else {
1178                         /* This is an option that requires an argument.  */
1179                         if (*d->nextchar != '\0') {
1180                                 d->custom_optarg = d->nextchar;
1181                                 /*
1182                                  * If we end this ARGV-element by taking the
1183                                  * rest as an arg, we must advance to the next
1184                                  * element now.
1185                                  */
1186                                 d->custom_optind++;
1187                         } else if (d->custom_optind == argc) {
1188                                 if (print_errors) {
1189                                         fprintf(stderr,
1190                                                 "%s: option requires an argument -- %c\n",
1191                                                 argv[0], c);
1192                                 }
1193                                 d->custom_optopt = c;
1194                                 if (optstring[0] == ':')
1195                                         c = ':';
1196                                 else
1197                                         c = '?';
1198                         } else
1199                                 /*
1200                                  * We already incremented `custom_optind' once;
1201                                  * increment it again when taking next ARGV-elt
1202                                  * as argument.
1203                                  */
1204                                 d->custom_optarg = argv[d->custom_optind++];
1205                         d->nextchar = NULL;
1206                 }
1207         }
1208         return c;
1209 }
1210
1211 /*
1212  * Scan elements of ARGV for option characters given in OPTSTRING.
1213  *
1214  * If an element of ARGV starts with '-', and is not exactly "-" or "--",
1215  * then it is an option element.  The characters of this element
1216  * (aside from the initial '-') are option characters.  If `getopt'
1217  * is called repeatedly, it returns successively each of the option characters
1218  * from each of the option elements.
1219  *
1220  * If `getopt' finds another option character, it returns that character,
1221  * updating `custom_optind' and `nextchar' so that the next call to `getopt' can
1222  * resume the scan with the following option character or ARGV-element.
1223  *
1224  * If there are no more option characters, `getopt' returns -1.
1225  * Then `custom_optind' is the index in ARGV of the first ARGV-element
1226  * that is not an option.  (The ARGV-elements have been permuted
1227  * so that those that are not options now come last.)
1228  *
1229  * OPTSTRING is a string containing the legitimate option characters.
1230  * If an option character is seen that is not listed in OPTSTRING,
1231  * return '?' after printing an error message.  If you set `custom_opterr' to
1232  * zero, the error message is suppressed but we still return '?'.
1233  *
1234  * If a char in OPTSTRING is followed by a colon, that means it wants an arg,
1235  * so the following text in the same ARGV-element, or the text of the following
1236  * ARGV-element, is returned in `custom_optarg'.  Two colons mean an option that
1237  * wants an optional arg; if there is text in the current ARGV-element,
1238  * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero.
1239  *
1240  * If OPTSTRING starts with `-' or `+', it requests different methods of
1241  * handling the non-option ARGV-elements.
1242  * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
1243  *
1244  * Long-named options begin with `--' instead of `-'.
1245  * Their names may be abbreviated as long as the abbreviation is unique
1246  * or is an exact match for some defined option.  If they have an
1247  * argument, it follows the option name in the same ARGV-element, separated
1248  * from the option name by a `=', or else the in next ARGV-element.
1249  * When `getopt' finds a long-named option, it returns 0 if that option's
1250  * `flag' field is nonzero, the value of the option's `val' field
1251  * if the `flag' field is zero.
1252  *
1253  * The elements of ARGV aren't really const, because we permute them.
1254  * But we pretend they're const in the prototype to be compatible
1255  * with other systems.
1256  *
1257  * LONGOPTS is a vector of `struct option' terminated by an
1258  * element containing a name which is zero.
1259  *
1260  * LONGIND returns the index in LONGOPT of the long-named option found.
1261  * It is only valid when a long-named option has been found by the most
1262  * recent call.
1263  *
1264  * Return the option character from OPTS just read.  Return -1 when there are
1265  * no more options.  For unrecognized options, or options missing arguments,
1266  * `custom_optopt' is set to the option letter, and '?' is returned.
1267  *
1268  * The OPTS string is a list of characters which are recognized option letters,
1269  * optionally followed by colons, specifying that that letter takes an
1270  * argument, to be placed in `custom_optarg'.
1271  *
1272  * If a letter in OPTS is followed by two colons, its argument is optional.
1273  * This behavior is specific to the GNU `getopt'.
1274  *
1275  * The argument `--' causes premature termination of argument scanning,
1276  * explicitly telling `getopt' that there are no more options.  If OPTS begins
1277  * with `--', then non-option arguments are treated as arguments to the option
1278  * '\0'.  This behavior is specific to the GNU `getopt'.
1279  */
1280
1281 static int getopt_internal_r(int argc, char *const *argv, const char *optstring,
1282                 const struct option *longopts, int *longind,
1283                 struct custom_getopt_data *d)
1284 {
1285         int ret, print_errors = d->custom_opterr;
1286
1287         if (optstring[0] == ':')
1288                 print_errors = 0;
1289         if (argc < 1)
1290                 return -1;
1291         d->custom_optarg = NULL;
1292
1293         /* 
1294          * This is a big difference with GNU getopt, since optind == 0
1295          * means initialization while here 1 means first call.
1296          */
1297         if (d->custom_optind == 0 || !d->initialized) {
1298                 if (d->custom_optind == 0)
1299                         d->custom_optind = 1;   /* Don't scan ARGV[0], the program name.  */
1300                 custom_getopt_initialize(d);
1301         }
1302         if (d->nextchar == NULL || *d->nextchar == '\0') {
1303                 ret = shuffle_argv(argc, argv, longopts, d);
1304                 if (ret)
1305                         return ret;
1306         }
1307         if (longopts && (argv[d->custom_optind][1] == '-' ))
1308                 return check_long_opt(argc, argv, optstring, longopts,
1309                         longind, print_errors, d);
1310         return check_short_opt(argc, argv, optstring, print_errors, d);
1311 }
1312
1313 static int custom_getopt_internal(int argc, char *const *argv, const char *optstring,
1314         const struct option *longopts, int *longind)
1315 {
1316         int result;
1317         /* Keep a global copy of all internal members of d */
1318         static struct custom_getopt_data d;
1319
1320         d.custom_optind = custom_optind;
1321         d.custom_opterr = custom_opterr;
1322         result = getopt_internal_r(argc, argv, optstring, longopts,
1323                 longind, &d);
1324         custom_optind = d.custom_optind;
1325         custom_optarg = d.custom_optarg;
1326         custom_optopt = d.custom_optopt;
1327         return result;
1328 }
1329
1330 static int custom_getopt_long (int argc, char *const *argv, const char *options,
1331         const struct option *long_options, int *opt_index)
1332 {
1333         return custom_getopt_internal(argc, argv, options, long_options,
1334                 opt_index);
1335 }
1336
1337
1338 static char *package_name = 0;
1339
1340 /**
1341  * @brief updates an option
1342  * @param field the generic pointer to the field to update
1343  * @param orig_field the pointer to the orig field
1344  * @param field_given the pointer to the number of occurrence of this option
1345  * @param prev_given the pointer to the number of occurrence already seen
1346  * @param value the argument for this option (if null no arg was specified)
1347  * @param possible_values the possible values for this option (if specified)
1348  * @param default_value the default value (in case the option only accepts fixed values)
1349  * @param arg_type the type of this option
1350  * @param check_ambiguity @see cmdline_parser_clitkRegionGrowing_params.check_ambiguity
1351  * @param override @see cmdline_parser_clitkRegionGrowing_params.override
1352  * @param no_free whether to free a possible previous value
1353  * @param multiple_option whether this is a multiple option
1354  * @param long_opt the corresponding long option
1355  * @param short_opt the corresponding short option (or '-' if none)
1356  * @param additional_error possible further error specification
1357  */
1358 static
1359 int update_arg(void *field, char **orig_field,
1360                unsigned int *field_given, unsigned int *prev_given, 
1361                char *value, char *possible_values[], const char *default_value,
1362                cmdline_parser_clitkRegionGrowing_arg_type arg_type,
1363                int check_ambiguity, int override,
1364                int no_free, int multiple_option,
1365                const char *long_opt, char short_opt,
1366                const char *additional_error)
1367 {
1368   char *stop_char = 0;
1369   const char *val = value;
1370   int found;
1371   char **string_field;
1372
1373   stop_char = 0;
1374   found = 0;
1375
1376   if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given)))
1377     {
1378       if (short_opt != '-')
1379         fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", 
1380                package_name, long_opt, short_opt,
1381                (additional_error ? additional_error : ""));
1382       else
1383         fprintf (stderr, "%s: `--%s' option given more than once%s\n", 
1384                package_name, long_opt,
1385                (additional_error ? additional_error : ""));
1386       return 1; /* failure */
1387     }
1388
1389     
1390   if (field_given && *field_given && ! override)
1391     return 0;
1392   if (prev_given)
1393     (*prev_given)++;
1394   if (field_given)
1395     (*field_given)++;
1396   if (possible_values)
1397     val = possible_values[found];
1398
1399   switch(arg_type) {
1400   case ARG_FLAG:
1401     *((int *)field) = !*((int *)field);
1402     break;
1403   case ARG_INT:
1404     if (val) *((int *)field) = strtol (val, &stop_char, 0);
1405     break;
1406   case ARG_DOUBLE:
1407     if (val) *((double *)field) = strtod (val, &stop_char);
1408     break;
1409   case ARG_STRING:
1410     if (val) {
1411       string_field = (char **)field;
1412       if (!no_free && *string_field)
1413         free (*string_field); /* free previous string */
1414       *string_field = gengetopt_strdup (val);
1415     }
1416     break;
1417   default:
1418     break;
1419   };
1420
1421   /* check numeric conversion */
1422   switch(arg_type) {
1423   case ARG_INT:
1424   case ARG_DOUBLE:
1425     if (val && !(stop_char && *stop_char == '\0')) {
1426       fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val);
1427       return 1; /* failure */
1428     }
1429     break;
1430   default:
1431     ;
1432   };
1433
1434   /* store the original value */
1435   switch(arg_type) {
1436   case ARG_NO:
1437   case ARG_FLAG:
1438     break;
1439   default:
1440     if (value && orig_field) {
1441       if (no_free) {
1442         *orig_field = value;
1443       } else {
1444         if (*orig_field)
1445           free (*orig_field); /* free previous string */
1446         *orig_field = gengetopt_strdup (value);
1447       }
1448     }
1449   };
1450
1451   return 0; /* OK */
1452 }
1453
1454 /**
1455  * @brief store information about a multiple option in a temporary list
1456  * @param list where to (temporarily) store multiple options
1457  */
1458 static
1459 int update_multiple_arg_temp(struct generic_list **list,
1460                unsigned int *prev_given, const char *val,
1461                char *possible_values[], const char *default_value,
1462                cmdline_parser_clitkRegionGrowing_arg_type arg_type,
1463                const char *long_opt, char short_opt,
1464                const char *additional_error)
1465 {
1466   char *multi_token, *multi_next; /* store single arguments */
1467
1468   if (arg_type == ARG_NO) {
1469     (*prev_given)++;
1470     return 0; /* OK */
1471   }
1472
1473   multi_token = get_multiple_arg_token(val);
1474   multi_next = get_multiple_arg_token_next (val);
1475
1476   while (1)
1477     {
1478       add_node (list);
1479       if (update_arg((void *)&((*list)->arg), &((*list)->orig), 0,
1480           prev_given, multi_token, possible_values, default_value, 
1481           arg_type, 0, 1, 1, 1, long_opt, short_opt, additional_error)) {
1482         if (multi_token) free(multi_token);
1483         return 1; /* failure */
1484       }
1485
1486       if (multi_next)
1487         {
1488           multi_token = get_multiple_arg_token(multi_next);
1489           multi_next = get_multiple_arg_token_next (multi_next);
1490         }
1491       else
1492         break;
1493     }
1494
1495   return 0; /* OK */
1496 }
1497
1498 /**
1499  * @brief free the passed list (including possible string argument)
1500  */
1501 static
1502 void free_list(struct generic_list *list, short string_arg)
1503 {
1504   if (list) {
1505     struct generic_list *tmp;
1506     while (list)
1507       {
1508         tmp = list;
1509         if (string_arg && list->arg.string_arg)
1510           free (list->arg.string_arg);
1511         if (list->orig)
1512           free (list->orig);
1513         list = list->next;
1514         free (tmp);
1515       }
1516   }
1517 }
1518
1519 /**
1520  * @brief updates a multiple option starting from the passed list
1521  */
1522 static
1523 void update_multiple_arg(void *field, char ***orig_field,
1524                unsigned int field_given, unsigned int prev_given, union generic_value *default_value,
1525                cmdline_parser_clitkRegionGrowing_arg_type arg_type,
1526                struct generic_list *list)
1527 {
1528   int i;
1529   struct generic_list *tmp;
1530
1531   if (prev_given && list) {
1532     *orig_field = (char **) realloc (*orig_field, (field_given + prev_given) * sizeof (char *));
1533
1534     switch(arg_type) {
1535     case ARG_INT:
1536       *((int **)field) = (int *)realloc (*((int **)field), (field_given + prev_given) * sizeof (int)); break;
1537     case ARG_DOUBLE:
1538       *((double **)field) = (double *)realloc (*((double **)field), (field_given + prev_given) * sizeof (double)); break;
1539     case ARG_STRING:
1540       *((char ***)field) = (char **)realloc (*((char ***)field), (field_given + prev_given) * sizeof (char *)); break;
1541     default:
1542       break;
1543     };
1544     
1545     for (i = (prev_given - 1); i >= 0; --i)
1546       {
1547         tmp = list;
1548         
1549         switch(arg_type) {
1550         case ARG_INT:
1551           (*((int **)field))[i + field_given] = tmp->arg.int_arg; break;
1552         case ARG_DOUBLE:
1553           (*((double **)field))[i + field_given] = tmp->arg.double_arg; break;
1554         case ARG_STRING:
1555           (*((char ***)field))[i + field_given] = tmp->arg.string_arg; break;
1556         default:
1557           break;
1558         }        
1559         (*orig_field) [i + field_given] = list->orig;
1560         list = list->next;
1561         free (tmp);
1562       }
1563   } else { /* set the default value */
1564     if (default_value && ! field_given) {
1565       switch(arg_type) {
1566       case ARG_INT:
1567         if (! *((int **)field)) {
1568           *((int **)field) = (int *)malloc (sizeof (int));
1569           (*((int **)field))[0] = default_value->int_arg; 
1570         }
1571         break;
1572       case ARG_DOUBLE:
1573         if (! *((double **)field)) {
1574           *((double **)field) = (double *)malloc (sizeof (double));
1575           (*((double **)field))[0] = default_value->double_arg;
1576         }
1577         break;
1578       case ARG_STRING:
1579         if (! *((char ***)field)) {
1580           *((char ***)field) = (char **)malloc (sizeof (char *));
1581           (*((char ***)field))[0] = gengetopt_strdup(default_value->string_arg);
1582         }
1583         break;
1584       default: break;
1585       }
1586       if (!(*orig_field)) {
1587         *orig_field = (char **) malloc (sizeof (char *));
1588         (*orig_field)[0] = NULL;
1589       }
1590     }
1591   }
1592 }
1593
1594 int
1595 cmdline_parser_clitkRegionGrowing_internal (int argc, char * const *argv, struct args_info_clitkRegionGrowing *args_info,
1596                         struct cmdline_parser_clitkRegionGrowing_params *params, const char *additional_error)
1597 {
1598   int c;        /* Character of the parsed option.  */
1599   union generic_value multiple_default_value;
1600
1601   struct generic_list * seed_list = NULL;
1602   struct generic_list * seedRadius_list = NULL;
1603   struct generic_list * radius_list = NULL;
1604   int error = 0;
1605   struct args_info_clitkRegionGrowing local_args_info;
1606   
1607   int override;
1608   int initialize;
1609   int check_required;
1610   int check_ambiguity;
1611   
1612   package_name = argv[0];
1613   
1614   override = params->override;
1615   initialize = params->initialize;
1616   check_required = params->check_required;
1617   check_ambiguity = params->check_ambiguity;
1618
1619   if (initialize)
1620     cmdline_parser_clitkRegionGrowing_init (args_info);
1621
1622   cmdline_parser_clitkRegionGrowing_init (&local_args_info);
1623
1624   optarg = 0;
1625   optind = 0;
1626   opterr = params->print_errors;
1627   optopt = '?';
1628
1629   while (1)
1630     {
1631       int option_index = 0;
1632
1633       static struct option long_options[] = {
1634         { "help",       0, NULL, 'h' },
1635         { "version",    0, NULL, 'V' },
1636         { "config",     1, NULL, 0 },
1637         { "verbose",    0, NULL, 'v' },
1638         { "input",      1, NULL, 'i' },
1639         { "output",     1, NULL, 'o' },
1640         { "type",       1, NULL, 't' },
1641         { "lower",      1, NULL, 'l' },
1642         { "upper",      1, NULL, 'u' },
1643         { "maxUpper",   1, NULL, 0 },
1644         { "minLower",   1, NULL, 0 },
1645         { "step",       1, NULL, 0 },
1646         { "minStep",    1, NULL, 0 },
1647         { "adaptLower", 0, NULL, 0 },
1648         { "adaptUpper", 0, NULL, 0 },
1649         { "multiplier", 1, NULL, 'm' },
1650         { "seed",       1, NULL, 's' },
1651         { "seedRadius", 1, NULL, 0 },
1652         { "pad",        1, NULL, 'p' },
1653         { "radius",     1, NULL, 'r' },
1654         { "maxSD",      1, NULL, 0 },
1655         { "full",       0, NULL, 0 },
1656         { "iter",       1, NULL, 0 },
1657         { NULL, 0, NULL, 0 }
1658       };
1659
1660       custom_optarg = optarg;
1661       custom_optind = optind;
1662       custom_opterr = opterr;
1663       custom_optopt = optopt;
1664
1665       c = custom_getopt_long (argc, argv, "hVvi:o:t:l:u:m:s:p:r:", long_options, &option_index);
1666
1667       optarg = custom_optarg;
1668       optind = custom_optind;
1669       opterr = custom_opterr;
1670       optopt = custom_optopt;
1671
1672       if (c == -1) break;       /* Exit from `while (1)' loop.  */
1673
1674       switch (c)
1675         {
1676         case 'h':       /* Print help and exit.  */
1677           cmdline_parser_clitkRegionGrowing_print_help ();
1678           cmdline_parser_clitkRegionGrowing_free (&local_args_info);
1679           exit (EXIT_SUCCESS);
1680
1681         case 'V':       /* Print version and exit.  */
1682           cmdline_parser_clitkRegionGrowing_print_version ();
1683           cmdline_parser_clitkRegionGrowing_free (&local_args_info);
1684           exit (EXIT_SUCCESS);
1685
1686         case 'v':       /* Verbose.  */
1687         
1688         
1689           if (update_arg((void *)&(args_info->verbose_flag), 0, &(args_info->verbose_given),
1690               &(local_args_info.verbose_given), optarg, 0, 0, ARG_FLAG,
1691               check_ambiguity, override, 1, 0, "verbose", 'v',
1692               additional_error))
1693             goto failure;
1694         
1695           break;
1696         case 'i':       /* Input image filename.  */
1697         
1698         
1699           if (update_arg( (void *)&(args_info->input_arg), 
1700                &(args_info->input_orig), &(args_info->input_given),
1701               &(local_args_info.input_given), optarg, 0, 0, ARG_STRING,
1702               check_ambiguity, override, 0, 0,
1703               "input", 'i',
1704               additional_error))
1705             goto failure;
1706         
1707           break;
1708         case 'o':       /* Output image filename.  */
1709         
1710         
1711           if (update_arg( (void *)&(args_info->output_arg), 
1712                &(args_info->output_orig), &(args_info->output_given),
1713               &(local_args_info.output_given), optarg, 0, 0, ARG_STRING,
1714               check_ambiguity, override, 0, 0,
1715               "output", 'o',
1716               additional_error))
1717             goto failure;
1718         
1719           break;
1720         case 't':       /* Region growing filter type: 0=threshold , 1=neighborhood-threshold , 2=confidence , 3= locally-adaptive-threshold, 4= explosion-controlled-threshold.  */
1721         
1722         
1723           if (update_arg( (void *)&(args_info->type_arg), 
1724                &(args_info->type_orig), &(args_info->type_given),
1725               &(local_args_info.type_given), optarg, 0, "0", ARG_INT,
1726               check_ambiguity, override, 0, 0,
1727               "type", 't',
1728               additional_error))
1729             goto failure;
1730         
1731           break;
1732         case 'l':       /* 1,2,3,4: Lower threshold value.  */
1733         
1734         
1735           if (update_arg( (void *)&(args_info->lower_arg), 
1736                &(args_info->lower_orig), &(args_info->lower_given),
1737               &(local_args_info.lower_given), optarg, 0, "310", ARG_DOUBLE,
1738               check_ambiguity, override, 0, 0,
1739               "lower", 'l',
1740               additional_error))
1741             goto failure;
1742         
1743           break;
1744         case 'u':       /* 1,2,3,4: Upper threshold value.  */
1745         
1746         
1747           if (update_arg( (void *)&(args_info->upper_arg), 
1748                &(args_info->upper_orig), &(args_info->upper_given),
1749               &(local_args_info.upper_given), optarg, 0, "4000", ARG_DOUBLE,
1750               check_ambiguity, override, 0, 0,
1751               "upper", 'u',
1752               additional_error))
1753             goto failure;
1754         
1755           break;
1756         case 'm':       /* 2-4: (2-3) accept if within mean+-mutiplier*SD, (4) explosion if size increases multiplier times.  */
1757         
1758         
1759           if (update_arg( (void *)&(args_info->multiplier_arg), 
1760                &(args_info->multiplier_orig), &(args_info->multiplier_given),
1761               &(local_args_info.multiplier_given), optarg, 0, "2.0", ARG_DOUBLE,
1762               check_ambiguity, override, 0, 0,
1763               "multiplier", 'm',
1764               additional_error))
1765             goto failure;
1766         
1767           break;
1768         case 's':       /* Seed index postion (in voxels).  */
1769         
1770           if (update_multiple_arg_temp(&seed_list, 
1771               &(local_args_info.seed_given), optarg, 0, "0", ARG_INT,
1772               "seed", 's',
1773               additional_error))
1774             goto failure;
1775         
1776           break;
1777         case 'p':       /* The replace padding value.  */
1778         
1779         
1780           if (update_arg( (void *)&(args_info->pad_arg), 
1781                &(args_info->pad_orig), &(args_info->pad_given),
1782               &(local_args_info.pad_given), optarg, 0, "1.0", ARG_DOUBLE,
1783               check_ambiguity, override, 0, 0,
1784               "pad", 'p',
1785               additional_error))
1786             goto failure;
1787         
1788           break;
1789         case 'r':       /* 1-3: The radius of the neighborhood.  */
1790         
1791           if (update_multiple_arg_temp(&radius_list, 
1792               &(local_args_info.radius_given), optarg, 0, "1", ARG_INT,
1793               "radius", 'r',
1794               additional_error))
1795             goto failure;
1796         
1797           break;
1798
1799         case 0: /* Long option with no short option */
1800           /* Config file.  */
1801           if (strcmp (long_options[option_index].name, "config") == 0)
1802           {
1803           
1804           
1805             if (update_arg( (void *)&(args_info->config_arg), 
1806                  &(args_info->config_orig), &(args_info->config_given),
1807                 &(local_args_info.config_given), optarg, 0, 0, ARG_STRING,
1808                 check_ambiguity, override, 0, 0,
1809                 "config", '-',
1810                 additional_error))
1811               goto failure;
1812           
1813           }
1814           /* 4: Maximum upper threshold value.  */
1815           else if (strcmp (long_options[option_index].name, "maxUpper") == 0)
1816           {
1817           
1818           
1819             if (update_arg( (void *)&(args_info->maxUpper_arg), 
1820                  &(args_info->maxUpper_orig), &(args_info->maxUpper_given),
1821                 &(local_args_info.maxUpper_given), optarg, 0, "2000", ARG_DOUBLE,
1822                 check_ambiguity, override, 0, 0,
1823                 "maxUpper", '-',
1824                 additional_error))
1825               goto failure;
1826           
1827           }
1828           /* 4: Minimum lower threshold value.  */
1829           else if (strcmp (long_options[option_index].name, "minLower") == 0)
1830           {
1831           
1832           
1833             if (update_arg( (void *)&(args_info->minLower_arg), 
1834                  &(args_info->minLower_orig), &(args_info->minLower_given),
1835                 &(local_args_info.minLower_given), optarg, 0, "-1000", ARG_DOUBLE,
1836                 check_ambiguity, override, 0, 0,
1837                 "minLower", '-',
1838                 additional_error))
1839               goto failure;
1840           
1841           }
1842           /* 4: Threshold step size.  */
1843           else if (strcmp (long_options[option_index].name, "step") == 0)
1844           {
1845           
1846           
1847             if (update_arg( (void *)&(args_info->step_arg), 
1848                  &(args_info->step_orig), &(args_info->step_given),
1849                 &(local_args_info.step_given), optarg, 0, "64.0", ARG_DOUBLE,
1850                 check_ambiguity, override, 0, 0,
1851                 "step", '-',
1852                 additional_error))
1853               goto failure;
1854           
1855           }
1856           /* 4: Minimum threshold step size.  */
1857           else if (strcmp (long_options[option_index].name, "minStep") == 0)
1858           {
1859           
1860           
1861             if (update_arg( (void *)&(args_info->minStep_arg), 
1862                  &(args_info->minStep_orig), &(args_info->minStep_given),
1863                 &(local_args_info.minStep_given), optarg, 0, "1", ARG_DOUBLE,
1864                 check_ambiguity, override, 0, 0,
1865                 "minStep", '-',
1866                 additional_error))
1867               goto failure;
1868           
1869           }
1870           /* 3,4: (locally) adapt lower thresholding.  */
1871           else if (strcmp (long_options[option_index].name, "adaptLower") == 0)
1872           {
1873           
1874           
1875             if (update_arg((void *)&(args_info->adaptLower_flag), 0, &(args_info->adaptLower_given),
1876                 &(local_args_info.adaptLower_given), optarg, 0, 0, ARG_FLAG,
1877                 check_ambiguity, override, 1, 0, "adaptLower", '-',
1878                 additional_error))
1879               goto failure;
1880           
1881           }
1882           /* 3,4: (locally) adapt upper thresholding.  */
1883           else if (strcmp (long_options[option_index].name, "adaptUpper") == 0)
1884           {
1885           
1886           
1887             if (update_arg((void *)&(args_info->adaptUpper_flag), 0, &(args_info->adaptUpper_given),
1888                 &(local_args_info.adaptUpper_given), optarg, 0, 0, ARG_FLAG,
1889                 check_ambiguity, override, 1, 0, "adaptUpper", '-',
1890                 additional_error))
1891               goto failure;
1892           
1893           }
1894           /* Radius used for seed dilatation(in voxel).  */
1895           else if (strcmp (long_options[option_index].name, "seedRadius") == 0)
1896           {
1897           
1898             if (update_multiple_arg_temp(&seedRadius_list, 
1899                 &(local_args_info.seedRadius_given), optarg, 0, "0", ARG_INT,
1900                 "seedRadius", '-',
1901                 additional_error))
1902               goto failure;
1903           
1904           }
1905           /* 3: Limit to SD.  */
1906           else if (strcmp (long_options[option_index].name, "maxSD") == 0)
1907           {
1908           
1909           
1910             if (update_arg( (void *)&(args_info->maxSD_arg), 
1911                  &(args_info->maxSD_orig), &(args_info->maxSD_given),
1912                 &(local_args_info.maxSD_given), optarg, 0, 0, ARG_DOUBLE,
1913                 check_ambiguity, override, 0, 0,
1914                 "maxSD", '-',
1915                 additional_error))
1916               goto failure;
1917           
1918           }
1919           /* 4: use full connectivity (not implemented yet).  */
1920           else if (strcmp (long_options[option_index].name, "full") == 0)
1921           {
1922           
1923           
1924             if (update_arg((void *)&(args_info->full_flag), 0, &(args_info->full_given),
1925                 &(local_args_info.full_given), optarg, 0, 0, ARG_FLAG,
1926                 check_ambiguity, override, 1, 0, "full", '-',
1927                 additional_error))
1928               goto failure;
1929           
1930           }
1931           /* 2: Iterations.  */
1932           else if (strcmp (long_options[option_index].name, "iter") == 0)
1933           {
1934           
1935           
1936             if (update_arg( (void *)&(args_info->iter_arg), 
1937                  &(args_info->iter_orig), &(args_info->iter_given),
1938                 &(local_args_info.iter_given), optarg, 0, "5", ARG_INT,
1939                 check_ambiguity, override, 0, 0,
1940                 "iter", '-',
1941                 additional_error))
1942               goto failure;
1943           
1944           }
1945           
1946           break;
1947         case '?':       /* Invalid option.  */
1948           /* `getopt_long' already printed an error message.  */
1949           goto failure;
1950
1951         default:        /* bug: option not considered.  */
1952           fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_CLITKREGIONGROWING_PACKAGE, c, (additional_error ? additional_error : ""));
1953           abort ();
1954         } /* switch */
1955     } /* while */
1956
1957
1958   update_multiple_arg((void *)&(args_info->seed_arg),
1959     &(args_info->seed_orig), args_info->seed_given,
1960     local_args_info.seed_given, 0 , 
1961     ARG_INT, seed_list);
1962   update_multiple_arg((void *)&(args_info->seedRadius_arg),
1963     &(args_info->seedRadius_orig), args_info->seedRadius_given,
1964     local_args_info.seedRadius_given, 0 , 
1965     ARG_INT, seedRadius_list);
1966   multiple_default_value.int_arg = 1;
1967   update_multiple_arg((void *)&(args_info->radius_arg),
1968     &(args_info->radius_orig), args_info->radius_given,
1969     local_args_info.radius_given, &multiple_default_value , 
1970     ARG_INT, radius_list);
1971
1972   args_info->seed_given += local_args_info.seed_given;
1973   local_args_info.seed_given = 0;
1974   args_info->seedRadius_given += local_args_info.seedRadius_given;
1975   local_args_info.seedRadius_given = 0;
1976   args_info->radius_given += local_args_info.radius_given;
1977   local_args_info.radius_given = 0;
1978   
1979   if (check_required)
1980     {
1981       error += cmdline_parser_clitkRegionGrowing_required2 (args_info, argv[0], additional_error);
1982     }
1983
1984   cmdline_parser_clitkRegionGrowing_release (&local_args_info);
1985
1986   if ( error )
1987     return (EXIT_FAILURE);
1988
1989   if (optind < argc)
1990     {
1991       int i = 0 ;
1992       int found_prog_name = 0;
1993       /* whether program name, i.e., argv[0], is in the remaining args
1994          (this may happen with some implementations of getopt,
1995           but surely not with the one included by gengetopt) */
1996
1997
1998       args_info->inputs_num = argc - optind - found_prog_name;
1999       args_info->inputs =
2000         (char **)(malloc ((args_info->inputs_num)*sizeof(char *))) ;
2001       while (optind < argc)
2002         args_info->inputs[ i++ ] = gengetopt_strdup (argv[optind++]) ;
2003     }
2004
2005   return 0;
2006
2007 failure:
2008   free_list (seed_list, 0 );
2009   free_list (seedRadius_list, 0 );
2010   free_list (radius_list, 0 );
2011   
2012   cmdline_parser_clitkRegionGrowing_release (&local_args_info);
2013   return (EXIT_FAILURE);
2014 }
2015
2016 #ifndef CONFIG_FILE_LINE_SIZE
2017 #define CONFIG_FILE_LINE_SIZE 2048
2018 #endif
2019 #define ADDITIONAL_ERROR " in configuration file "
2020
2021 #define CONFIG_FILE_LINE_BUFFER_SIZE (CONFIG_FILE_LINE_SIZE+3)
2022 /* 3 is for "--" and "=" */
2023
2024 static int
2025 _cmdline_parser_clitkRegionGrowing_configfile (char * const filename, int *my_argc)
2026 {
2027   FILE* file;
2028   char my_argv[CONFIG_FILE_LINE_BUFFER_SIZE+1];
2029   char linebuf[CONFIG_FILE_LINE_SIZE];
2030   int line_num = 0;
2031   int result = 0, equal;
2032   char *fopt, *farg;
2033   char *str_index;
2034   size_t len, next_token;
2035   char delimiter;
2036
2037   if ((file = fopen(filename, "r")) == NULL)
2038     {
2039       fprintf (stderr, "%s: Error opening configuration file '%s'\n",
2040                CMDLINE_PARSER_CLITKREGIONGROWING_PACKAGE, filename);
2041       return EXIT_FAILURE;
2042     }
2043
2044   while ((fgets(linebuf, CONFIG_FILE_LINE_SIZE, file)) != NULL)
2045     {
2046       ++line_num;
2047       my_argv[0] = '\0';
2048       len = strlen(linebuf);
2049       if (len > (CONFIG_FILE_LINE_BUFFER_SIZE-1))
2050         {
2051           fprintf (stderr, "%s:%s:%d: Line too long in configuration file\n",
2052                    CMDLINE_PARSER_CLITKREGIONGROWING_PACKAGE, filename, line_num);
2053           result = EXIT_FAILURE;
2054           break;
2055         }
2056
2057       /* find first non-whitespace character in the line */
2058       next_token = strspn (linebuf, " \t\r\n");
2059       str_index  = linebuf + next_token;
2060
2061       if ( str_index[0] == '\0' || str_index[0] == '#')
2062         continue; /* empty line or comment line is skipped */
2063
2064       fopt = str_index;
2065
2066       /* truncate fopt at the end of the first non-valid character */
2067       next_token = strcspn (fopt, " \t\r\n=");
2068
2069       if (fopt[next_token] == '\0') /* the line is over */
2070         {
2071           farg  = NULL;
2072           equal = 0;
2073           goto noarg;
2074         }
2075
2076       /* remember if equal sign is present */
2077       equal = (fopt[next_token] == '=');
2078       fopt[next_token++] = '\0';
2079
2080       /* advance pointers to the next token after the end of fopt */
2081       next_token += strspn (fopt + next_token, " \t\r\n");
2082
2083       /* check for the presence of equal sign, and if so, skip it */
2084       if ( !equal )
2085         if ((equal = (fopt[next_token] == '=')))
2086           {
2087             next_token++;
2088             next_token += strspn (fopt + next_token, " \t\r\n");
2089           }
2090       str_index  += next_token;
2091
2092       /* find argument */
2093       farg = str_index;
2094       if ( farg[0] == '\"' || farg[0] == '\'' )
2095         { /* quoted argument */
2096           str_index = strchr (++farg, str_index[0] ); /* skip opening quote */
2097           if (! str_index)
2098             {
2099               fprintf
2100                 (stderr,
2101                  "%s:%s:%d: unterminated string in configuration file\n",
2102                  CMDLINE_PARSER_CLITKREGIONGROWING_PACKAGE, filename, line_num);
2103               result = EXIT_FAILURE;
2104               break;
2105             }
2106         }
2107       else
2108         { /* read up the remaining part up to a delimiter */
2109           next_token = strcspn (farg, " \t\r\n#\'\"");
2110           str_index += next_token;
2111         }
2112
2113       /* truncate farg at the delimiter and store it for further check */
2114       delimiter = *str_index, *str_index++ = '\0';
2115
2116       /* everything but comment is illegal at the end of line */
2117       if (delimiter != '\0' && delimiter != '#')
2118         {
2119           str_index += strspn(str_index, " \t\r\n");
2120           if (*str_index != '\0' && *str_index != '#')
2121             {
2122               fprintf
2123                 (stderr,
2124                  "%s:%s:%d: malformed string in configuration file\n",
2125                  CMDLINE_PARSER_CLITKREGIONGROWING_PACKAGE, filename, line_num);
2126               result = EXIT_FAILURE;
2127               break;
2128             }
2129         }
2130
2131     noarg:
2132       if (!strcmp(fopt,"include")) {
2133         if (farg && *farg) {
2134           result = _cmdline_parser_clitkRegionGrowing_configfile(farg, my_argc);
2135         } else {
2136           fprintf(stderr, "%s:%s:%d: include requires a filename argument.\n",
2137                   CMDLINE_PARSER_CLITKREGIONGROWING_PACKAGE, filename, line_num);
2138         }
2139         continue;
2140       }
2141       len = strlen(fopt);
2142       strcat (my_argv, len > 1 ? "--" : "-");
2143       strcat (my_argv, fopt);
2144       if (len > 1 && ((farg && *farg) || equal))
2145         strcat (my_argv, "=");
2146       if (farg && *farg)
2147         strcat (my_argv, farg);
2148       ++(*my_argc);
2149
2150       cmd_line_list_tmp = (struct line_list *) malloc (sizeof (struct line_list));
2151       cmd_line_list_tmp->next = cmd_line_list;
2152       cmd_line_list = cmd_line_list_tmp;
2153       cmd_line_list->string_arg = gengetopt_strdup(my_argv);
2154     } /* while */
2155
2156   if (file)
2157     fclose(file);
2158   return result;
2159 }
2160
2161 int
2162 cmdline_parser_clitkRegionGrowing_configfile (char * const filename,
2163                            struct args_info_clitkRegionGrowing *args_info,
2164                            int override, int initialize, int check_required)
2165 {
2166   struct cmdline_parser_clitkRegionGrowing_params params;
2167
2168   params.override = override;
2169   params.initialize = initialize;
2170   params.check_required = check_required;
2171   params.check_ambiguity = 0;
2172   params.print_errors = 1;
2173   
2174   return cmdline_parser_clitkRegionGrowing_config_file (filename, args_info, &params);
2175 }
2176
2177 int
2178 cmdline_parser_clitkRegionGrowing_config_file (char * const filename,
2179                            struct args_info_clitkRegionGrowing *args_info,
2180                            struct cmdline_parser_clitkRegionGrowing_params *params)
2181 {
2182   int i, result;
2183   int my_argc = 1;
2184   char **my_argv_arg;
2185   char *additional_error;
2186
2187   /* store the program name */
2188   cmd_line_list_tmp = (struct line_list *) malloc (sizeof (struct line_list));
2189   cmd_line_list_tmp->next = cmd_line_list;
2190   cmd_line_list = cmd_line_list_tmp;
2191   cmd_line_list->string_arg = gengetopt_strdup (CMDLINE_PARSER_CLITKREGIONGROWING_PACKAGE);
2192
2193   result = _cmdline_parser_clitkRegionGrowing_configfile(filename, &my_argc);
2194
2195   if (result != EXIT_FAILURE) {
2196     my_argv_arg = (char **) malloc((my_argc+1) * sizeof(char *));
2197     cmd_line_list_tmp = cmd_line_list;
2198
2199     for (i = my_argc - 1; i >= 0; --i) {
2200       my_argv_arg[i] = cmd_line_list_tmp->string_arg;
2201       cmd_line_list_tmp = cmd_line_list_tmp->next;
2202     }
2203
2204     my_argv_arg[my_argc] = 0;
2205
2206     additional_error = (char *)malloc(strlen(filename) + strlen(ADDITIONAL_ERROR) + 1);
2207     strcpy (additional_error, ADDITIONAL_ERROR);
2208     strcat (additional_error, filename);
2209     result =
2210       cmdline_parser_clitkRegionGrowing_internal (my_argc, my_argv_arg, args_info,
2211                               params,
2212                               additional_error);
2213
2214     free (additional_error);
2215     free (my_argv_arg);
2216   }
2217
2218   free_cmd_list();
2219   if (result == EXIT_FAILURE)
2220     {
2221       cmdline_parser_clitkRegionGrowing_free (args_info);
2222       exit (EXIT_FAILURE);
2223     }
2224   
2225   return result;
2226 }