aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/genconfig.sh3
-rw-r--r--toys/hello.c15
-rw-r--r--www/code.html106
3 files changed, 113 insertions, 11 deletions
diff --git a/scripts/genconfig.sh b/scripts/genconfig.sh
index 59c63c5b..126e52ef 100755
--- a/scripts/genconfig.sh
+++ b/scripts/genconfig.sh
@@ -1,5 +1,8 @@
#!/bin/bash
+# This has to be a separate file from scripts/make.sh so it can be called
+# before menuconfig. (It's called again from scripts/make.sh just to be sure.)
+
mkdir -p generated
function genconfig()
diff --git a/toys/hello.c b/toys/hello.c
index a8caeefe..e5d78f6a 100644
--- a/toys/hello.c
+++ b/toys/hello.c
@@ -7,7 +7,7 @@
* Not in SUSv3.
* See http://www.opengroup.org/onlinepubs/009695399/utilities/
-USE_HELLO(NEWTOY(hello, NULL, TOYFLAG_USR|TOYFLAG_BIN))
+USE_HELLO(NEWTOY(hello, "e@d*c#b:a", TOYFLAG_USR|TOYFLAG_BIN))
config HELLO
bool "hello"
@@ -21,6 +21,19 @@ config HELLO
#include "toys.h"
+// Hello doesn't use these globals, they're here for example/skeleton purposes.
+
+DEFINE_GLOBALS(
+ char *b_string;
+ long c_number;
+ struct arg_list *d_list;
+ long e_count;
+
+ int more_globals;
+)
+
+#define TT this.hello
+
void hello_main(void)
{
printf("Hello world\n");
diff --git a/www/code.html b/www/code.html
index f92fcc77..06c777d9 100644
--- a/www/code.html
+++ b/www/code.html
@@ -17,25 +17,105 @@ to spot as overrides to the normal flow of control, which they are.</p>
<p><h1>Infrastructure:</h1></p>
-<p>The toybox source code is in three directories. The top level directory
-contains the file main.c and the header file toys.h. The "lib" directory
-contains generic functions shared by multiple commands. The "toys" directory
-contains the implementations of individual commands.</p>
+<p>The toybox source code is in following directories:</p>
+<ul>
+<li>The <a href="#top">top level directory</a> contains the file main.c (were
+execution starts), the header file toys.h (included by every command), and
+other global infrastructure.</li>
+<li>The <a href="#lib">lib directory</a> contains common functions shared by
+multiple commands.</li>
+<li>The <a href="#toys">toys directory</a> contains the C files implementating
+each command.</li>
+<li>The <a href="#scripts">scripts directory</a> contains the build and
+test infrastructure.</li>
+<li>The <a href="#kconfig">kconfig directory</a> contains the configuration
+infrastructure implementing menuconfig (copied from the Linux kernel).</li>
+<li>The <a href="#generated">generated directory</a> contains intermediate
+files generated from other parts of the source code.</li>
+</ul>
-<p><h2>Top level directory.</h2></p>
+<p><h1>Adding a new command</h1></p>
+<p>To add a new command to toybox, add a C file implementing that command to
+the toys directory. No other files need to be modified; the build extracts
+other information it needs (such as command line arguments) from specially
+formatted comments and macros in the C file. (See the description of the
+<a href="#generated">generated directory</a> for details.)</p>
-<p>lib: llist, getmountlist(), error_msg/error_exit, xmalloc(),
-strlcpy(), xexec(), xopen()/xread(), xgetcwd(), xabspath(), find_in_path(),
-itoa().</p>
+<p>An easy way to start a new command is copy the file "hello.c" to
+the name of the new command, and modify this copy to implement the new command.
+This file is a small, simple command meant to be used as a "skeleton" for
+new commands (more or less by turning every instance of "hello" into the
+name of your command, updating the command line arguments, globals, and
+help data, and then filling out its "main" function with code that does
+something interesting).</p>
+
+<p>Here's a checklist of steps to turn hello.c into another command:</p>
+
+<ul>
+<li><p>First "cd toys" and "cp hello.c yourcommand.c". Note that the name
+of this file is significant, it's the name of the new command you're adding
+to toybox. Open your new file in your favorite editor.</p></li>
+
+<li><p>Change the one line comment at the top of the file (currently
+"hello.c - A hello world program") to describe your new file.</p></li>
+
+<li><p>Change the copyright notice to your name, email, and the current
+year.</p></li>
+
+<li><p>Give a URL to the relevant standards document, or say "Not in SUSv3" if
+there is no relevant standard. (Currently both lines are there, delete
+whichever is appropriate.) The existing link goes to the directory of SUSv3
+command line utility standards on the Open Group's website, where there's often
+a relevant commandname.html file. Feel free to link to other documentation or
+standards as appropriate.</p></li>
+
+<li><p>Update the USE_YOURCOMMAND(NEWTOY(yourcommand,NULL,0)) line. This
+specifies the name used to run your command, the command line arguments (NULL
+if none), and where your command should be installed on a running system. See
+[TODO] for details.</p></li>
+
+<li><p>Change the kconfig data (from "config YOURCOMMAND" to the end of the
+comment block) to supply your command's configuration and help
+information. The uppper case config symbols are used by menuconfig, and are
+also what the CFG_ and USE_() macros are generated from (see [TODO]). The
+help information here is used by menuconfig, and also by the "help" command to
+describe your new command. (See [TODO] for details.) By convention,
+unfinished commands default to "n" and finished commands default to "y".<p></li>
+
+<li><p>Update the DEFINE_GLOBALS() macro to contain your command's global
+variables, and also change the name "hello" in the #define TT line afterwards
+to the name of your command. If your command has no global variables, delete
+this macro (and the #define TT line afterwards). Note that if you specified
+two-character command line arguments in NEWTOY(), the first few global
+variables will be initialized by the automatic argument parsing logic, and
+the type and order of these variables must correspond to the arguments
+specified in NEWTOY(). See [TODO] for details.</p></li>
+
+<li><p>Change the "#define TT this.hello" line to use your command name in
+place of the "hello". This is a shortcut to access your global variables
+as if they were members of the global struct "TT". (Access these members with
+a period ".", not a right arrow "->".)</p></li>
+
+<li><p>Rename hello_main() to yourcommand_main(). This is the main() function
+where execution off your command starts. See [TODO] to figure out what
+happened to your command line arguments and how to access them.</p></li>
+</ul>
+
+<p><a name="top" /><h2>Top level directory.</h2></p>
+
+<p>This directory contains global infrastructure.
<h3>main.c</h3>
<p>Contains the main() function where execution starts, plus
common infrastructure to initialize global variables and select which command
-to run.</p>
+to run. The "toybox" multiplexer command is also defined here. (This is the
+only command defined outside of the toys directory.)</p>
<p>Execution starts in main() which removes the path from the first command
name and calls toybox_main(), which calls toy_exec(), which calls toy_find(),
-toy_init() and the appropriate command's function from toy_list.</p>
+toy_init() and the appropriate command's function from toy_list. If
+the command is "toybox", execution returns to toybox_main(), otherwise
+the call goes to the appropriate command_main() from the toys directory.</p>
<p>The following global variables are defined here:</p>
<ul>
@@ -232,6 +312,12 @@ in toys/help.c.</p>
<h2>Directory lib/</h2>
+<p>lib: llist, getmountlist(), error_msg/error_exit, xmalloc(),
+strlcpy(), xexec(), xopen()/xread(), xgetcwd(), xabspath(), find_in_path(),
+itoa().</p>
+
+
+
<h2>Directory scripts/</h2>
<h3>scripts/cfg2files.sh</h3>