~ubuntu-branches/ubuntu/hardy/gengetopt/hardy

« back to all changes in this revision

Viewing changes to tests/more_than_once_cmd.c.test

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2008-01-29 14:55:40 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20080129145540-bkah1bl330gpelmh
Tags: 2.22-1ubuntu1
* Merge with Debian; remaining changes:
  - Fix build failures with g++-4.3.

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
    0
36
36
};
37
37
 
 
38
typedef enum {ARG_NO
 
39
  , ARG_STRING
 
40
  , ARG_INT
 
41
} more_than_once_cmd_parser_arg_type;
 
42
 
38
43
static
39
44
void clear_given (struct gengetopt_args_info *args_info);
40
45
static
69
74
static
70
75
void init_args_info(struct gengetopt_args_info *args_info)
71
76
{
 
77
 
 
78
 
72
79
  args_info->help_help = gengetopt_args_info_help[0] ;
73
80
  args_info->version_help = gengetopt_args_info_help[1] ;
74
81
  args_info->foo_help = gengetopt_args_info_help[2] ;
82
89
  printf ("%s %s\n", MORE_THAN_ONCE_CMD_PARSER_PACKAGE, MORE_THAN_ONCE_CMD_PARSER_VERSION);
83
90
}
84
91
 
85
 
void
86
 
more_than_once_cmd_parser_print_help (void)
87
 
{
88
 
  int i = 0;
 
92
static void print_help_common(void) {
89
93
  more_than_once_cmd_parser_print_version ();
90
94
 
91
95
  if (strlen(gengetopt_args_info_purpose) > 0)
92
96
    printf("\n%s\n", gengetopt_args_info_purpose);
93
97
 
94
 
  printf("\n%s\n\n", gengetopt_args_info_usage);
 
98
  if (strlen(gengetopt_args_info_usage) > 0)
 
99
    printf("\n%s\n", gengetopt_args_info_usage);
 
100
 
 
101
  printf("\n");
95
102
 
96
103
  if (strlen(gengetopt_args_info_description) > 0)
97
104
    printf("%s\n", gengetopt_args_info_description);
 
105
}
98
106
 
 
107
void
 
108
more_than_once_cmd_parser_print_help (void)
 
109
{
 
110
  int i = 0;
 
111
  print_help_common();
99
112
  while (gengetopt_args_info_help[i])
100
113
    printf("%s\n", gengetopt_args_info_help[i++]);
101
114
}
111
124
  args_info->inputs_num = 0;
112
125
}
113
126
 
114
 
struct more_than_once_cmd_parser_params *
115
 
more_than_once_cmd_parser_params_init()
 
127
void
 
128
more_than_once_cmd_parser_params_init(struct more_than_once_cmd_parser_params *params)
116
129
{
117
 
  struct more_than_once_cmd_parser_params *params = 
118
 
    (struct more_than_once_cmd_parser_params *)malloc(sizeof(struct more_than_once_cmd_parser_params));
119
 
 
120
130
  if (params)
121
131
    { 
122
132
      params->override = 0;
123
 
      params->initialize = 0;
124
 
      params->check_required = 0;
 
133
      params->initialize = 1;
 
134
      params->check_required = 1;
125
135
      params->check_ambiguity = 0;
 
136
      params->print_errors = 1;
126
137
    }
127
 
    
 
138
}
 
139
 
 
140
struct more_than_once_cmd_parser_params *
 
141
more_than_once_cmd_parser_params_create(void)
 
142
{
 
143
  struct more_than_once_cmd_parser_params *params = 
 
144
    (struct more_than_once_cmd_parser_params *)malloc(sizeof(struct more_than_once_cmd_parser_params));
 
145
  more_than_once_cmd_parser_params_init(params);  
128
146
  return params;
129
147
}
130
148
 
131
149
static void
 
150
free_string_field (char **s)
 
151
{
 
152
  if (*s)
 
153
    {
 
154
      free (*s);
 
155
      *s = 0;
 
156
    }
 
157
}
 
158
 
 
159
 
 
160
static void
132
161
more_than_once_cmd_parser_release (struct gengetopt_args_info *args_info)
133
162
{
134
 
  
135
163
  unsigned int i;
136
 
  if (args_info->foo_orig)
137
 
    {
138
 
      free (args_info->foo_orig); /* free previous argument */
139
 
      args_info->foo_orig = 0;
140
 
    }
141
 
  if (args_info->bar_arg)
142
 
    {
143
 
      free (args_info->bar_arg); /* free previous argument */
144
 
      args_info->bar_arg = 0;
145
 
    }
146
 
  if (args_info->bar_orig)
147
 
    {
148
 
      free (args_info->bar_orig); /* free previous argument */
149
 
      args_info->bar_orig = 0;
150
 
    }
 
164
  free_string_field (&(args_info->foo_orig));
 
165
  free_string_field (&(args_info->bar_arg));
 
166
  free_string_field (&(args_info->bar_orig));
 
167
  
151
168
  
152
169
  for (i = 0; i < args_info->inputs_num; ++i)
153
170
    free (args_info->inputs [i]);
154
 
  
 
171
 
155
172
  if (args_info->inputs_num)
156
173
    free (args_info->inputs);
 
174
 
 
175
  clear_given (args_info);
 
176
}
 
177
 
 
178
 
 
179
static void
 
180
write_into_file(FILE *outfile, const char *opt, const char *arg, char *values[])
 
181
{
 
182
  if (arg) {
 
183
    fprintf(outfile, "%s=\"%s\"\n", opt, arg);
 
184
  } else {
 
185
    fprintf(outfile, "%s\n", opt);
 
186
  }
 
187
}
 
188
 
 
189
 
 
190
int
 
191
more_than_once_cmd_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info)
 
192
{
 
193
  int i = 0;
 
194
 
 
195
  if (!outfile)
 
196
    {
 
197
      fprintf (stderr, "%s: cannot dump options to stream\n", MORE_THAN_ONCE_CMD_PARSER_PACKAGE);
 
198
      return EXIT_FAILURE;
 
199
    }
 
200
 
 
201
  if (args_info->help_given)
 
202
    write_into_file(outfile, "help", 0, 0 );
 
203
  if (args_info->version_given)
 
204
    write_into_file(outfile, "version", 0, 0 );
 
205
  if (args_info->foo_given)
 
206
    write_into_file(outfile, "foo", args_info->foo_orig, 0);
 
207
  if (args_info->bar_given)
 
208
    write_into_file(outfile, "bar", args_info->bar_orig, 0);
157
209
  
158
 
  clear_given (args_info);
 
210
 
 
211
  i = EXIT_SUCCESS;
 
212
  return i;
159
213
}
160
214
 
161
215
int
172
226
      return EXIT_FAILURE;
173
227
    }
174
228
 
175
 
  if (args_info->help_given) {
176
 
    fprintf(outfile, "%s\n", "help");
177
 
  }
178
 
  if (args_info->version_given) {
179
 
    fprintf(outfile, "%s\n", "version");
180
 
  }
181
 
  if (args_info->foo_given) {
182
 
    if (args_info->foo_orig) {
183
 
      fprintf(outfile, "%s=\"%s\"\n", "foo", args_info->foo_orig);
184
 
    } else {
185
 
      fprintf(outfile, "%s\n", "foo");
186
 
    }
187
 
  }
188
 
  if (args_info->bar_given) {
189
 
    if (args_info->bar_orig) {
190
 
      fprintf(outfile, "%s=\"%s\"\n", "bar", args_info->bar_orig);
191
 
    } else {
192
 
      fprintf(outfile, "%s\n", "bar");
193
 
    }
194
 
  }
195
 
  
 
229
  i = more_than_once_cmd_parser_dump(outfile, args_info);
196
230
  fclose (outfile);
197
231
 
198
 
  i = EXIT_SUCCESS;
199
232
  return i;
200
233
}
201
234
 
205
238
  more_than_once_cmd_parser_release (args_info);
206
239
}
207
240
 
208
 
 
209
 
/* gengetopt_strdup() */
210
 
/* strdup.c replacement of strdup, which is not standard */
 
241
/** @brief replacement of strdup, which is not standard */
211
242
char *
212
243
gengetopt_strdup (const char *s)
213
244
{
254
285
  params.initialize = initialize;
255
286
  params.check_required = check_required;
256
287
  params.check_ambiguity = 0;
 
288
  params.print_errors = 1;
257
289
 
258
290
  result = more_than_once_cmd_parser_internal (argc, argv, args_info, &params, NULL);
259
291
 
272
304
  return EXIT_SUCCESS;
273
305
}
274
306
 
 
307
 
 
308
static char *package_name = 0;
 
309
 
 
310
/**
 
311
 * @brief updates an option
 
312
 * @param field the generic pointer to the field to update
 
313
 * @param orig_field the pointer to the orig field
 
314
 * @param field_given the pointer to the number of occurrence of this option
 
315
 * @param prev_given the pointer to the number of occurrence already seen
 
316
 * @param value the argument for this option (if null no arg was specified)
 
317
 * @param possible_values the possible values for this option (if specified)
 
318
 * @param default_value the default value (in case the option only accepts fixed values)
 
319
 * @param arg_type the type of this option
 
320
 * @param check_ambiguity @see more_than_once_cmd_parser_params.check_ambiguity
 
321
 * @param override @see more_than_once_cmd_parser_params.override
 
322
 * @param no_free whether to free a possible previous value
 
323
 * @param multiple_option whether this is a multiple option
 
324
 * @param long_opt the corresponding long option
 
325
 * @param short_opt the corresponding short option (or '-' if none)
 
326
 * @param additional_error possible further error specification
 
327
 */
 
328
static
 
329
int update_arg(void *field, char **orig_field,
 
330
               unsigned int *field_given, unsigned int *prev_given, 
 
331
               char *value, char *possible_values[], const char *default_value,
 
332
               more_than_once_cmd_parser_arg_type arg_type,
 
333
               int check_ambiguity, int override,
 
334
               int no_free, int multiple_option,
 
335
               const char *long_opt, char short_opt,
 
336
               const char *additional_error)
 
337
{
 
338
  char *stop_char = 0;
 
339
  const char *val = value;
 
340
  int found;
 
341
  char **string_field;
 
342
 
 
343
  stop_char = 0;
 
344
  found = 0;
 
345
 
 
346
  if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given)))
 
347
    {
 
348
      if (short_opt != '-')
 
349
        fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", 
 
350
               package_name, long_opt, short_opt,
 
351
               (additional_error ? additional_error : ""));
 
352
      else
 
353
        fprintf (stderr, "%s: `--%s' option given more than once%s\n", 
 
354
               package_name, long_opt,
 
355
               (additional_error ? additional_error : ""));
 
356
      return 1; /* failure */
 
357
    }
 
358
 
 
359
    
 
360
  if (field_given && *field_given && ! override)
 
361
    return 0;
 
362
  if (prev_given)
 
363
    (*prev_given)++;
 
364
  if (field_given)
 
365
    (*field_given)++;
 
366
  if (possible_values)
 
367
    val = possible_values[found];
 
368
 
 
369
  switch(arg_type) {
 
370
  case ARG_INT:
 
371
    if (val) *((int *)field) = strtol (val, &stop_char, 0);
 
372
    break;
 
373
  case ARG_STRING:
 
374
    if (val) {
 
375
      string_field = (char **)field;
 
376
      if (!no_free && *string_field)
 
377
        free (*string_field); /* free previous string */
 
378
      *string_field = gengetopt_strdup (val);
 
379
    }
 
380
    break;
 
381
  default:
 
382
    break;
 
383
  };
 
384
 
 
385
  /* check numeric conversion */
 
386
  switch(arg_type) {
 
387
  case ARG_INT:
 
388
    if (val && !(stop_char && *stop_char == '\0')) {
 
389
      fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val);
 
390
      return 1; /* failure */
 
391
    }
 
392
    break;
 
393
  default:
 
394
    ;
 
395
  };
 
396
 
 
397
  /* store the original value */
 
398
  switch(arg_type) {
 
399
  case ARG_NO:
 
400
    break;
 
401
  default:
 
402
    if (value && orig_field) {
 
403
      if (no_free) {
 
404
        *orig_field = value;
 
405
      } else {
 
406
        if (*orig_field)
 
407
          free (*orig_field); /* free previous string */
 
408
        *orig_field = gengetopt_strdup (value);
 
409
      }
 
410
    }
 
411
  };
 
412
 
 
413
  return 0; /* OK */
 
414
}
 
415
 
 
416
 
275
417
int
276
418
more_than_once_cmd_parser_internal (int argc, char * const *argv, struct gengetopt_args_info *args_info,
277
419
                        struct more_than_once_cmd_parser_params *params, const char *additional_error)
286
428
  int check_required;
287
429
  int check_ambiguity;
288
430
  
 
431
  package_name = argv[0];
 
432
  
289
433
  override = params->override;
290
434
  initialize = params->initialize;
291
435
  check_required = params->check_required;
298
442
 
299
443
  optarg = 0;
300
444
  optind = 0;
301
 
  opterr = 1;
 
445
  opterr = params->print_errors;
302
446
  optopt = '?';
303
447
 
304
448
  while (1)
305
449
    {
306
450
      int option_index = 0;
307
 
      char *stop_char;
308
451
 
309
452
      static struct option long_options[] = {
310
453
        { "help",       0, NULL, 'h' },
314
457
        { NULL, 0, NULL, 0 }
315
458
      };
316
459
 
317
 
      stop_char = 0;
318
460
      c = getopt_long (argc, argv, "hVf:b:", long_options, &option_index);
319
461
 
320
462
      if (c == -1) break;       /* Exit from `while (1)' loop.  */
332
474
          exit (EXIT_SUCCESS);
333
475
 
334
476
        case 'f':       /* foo option.  */
335
 
          if (local_args_info.foo_given || (check_ambiguity && args_info->foo_given))
336
 
            {
337
 
              fprintf (stderr, "%s: `--foo' (`-f') option given more than once%s\n", argv[0], (additional_error ? additional_error : ""));
338
 
              goto failure;
339
 
            }
340
 
          if (args_info->foo_given && ! override)
341
 
            continue;
342
 
          local_args_info.foo_given = 1;
343
 
          args_info->foo_given = 1;
344
 
          args_info->foo_arg = strtol (optarg, &stop_char, 0);
345
 
          if (!(stop_char && *stop_char == '\0')) {
346
 
            fprintf(stderr, "%s: invalid numeric value: %s\n", argv[0], optarg);
 
477
        
 
478
        
 
479
          if (update_arg( (void *)&(args_info->foo_arg), 
 
480
               &(args_info->foo_orig), &(args_info->foo_given),
 
481
              &(local_args_info.foo_given), optarg, 0, 0, ARG_INT,
 
482
              check_ambiguity, override, 0, 0,
 
483
              "foo", 'f',
 
484
              additional_error))
347
485
            goto failure;
348
 
          }
349
 
          if (args_info->foo_orig)
350
 
            free (args_info->foo_orig); /* free previous string */
351
 
          args_info->foo_orig = gengetopt_strdup (optarg);
 
486
        
352
487
          break;
353
 
 
354
488
        case 'b':       /* bar option.  */
355
 
          if (local_args_info.bar_given || (check_ambiguity && args_info->bar_given))
356
 
            {
357
 
              fprintf (stderr, "%s: `--bar' (`-b') option given more than once%s\n", argv[0], (additional_error ? additional_error : ""));
358
 
              goto failure;
359
 
            }
360
 
          if (args_info->bar_given && ! override)
361
 
            continue;
362
 
          local_args_info.bar_given = 1;
363
 
          args_info->bar_given = 1;
364
 
          if (args_info->bar_arg)
365
 
            free (args_info->bar_arg); /* free previous string */
366
 
          args_info->bar_arg = gengetopt_strdup (optarg);
367
 
          if (args_info->bar_orig)
368
 
            free (args_info->bar_orig); /* free previous string */
369
 
          args_info->bar_orig = gengetopt_strdup (optarg);
 
489
        
 
490
        
 
491
          if (update_arg( (void *)&(args_info->bar_arg), 
 
492
               &(args_info->bar_orig), &(args_info->bar_given),
 
493
              &(local_args_info.bar_given), optarg, 0, 0, ARG_STRING,
 
494
              check_ambiguity, override, 0, 0,
 
495
              "bar", 'b',
 
496
              additional_error))
 
497
            goto failure;
 
498
        
370
499
          break;
371
500
 
372
 
 
373
501
        case 0: /* Long option with no short option */
374
502
        case '?':       /* Invalid option.  */
375
503
          /* `getopt_long' already printed an error message.  */