changeset 239:4f1ca01db000

Fluff out hello.c to supply more example code as a skeleton for new commands, and update a chunk of code.html (much more to do there).
author Rob Landley <rob@landley.net>
date Sun, 20 Jan 2008 19:00:16 -0600
parents 630b2e12db16
children 362e7550a1c4
files scripts/genconfig.sh toys/hello.c www/code.html
diffstat 3 files changed, 113 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/genconfig.sh	Sun Jan 20 17:34:53 2008 -0600
+++ b/scripts/genconfig.sh	Sun Jan 20 19:00:16 2008 -0600
@@ -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()
--- a/toys/hello.c	Sun Jan 20 17:34:53 2008 -0600
+++ b/toys/hello.c	Sun Jan 20 19:00:16 2008 -0600
@@ -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 @@
 
 #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");
--- a/www/code.html	Sun Jan 20 17:34:53 2008 -0600
+++ b/www/code.html	Sun Jan 20 19:00:16 2008 -0600
@@ -17,25 +17,105 @@
 
 <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><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>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>
 
-<p><h2>Top level directory.</h2></p>
+<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>
 
-<p>lib: llist, getmountlist(), error_msg/error_exit, xmalloc(),
-strlcpy(), xexec(), xopen()/xread(), xgetcwd(), xabspath(), find_in_path(),
-itoa().</p>
+<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 @@
 
 <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>