a6bfa68feeecca39c8f8cac8d89daa91ac61ba66
[zilutils.git] / zilasm / main.c
1 /*
2  * main.c
3  *
4  * Copyright (C) 2015 Alexander Andrejevic <theflash AT sdf DOT lonestar DOT org>
5  * Copyright (C) 2015 Jason Self <j@jxself.org>
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>
19  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <getopt.h>
25 #include <time.h>
26 #include <ctype.h>
27
28 #include "config.h"
29
30 enum { ZVERSION = 11, ZORKID, ZSERIAL };
31
32 static struct option const long_options[] =
33 {
34     { "help",     no_argument,       NULL, 'h' },
35     { "version",  no_argument,       NULL, 'V' },
36     { "zversion", required_argument, NULL, ZVERSION },
37     { "zorkid",   required_argument, NULL, ZORKID   },
38     { "serial",   required_argument, NULL, ZSERIAL  },
39     { NULL, 0, NULL, 0 }
40
41 };
42
43 struct
44 {
45     int  zversion;     /* 0 - 8     */
46     int  zorkid;       /* 0 - 65535 */
47     char zserial[7];   /* YYMMDD    */
48 } Config;
49
50 void wrong_arg()
51 {
52     fprintf(stderr, "Try `" PACKAGE_NAME " --help' for more information.\n");
53     exit(1);
54 }
55
56 void print_version()
57 {
58     printf( PACKAGE_STRING "\n"
59             "License AGPLv3+: GNU AGPL version 3 or later\n"
60             "<http://gnu.org/licenses/agpl.html>\n"
61             "This is free software: you are free to change and redistribute it.\n"
62             "There is NO WARRANTY, to the extent permitted by law.\n"
63           );
64     exit(0);
65 }
66
67 void print_usage(int failed)
68 {
69     printf("Usage: " PACKAGE_NAME " [OPTION...] [FILES...]\n"
70            "\n"
71            "--version  Display program version and exit\n"
72            "--help     Display this help\n"
73            "\n"
74            "--zversion (accepts numbers 1 - 8, defaults to 1 if not specified)\n"
75            "--zorkid   (integer between 0 and 65535, defaults to 0 if not specified)\n"
76            "--serial   (six characters of ASCII, defaults to current date\n"
77            "            in the form YYMMDD if not specified)\n"
78           );
79     exit(failed);
80 }
81
82 void fill_zserial(void)
83 {
84     time_t t;
85     struct tm *timeinfo;
86     time (&t);
87     timeinfo = localtime(&t);
88     strftime (Config.zserial, sizeof(Config.zserial), "%y%m%d", timeinfo);
89 }
90
91 void fill_config(void)
92 {
93     Config.zversion = 6;
94     Config.zorkid   = 0;
95     fill_zserial();
96 }
97
98 void parse_intarg(int *dest, const char name[], int min, int max, int defval)
99 {
100     if (!optarg)
101     {
102         *dest = defval;
103         return;
104     }
105     int n = atoi(optarg);
106     if (n >= min && n <= max)
107     {
108         *dest = n;
109         return;
110     }
111     fprintf(stderr, "Wrong %s value %s, must be integer between %d and %d\n",
112             name, optarg, min, max);
113     wrong_arg();
114 }
115
116 void parse_zserial(void)
117 {
118     if (!optarg)
119     {
120         fill_zserial();
121         return;
122     }
123     size_t n = strlen(optarg);
124     if (n == sizeof(Config.zserial) - 1)
125     {
126         char *p = optarg;
127         while (*p && isalnum(*p))
128             p++;
129         if (!*p)    /* ..optarg contains alphanumeric only? */
130         {
131             strncpy(Config.zserial, optarg, sizeof(Config.zserial));
132             return;
133         }
134     }
135     fprintf(stderr, "Wrong zserial value %s, must be 6 ascii characters\n", optarg);
136     wrong_arg();
137 }
138
139 int main(int argc, char *argv[], char *envp[])
140 {
141     fill_config();
142
143     int opt = 0;
144     while ((opt = getopt_long (argc, argv, "hV", long_options, NULL)) != -1)
145     {
146         switch(opt)
147         {
148         case 'h'     :
149             print_usage(0);
150         case 'V'     :
151             print_version();
152         case ZVERSION:
153             parse_intarg(&Config.zversion, "zversion", 1, 8,      1);
154             break;
155         case ZORKID  :
156             parse_intarg(&Config.zorkid,   "zorkid",   0, 0xFFFF, 0);
157             break;
158         case ZSERIAL :
159             parse_zserial();
160             break;
161         default      :
162             wrong_arg();
163         }
164     }
165
166     // TODO: Everything :)
167
168     printf("Config:\n"
169            "- ZVersion: %d\n"
170            "- ZorkID:   %d\n"
171            "- ZSerial:  %s\n",
172            Config.zversion, Config.zorkid, Config.zserial
173           );
174
175     return 0;
176 }