hush: support ${VAR:N:-M}
[oweals/busybox.git] / docs / new-applet-HOWTO.txt
index 2f237564d5680c846cb70ff8ff3caa5cdf864a8a..078e77bce2bcec0aa5ae1912241daf4c24d57e36 100644 (file)
@@ -6,7 +6,7 @@ This document details the steps you must take to add a new applet to BusyBox.
 Credits:
 Matt Kraai - initial writeup
 Mark Whitley - the remix
-Thomas Lundquist - Trying to keep it updated.
+Thomas Lundquist - trying to keep it updated
 
 When doing this you should consider using the latest git HEAD.
 This is a good thing if you plan to getting it committed into mainline.
@@ -16,15 +16,14 @@ Initial Write
 
 First, write your applet.  Be sure to include copyright information at the top,
 such as who you stole the code from and so forth. Also include the mini-GPL
-boilerplate. Be sure to name the main function <applet>_main instead of main.
-And be sure to put it in <applet>.c. Usage does not have to be taken care of by
-your applet.
-Make sure to #include "libbb.h" as the first include file in your applet so
-the bb_config.h and appropriate platform specific files are included properly.
+boilerplate and Config.in/Kbuild/usage/applet.h snippets (more on that below
+in this document). Be sure to name the main function <applet>_main instead
+of main. And be sure to put it in <applet>.c. Make sure to #include "libbb.h"
+as the first include file in your applet.
 
 For a new applet mu, here is the code that would go in mu.c:
 
-(busybox.h already includes most usual header files. You do not need
+(libbb.h already includes most usual header files. You do not need
 #include <stdio.h> etc...)
 
 
@@ -42,6 +41,22 @@ For a new applet mu, here is the code that would go in mu.c:
 #include "libbb.h"
 #include "other.h"
 
+//config:config MU
+//config:      bool "MU"
+//config:      default y
+//config:      help
+//config:        Returns an indeterminate value.
+
+//kbuild:lib-$(CONFIG_MU) += mu.o
+//applet:IF_MU(APPLET(mu, BB_DIR_USR_BIN, BB_SUID_DROP))
+
+//usage:#define mu_trivial_usage
+//usage:       "[-abcde] FILE..."
+//usage:#define mu_full_usage
+//usage:       "Returns an indeterminate value\n"
+//usage:     "\n       -a      First function"
+//usage:     "\n       -b      Second function"
+
 int mu_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int mu_main(int argc, char **argv)
 {
@@ -91,6 +106,8 @@ Make a new file named <function_name>.c
 #include "libbb.h"
 #include "other.h"
 
+//kbuild:lib-y += function.o
+
 int function(char *a)
 {
        return *a;
@@ -98,72 +115,78 @@ int function(char *a)
 
 ----end example code------
 
-Add <function_name>.o in the right alphabetically sorted place
-in libbb/Kbuild. You should look at the conditional part of
-libbb/Kbuild aswell.
+Remember about the kbuild snippet.
 
 You should also try to find a suitable place in include/libbb.h for
 the function declaration. If not, add it somewhere anyway, with or without
 ifdefs to include or not.
 
-You can look at libbb/Config.in and try to find out if the function is
+You can look at libbb/Config.src and try to find out if the function is
 tunable and add it there if it is.
 
 
+Kbuild/Config.in/usage/applets.h snippets in .c files
+-----------------------------------------------------
+
+The old way of adding new applets was to put all the information needed by the
+configuration and build system into appropriate files (namely: Kbuild.src and
+Config.src in new applet's directory) and to add the applet declaration and
+usage info text to include/applets.src.h and include/usage.src.h respectively.
+
+Since the scripts/gen_build_files.sh script had been introduced, the preferred
+way is to have all these declarations contained within the applet .c files.
+
+Every line intended to be processed by gen_build_files.sh should start as a
+comment without any preceding whitespaces and be followed by an appropriate
+keyword - kbuild, config, usage or applet - and a colon, just like shown in the
+first example above.
+
+
 Placement / Directory
 ---------------------
 
 Find the appropriate directory for your new applet.
 
-Make sure you find the appropriate places in the files, the applets are
-sorted alphabetically.
+Add the kbuild snippet to the .c file:
 
-Add the applet to Kbuild in the chosen directory:
+//kbuild:lib-$(CONFIG_MU) += mu.o
 
-lib-$(CONFIG_MU)               += mu.o
+Add the config snippet to the .c file:
 
-Add the applet to Config.in in the chosen directory:
-
-config MU
-       bool "MU"
-       default n
-       help
-         Returns an indeterminate value.
+//config:config MU
+//config:      bool "MU"
+//config:      default y
+//config:      help
+//config:        Returns an indeterminate value.
 
 
 Usage String(s)
 ---------------
 
-Next, add usage information for you applet to include/usage.h.
+Next, add usage information for your applet to the .c file.
 This should look like the following:
 
-       #define mu_trivial_usage \
-               "-[abcde] FILES"
-       #define mu_full_usage \
-               "Returns an indeterminate value.\n\n" \
-               "Options:\n" \
-               "\t-a\t\tfirst function\n" \
-               "\t-b\t\tsecond function\n" \
-               ...
+//usage:#define mu_trivial_usage
+//usage:       "[-abcde] FILE..."
+//usage:#define mu_full_usage
+//usage:       "Returns an indeterminate value\n"
+//usage:     "\n       -a      First function"
+//usage:     "\n       -b      Second function"
+//usage:       ...
 
 If your program supports flags, the flags should be mentioned on the first
-line (-[abcde]) and a detailed description of each flag should go in the
-mu_full_usage section, one flag per line. (Numerous examples of this
-currently exist in usage.h.)
+line ([-abcde]) and a detailed description of each flag should go in the
+mu_full_usage section, one flag per line.
 
 
 Header Files
 ------------
 
-Next, add an entry to include/applets.h.  Be *sure* to keep the list
-in alphabetical order, or else it will break the binary-search lookup
-algorithm in busybox.c and the Gods of BusyBox smite you. Yea, verily:
-
-Be sure to read the top of applets.h before adding your applet.
+Finally add the applet declaration snippet. Be sure to read the top of
+applets.src.h before adding your applet - it contains important info
+on applet macros and conventions.
 
-       /* all programs above here are alphabetically "less than" 'mu' */
-       IF_MU(APPLET(mu, _BB_DIR_USR_BIN, _BB_SUID_DROP))
-       /* all programs below here are alphabetically "greater than" 'mu' */
+//applet:IF_MU(APPLET(mu, BB_DIR_USR_BIN, BB_SUID_DROP))
 
 
 The Grand Announcement