Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

lissom.c

Go to the documentation of this file.
00001 
00009 #include <string.h>
00010 #include <time.h>
00011 #include <stdio.h>
00012 
00013 #include "ipc.h"
00014 #include "cmdparam.h"
00015 #include "binarysave.h"
00016 #include "inputs.h"
00017 #include "globals.h"
00018 
00019 
00020 /* Optional support for the GNU readline library */
00021 #ifdef USE_READLINE_LIBRARY
00022 
00027 typedef char   *CPFunction (char *, int);
00028 typedef char **CPPFunction (char *, int);
00029 extern CPPFunction *rl_attempted_completion_function;
00030 EXTERNAL_C_LINKAGE char *readline (  char *prompt);
00031 EXTERNAL_C_LINKAGE void add_history (char *string);
00032 EXTERNAL_C_LINKAGE char **completion_matches (char *text, CPFunction *entry_function);
00033 #endif
00034 
00035 
00036 /******************************************************************************/
00037 /* Defines and typedefs                                                       */
00038 /******************************************************************************/
00039 
00040 #define MAX_PROMPT_CHARS 1024
00041 
00042 
00043 
00044 /******************************************************************************/
00045 /* Global variables                                                           */
00046 /******************************************************************************/
00047 
00048 #define RCFILENAME ".lissomrc"
00049 
00050 bool has_command_file=false;
00051 
00052 const char lissom_version[]="4.0";
00053 
00054 /* Main page for generated code documentation */
00128 const char title_string[]=
00129 "                         RF-LISSOM SOFTWARE\n"
00130 "\n"
00131 "                           James A. Bednar\n"
00132 "                   Department of Computer Sciences\n"
00133 "                  The University of Texas at Austin\n"
00134 "\n"
00135 "                         Version: %s\n"
00136 "                 Compiled on %s at %s.\n";
00137 
00138 
00139 const char intro_string[]=
00140 "`lissom' is a Receptive-Field LISSOM implementation that currently\n"
00141 "runs on single-processor UNIX machines.  Since `lissom' is a living\n"
00142 "program used for research, all documentation in this file and others\n"
00143 "should be considered preliminary, incomplete, outdated, and otherwise\n"
00144 "inaccurate.  Then again, it is hopefully better than nothing ;^).\n\n"
00145 
00146 "This program is free software; you can redistribute it and/or modify it\n"
00147 "under the terms of the GNU General Public License version 2 as published\n"
00148 "by the Free Software Foundation. This program is distributed in the hope\n"
00149 "that it will be useful, but without any warranty; without even the\n"
00150 "implied warranty of merchantability or fitness for a particular purpose.\n"
00151 "See the GNU General Public License for more details.\n\n"
00152 
00153 "Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003 James A. Bednar\n";
00154 
00155 
00156 const char usage[]=
00157 "Usage: %s [<options>]*\n\n"
00158 
00159 " where <options> may be any of the following:\n\n"
00160 
00161 "   --no-init-file                  Do not process any " RCFILENAME " file(s).\n"
00162 "                                   If present must be the first option given.\n\n"
00163 
00164 "   <param>=<value>                 Set the given parameter to the given value\n\n"
00165 
00166 "   --help                          Print this message\n\n"
00167 
00168 "   [--file] <command file>         Execute commands in the given file\n\n"
00169 "   --train                         Train network until tend\n"
00170 "   --test                          Test network (without learning) until tend\n\n"
00171 
00172 "   --batch                         Suppress interactive prompt & image viewing\n"
00173 "   --interactive                   Force interactive prompt\n"
00174 "   --remote                        Use ppm_remote_viewer, not ppm_image_viewer\n\n"
00175 "   --display                       Call the plot cmd for every presentation\n\n"
00176 
00177 "   --filebase <basename>           Basename to use for generated files\n\n"
00178 
00179 "   --verbose                       Increase level of messages printed\n\n"
00180 "   --quiet                         Reduce level of messages printed\n\n"
00181 
00182 "   --command '<command> [<arg>]*'  Execute the given command with given args\n"
00183 "   -c '<command> [<arg>]*'         Shortcut for --command\n\n"
00184 
00185 
00186 "Each option is processed strictly in the order given on the command line,\n"
00187 "repeatedly if given more than once.  This means that you can e.g. set\n"
00188 "a parameter to have one value when processing one command file, and another\n"
00189 "when processing the next, or else override a value set in one before going\n"
00190 "on to the next.  After the options have all been processed, interactive\n"
00191 "command-prompt mode is entered if requested explicitly or if no command\n"
00192 "has yet been executed that caused the network to be initialized. Type\n"
00193 "`help' in interactive mode for more information on commands and parameters.\n";
00194 
00195 
00196 const char param_help_string[]= 
00197 "Parameters are given values using the command `set', which takes\n"
00198 "any number of pairs of parameter names and values in the form \n"
00199 "[[[::]<path>::]<name>=<value>], up to the maximum number of\n"
00200 "command arguments defined in cmdparam.h.  See `help set' for\n"
00201 "information about valid parameter values, such as numeric\n"
00202 "expressions.  See `help parameters list' to find out what\n"
00203 "parameters are available.  See `help constants list' to find\n"
00204 "out available symbolic constants, which are like parameters\n"
00205 "except they cannot be set.\n\n"
00206 
00207 "Type `help <name>' for more information about a particular\n"
00208 "parameter, and for even more information search the source code\n"
00209 "to see where that parameter is used.  Be careful not to assume\n"
00210 "that a given parameter is supported in all cases where it might\n"
00211 "conceptually apply, since the code is continually under\n"
00212 "development; if in doubt check the code or run an experiment.\n\n"
00213 
00214 "Nearly all parameters have default values, but the default will often\n"
00215 "need to be overridden for a particular case.  Many parameters also\n"
00216 "have hard-coded limits, and `set' will (in most cases) refuse\n"
00217 "to set the value if the limits are violated.  Legal ranges for\n"
00218 "parameters often begin at Uninitialized, which is currently -1.\n"
00219 "Uninitialized generally means that the program will try to\n"
00220 "dynamically determine an appropriate default; see the help for a\n"
00221 "particular parameter for more information.   The help lists the\n"
00222 "current parameter value and the current limits on its value, but\n"
00223 "remember that these differ at different times and for different\n"
00224 "compilation constant definitions.  An asterisk in a range (`*')\n"
00225 "indicates that there is no limit of the indicated type, e.g.\n"
00226 "`[0,*]' denotes a parameter which may take any positive value.\n\n"
00227 
00228 "Note that, at this time, dynamic restructuring of the network connections\n"
00229 "is supported only for the special case of decreasing exc_rad.  Changes to\n"
00230 "other network architecture parameters will be refused after a network is\n"
00231 "initialized.\n\n";
00232 
00233 
00234 const char cmd_help_string[]=
00235 "Commands may be specified through any of the following means, listed\n"
00236 "in order of processing (and thus in reverse order of precedence):\n\n"
00237 
00238 "  ${HOME}/" RCFILENAME "                        (if present)\n"
00239 "  ./" RCFILENAME "                              (if present)\n"
00240 "  file(s) specified on the command-line    (if any, in order)\n"
00241 "  command-prompt command(s)                (if any, as entered)\n\n"
00242 
00243 "Arguments to the set command (e.g. 'x=y') can be entered in lieu of a\n"
00244 "command; see the documentation for set for more details. In all other\n"
00245 "cases a command consists of a command name followed by its arguments,\n"
00246 "separated by spaces, all on a single line except that multiple\n"
00247 "command-file lines ending in a backslash (`\\') are concatenated.  Single\n"
00248 "or double quotes may be used to ensure that an argument containing spaces\n"
00249 "is interpreted as a single argument.  At the command prompt or in a command\n"
00250 "file, blank lines and comment lines (lines whose first non-blank character\n"
00251 "is `#') are ignored.  Comments are also allowed after commands if they are\n"
00252 "preceded by `#'.\n\n"
00253 
00254 "Type `help command <name>' for more information about a particular\n"
00255 "command, and for more information than that search the source code for\n"
00256 "cmd_<name> see where that command is defined.  Each command may take\n"
00257 "a certain fixed minimum number of arguments, followed by an arbitrary\n"
00258 "number of optional arguments.  Some commands accept named arguments\n"
00259 "of the form x=y following the command name; if so they will list which\n"
00260 "arguments are accepted.  Almost all commands accept the same\n"
00261 "form of expressions for all numeric and string arguments as the\n"
00262 "`set' command does; see `help set' for more details.\n\n"
00263 
00264 "In practice, the first command file specified on the command line, if\n"
00265 "any, will usually be used to set the starting values of training\n"
00266 "parameters. It will often also set up automatic changes to some of\n"
00267 "these parameters at predetermined times during training (see help\n"
00268 "for the command `hook').  For instance, the excitatory radius is\n"
00269 "generally decreased as training progresses, and this is usually done\n"
00270 "using `hook' with `set'.\n\n"
00271 
00272 "The actual training and/or testing of the network can be performed by\n"
00273 "adding more commands (e.g. `training' or `testing') to the end of\n"
00274 "first command file.  However, to keep that file general often you will\n"
00275 "want to put such commands into a second file, so that it can be\n"
00276 "omitted when working with the network interactively.  If just simple\n"
00277 "training until `tend' is desired, the second file isn't needed; just\n"
00278 "specify the appropriate command on the command line, e.g. `--train',\n"
00279 "`--test' or `--command ...', or type it at the interactive prompt.\n\n"
00280 
00281 "The global and per-directory options files (named " RCFILENAME ") are\n"
00282 "useful for setting host-specific parameters, such as running_remotely,\n"
00283 "or e.g. default network parameter sizes.\n";
00284 
00285 
00286 const char file_types_string[]=
00287 "%s can create many files over the course of a run.  Depending\n"
00288 "on the commands used, different files will be created, but most will\n"
00289 "be of one of the formats below.  All of the filenames should start\n"
00290 "with the value of the filebase parameter.  This parameter defaults to\n"
00291 "`lissom' for runs with no command file, the name of the first command\n"
00292 "file (minus `.param' extension, if any).  The extensions may be any of\n"
00293 "the following:\n\n"
00294 // (No-longer generated files are commented out)
00295 
00296 ".<t>.params               Command file with parameter values as defined\n"
00297 "                          when init_network was called; can be used to\n"
00298 "                          recreate a starting state later.\n\n"
00299                            
00300 ".log                      Generic logging output from commands, if any\n\n"
00301                            
00302 ".<t>.<angle>.p<pres>.ppm  Input and activity image in PPM format.\n\n"
00303                            
00304 //".input                  Input patterns on retina in ASCII.\n"
00305 //".act                    Network activities in ASCII.\n\n"
00306 //".map                    Center of gravity of each neuron, in ASCII retinal\n"
00307 //"                        coordinates.\n"
00308 //".od                     Ocular dominance values of each neuron, in ASCII.\n\n"
00309                            
00310 ".aff_map.ppm              PPM plot of afferent weights to each neuron.\n\n"
00311                            
00312 ".<t>.or.ppm               Orientation map in PPM format.\n\n"
00313                            
00314 //".<t>.or                 Orientation and specificity of each neuron in ASCII.\n"
00315 //".<t>.sp                 Sigma of major and minor axes of preferred input\n"
00316 //"                        Gaussian for each neuron, in ASCII.\n\n"
00317                            
00318 //".<t>.features           Retinotopic points of interest.\n"
00319 //".<t>.spfeatures         Spatial frequency points of interest.\n"
00320 //".<t>.odfeatures         Ocular dominance points of interest.\n\n"
00321                            
00322 ".<t>.wts                  ASCII or binary weight state file.\n\n"
00323 ".<t>.wts.<ui>_<uj>.ppm    Weights for the neuron (ui,uj) in PPM format\n"
00324                            
00325 //".<ui>_<uj>.<t>.ex.ma    Mathematica plot of excitatory weights.\n"
00326 //".<ui>_<uj>.<t>.in.ma    Mathematica plot of inhibitory weights.\n"
00327 //".<ui>_<uj>.<t>.mx.ma    Mathematica plot of Mexican hats (exc+inh weights).\n"
00328 //".<ui>_<uj>.<t>.aff.ma   Mathematica plot of afferent weights.\n"
00329 //".<ui>_<uj>.<t>.od.ma    Mathematica plot of ocular dominance.\n"
00330 //".<ui>_<uj>.<t>.ex.mp    Maple plot of excitatory weights.\n"
00331 //".<ui>_<uj>.<t>.in.mp    Maple plot of inhibitory lateral weights.\n"
00332 //".<ui>_<uj>.<t>.mx.mp    Maple plot of Mexican hats (exc+inh weights).\n"
00333 //".<ui>_<uj>.<t>.aff.mp   Maple plot of afferent weights.\n"
00334 //".<ui>_<uj>.<t>.od.mp    Maple plot of ocular dominance.\n"
00335 //".<ui>_<uj>.drf          Dynamic receptive fields\n\n"
00336                            
00337 //".<row>.in               Dump of lateral weights for a row, in ASCII.\n"
00338 //".<neuron>.<t>.lat       Dump of lateral weights for a neuron, in ASCII.\n\n"
00339                            
00340 //".stat.<sel>.<m>.mp      Maple plot of orientation specificity histogram.\n"
00341 //".stat.<sel>.<m>.count   Orientation preference counts.\n"
00342 ;
00343 
00344 
00345 
00346 
00347 
00348 
00349 /******************************************************************************/
00350 /* Prototypes for private functions                                           */
00351 /******************************************************************************/
00352 
00353 CMD_DECLARE(help);
00354 CMD_DECLARE(make_doc);
00356 char**  command_prompt_completion (char *text, int start, int end);
00357 int     get_line_from_prompt( void );
00358 void    lissom_init_hooks(void);
00359 bool    process_command_line_args(int argc, char **argv);
00360 void    set_filebase(string commandfilename);
00361 void    wrong_usage(const char* filename);
00362 void    read_command_file_if_present(string name);
00363 
00364 
00365 
00366 /******************************************************************************/
00367 /* Main function                                                              */
00368 /******************************************************************************/
00369 
00371 int main(int argc, char **argv)
00372 {
00373   time_t start_time = time(NULL);
00374 
00375   /* Initialize various modules */
00376   lissom_init_hooks();
00377 
00378   /* Announce program start */
00379   ipc_notify(IPC_ONE,IPC_SUMMARY,"Execution of %s started %.24s on %s",
00380              argv[0], ctime(&start_time), getenv("HOST") );
00381 
00382   /* Read and execute commands and files specified on the command line */
00383   const bool is_interactive = process_command_line_args(argc,argv);
00384   
00385   /* Read further commands from terminal prompt, if appropriate */
00386   if (is_interactive) {
00387     if (!has_command_file) 
00388       ipc_init_logfile(filebase.c_str());
00389     cmdparam_changes_verbose=True;
00390     cmddefs_exec_batch(&get_line_from_prompt,"prompt");
00391   }
00392   
00393   /* Exit */
00394   ipc_exit(IPC_EXIT_NORMAL,"Exited normally");
00395   return 0; /* never reached */
00396 } 
00397 
00398 
00399 
00400 /******************************************************************************/
00401 /* Initialization hook                                                        */
00402 /******************************************************************************/
00403 
00405 void lissom_init_hooks(void)
00406 {
00407   /* Ensure this machine has appropriate types defined */
00408   if (check_ind_types(False))
00409     ipc_exit(0,"Need to add definitions to ind_types.c for this architecture.");
00410 
00411   ipc_init();
00412 
00413   /* Register message handlers using IPC routines */
00414   static Msg::LevelHandler<> ipc_message_handler;
00415   ipc_message_handler.register_handler( Msg::Verbose,   Msg::ipc_verbose   );
00416   ipc_message_handler.register_handler( Msg::Notify,    Msg::ipc_notify    );
00417   ipc_message_handler.register_handler( Msg::Requested, Msg::ipc_requested );
00418   ipc_message_handler.register_handler( Msg::Warning,   Msg::ipc_warning   );
00419   ipc_message_handler.register_handler( Msg::Error,     Msg::ipc_error     );
00420   Msg::LevelHandler<>::set_default_instance(&ipc_message_handler);
00421 
00422   /* Add typical constants */
00423   blackboard.add_constants();
00424 
00425   /* Turn off buffering so no messages are lost */
00426   setvbuf( stdout, NULL, _IONBF , 0); 
00427 
00428 #ifdef USE_READLINE_LIBRARY
00429   rl_attempted_completion_function = (CPPFunction *)command_prompt_completion;
00430 #endif
00431   
00432   CMD_DOC(help,NULL,0,"%s [<options>]",
00433           "Try:\n\n"
00434           
00435           "   help parameters          for general help using parameters and constants\n"
00436           "   help parameters list     for a concise list of the available parameters\n"
00437           "   help parameters doc      for help on all parameters\n"
00438           "   help constants list      for a concise list of the available constants\n"
00439           "   help constants doc       for help on all constants\n"
00440 
00441           "   help commands            for general help using commands\n"
00442           "   help commands list       for a concise list of the available commands\n"
00443           "   help commands doc        for help on all commands\n"
00444 
00445           "   help usage               for help on the command-line options\n"
00446           "   help version             for the date and number of this version of LISSOM\n"
00447 
00448           "   help <name>              for help with a specific parameter, constant,\n"
00449           "                             or command");
00450   
00451   
00452   CMD_DOC(make_doc,NULL,0,"%s [<filename>]",
00453           "Create a file with the specified name containing all the help information\n"
00454           "available.  It is currently formatted as an ASCII document.");
00455   
00456   /* Call hooks to initialize each source file */ 
00457   globals_init_hook();
00458   kernel_init_hook();
00459   Inputs::global_entry().register_params_and_commands();
00460   LISSOMBinaryStateSaver::init_hook();
00461   cmdparam_init_hook();
00462 
00463   /* Redefine help string for cmd_hook to make it specific to LISSOM */
00464   cmddefs_define_command_doc
00465     ("hook","%s <hook_location> <iteration_specifier> <command> [<arguments>]",
00466      "This command allows you to specify that any other command should be\n"
00467      "executed at a specified iteration or iterations.\n\n"
00468 
00469      "The <command> and its <arguments> may be any valid command and any\n"
00470      "arguments that it accepts.  Any command arguments are evaluated when the\n"
00471      "command is run, not when the hook is first defined.\n\n"
00472 
00473      "The <iteration_specifier> should be of the (recursive) form:\n\n"
00474 
00475      "   <start_iteration>[-<end_iteration>[%<step>]][,<iteration_specifier>]\n\n"
00476 
00477      "Each of the first three quantities may be a <term> as defined by the command\n"
00478      "`set', which means that any compound expressions must be parenthesized.  For\n"
00479      "example, the <iteration_specifier> can be:\n\n"
00480 
00481      "   a single iteration      (e.g. `1000'),\n"
00482      "   a range of iterations   (e.g. `1-1000'), \n"
00483      "   a range with a stepsize (e.g. `1-1000%%10'), or\n"
00484      "   a list of any of these  (e.g. `1,10,100-200%%100,7,50-52,(tend-2)-tend').\n\n"
00485 
00486      "In the first case, the command is executed only once, at iteration 1000,\n"
00487      "in the second it is executed 1000 times, once per iteration, in the third,\n"
00488      "it is executed 100 times, at iterations 10, 20, etc. (all those evenly\n"
00489      "divisible by 10), and in the last one it is executed at iterations 1,7,\n"
00490      "10,50,51,52,100,200,19998,19999, and 20000, assuming tend==20000.  Note\n"
00491      "that the <iteration_specifier> must not contain any spaces.\n\n"
00492 
00493      "The <hook_location> specifies where in the code the hook is checked\n"
00494      "for (and executed at the appropriate time.)  Currently hooks can be\n"
00495      "inserted at the following locations within an iteration of the training\n"
00496      "or testing commands:\n\n"
00497 
00498      " before_input:  At the start of the training iteration, before input,\n"
00499      "   activation, settling, or learning.  Useful for setting parameters,\n"
00500      "   loading a saved state, etc.\n\n"
00501 
00502      " after_learning:  At the end of the training iteration, after input,\n"
00503      "   activation, settling, and learning.  Useful for saving state,\n"
00504      "   plotting, analyzing the activity, etc.\n\n"
00505 
00506      "At a given hook_location and iteration, all the hooks that apply\n"
00507      "are executed in the order of their start_iteration and (if those\n"
00508      "match) the order in which they were defined.\n\n"
00509 
00510      "Hooks can also be defined to execute multiple times within a given\n"
00511      "specified iteration or iterations(s) using the following hooklist:\n\n"
00512 
00513 //     " after_presentation:  After any input has been presented to the\n"
00514 //     "   network subsequent to the original training or testing for an\n"
00515 //     "   iteration.  Useful primarily in conjunction with commands that\n"
00516 //     "   present or modify input or network activation without advancing\n"
00517 //     "   the iteration number, such as input_draw and input_present.  For\n"
00518 //     "   instance, such commands can be used to graph or analyze the\n"
00519 //     "   response to a set of different inputs at periodic times during\n"
00520 //     "   training without disrupting the network or the iteration numbers.\n\n"
00521 
00522      "Examples:\n\n"
00523 
00524      "  hook before_input        501 set exc_rad=9 delta=0.12 beta=0.67\n"
00525      "  hook before_input       1001 set exc_rad=6 delta=0.15 beta=0.65\n\n"
00526      
00527      "These could be part of a training schedule that gradually reduces the\n"
00528      "excitation radius while increasing the slope of the sigmoid.\n\n"
00529 
00530      "  hook after_learning  1-100%%2 plot\n"
00531      "  hook after_learning     1000 plot\n\n"
00532      
00533      "  hook after_learning    10000 kill_connections 0.0001\n\n"
00534 
00535      "The top two specify 101 iterations at which the input and activity\n"
00536      "should be plotted.  The next specifies that inhibitory weights smaller\n"
00537      "than 0.0001 should be pruned at iteration 10000.\n\n"
00538 
00539 //   "  hook after_presentation    1 analyze_portions\n"
00540      "  hook after_learning        1 for f=0 f<PI f=f+PI/18 input_present_object \"\" Input_Gaussian f\n\n"
00541 
00542      "This hook presents a variety of stimuli at iteration 1.");
00543 
00544   /* Parameter used by this file */
00545   PARAM_A(blackboard,"command_prompt_format",
00546           string("lissom.t${iteration}.p${presentation}.c${command_num_called}${current_param_set_path}> "),,
00547           "Command prompt for an interactive session.  The value of this parameter\n"
00548           "is evaluated as for a string argument to a command, substituting the\n"
00549           "value of any specified parameters at the time the prompt is printed.\n\n"
00550           
00551           "As a special case, the string '${param_set_path}' is globally replaced\n"
00552           "by the path to the parameter set currently selected, even though there\n"
00553           "is currently no parameter by that name.\n\n"
00554 
00555           "As another special case, the characters '\\033' are replaced by the\n"
00556           "escape character.  This allows ANSI color codes to be used in the\n"
00557           "prompt.  Example:\n\n"
00558           
00559           "  command_prompt_format=\"\\033[33;40;1mlissom.t$${iteration}.p$${presentation}.c$${command_num_called}$${current_param_set_path}>\\033[m \"");
00560 
00561   
00562   cmddefs_exec_str("uninit_network");
00563 }
00564 
00565 
00566 
00567 /******************************************************************************/
00568 /* Private functions                                                          */
00569 /******************************************************************************/
00570 
00572 void wrong_usage(const char* filename)
00573 {
00574   if (AMPARENTPE)
00575     fprintf(stdout,usage,filename);
00576   ipc_exit(IPC_EXIT_WRONG_USAGE,"Wrong usage");
00577 }
00578 
00579 
00580 
00582 void read_command_file_if_present(string name)
00583 {
00584   cmdparam_changes_verbose=network_initialized;
00585   FILE *file=fopen(name.c_str(),"r");
00586   if (file) {
00587     ipc_notify(IPC_ONE,IPC_STD,"Processing command file %s", name.c_str()); 
00588     fclose(file);
00589     if (cmddefs_exec_file(name.c_str()))
00590       ipc_notify(IPC_ONE,IPC_ERROR,"Problem with command file %s",name.c_str());
00591   }
00592 }
00593 
00594 
00596 #define nextargis(str) (arglist.nextis(string(str)))
00597 
00606 bool process_command_line_args(int argc, char **argv)
00607 {
00608   CMD_ARG_LIST;
00609   
00610   Tristate force_interactive=Uninitialized;
00611   const string progname=arglist.next(string("lissom"));
00612 
00613 
00614   /* Process global and this-directory options files first so that they
00615      may be overriden by options specified on the command line */
00616   if (arglist.empty() || !arglist.nextis(string("--no-init-file"))) {
00617     read_command_file_if_present(string(getenv("HOME"))+"/" RCFILENAME);
00618     read_command_file_if_present(RCFILENAME);
00619   }
00620 
00621   /* True if filebase has been set explicitly */
00622   bool has_filebase=false;
00623   
00624   while (!arglist.empty()) {
00625     /* Allow parameter setting of the form name=val anywhere on command line */
00626     cmdparams_set(blackboard,arglist,true,false,true);
00627     
00628     if (nextargis("--help") || nextargis("-h"))
00629       fprintf(stdout,usage,progname.c_str());
00630 
00631     else if (nextargis("--batch")) {
00632       cmdparam_set("interactive","False");
00633       force_interactive=False;
00634     }
00635     else if (nextargis("--interactive")) {
00636       cmdparam_set("interactive","True");
00637       force_interactive=True;
00638     }
00639     else if (nextargis("--remote"))       cmdparam_set("running_remotely","True");
00640     else if (nextargis("--display"))      cmdparam_set("display","1");
00641     else if (nextargis("--verbose"))      ipc_msg_level+=2;
00642     else if (nextargis("--quiet"))        ipc_msg_level-=2;
00643 
00644     else if (nextargis("--filebase")) {
00645       if (arglist.empty())
00646         wrong_usage(progname.c_str());
00647       else {
00648         filebase = arglist.next(string(""));
00649         has_filebase=true;
00650       }
00651     }
00652     
00653     else if (nextargis("--command") || nextargis("-c")) {
00654       if (arglist.empty())
00655         wrong_usage(progname.c_str());
00656       else {
00657         ipc_init_logfile(filebase.c_str());
00658         const string cmd=arglist.next(string(""));
00659         cmddefs_exec_str(cmd.c_str());
00660       }
00661     }
00662     
00663     else if (nextargis("--set")) {
00664       const string param=arglist.next(string(""));
00665       if (arglist.empty())
00666         wrong_usage(progname.c_str());
00667       else {
00668         const string val=arglist.next(string(""));
00669         cmdparam_set(param,val);
00670       }
00671     }
00672     
00673     else if (nextargis("--train")) {
00674       ipc_init_logfile(filebase.c_str());
00675       cmddefs_exec_str("training");
00676       cmdparam_set("interactive","False");
00677     }
00678     
00679     else if (nextargis("--test")) {
00680       ipc_init_logfile(filebase.c_str());
00681       cmddefs_exec_str("testing");
00682       cmdparam_set("interactive","False");
00683     }
00684     
00685     else if (!arglist.empty()) { /* Assumes any other argument is a file to process */
00686       const string filename=arglist.next(string(""));
00687       const string start=string(filename,0,2);
00688       
00689       if (start == "--") { /* Reserve "--" for options */
00690         if (nextargis("--file"));
00691         else
00692           wrong_usage(progname.c_str());
00693       }
00694       
00695       if (filename=="")
00696         wrong_usage(progname.c_str());
00697       else {
00698         if (!has_command_file) { /* Set file basename to first command file */
00699           has_command_file=true;
00700           if (!has_filebase)
00701             set_filebase(filename.c_str());
00702           ipc_init_logfile(filebase.c_str());
00703         }
00704         /* Suppress reporting of parameters changed in command files until
00705            .init.param file created */
00706         cmdparam_changes_verbose=network_initialized; 
00707         
00708         /* Execute the file of commands */
00709         ipc_notify(IPC_ONE,IPC_STD,"Processing command file %s", filename.c_str());
00710         if (cmddefs_exec_file(filename.c_str()))
00711           ipc_abort(IPC_EXIT_FILE_PROBLEM,"Problem with command file %s",
00712                     filename.c_str());
00713         cmdparam_changes_verbose=True; 
00714       }
00715     }
00716   }
00717 
00718   /* Default to showing interactive prompt if not specified and
00719      network hasn't been trained */
00720   if (force_interactive == Uninitialized && !network_initialized)
00721     cmdparam_set("interactive","True");
00722 
00723   return blackboard.get_with_default("interactive",True);
00724 }
00725 #undef nextargis
00726 
00727 
00728 
00733 void set_filebase(string commandfilename)
00734 {
00735   int extension = commandfilename.rfind(".param");
00736   filebase = 
00737     ((extension<0 || extension>=int(commandfilename.length()))?
00738      commandfilename :
00739      commandfilename.replace(extension,commandfilename.length(),""));
00740 }
00741 
00742 
00743 
00745 int get_line_from_prompt( void )
00746 {
00747   const string param_set_name = (blackboard.path_name()=="" ? "" : "::"+blackboard.path_name());
00748   const string promptformat   = blackboard.get_with_default("command_prompt_format",string(""));
00749 
00750   /* Hacks: replace current_param_set_path with actual path and
00751      escape code with escape character */
00752   unsigned pos;
00753   string p = promptformat;
00754   const string param_set_marker="${current_param_set_path}";
00755   const string escape_marker="\\033";
00756   while ((pos=p.find(param_set_marker))<p.length())
00757     p.replace(pos,param_set_marker.length(),param_set_name);
00758   while ((pos=p.find(escape_marker))<p.length())
00759     p.replace(pos,escape_marker.length(),"\033");
00760   
00761   /* String substitution */
00762   const string promptstr    = Parse(blackboard,p.c_str()).cmds();
00763 
00764   /* Copied into an array because readline insists on a non-const pointer */
00765   char prompt[MAX_PROMPT_CHARS];
00766   SNPRINTF(prompt, MAX_PROMPT_CHARS, "%s",promptstr.c_str());
00767 
00768   char *lineptr=NULL;
00769 #ifdef USE_READLINE_LIBRARY
00770   lineptr= readline(prompt);
00771   if (lineptr) {
00772     if (*lineptr) add_history(lineptr);
00773     strncpy(cmddefs_line_buffer,lineptr,CMD_MAX_LINE_LENGTH+1);
00774     free(lineptr);
00775     lineptr=cmddefs_line_buffer;
00776   }
00777   else
00778     fprintf(stdout,"\n"); /* About to exit */
00779 #else
00780   fprintf(stdout,prompt);
00781   lineptr = fgets(cmddefs_line_buffer,CMD_MAX_LINE_LENGTH+1,stdin);
00782 #endif
00783 
00784   return (lineptr==NULL);
00785 }
00786 
00787 
00788 
00789 #ifdef USE_READLINE_LIBRARY
00790 char ** command_prompt_completion (char *text, int start, int end)
00791 {
00792   (void)end;   /* Unused */
00793   
00794   /* First word must be a command; others are usually a param */
00795   return (start==0 ? 
00796           completion_matches(text, cmddefs_completion_generator) :
00797           completion_matches(text, params_completion_generator) );
00798 }
00799 #endif
00800 
00801 
00802 
00803 #define COMPAREARG(arg,string) (argc>(arg) && !strcmp(argv[arg],string))
00804 cmdstat cmd_help( CMD_ARGS )
00805 {
00806   if (AMPARENTPE) {
00807 
00808     /* Help with parameters */
00809     if (COMPAREARG(0,"parameters")) {
00810       if      (COMPAREARG(1,"list"))        params_print_parameters(stdout);
00811       else if (COMPAREARG(1,"doc"))         params_print_parameters_doc(stdout);
00812       else                                  fprintf(stdout,param_help_string);
00813     }
00814     
00815     /* Help with constants */
00816     else if (COMPAREARG(0,"constants")) {
00817       if      (COMPAREARG(1,"list"))        params_print_constants(stdout);
00818       else if (COMPAREARG(1,"doc"))         params_print_constants_doc(stdout);
00819       else                                  fprintf(stdout,param_help_string);
00820     }
00821 
00822     /* Help with commands */
00823     else if (COMPAREARG(0,"commands")) {
00824       if      (COMPAREARG(1,"list"))        cmddefs_print_all(stdout);
00825       else if (COMPAREARG(1,"doc"))         cmddefs_print_all_doc(stdout);
00826       else                                  fprintf(stdout,cmd_help_string);
00827     }
00828 
00829     /* Help with setting */
00830     else if (COMPAREARG(0,"set")) {
00831       cmdparams_print_doc(stdout, "set");
00832       fprintf(stdout,"\nAt present, parameters may be set in any of the following paths:\n(default)\n");
00833       blackboard.print_children(stdout);
00834     }
00835 
00836     /* Other general topics */
00837     else if (COMPAREARG(0,"files"))         fprintf(stdout,file_types_string,"lissom");
00838     else if (COMPAREARG(0,"usage"))         fprintf(stdout,usage,"lissom");
00839     else if (COMPAREARG(0,"version")) {
00840       fprintf(stdout,"This is version %s of LISSOM, compiled on %s at %s.\n",
00841               lissom_version,__DATE__, __TIME__);
00842     }
00843 
00844     /* Help with a particular item */
00845     else if (argc>0 && cmdparams_print_doc(stdout, argv[0]));/* object found, help printed */
00846 
00847     /* Nothing else matched; explain help system itself */
00848     else
00849       cmddefs_print_doc(stdout,"help");      
00850   }
00851   
00852   return CMD_NO_ERROR;
00853 }
00854 #undef COMPARE_ARG
00855 
00857 #define NEW_SECTION(name) \
00858  fprintf(file,"\nSECTION: " #name "\n\n")
00859 
00861 #define NEW_SUBSECTION(name) \
00862  fprintf(file,"\nSUBSECTION: " #name "\n\n")
00863 
00865 cmdstat cmd_make_doc( CMD_ARGS )
00866 {
00867   const char *filename=(argc>0 ? PARSE_C(argv[0]) : "USERDOC");
00868   
00869   if (AMPARENTPE) {
00870     FILE *file;
00871     if ((file=fopen(filename,"w+"))==NULL){
00872       ipc_notify(IPC_ALL,IPC_ERROR,"Could not open output file %s", filename);
00873       return CMD_FILE_ERROR;
00874     }
00875 
00876     fprintf(file,title_string,lissom_version,__DATE__, __TIME__);
00877 
00878     NEW_SECTION(INTRODUCTION);
00879     fprintf(file,intro_string);
00880 
00881     NEW_SECTION(USAGE);
00882     fprintf(file,usage,"lissom");
00883 
00884     NEW_SECTION(PARAMETERS);
00885     fprintf(file,param_help_string);
00886     fprintf(file,"\nList of valid parameters:\n\n");
00887     params_print_parameters(file);
00888     
00889     NEW_SUBSECTION(PARAMETER DOCUMENTATION);
00890     params_print_parameters_doc(file);
00891 
00892     NEW_SECTION(CONSTANTS);
00893     fprintf(file,"\nList of valid constants:\n\n");
00894     params_print_constants(file);
00895     
00896     NEW_SUBSECTION(CONSTANT DOCUMENTATION);
00897     params_print_constants_doc(file);
00898 
00899     NEW_SECTION(COMMANDS);
00900     fprintf(file,cmd_help_string);
00901     fprintf(file,"\nList of valid commands:\n\n");
00902     cmddefs_print_all(file);
00903     
00904     NEW_SUBSECTION(COMMAND DOCUMENTATION);
00905     cmddefs_print_all_doc(file);
00906 
00907     NEW_SECTION(FILES);
00908     fprintf(file,file_types_string,"lissom");
00909 
00910     fclose(file);
00911   }
00912 
00913   ipc_notify(IPC_ONE,IPC_STD,"Created documentation file %s",filename);
00914   
00915   return CMD_NO_ERROR;
00916 }
00917 #undef NEW_SECTION
00918 #undef NEW_SUBSECTION
00919 

Generated on Mon Jan 20 02:35:44 2003 for RF-LISSOM by doxygen1.3-rc2