added "C++FLAGS.all" (and "OBJCFLAGS.all"); "CFLAGS.all" is still in effect
[k8jam.git] / src / option.c
blob81d2f8512a99e763b8d63e3c00aa9dd6183d2b88
1 /* coded by Ketmar // Invisible Vector (psyc://ketmar.no-ip.org/~Ketmar)
2 * Understanding is not required. Only obedience.
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, version 3 of the License ONLY.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 * option.c - command line option processing
19 #include <stddef.h>
20 #include <stdint.h>
22 #include "jam.h"
23 #include "option.h"
26 int num_cfgargs = 0;
27 char **cfgargs = NULL;
30 #define PUSH_BACK(_c) (*ress)[dpos++] = (_c)
31 #define DECODE_TUPLE(tuple,bytes) \
32 for (tmp = bytes; tmp > 0; tmp--, tuple = (tuple&0x00ffffff)<<8) \
33 PUSH_BACK((char)((tuple>>24)&0xff))
35 // returns ress length
36 static int ascii85Decode (char **ress, const char *srcs/*, int start, int length*/) {
37 static uint32_t pow85[5] = { 85*85*85*85UL, 85*85*85UL, 85*85UL, 85UL, 1UL };
38 const uint8_t *data = (const uint8_t *)srcs;
39 int len = strlen(srcs);
40 uint32_t tuple = 0;
41 int count = 0, c = 0;
42 int dpos = 0;
43 int start = 0, length = len;
44 int tmp;
46 if (start < 0) start = 0; else { len -= start; data += start; }
47 if (length < 0 || len < length) length = len;
49 if (length > 0) {
50 int xlen = 4*((length+4)/5);
51 kstringReserve(ress, xlen);
55 *ress = (char *)calloc(1, len+1);
56 for (int f = length; f > 0; --f, ++data) {
57 c = *data;
58 if (c <= ' ') continue; // skip blanks
59 switch (c) {
60 case 'z': // zero tuple
61 if (count != 0) {
62 //fprintf(stderr, "%s: z inside ascii85 5-tuple\n", file);
63 free(*ress);
64 *ress = NULL;
65 return -1;
67 PUSH_BACK('\0');
68 PUSH_BACK('\0');
69 PUSH_BACK('\0');
70 PUSH_BACK('\0');
71 break;
72 case '~': // '~>': end of sequence
73 if (f < 1 || data[1] != '>') { free(*ress); return -2; } // error
74 if (count > 0) { f = -1; break; }
75 /* fallthrough */
76 default:
77 if (c < '!' || c > 'u') {
78 //fprintf(stderr, "%s: bad character in ascii85 region: %#o\n", file, c);
79 free(*ress);
80 return -3;
82 tuple += ((uint8_t)(c-'!'))*pow85[count++];
83 if (count == 5) {
84 DECODE_TUPLE(tuple, 4);
85 count = 0;
86 tuple = 0;
88 break;
91 // write last (possibly incomplete) tuple
92 if (count-- > 0) {
93 tuple += pow85[count];
94 DECODE_TUPLE(tuple, count);
96 return dpos;
99 #undef PUSH_BACK
100 #undef DECODE_TUPLE
103 static void decodeBA (char *str, int len) {
104 char pch = 42;
106 for (int f = 0; f < len; ++f, ++str) {
107 char ch = *str;
109 ch = (ch-f-1)^pch;
110 *str = ch;
111 pch = ch;
116 static void printEC (const char *txt) {
117 char *dest;
118 int len;
120 if ((len = ascii85Decode(&dest, txt)) >= 0) {
121 decodeBA(dest, len);
122 fprintf(stderr, "%s\n", dest);
123 free(dest);
128 static int isStr85Equ (const char *txt, const char *str) {
129 char *dest;
130 int len, res = 0;
132 if ((len = ascii85Decode(&dest, txt)) >= 0) {
133 res = (strcmp(dest, str) == 0);
134 free(dest);
136 return res;
140 static int checkEGG (const char *str) {
141 if (isStr85Equ("06:]JASq", str) || isStr85Equ("0/i", str)) {
142 printEC(
143 "H8lZV&6)1>+AZ>m)Cf8;A1/cP+CnS)0OJ`X.QVcHA4^cc5r3=m1c%0D3&c263d?EV6@4&>"
144 "3DYQo;c-FcO+UJ;MOJ$TAYO@/FI]+B?C.L$>%:oPAmh:4Au)>AAU/H;ZakL2I!*!%J;(AK"
145 "NIR#5TXgZ6c'F1%^kml.JW5W8e;ql0V3fQUNfKpng6ppMf&ip-VOX@=jKl;#q\"DJ-_>jG"
146 "8#L;nm]!q;7c+hR6p;tVY#J8P$aTTK%c-OT?)<00,+q*8f&ff9a/+sbU,:`<H*[fk0o]7k"
147 "^l6nRkngc6Tl2Ngs!!P2I%KHG=7n*an'bsgn>!*8s7TLTC+^\\\"W+<=9^%Ol$1A1eR*Be"
148 "gqjEag:M0OnrC4FBY5@QZ&'HYYZ#EHs8t4$5]!22QoJ3`;-&=\\DteO$d6FBqT0E@:iu?N"
149 "a5ePUf^_uEEcjTDKfMpX/9]DFL8N-Ee;*8C5'WgbGortZuh1\\N0;/rJB6'(MSmYiS\"6+"
150 "<NK)KDV3e+Ad[@).W:%.dd'0h=!QUhghQaNNotIZGrpHr-YfEuUpsKW<^@qlZcdTDA!=?W"
151 "Yd+-^`'G8Or)<0-T&CT.i+:mJp(+/M/nLaVb#5$p2jR2<rl7\"XlngcN`mf,[4oK5JLr\\"
152 "m=X'(ue;'*1ik&/@T4*=j5t=<&/e/Q+2=((h`>>uN(#>&#i>2/ajK+=eib1coVe3'D)*75"
153 "m_h;28^M6p6*D854Jj<C^,Q8Wd\"O<)&L/=C$lUAQNN<=eTD:A6kn-=EItXSss.tAS&!;F"
154 "EsgpJTHIYNNnh'`kmX^[`*ELOHGcWbfPOT`J]A8P`=)AS;rYlR$\"-.RG440lK5:Dg?G'2"
155 "['dE=nEm1:k,,Se_=%-6Z*L^J[)EC"
157 return 1;
159 if (isStr85Equ("04Jj?B)", str)) {
160 printEC(
161 "IPaSa(`c:T,o9Bq3\\)IY++?+!-S9%P0/OkjE&f$l.OmK'Ai2;ZHn[<,6od7^8;)po:HaP"
162 "m<'+&DRS:/1L7)IA7?WI$8WKTUB2tXg>Zb$.?\"@AIAu;)6B;2_PB5M?oBPDC.F)606Z$V"
163 "=ONd6/5P*LoWKTLQ,d@&;+Ru,\\ESY*rg!l1XrhpJ:\"WKWdOg?l;=RHE:uU9C?aotBqj]"
164 "=k8cZ`rp\"ZO=GjkfD#o]Z\\=6^]+Gf&-UFthT*hN"
166 return 1;
168 if (isStr85Equ("04o69A7Tr", str)) {
169 printEC(
170 "Ag7d[&R#Ma9GVV5,S(D;De<T_+W).?,%4n+3cK=%4+0VN@6d\")E].np7l?8gF#cWF7SS_m"
171 "4@V\\nQ;h!WPD2h#@\\RY&G\\LKL=eTP<V-]U)BN^b.DffHkTPnFcCN4B;]8FCqI!p1@H*_"
172 "jHJ<%g']RG*MLqCrbP*XbNL=4D1R[;I(c*<FuesbWmSCF1jTW+rplg;9[S[7eDVl6YsjT"
174 return 1;
176 return 0;
180 int getoptions (int argc, char **argv, const char *opts, option *optv, char** targets) {
181 char *arg;
182 const char *f;
183 int i, n;
184 int optc = N_OPTS;
185 /* count cfgargs */
186 num_cfgargs = 0;
187 for (i = 0; i < argc; ++i) {
188 if (argv[i][0] == '-' && argv[i][1] == '-' && argv[i][2]) {
189 /* cfgarg */
190 ++num_cfgargs;
193 cfgargs = calloc(num_cfgargs+1, sizeof(char *));
194 num_cfgargs = 0;
195 memset((char *)optv, '\0', sizeof(*optv)*N_OPTS);
196 n = 0;
197 for (i = 0; i < argc; ++i) {
198 if (checkEGG(argv[i])) exit(1);
199 if (argv[i][0] == '-' && argv[i][1] == '-' && argv[i][2]) {
200 /* cfgarg */
201 cfgargs[num_cfgargs++] = strdup(argv[i]);
202 continue;
204 if (argv[i][0] == '-') {
205 if (!optc--) { printf("too many options (%d max)\n", N_OPTS); return -1; }
206 for (arg = &argv[i][1]; *arg; ++arg) {
207 for (f = opts; *f; ++f) if (*f == *arg) break;
208 if (!*f) { printf("invalid option: -%c\n", *arg); return -1; }
209 optv->flag = *f;
210 if (f[1] != ':') { optv++->val = "true"; }
211 else if (arg[1]) { optv++->val = &arg[1]; break; }
212 else if (++i < argc) { optv++->val = argv[i]; break; }
213 else { printf("option: -%c needs argument\n", *f); return -1; }
215 } else if (argv[i][0] != '=' && strchr(argv[i], '=')) {
216 /* something like VARNAME=.... is treated as an implicit '-s' flag */
217 if (!optc--) { printf("too many options (%d max)\n", N_OPTS); return -1; }
218 optv->flag = 's';
219 optv++->val = argv[i];
220 } else {
221 // target
222 if (n >= N_TARGETS) { printf("too many targets (%d max)\n", N_TARGETS); return -1; }
223 targets[n++] = argv[i];
226 return n;
231 * Name: getoptval() - find an option given its character
233 JAMFA_PURE const char *getoptval (option *optv, char opt, int subopt) {
234 for (int i = 0; i < N_OPTS; ++i, ++optv) if (optv->flag == opt && !subopt--) return optv->val;
235 return 0;