Skip to content

Commit 58fcc48

Browse files
committed
sort code
1 parent df97efc commit 58fcc48

File tree

1 file changed

+95
-117
lines changed

1 file changed

+95
-117
lines changed

index.js

Lines changed: 95 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
'use strict';
2-
const isA = Array.isArray,
3-
isB = x => typeof x === 'boolean';
2+
const isA = Array.isArray;
43
/**
54
* @typedef {string} VarKey Variable name
65
* @typedef {string | boolean | string[]} VarVal Variable value
76
* @typedef {string} OptStr Option string, e.g. '--', '-o', '--option'
8-
* @typedef {OptStr | null} OptDef Option definitions, e.g. '--', '-o', '--option', or `null` to refer to the variable name
7+
* @typedef {OptStr | null} OptDef Option definitions, e.g. '--', '-o', '--option', or null to refer to the variable name
98
* @typedef {OptDef | OptDef[]} OptKit one or more option definitions
109
*
1110
* @typedef {object} VarKit Variable configuration object
1211
* @property {VarVal} def Variable **def**inition & **def**ault value (pun intended)
1312
* @property {OptKit} [set] Array of options to set the variable value
1413
* @property {OptKit} [rst] Array of options to reset the variable value
1514
*
16-
* @typedef {OptKit} HaltKit Halt options, identical to `OptKit`, for now...
15+
* @typedef {OptDef | OptDef[]} HaltKit Halt options, identical to `OptKit`, for now...
1716
* @typedef {{opt: OptStr, key: VarKey}} HaltRes
1817
* @typedef {Record<VarKey, VarKit | HaltKit>} KeyKitMap
1918
* @typedef {Record<VarKey, VarVal>} KeyValMap
@@ -23,6 +22,8 @@ const isA = Array.isArray,
2322
* @returns {boolean} Whether the parsing should continue (false) or quit (true)
2423
* @typedef {Record<OptStr, VarKey>} OptKeyMap internal type
2524
*/
25+
/** @param {OptKit} ok */
26+
const god = ok => typeof ok === 'string' ? [ok] : isA(ok) ? ok : [];
2627
/**
2728
* Command line argument parser function
2829
* @param {string[]} argv Command line arguments array
@@ -42,15 +43,19 @@ export default function parse(argv, i, req, res, err) {
4243
const hlt_ = {};
4344
/** @type {OptStr} option */
4445
let opt = '';
45-
/** @type {OptStr | null} option of an extension */
46-
let ext = null;
47-
/** @type {VarKey | undefined} key (because of using object...) */
46+
/** @type {OptStr} option of the extension */
47+
let ext = '';
48+
/** @type {VarKey | undefined} key */
4849
let key;
49-
/** @type {VarKey | undefined} key of anonymous variable */
50-
let ann;
51-
// methods
50+
/** @type {VarKey | undefined} key to set the universe variable */
51+
let suv;
52+
/** @type {boolean} set universe variable to halt (?) */
53+
let sun = false;
54+
// methodsze
55+
/** @param {string} msg @param {VarVal} [val] */
5256
const ask = (msg, val) => err({msg, i, opt, key, val});
53-
// assert(key != null)
57+
// below: assert(key != null)
58+
/** @param {VarVal} val */
5459
const set = val => {
5560
const cur = res[key];
5661
if (isA(cur)) cur.push(val); else res[key] = val;
@@ -61,136 +66,109 @@ export default function parse(argv, i, req, res, err) {
6166
};
6267
const noB = () => {
6368
const def = req[key].def;
64-
if (isB(def)) res[key] = !def; else return true;
69+
if (typeof def === 'boolean') {
70+
res[key] = !def;
71+
return false;
72+
} return true;
73+
};
74+
/** @param {string} s */
75+
const one = s => {
76+
if (key = set_[opt = s]) {
77+
if (noB()) ext = opt;
78+
} else if (key = rst_[opt]) rst();
79+
else return ask('invalid option');
80+
return false;
6581
};
6682
// prepare
6783
for (key in req) {
6884
const vk = req[key];
69-
H: {
70-
/** @type {HaltKit} */
71-
let hk;
72-
if (vk == null) hk = [key];
73-
else if (isA(vk)) hk = vk;
74-
else if (typeof vk === 'object') break H;
75-
else hk = [vk];
76-
for (const od of hk)
77-
if (od!=='--') hlt_[od||key] = key;
78-
continue;
79-
}
80-
let ok = vk.set;
85+
H: { let hk;
86+
switch (typeof vk) {
87+
case 'object':
88+
if (vk == null) hk = [key];
89+
else if (isA(vk)) hk = vk;
90+
else break H; break;
91+
case 'string': hk = [vk]; break;
92+
default: continue; }
93+
for (const o of hk) if (o!=='--') hlt_[o||key] = key; else suv = key, sun = true; // lol
94+
continue; }
8195
const def = vk.def;
82-
if (isA(def)) {
83-
res[key] = def.slice();
84-
if (ok !== undefined)
85-
for (const od of isA(ok)?ok:[ok])
86-
if (od!=='--') set_[od||key] = key; else ann = key;
87-
} else {
88-
res[key] = def;
89-
if (ok !== undefined)
90-
for (const od of isA(ok)?ok:[ok])
91-
if (od!=='--') set_[od||key] = key; // no stomach
92-
}
93-
if ((ok = vk.rst) !== undefined)
94-
for (const od of isA(ok)?ok:[ok])
95-
if (od!=='--') rst_[od||key] = key;
96+
res[key] = isA(def) ? def.slice() : def; // just rst() with known `def`
97+
for (const o of god(vk.set)) if (o!=='--') set_[o||key] = key; else suv = key, sun = false;
98+
for (const o of god(vk.rst)) if (o!=='--') rst_[o||key] = key; // ?? wanna reset around?
9699
}
97100
// process
98101
/** @type {HaltRes} */
99102
let halt = null;
100103
I: for (; i < argv.length; ++i) {
101104
const s = argv[i];
102-
// extension ~ Just bite one more thing
103-
if (ext != null) { // fact(const val = s)
104-
ext = null; // assert(opt === ext)
105-
if (key != null) { // assert(key === set_[opt])
105+
// extension ~ Just one more thing
106+
if (ext) { // fact(const val = s)
107+
ext = ''; // assert(opt === ext)
108+
if (key) { // assert(key === set_[opt])
106109
set(s);
107-
continue I;
108-
} else {
109-
if (ask('invalid option', s)) break I;
110+
continue;
110111
}
112+
if (ask('invalid option', s)) break;
111113
}
112-
// halt ~ It should be this simple, right?
113-
if (key = hlt_[s]) {
114-
opt = s;
115-
halt = {opt, key};
116-
break I;
117-
}
118-
// ordinary ~ No more dashes!
114+
// halt ~ Basic so that `i` is usable for resuming parsing
115+
if (key = hlt_[opt = s]) { ++i; halt = {opt, key}; break; }
116+
// abc
119117
if (s.length < 2 || s[0] !== '-') {
120-
opt = s;
121-
if (key = set_[opt]) {
118+
if (key = set_[opt = s]) {
122119
if (noB()) ext = opt;
123-
} else if (key = rst_[opt]) {
124-
rst();
125-
} else if (ann) {
126-
res[ann].push(opt);
127-
} else {
128-
if (ask('invalid option')) break I;
129-
}
130-
continue I;
131-
}
132-
// ultimate ~ Eat you all nom nom
133-
if (s === '--') {
134-
opt = s;
135-
if (key = ann) {
136-
const val = res[key]; // assert(isA(val))
137-
for (++i; i < argv.length; ++i) val.push(argv[i]);
138-
break I;
139-
} else {
140-
if (ask('unexpected argument')) break I;
141-
}
142-
continue I;
120+
} else if (key = rst_[opt]) rst();
121+
else if (key = suv) if (sun) { ++i; halt = {opt, key}; break; } else set(s);
122+
else if (ask('invalid option', s)) break;
123+
continue;
143124
}
144-
// --opt?val
145-
if (s[1] === '-') {
146-
const j = s.indexOf('=');
147-
// --opt val ~ Make extension
148-
if (j < 0) {
149-
opt = s;
150-
key = set_[opt]; // for the assertion
151-
ext = opt;
152-
continue I;
153-
}
154-
// --opt=val ~ Explicit assignment
155-
opt = s.slice(0, j);
156-
if (key = set_[opt]) {
157-
const val = s.slice(j + 1);
158-
if (isB(res[key])) {
159-
if (ask('Cannot assign a value to a boolean-type option', val)) break I;
160-
} else {
161-
set(val);
162-
}
163-
} else if (key = rst_[opt]) {
164-
if (ask('Cannot assign a value to a reset-type option')) break I;
165-
} else {
166-
if (ask('invalid option')) break I;
125+
// -abc
126+
if (s[1] !== '-') {
127+
// -ab ~ no extension
128+
const J = s.length - 1;
129+
for (let j = 1; j < J; ++j) {
130+
opt = '-' + s[j];
131+
if (key = set_[opt]) {
132+
if (noB()) {
133+
set(s.slice(j + 1));
134+
continue I;
135+
}
136+
} else if (key = rst_[opt]) rst();
137+
else if (ask('invalid option')) break I;
167138
}
168-
continue I;
139+
// -c ~ not universe
140+
if (one('-' + s[J])) break;
141+
continue;
169142
}
170-
// ab in -abc123 ~ Cannot make extension
171-
const J = s.length - 1;
172-
for (let j = 1; j < J; ++j) {
173-
opt = '-' + s[j];
143+
// --abc
144+
if (s.length > 2) {
145+
const k = s.indexOf('=');
146+
// --opt ~ not universe
147+
if (k < 0) if (one(s)) break; else continue;
148+
// --opt=val ~ explicit assignment
149+
opt = s.slice(0, k);
150+
const val = s.slice(k + 1);
174151
if (key = set_[opt]) {
175-
if (noB()) {
176-
set(s.slice(j + 1));
177-
continue I;
178-
}
152+
if (typeof res[key] === 'boolean') {
153+
if (ask('Cannot assign a value to a boolean-type option', val)) break;
154+
} else set(val);
179155
} else if (key = rst_[opt]) {
180-
rst();
156+
if (ask('Cannot assign a value to a reset-type option', val)) break;
181157
} else {
182-
if (ask('invalid option')) break I;
158+
if (ask('invalid option', val)) break;
183159
}
160+
continue;
161+
}
162+
// -- ~ collect all
163+
opt = '--';
164+
if (key = suv) { ++i;
165+
if (sun) { halt = {opt, key}; break; }
166+
const cur = res[key], len = argv.length;
167+
if (isA(cur)) while (i < len) cur.push(argv[i++]);
168+
else if (i < len) res[key] = argv[(i = len) - 1];
169+
break;
184170
}
185-
// c in -abc123 ~ You can't be annonymous
186-
opt = '-' + s[J];
187-
if (key = set_[opt]) {
188-
if (noB()) ext = opt;
189-
} else if (key = rst_[opt]) {
190-
rst();
191-
} else {
192-
if (ask('invalid option')) break I;
193-
}
171+
if (ask('unexpected argument')) break;
194172
}
195173
if (ext) ask('This option requires an argument'); // assertion same as above
196174
return {i, halt};

0 commit comments

Comments
 (0)