-
Notifications
You must be signed in to change notification settings - Fork 10
/
wsx.wsf
executable file
·379 lines (299 loc) · 11.2 KB
/
wsx.wsf
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
<?xml version="1.0" encoding="utf-8" ?>
<!-- :
@echo off
setlocal
set "wsx.quiet="
timeout /t 0 >nul 2>&1 || set "wsx.quiet=/quiet"
endlocal && cscript //nologo "%~f0?.wsf" %wsx.quiet% %*
goto :EOF
: -->
<package>
<job id="wsx">
<?job error="false" debug="false" ?>
<script language="javascript"><![CDATA[
var NAME = 'WSX';
var VERSION = '1.1.2 Alpha';
]]></script>
<script language="javascript" src="./core/globals.js"></script>
<script language="javascript" src="./core/util.js"></script>
<script language="javascript" src="./core/console.js"></script>
<script language="javascript" src="./core/require.js"></script>
<script language="vbscript" src="./core/exporter.vbs"></script>
<script language="javascript" src="./core/REPL.js"></script>
<script language="javascript" src="./core/program.js"></script>
<script language="javascript"><![CDATA[
program.parseArguments();
if ( program.check ) {
program.showPseudoCode();
} else {
program.run();
}
]]></script>
<runtime>
<description><![CDATA[
# NAME
**WSX** - execute external scripts, one-liner programs or run in REPL mode
# USAGE
The CLI options supplying the program codes for execution could be infixed with the language identifier (`js` or `vbs`) supposed to be used for processing these options. See examples below.
## Usage (briefly)
Run the script file
wsx [options] scriptfile [arguments]
Run in the interactive mode
wsx [options] [/quiet]
wsx [options] [/q]
Run the one line program
wsx [options] [/begin:...] [/end:...] /e:... [arguments]
Run the program in a loop
wsx [options] /n [/begin:...] [/end:...] [/beginfile:...] [/endfile:...] [/e:...] [arguments]
wsx [options] /p [/begin:...] [/end:...] [/beginfile:...] [/endfile:...] [/e:...] [arguments]
The [options] above refers to other options not mentioned explicitly (see below).
## Usage (in details)
Be aware: the options following after the script file or after the options declaring the parts of the one-liner program are considered as the arguments of the program and will be passed respectively.
```
]]></description>
<!--
We are sure that the full usage is generated automatically from the
<named> and <unnamed> tags below and will be placed here: immediately
after the <description> section and before the <example> section. As
a result, it will become placed between two code fencings (first one
ends <description> and the second one begins <example>. So it will be
correctly rendered as the code block in markdown.
The more detailed description of the program and its internal objects
is placed within the <resource> tag that can be found at the end of the
file. This description is available by the proper command line option.
-->
<example><![CDATA[
```
]]></example>
<named
name="help"
helpstring="Print full description and exit ("/h" shortcut)"
type="simple"
required="false"
/>
<named
name="version"
helpstring="Print version information and exit"
type="simple"
required="false"
/>
<named
name="check"
helpstring="Show in pseudo-code what is assumed to be executed and exit. It MUST preface other options"
type="simple"
required="false"
/>
<!--
<named
name="compile"
helpstring="Compile and store to another file without execution"
type="simple"
required="false"
/>
-->
<named
name="quiet"
helpstring="Be quiet in the interactive mode ("/q" shortcut)"
type="simple"
required="false"
/>
<named
name="lib"
helpstring="Prepend directories to the search path for modules ("/l" shortcut)"
type="string"
required="false"
/>
<named
name="vt"
helpstring="Enable VT globally, for all outputs"
type="simple"
required="false"
/>
<named
name="use"
helpstring="Use (switch to) the language ("js" or "vbs")"
type="string"
required="false"
/>
<named
name="m"
helpstring="Load the module and import identifiers "[alias=]module[,[alias=]id,...]""
type="string"
required="false"
/>
<named
name="let"
helpstring="Assign the value: "name=value""
type="string"
required="false"
/>
<named
name="set"
helpstring="Create the object: "name=CreateObject(object)""
type="string"
required="false"
/>
<named
name="get"
helpstring="Get the object: "name=GetObject(object)""
type="string"
required="false"
/>
<named
name="re"
helpstring="Assign the regular expression: "name=regexp" or "name=/regexp/igm""
type="string"
required="false"
/>
<named
name="split"
helpstring="Split "LINE" to "FIELDS" by a pattern (string or regexp; defaults to "/\s+/")"
type="string"
required="false"
/>
<named
name="n"
helpstring="Apply a program in the loop like "while read LINE { ... }""
type="simple"
required="false"
/>
<named
name="p"
helpstring="Apply a program in the loop like "while read LINE { ... print LINE }""
type="simple"
required="false"
/>
<named
name="e"
helpstring="One line program (multiple "/e"'s supported)"
type="string"
required="false"
/>
<named
name="begin"
helpstring="The code for executing before the loop or main program"
type="string"
required="false"
/>
<named
name="end"
helpstring="The code for executing after the loop or main program"
type="string"
required="false"
/>
<named
name="beginfile"
helpstring="The code for executing before processing the input file"
type="string"
required="false"
/>
<named
name="endfile"
helpstring="The code for executing after processing the input file"
type="string"
required="false"
/>
<unnamed
name="scriptfile"
helpstring="The script file"
required="false"
/>
<!--
<named
name="@"
helpstring="Read arguments from the specified file"
type="string"
required="false"
/>
-->
<named
name="f"
helpstring="Open a file as "ascii", "unicode" or using system "default""
type="string"
required="false"
/>
<unnamed
name="arguments"
helpstring="Other arguments to be passed to the program"
required="false"
/>
</runtime>
<resource id="HELP"><![CDATA[
# DESCRIPTION
**WSX** stands for the recursive acronym **WSX Simulating eXecutable**.
It runs an external script file in the same way as it can be done traditionally via CScript or WScript with additional benefits making its usage closer to NodeJS, Perl, Python etc.
Run itself in the interactive mode. Type in the prompt any JS or VBS commands and execute them immediately. In this mode each entered line is evaluated immediately. To enable many lines executed as one you need to surround them with the double colons `::`. The first double colon turns on the multiline mode, the second one turns it off. After that everything entered will be executed.
It runs the one-liner program from CLI and apply it on inputstream and other files. The one-line program allows to estimate some code on the fly, without creating a temporary file. Writing it, you focus on the most important parts of the program implementation. Even if some implementation stuff -- like objects initialization, preliminary I/O operations etc -- are hidden off your eyes, they are still executed implicitly.
If the tool is launched with the one-liner program, everything after is assumed as a file name. Each argument is opened as a file and processed line by line until the end of file. Otherwise, if no any one-liner program is entered, the first item of the argument list is the script file and the rest of arguments are arguments for the script file. They could be everything and the script can use them accordingly its functionality.
# VARIABLES, FUNCTIONS and OBJECTS
The tool supplies set of predefined objects to make its own functionality closer to NodeJS, Rhino and other modern and powerful JavaScript engines.
For more convenience they are presented separately in the sections below.
## CommonJS
This script implements few features suggested by CommonJS extending them with WSH specialties.
* `console.log()` - display messages
* `require()` - load a JS module in RT
* `require.vbs()` - ditto for VBS (extension)
For details see these links:
* https://nodejs.org/api/console.html
* https://nodejs.org/api/modules.html
## Frequently used WSH objects
* `FSO` - The object `Scripting.FileSystemObject`
* `SHELL` - The object `WScript.Shell`
* `STDIN` - The reference to `WScript.StdIn`
* `STDOUT` - The reference to `WScript.StdOut`
* `STDERR` - The reference to `WScript.StdErr`
## General purpose objects
Functions:
* `print()`, `warn()` - Print expressions
* `sprintf()` - Format the arguments in a C-like style
* `exit(n)` - Quit this shell
* `sleep(n)` - Sleep n milliseconds
* `cmd(command)` - Run a command or DOS-session
* `exec(command, cb)` - Run a command in a child shell
(a callback can handle StdIn/StdOut/StdErr)
* `enableVT()` - Enable VT globally, for all outputs
* `clip()` - Read from or write to clipboard
Objects:
* `ERROR` - The variable keeping the last error
* `ARGV` - The CLI arguments
## Loop mode
The following objects are available when the tool is executed in the loop mode as `wsx /n /e:...` or `wsx /p /e:...`.
* `STREAM` - The reference to the stream of the current file
* `FILE` - The name of the current file
* `FILEFMT` - The format to open files
(`ascii`, `unicode` or system `default`)
* `LINE` - The current line
* `FLN` - The line number in the current file
* `LN` - The total line number
The following array is available when the split mode is turned on with the `/split:...` option.
* `FIELDS` - The array of fields
These special functions can be used in the loop mode only to cover the issue when we can't use `continue` and `break`.
* `next()` - acts as the `continue` operator
* `last()` - acts as the `break` operator
## REPL mode
The interactive mode provides the following useful properties for referencing to the history of the commands and REPL mode:
* `REPL.number` - the current line number
* `REPL.history` - the list of all commands entered in the current session
* `REPL.quiet` - the current session mode
# EXAMPLES
Count the number of lines (similar to `wc -l` in Unix).
wsx /n /endfile:"echo(FLN, FILE)" /end:"echo(LN)"
wsx /n /endfile:vbs:"echo FLN, FILE" /end:vbs:"echo LN"
wsx /use:vbs /n /endfile:"echo FLN, FILE" /end:"echo LN"
Numerate lines of each input file (similar to `cat -n` in Unix).
wsx /p /e:"LINE = LN + ':' + LINE"
wsx /let:delim=":" /p /e:vbs:"LINE = LN & delim & LINE"
Print first 5 lines (similar to `head -n 5` in Unix). Due to VBScript specifics and necessity of str-to-int conversion, the one-liner program is almost twice longer.
wsx /let:limit=5 /p /e:"LN > limit && last()"
wsx /use:vbs /let:limit=5 /begin:"limit = cint(limit)" /p /e:"if LN > limit then last"
Print last 5 lines (similar to `tail -n 5` in Unix). The example is splitted on two lines for better readability.
wsx /let:limit=5 /n /begin:"L=[]" /end:"echo(L.join('\n'))" ^
/e:"L.push(LINE); L.length > limit && L.shift()"
# AUTHORS and CONTRIBUTORS
Ildar Shaimordanov is the author maintaining the tool since 2009. This script was risen from JSCmd.js, the simple jscript file able to perform REPL. Later it evolved to wscmd.bat, the more powerful and configurable BAT+JS hybrid script creating a temporary WSF-file and executing it.
Copyright (C) 2009-2015, 2019-2024 Ildar Shaimordanov
# LICENSE
MIT
]]></resource>
</job>
</package>