add some notes regarding the distinction between applications and functions
[asterisk/asterisk.git] / doc / CODING-GUIDELINES
index 7239f47..f4eb9a1 100755 (executable)
@@ -4,7 +4,13 @@ To be accepted into the codebase, all non-trivial changes must be
 disclaimed to Digium or placed in the public domain. For more information
 see http://bugs.digium.com
 
-Patches should be in the form of a unified (-u) diff.
+Patches should be in the form of a unified (-u) diff, made from the directory
+above the top-level Asterisk source directory. For example:
+
+- the base code you are working from is in ~/work/asterisk-base
+- the changes are in ~/work/asterisk-new
+
+~/work$ diff -urN asterisk-base asterisk-new
 
 All code, filenames, function names and comments must be in ENGLISH.
 
@@ -24,6 +30,10 @@ Try to match the existing formatting of the file you are working on.
 Functions and variables that are not intended to be global must be
 declared static.
 
+When reading integer numeric input with scanf (or variants), do _NOT_ use '%i'
+unless specifically want to allow non-base-10 input; '%d' is always a better
+choice, since it will not silently turn numbers with leading zeros into base-8.
+
 Roughly, Asterisk coding guidelines are generally equivalent to the 
 following:
 
@@ -78,7 +88,6 @@ for (x=0;x<5;x++) {
 }
 
 
-
 Make sure you never use an uninitialized variable.  The compiler will 
 usually warn you if you do so.
 
@@ -124,22 +133,62 @@ the scope of your function try ast_strdupa() or declare struts static
 and pass them as a pointer with &.
 
 If you are going to reuse a computable value, save it in a variable
-instead of recomputing it over and over.
+instead of recomputing it over and over.  This can prevent you from 
+making a mistake in subsequent computations, make it easier to correct
+if the formula has an error and may or may not help optimization but 
+will at least help readability.
+
+Just an example, so don't over analyze it, that'd be a shame:
 
-Just an Example:
 
- if (strlen(name)) {
-  newname = alloca(strlen(name));
-  strncpy(newname, name, strlen(name);
- }
-  
+const char *prefix = "pre";    
+const char *postfix = "post";
+char *newname = NULL;
+char *name = "data";
+
+if (name && (newname = (char *) alloca(strlen(name) + strlen(prefix) + strlen(postfix) + 3)))
+       snprintf(newname, strlen(name) + strlen(prefix) + strlen(postfix) + 3, "%s/%s/%s", prefix, name, postfix);
+
 vs
 
- if((len = strlen(name))) {
-  newname = alloca(len);
-  strncpy(newname, name, len);
- }
+const char *prefix = "pre";
+const char *postfix = "post";
+char *newname = NULL;
+char *name = "data";
+int len = 0;
+
+if (name && (len = strlen(name) + strlen(prefix) + strlen(postfix) + 3) && (newname = (char *) alloca(len)))
+       snprintf(newname, len, "%s/%s/%s", prefix, name, postfix);
 
 
 Use const on pointers which your function will not be modifying, as this 
 allows the compiler to make certain optimizations.
+
+== CLI Commands ==
+
+New CLI commands should be named using the module's name, followed by a verb
+and then any parameters that the command needs. For example:
+
+*CLI> iax2 show peer <peername>
+
+not
+
+*CLI> show iax2 peer <peername>
+
+== New dialplan applications/functions ==
+
+There are two methods of adding functionality to the Asterisk
+dialplan: applications and functions. Applications (found generally in
+the apps/ directory) should be collections of code that interact with
+a channel and/or user in some significant way. Functions (which can be
+provided by any type of module) are used when the provided
+functionality is simple... getting/retrieving a value, for
+example. Functions should also be used when the operation is in no way
+related to a channel (a computation or string operation, for example).
+
+Applications are registered and invoked using the
+ast_register_application function; see the apps/app_skel.c file for an
+example.
+
+Functions are registered using 'struct ast_custom_function_obj'
+structures and the ast_custom_function_register function.