CLIte/readme-programs.txt
2025-09-02 20:26:42 +10:00

146 lines
4.4 KiB
Text

CLIte command details and API:
Commands are mostly contained in clite/commands.js and are loaded in
at runtime. Each command looks something like:
clite.commands.load('name',function(args,env,io) {
io.write("Hello World!");
return 0;
}
The load function is only available during boot time, and will:
1. load the program into the vfs at /bin/name
2. load the source of the program into the vfs at /usr/src/name.js
The function in the second argument is roughly equivalent to main() in C.
This function takes 3 arguments:
'args' is equivalent to argv in C, being an array of strings containing
the command line arguments, args[0] is the command itself, args.length
is equivalent to argc in C.
'env' contains the current environment variables: env.PWD contains the
present working directory, and so on.
'io' contains file descriptors for accessing standard input, output,
and error, as well as a method for loading in libraries:
io.stdout
file descriptor for standard output
io.stderr
file descriptor for standard error
io.stdin
file descriptor for standard input
io.exit(value)
exits the program, equivalent to the C exit() function.
A program can also be exited by returning a non-null value from
the 'main' function.
io.include('name')
Loads a library into the current scope for use. See the libs
readme file for more details.
Example Programs:
Due to the nature of javascript, it is not possible to simply stop half
way through a function to wait for user input or for some remote data
to load. Instead we have to use a callback function, which complicates
things a little, and means there are two kinds of programs: Synchronous,
and Asynchronous.
Synchronous Program:
A Synchronous program runs and then exits, with no waiting for callbacks.
As such, it looks much like a regular unix program might, and simply
returns with an exit code.
Here's a "Hello World" as an example:
clite.commands.load('hello',function(args,env,io) {
var stdio = io.include('stdio');
function main(argc,argv) {
stdio.printf("Hello World!\n");
return 0;
}
return main(args.length,args);
}
Asynchronous Program:
An Asynchronous program typically uses io calls to interact with data
that may not be immediately available; such as remotely loading file
data or reading input from a user. As such callbacks are needed to
handle that data once it is available.
Therefore a return null is used, which lets the system know it is an
asyncronous program that will exit later using the io.exit() function.
Here's a simple program that reads in a file, and prints it to stdout:
clite.commands.load('show',function(args,env,io) {
var stdlib = io.include('stdlib');
var stdio = io.include('stdio');
// file callback function that will receive the file descriptor
// once the file has data in it
function fcb(fd) {
if (!fd) {
// print an error, exit the program, then end
stdio.write(io.stderr,'could not open file\n');
io.exit(1);
return;
}
// read in the whole file in one go
var data = stdio.readAll(fd);
// close the file
stdio.close(fd);
// check there's something there
if (!data) {
// print an error, exit the program, then end
stdio.write(io.stderr,'could not read file\n');
io.exit(1);
return;
}
// write to stdout
stdio.write(io.stdout,data);
// and exit successfully
io.exit(0);
}
function main(argc,argv) {
// check there's a file to read from
if (argc != 2) {
stdio.write(io.stderr,'Specify a file to read\n');
return 1; // not asyncronous yet, so just return
}
// take the argument, and get it's full path
var file = stdlib.resolvePath(argv[1]);
// open the file, and set the callback
var fd = stdio.open(file,stdio.flags.O_RDONLY,fcb);
// we don't want to exit the program yet,
// so return null to let the system know that the
// program is asyncronous (reads user data, or loads remote data)
return null;
}
return main(args.length,args);
}
Programs written in CLIte may be compiled using the `cc' command, this
will turn a javascript source file into an excutable object. There is
currently no support for compiling programs from multiple source files,
yet. However simple single-file programs may be compiled easily, for
instance a simple hello world's source would look like this:
var stdio = io.include('stdio');
function main(argc,argv) {
stdio.printf("Hello World!\n");
return 0;
}
Which would be compiled with:
cc -o hw hw.js
The file 'hw' could then be executed from the shell.