-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathversion-lt.c
More file actions
148 lines (124 loc) · 3.16 KB
/
Copy pathversion-lt.c
File metadata and controls
148 lines (124 loc) · 3.16 KB
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
* Copyright 2016-2018 Gaël PORTAY <gael.portay@gmail.com>
*
* Licensed under the MIT license.
*
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#else
const char VERSION[] = __DATE__ " " __TIME__;
#endif /* HAVE_CONFIG_H */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>
#include "verrevcmp.h"
static int DEBUG = 0;
#define debug(fmt, ...) if (DEBUG) printf(fmt, ##__VA_ARGS__)
#define debug2(fmt, ...) if (DEBUG >= 2) printf(fmt, ##__VA_ARGS__)
struct options {
int equal;
int quiet;
};
static inline const char *applet(const char *arg0)
{
char *s = strrchr(arg0, '/');
if (!s)
return arg0;
return s+1;
}
void usage(FILE * f, char * const arg0)
{
fprintf(f, "Usage: %s [OPTIONS] VERS VERS_REF\n\n"
"Prints the Lower version of VERS and VERS_REF.\n\n"
"Exits success if VERS is Lower Than (lt) VERS_REF.\n\n"
"Options:\n"
" -e or --equal Lower or Equal.\n"
" -q or --quiet Quiet.\n"
" -D or --debug Turn on debug traces.\n"
" -h or --help Display this message.\n"
" -V or --version Display the version.\n"
"", applet(arg0));
}
int parse_arguments(struct options *opts, int argc, char * const argv[])
{
static const struct option long_options[] = {
{ "equal", no_argument, NULL, 'e' },
{ "quiet", no_argument, NULL, 'q' },
{ "debug", no_argument, NULL, 'D' },
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'V' },
{ NULL, no_argument, NULL, 0 }
};
for (;;) {
int option_index;
int c = getopt_long(argc, argv, "eqDhV", long_options, &option_index);
if (c == -1) {
break;
}
switch (c) {
case 'e':
opts->equal = 1;
break;
case 'q':
opts->quiet = 1;
break;
case 'D':
DEBUG++;
break;
case 'h':
usage(stdout, argv[0]);
exit(EXIT_SUCCESS);
break;
case 'V':
printf("%s\n", VERSION);
exit(EXIT_SUCCESS);
break;
case '?':
exit(EXIT_FAILURE);
break;
default:
fprintf(stderr, "Error: Illegal option code 0x%x!\n", c);
exit(EXIT_FAILURE);
}
}
return optind;
}
int main(int argc, char * const argv[])
{
int cmp, ret = EXIT_FAILURE;
static struct options options;
int argi = parse_arguments(&options, argc, argv);
if (argi < 0) {
exit(EXIT_FAILURE);
}
else if (argc - argi < 1) {
usage(stdout, argv[0]);
fprintf(stderr, "Error: Too few arguments!\n");
exit(EXIT_FAILURE);
}
else if (argc - argi > 2) {
usage(stdout, argv[0]);
fprintf(stderr, "Error: Too many arguments!\n");
exit(EXIT_FAILURE);
}
cmp = verrevcmp(argv[argi], argv[argi+1]);
debug2("verrevcmp(VERS: %s, VERS_REF: %s): %i\n", argv[argi], argv[argi+1], cmp);
if (options.equal) {
debug2("Lower or Equal\n");
ret = (cmp <= 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
else {
ret = (cmp < 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
debug("%s is%s lower%s than %s!\n",
argv[argi],
(ret == EXIT_SUCCESS) ? "" : " not",
(options.equal == 0) ? "" : " or equal",
argv[argi+1]);
if (ret == EXIT_SUCCESS && !options.quiet)
printf("%s\n", (cmp < 0) ? argv[argi] : argv[argi+1]);
return ret;
}