Add API for accessing command-line arguments.

- Add process module with Process class.
- Add "arguments" and "allArguments" methods.
- Docs for same.
- Support passing additional arguments to command line.
- Add "--help" support to command line.
This commit is contained in:
Bob Nystrom
2016-01-22 07:57:26 -08:00
parent 860220869a
commit 71e2458a6c
14 changed files with 211 additions and 4 deletions

View File

@ -44,5 +44,6 @@ applications that want to embed Wren.
[libuv]: http://libuv.org
* [io](io)
* [process](process)
* [scheduler](scheduler)
* [timer](timer)

View File

@ -0,0 +1,5 @@
^title Module "process"
The process module exposes a single class for working with operating processes.
* [Process](process.html)

View File

@ -0,0 +1,38 @@
^title Process Class
The Process class lets you work with operating processes, including the
currently running one.
## Static Methods
### **allArguments**
The list of command-line arguments that were passed when the Wren process was
spawned. This includes the Wren executable itself, the path to the file being
run (if any), and any other options passed to Wren itself.
If you run:
:::bash
$ wren file.wren arg
This returns:
:::wren
System.print(Process.allArguments) //> ["wren", "file.wren", "arg"]
### **arguments**
The list of command-line arguments that were passed to your program when the
Wren process was spawned. This does not include arguments handled by Wren
itself.
If you run:
:::bash
$ wren file.wren arg
This returns:
:::wren
System.print(Process.arguments) //> ["arg"]

View File

@ -0,0 +1,74 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<title>{title} &ndash; Wren</title>
<link rel="stylesheet" type="text/css" href="../../style.css" />
<link href='//fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,400italic,700italic|Source+Code+Pro:400|Lato:400|Sanchez:400italic,400' rel='stylesheet' type='text/css'>
<!-- Tell mobile browsers we're optimized for them and they don't need to crop
the viewport. -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
</head>
<body id="top" class="module">
<header>
<div class="page">
<div class="main-column">
<h1><a href="../../">wren</a></h1>
<h2>a classy little scripting language</h2>
</div>
</div>
</header>
<div class="page">
<nav class="big">
<ul>
<li><a href="../">Modules</a></li>
<li><a href="./">process</a></li>
</ul>
<section>
<h2>process classes</h2>
<ul>
<li><a href="process.html">Process</a></li>
</ul>
</section>
</nav>
<nav class="small">
<table>
<tr>
<td><a href="../">Modules</a></td>
<td><a href="./">process</a></td>
</tr>
<tr>
<td colspan="2"><h2>process classes</h2></td>
</tr>
<tr>
<td>
<ul>
<li><a href="process.html">Process</a></li>
</ul>
</td>
<td>
<ul>
</ul>
</td>
</tr>
</table>
</nav>
<main>
<h1>{title}</h1>
{html}
</main>
</div>
<footer>
<div class="page">
<div class="main-column">
<p>Wren lives
<a href="https://github.com/munificent/wren">on GitHub</a>
&mdash; Made with &#x2764; by
<a href="http://journal.stuffwithstuff.com/">Bob Nystrom</a> and
<a href="https://github.com/munificent/wren/blob/master/AUTHORS">friends</a>.
</p>
<div class="main-column">
</div>
</footer>
</body>
</html>

View File

@ -37,6 +37,7 @@
<h2>cli</h2>
<ul>
<li><a href="io">io</a></li>
<li><a href="process">process</a></li>
<li><a href="scheduler">scheduler</a></li>
<li><a href="timer">timer</a></li>
</ul>
@ -64,6 +65,7 @@
<td>
<ul>
<li><a href="io">io</a></li>
<li><a href="process">process</a></li>
<li><a href="scheduler">scheduler</a></li>
<li><a href="timer">timer</a></li>
</ul>

View File

@ -1,22 +1,26 @@
#include <stdio.h>
#include <string.h>
#include "process.h"
#include "vm.h"
#include "wren.h"
int main(int argc, const char* argv[])
{
if (argc < 1 || argc > 2)
if (argc == 2 && strcmp(argv[1], "--help") == 0)
{
fprintf(stderr, "Usage: wren [file]\n");
return 64; // EX_USAGE.
printf("Usage: wren [file] [arguments...]\n");
printf(" --help Show command line usage\n");
return 0;
}
processSetArguments(argc, argv);
if (argc == 1)
{
runRepl();
}
else if (argc == 2)
else
{
runFile(argv[1]);
}

View File

@ -4,6 +4,7 @@
#include "modules.h"
#include "io.wren.inc"
#include "process.wren.inc"
#include "scheduler.wren.inc"
#include "timer.wren.inc"
@ -17,6 +18,7 @@ extern void fileClose(WrenVM* vm);
extern void fileDescriptor(WrenVM* vm);
extern void fileReadBytes(WrenVM* vm);
extern void fileSize(WrenVM* vm);
extern void processAllArguments(WrenVM* vm);
extern void stdinReadStart(WrenVM* vm);
extern void stdinReadStop(WrenVM* vm);
extern void schedulerCaptureMethods(WrenVM* vm);
@ -109,6 +111,11 @@ static ModuleRegistry modules[] =
STATIC_METHOD("readStop_()", stdinReadStop)
END_CLASS
END_MODULE
MODULE(process)
CLASS(Process)
STATIC_METHOD("allArguments", processAllArguments)
END_CLASS
END_MODULE
MODULE(scheduler)
CLASS(Scheduler)
STATIC_METHOD("captureMethods_()", schedulerCaptureMethods)

23
src/module/process.c Normal file
View File

@ -0,0 +1,23 @@
#include "process.h"
#include "wren.h"
int numArgs;
const char** args;
void processSetArguments(int argc, const char* argv[])
{
numArgs = argc;
args = argv;
}
void processAllArguments(WrenVM* vm)
{
wrenEnsureSlots(vm, 2);
wrenSetSlotNewList(vm, 0);
for (int i = 0; i < numArgs; i++)
{
wrenSetSlotString(vm, 1, args[i]);
wrenInsertInList(vm, 0, -1, 1);
}
}

9
src/module/process.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef process_h
#define process_h
#include "wren.h"
// Stores the command line arguments passed to the CLI.
void processSetArguments(int argc, const char* argv[]);
#endif

6
src/module/process.wren Normal file
View File

@ -0,0 +1,6 @@
class Process {
// TODO: This will need to be smarter when wren supports CLI options.
static arguments { allArguments[2..-1] }
foreign static allArguments
}

View File

@ -0,0 +1,7 @@
// Generated automatically from src/module/process.wren. Do not edit.
static const char* processModuleSource =
"class Process {\n"
" static arguments { allArguments[2..-1] }\n"
"\n"
" foreign static allArguments\n"
"}\n";

View File

@ -0,0 +1,11 @@
import "process" for Process
var args = Process.allArguments
System.print(args is List) // expect: true
System.print(args.count) // expect: 2
// Includes wren executable and file being run.
System.print(args[0].endsWith("wrend")) // expect: true
System.print(args[1]) // expect: test/process/all_arguments.wren
// TODO: Test passing additional args once we have an API to spawn a process.

View File

@ -0,0 +1,6 @@
import "process" for Process
// No additional arguments are passed to the test.
System.print(Process.arguments) // expect: []
// TODO: Test passing additional args once we have an API to spawn a process.

View File

@ -37,6 +37,10 @@
29A4273A1BDBE435001E6E22 /* wren_opt_random.wren.inc in Sources */ = {isa = PBXBuildFile; fileRef = 29A427331BDBE435001E6E22 /* wren_opt_random.wren.inc */; };
29A4273B1BDBE435001E6E22 /* wren_opt_random.wren.inc in Sources */ = {isa = PBXBuildFile; fileRef = 29A427331BDBE435001E6E22 /* wren_opt_random.wren.inc */; };
29C8A9331AB71FFF00DEC81D /* vm.c in Sources */ = {isa = PBXBuildFile; fileRef = 29C8A9311AB71FFF00DEC81D /* vm.c */; };
29D025E31C19CD1000A3BB28 /* process.c in Sources */ = {isa = PBXBuildFile; fileRef = 29D025E01C19CD1000A3BB28 /* process.c */; };
29D025E41C19CD1000A3BB28 /* process.c in Sources */ = {isa = PBXBuildFile; fileRef = 29D025E01C19CD1000A3BB28 /* process.c */; };
29D025E51C19CD1000A3BB28 /* process.wren.inc in Sources */ = {isa = PBXBuildFile; fileRef = 29D025E21C19CD1000A3BB28 /* process.wren.inc */; };
29D025E61C19CD1000A3BB28 /* process.wren.inc in Sources */ = {isa = PBXBuildFile; fileRef = 29D025E21C19CD1000A3BB28 /* process.wren.inc */; };
29DC149F1BBA2FCC008A8274 /* vm.c in Sources */ = {isa = PBXBuildFile; fileRef = 29C8A9311AB71FFF00DEC81D /* vm.c */; };
29DC14A01BBA2FD6008A8274 /* timer.c in Sources */ = {isa = PBXBuildFile; fileRef = 2901D7621B74F4050083A2C8 /* timer.c */; };
29DC14A11BBA2FEC008A8274 /* scheduler.c in Sources */ = {isa = PBXBuildFile; fileRef = 291647C21BA5EA45006142EE /* scheduler.c */; };
@ -128,6 +132,9 @@
29D009AB1B7E39A8000CE58C /* slots.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = slots.h; path = ../../test/api/slots.h; sourceTree = "<group>"; };
29D009AC1B7E39A8000CE58C /* value.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = value.c; path = ../../test/api/value.c; sourceTree = "<group>"; };
29D009AD1B7E39A8000CE58C /* value.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = value.h; path = ../../test/api/value.h; sourceTree = "<group>"; };
29D025E01C19CD1000A3BB28 /* process.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = process.c; path = ../../src/module/process.c; sourceTree = "<group>"; };
29D025E11C19CD1000A3BB28 /* process.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = process.h; path = ../../src/module/process.h; sourceTree = "<group>"; };
29D025E21C19CD1000A3BB28 /* process.wren.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = process.wren.inc; path = ../../src/module/process.wren.inc; sourceTree = "<group>"; };
29F384111BD19706002F84E0 /* io.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = io.h; path = ../../src/module/io.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -157,6 +164,9 @@
29F384111BD19706002F84E0 /* io.h */,
29729F2E1BA70A620099CA20 /* io.c */,
29729F301BA70A620099CA20 /* io.wren.inc */,
29D025E11C19CD1000A3BB28 /* process.h */,
29D025E01C19CD1000A3BB28 /* process.c */,
29D025E21C19CD1000A3BB28 /* process.wren.inc */,
291647C31BA5EA45006142EE /* scheduler.h */,
291647C21BA5EA45006142EE /* scheduler.c */,
291647CD1BA5ED26006142EE /* scheduler.wren.inc */,
@ -354,6 +364,8 @@
29A427341BDBE435001E6E22 /* wren_opt_meta.c in Sources */,
29205C9B1AB4E6430073018D /* wren_debug.c in Sources */,
29205C9D1AB4E6430073018D /* wren_utils.c in Sources */,
29D025E51C19CD1000A3BB28 /* process.wren.inc in Sources */,
29D025E31C19CD1000A3BB28 /* process.c in Sources */,
29729F311BA70A620099CA20 /* io.c in Sources */,
29A427361BDBE435001E6E22 /* wren_opt_meta.wren.inc in Sources */,
29205C9E1AB4E6430073018D /* wren_value.c in Sources */,
@ -367,6 +379,7 @@
buildActionMask = 2147483647;
files = (
29A427371BDBE435001E6E22 /* wren_opt_meta.wren.inc in Sources */,
29D025E41C19CD1000A3BB28 /* process.c in Sources */,
29729F321BA70A620099CA20 /* io.c in Sources */,
29932D541C210F8D00099DEE /* lists.c in Sources */,
291647C81BA5EC5E006142EE /* modules.c in Sources */,
@ -383,6 +396,7 @@
29DC14A71BBA301A008A8274 /* wren_utils.c in Sources */,
29DC14A81BBA301D008A8274 /* wren_value.c in Sources */,
29A4273B1BDBE435001E6E22 /* wren_opt_random.wren.inc in Sources */,
29D025E61C19CD1000A3BB28 /* process.wren.inc in Sources */,
29DC14A91BBA302F008A8274 /* wren_vm.c in Sources */,
29DC14AA1BBA3032008A8274 /* main.c in Sources */,
293D46961BB43F9900200083 /* call.c in Sources */,