aboutsummaryrefslogtreecommitdiff
path: root/src/opts.c
blob: 861ef2be97d4fd9f33c5e28e0e4c50267b2d5cd2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "unalf.h"

#define OPTIONS "aefFklLon:pqstTvVd:x:"

/* uncomment to test exclude/include glob lists */
// #define DEBUG_GLOBS

static void add_exclude(const char *glob) {
	if(exclude_count == MAX_EXCLUDES)
		return;
	exclude_globs[exclude_count++] = glob;
}

#ifdef DEBUG_GLOBS
static void show_globs(void) {
	int i;

	printf("Include globs:\n");
	while(*include_globs)
		printf(" + %s\n", *include_globs++);
	printf("Exclude globs:\n");
	for(i = 0; i < exclude_count; i++)
		printf(" - %s\n", exclude_globs[i]);
	exit(0);
}
#endif

int parsenum(const char opt, const char *arg) {
	const char *p = arg;
	int result, err = 0;

	if(opts.extract_num) {
		fprintf(stderr, "%s: fatal: can't use multiple -%c arguments (try --help).\n", self, opt);
		exit(1);
	}

	for(p = arg; *p && (*p >= '0' && *p <= '9'); p++)
		;

	if(*p || p == arg) {
		err++;
	} else {
		result = atoi(arg);
		if(!result) err++;
	}

	if(err) {
		fprintf(stderr, "%s: fatal: invalid number '%s' for -%c option (try --help).\n", self, arg, opt);
		exit(1);
	}

	return result;
}

void parse_opts(int argc, char * const *argv) {
	int opt;
	char **ig;

	/* don't let getopt() print error message for us. */
	opterr = 0;

	while((opt = getopt(argc, argv, OPTIONS)) != -1) {
		switch(opt) {
			case 'a': opts.txtconv++; break;
			case 'e': opts.listonly = opts.testonly = 0; break;
			case 'k': opts.keepdot++; break;
			case 'f': opts.fixjunk++; opts.testonly = 1; opts.listonly = 0; opts.quiet = 1; break;
			case 'F': opts.force++; break;
			case 'l': opts.listonly++; opts.testonly = 0; break;
			case 'L': opts.lowercase++; break;
			case 'n': opts.extract_num = parsenum('n', optarg); break;
			case 'o': opts.overwrite++; break;
			case 'p': opts.extract_to_stdout++; opts.quiet++; break;
			case 'q': opts.quiet++; break;
			case 's': opts.split++; opts.testonly = 0; opts.listonly = 0; break;
			case 't': opts.testonly++; opts.listonly = 0; break;
			case 'T': opts.ignore_datetime = 1; break;
			case 'v': opts.listonly = 1; opts.testonly = 0; opts.verbose_list++; break;
			case 'V': puts(VERSION); exit(0); break;
			case 'd': opts.outdir = optarg; break;
			case 'x': add_exclude(optarg); break;
			default:
				fprintf(stderr, "%s: fatal: invalid option '-%c' (try -h or --help)\n", self, optopt);
				exit(1);
		}
	}

	if(optind >= argc) {
		fprintf(stderr, "%s: fatal: missing alf file argument (try -h or --help)\n", self);
		exit(1);
	}

	in_filename = argv[optind];
	if(optind < argc)
		include_globs = &argv[optind + 1]; /* might be null, that's OK */

	ig = (char **)include_globs;
	if(opts.extract_num && *ig) {
		fprintf(stderr, "%s: fatal: can't use wildcards with -n (try -h or --help)\n.", self);
		exit(1);
	}

	while(*ig) {
		if(globmatch("*.alf", *ig)) {
			fprintf(stderr, "%s: ALF files don't normally contain other ALF files, are you trying to extract/list multiple ALF files at once?\n", self);
			break;
		}
		ig++;
	}

#ifdef DEBUG_GLOBS
	show_globs();
#endif
}