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 "ppm_draw.h"
00018 #ifndef NO_TILT
00019 #include "tilt.h"
00020 #endif
00021 #include "analyze.h"
00022 #include "file_io.h"
00023 #include "globals.h"
00024 #include "kernel.h"
00025 #include "lissom.h"
00026
00027
00028
00029
00030 #ifdef USE_READLINE_LIBRARY
00031
00036 typedef char *CPFunction (char *, int);
00037 typedef char **CPPFunction (char *, int);
00038 extern CPPFunction *rl_attempted_completion_function;
00039 EXTERNAL_C_LINKAGE char *readline ( char *prompt);
00040 EXTERNAL_C_LINKAGE void add_history (char *string);
00041 EXTERNAL_C_LINKAGE char **completion_matches (char *text, CPFunction *entry_function);
00042 #endif
00043
00044
00045
00046
00047
00048
00049 #define MAX_PROMPT_CHARS 48
00050
00051
00052
00053
00054
00055
00056
00057 #define RCFILENAME ".lissomrc"
00058
00059 int has_command_file=False;
00060
00061 const char lissom_version[]="3.0a1";
00062
00063
00137 const char title_string[]=
00138 " RF-LISSOM SOFTWARE\n"
00139 "\n"
00140 " James A. Bednar\n"
00141 " Department of Computer Sciences\n"
00142 " The University of Texas at Austin\n"
00143 "\n"
00144 " Version: %s\n"
00145 " Compiled on %s at %s.\n";
00146
00147
00148 const char intro_string[]=
00149 "`lissom' is a Receptive-Field LISSOM implementation that runs\n"
00150 "on the Cray T3E massively parallel supercomputer as well as on\n"
00151 "single-processor UNIX machines. Since `lissom' is a living\n"
00152 "program used for research, all documentation in this file and others\n"
00153 "should be considered preliminary, incomplete, outdated, and otherwise\n"
00154 "inaccurate. Then again, it is hopefully better than nothing ;^).\n\n"
00155
00156 "This program is free software; you can redistribute it and/or modify it\n"
00157 "under the terms of the GNU General Public License version 2 as published\n"
00158 "by the Free Software Foundation. This program is distributed in the hope\n"
00159 "that it will be useful, but without any warranty; without even the\n"
00160 "implied warranty of merchantability or fitness for a particular purpose.\n"
00161 "See the GNU General Public License for more details.\n\n"
00162
00163 "Copyright (C) 1995,1996,1997,1998,1999,2000 James A. Bednar\n";
00164
00165
00166 const char usage[]=
00167 "Usage: %s [<options>]*\n\n"
00168
00169 " where <options> may be any of the following:\n\n"
00170
00171 " --help Print this message\n\n"
00172
00173 " [--file] <command file> Execute commands in the given file\n\n"
00174 " --train Train network until tend\n"
00175 " --test Test network (without learning) until tend\n\n"
00176
00177 " --batch Suppress interactive prompt & image viewing\n"
00178 " --interactive Force interactive prompt\n"
00179 " --remote Choose ppm_remote_viewer instead of ppm_image_viewer\n\n"
00180 " --display Generate activity images at every presentation\n\n"
00181
00182 " --filebase <basename> Basename to use for generated files\n\n"
00183
00184 " --verbose Increase level of messages printed\n\n"
00185 " --quiet Reduce level of messages printed\n\n"
00186
00187 " --set <param> <value> Set the given parameter to the given value\n"
00188 " --command '<command> [<arg>]*' Execute the given command with given args\n\n"
00189
00190
00191 "Each option is processed strictly in the order given on the command line,\n"
00192 "repeatedly if given more than once. This means that you can e.g. set\n"
00193 "a parameter to have one value when processing one command file, and another\n"
00194 "when processing the next, or else override a value set in one before going\n"
00195 "on to the next. After the options have all been processed, interactive\n"
00196 "command-prompt mode is entered if requested explicitly or if no command\n"
00197 "has yet been executed that caused the network to be initialized. Type\n"
00198 "`help' in interactive mode for more information on commands and parameters.\n";
00199
00200
00201 const char param_help_string[]=
00202 "Parameters are given values using the command `set', which takes\n"
00203 "any number of pairs of parameter names and values in the form \n"
00204 "<name>=<value>, up to the maximum number of command arguments\n"
00205 "defined in cmdparam.h. See `help set' for information about\n"
00206 "valid parameter values, such as numeric expressions. See `help\n"
00207 "parameters list' to find out what parameters are available. See\n"
00208 "`help constants list' to find out available symbolic constants,\n"
00209 "which are like parameters except they cannot be set.\n\n"
00210
00211 "Type `help <name>' for more information about a particular\n"
00212 "parameter, and for even more information search the source code\n"
00213 "to see where that parameter is used. Be careful not to assume\n"
00214 "that a given parameter is supported in all cases where it might\n"
00215 "conceptually apply, since the code is continually under\n"
00216 "development; if in doubt check the code.\n\n"
00217
00218 "Nearly all parameters have default values, but the default will often\n"
00219 "need to be overridden for a particular case. Many parameters also\n"
00220 "have hard-coded limits, and `set' will (in most cases) refuse\n"
00221 "to set the value if the limits are violated. Legal ranges for\n"
00222 "parameters often begin at Uninitialized, which is currently -1.\n"
00223 "Uninitialized generally means that the program will try to\n"
00224 "dynamically determine an appropriate default; see the help for a\n"
00225 "particular parameter for more information. The help lists the\n"
00226 "current parameter value and the current limits on its value, but\n"
00227 "remember that these differ at different times and for different\n"
00228 "compilation constant definitions. An asterix in a range (`*')\n"
00229 "indicates that there is no limit of the indicated type, e.g.\n"
00230 "`[0,*]' denotes a parameter which may take any positive value.\n\n"
00231
00232 "Note that, at this time, dynamic restructuring of the network connections\n"
00233 "is supported only for the special case of decreasing exc_rad. Changes to\n"
00234 "other network architecture parameters will be refused after a network is\n"
00235 "initialized.\n\n";
00236
00237
00238 const char cmd_help_string[]=
00239 "Commands may be specified through any of the following means, listed\n"
00240 "in order of processing (and thus of precedence):\n\n"
00241
00242 " ${HOME}/" RCFILENAME " (if present)\n"
00243 " ./" RCFILENAME " (if present)\n"
00244 " file(s) specified on the command-line (if any, in order)\n"
00245 " command-prompt command(s) (if any, as entered)\n\n"
00246
00247 "In all cases a command consists of a command name followed by its arguments,\n"
00248 "separated by spaces, all on a single line except that multiple\n"
00249 "command-file lines ending in a backslash (`\\') are concatenated. Single\n"
00250 "or double quotes may be used to ensure that an argument containing spaces\n"
00251 "is interpreted as a single argument. At the command prompt or in a command\n"
00252 "file, blank lines and comment lines (lines whose first non-blank character\n"
00253 "is `#') are ignored. Comments are also allowed after commands if they are\n"
00254 "preceded by `#'.\n\n"
00255
00256 "Type `help command <name>' for more information about a particular\n"
00257 "command, and for more information than that search the source code for\n"
00258 "cmd_<name> see where that command is defined. Each command may take\n"
00259 "a certain fixed minimum number of arguments, followed by an arbitrary\n"
00260 "number of optional arguments. Almost all commands accept the same\n"
00261 "form of expressions for numeric and string arguments as the `set'\n"
00262 "command does; see `help set' for more details. Many commands have\n"
00263 "parameters whose names start with `max_'; these indicate the maximum\n"
00264 "value for which to test that quantity.\n\n"
00265
00266 "In practice, the first command file specified on the command line, if\n"
00267 "any, will usually be used to set the starting values of training\n"
00268 "parameters. It will often also set up automatic changes to some of\n"
00269 "these parameters at predetermined times during training (see help\n"
00270 "for the command `hook'). For instance, the excitatory radius is\n"
00271 "generally decreased as training progresses, and this is usually done\n"
00272 "using `hook' with `set'.\n\n"
00273
00274 "The actual training and/or testing of the network can be performed by\n"
00275 "adding more commands (e.g. `training' or `testing') to the end of\n"
00276 "first command file. However, to keep that file general often you will\n"
00277 "want to put such commands into a second file, so that it can be\n"
00278 "omitted when working with the network interactively. If just simple\n"
00279 "training until `tend' is desired, the second file isn't needed; just\n"
00280 "specify the appropriate command on the command line, e.g. `--train',\n"
00281 "`--test' or `--command ...', or type it at the interactive prompt.\n\n"
00282
00283 "The global and per-directory options files (named " RCFILENAME ") are\n"
00284 "useful for setting host-specific parameters, such as running_remotely,\n"
00285 "or e.g. default network parameter sizes.\n";
00286
00287
00288 const char file_types_string[]=
00289 "%s can create many files over the course of a run. Depending\n"
00290 "on the commands used, different files will be created, but most will\n"
00291 "be of one of the formats below. All of the filenames should start\n"
00292 "with the value of the filebase parameter. This parameter defaults to\n"
00293 "`lissom' for runs with no command file, the name of the first command\n"
00294 "file (minus `.param' extension, if any). The extensions may be any of\n"
00295 "the following:\n\n"
00296
00297 ".log Generic logging output from commands, if any\n\n"
00298
00299 ".init.param Command file with parameter values as defined\n"
00300 " when init_network was called; can be used to\n"
00301 " recreate a starting state later.\n\n"
00302
00303 ".<t>.<angle>.p<pres>.ppm Input and activity image in PPM format.\n"
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 ".fort.3 Log file from NPSOL non-linear function optimizer.\n"
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"
00313 ".<t>.or Orientation and specificity of each neuron in ASCII.\n"
00314 ".<t>.sp Sigma of major and minor axes of preferred input\n"
00315 " gaussian for each neuron, in ASCII.\n\n"
00316
00317 ".<t>.features Retinotopic points of interest.\n"
00318 ".<t>.spfeatures Spatial frequency points of interest.\n"
00319 ".<t>.odfeatures Ocular dominance points of interest.\n\n"
00320
00321 ".<t>.wts ASCII or binary weight state file.\n\n"
00322 ".<t>.wts.<ui>_<uj>.ppm Weights for the neuron (ui,uj) in PPM format\n"
00323
00324 ".<ui>_<uj>.<t>.ex.ma Mathematica plot of excitatory weights.\n"
00325 ".<ui>_<uj>.<t>.in.ma Mathematica plot of inhibitory weights.\n"
00326 ".<ui>_<uj>.<t>.mx.ma Mathematica plot of Mexican hats (exc+inh weights).\n"
00327 ".<ui>_<uj>.<t>.aff.ma Mathematica plot of afferent weights.\n"
00328 ".<ui>_<uj>.<t>.od.ma Mathematica plot of ocular dominance.\n"
00329 ".<ui>_<uj>.<t>.ex.mp Maple plot of excitatory weights.\n"
00330 ".<ui>_<uj>.<t>.in.mp Maple plot of inhibitory lateral weights.\n"
00331 ".<ui>_<uj>.<t>.mx.mp Maple plot of Mexican hats (exc+inh weights).\n"
00332 ".<ui>_<uj>.<t>.aff.mp Maple plot of afferent weights.\n"
00333 ".<ui>_<uj>.<t>.od.mp Maple plot of ocular dominance.\n"
00334 ".<ui>_<uj>.drf Dynamic receptive fields\n\n"
00335
00336 ".<row>.in Dump of lateral weights for a row, in ASCII.\n"
00337 ".<neuron>.<t>.lat Dump of lateral weights for a neuron, in ASCII.\n\n"
00338
00339 ".stat.<sel>.<m>.mp Maple plot of orientation specificity histogram.\n"
00340 ".stat.<sel>.<m>.count Orientation preference counts.\n";
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 CMD_DECLARE(help);
00352 CMD_DECLARE(make_doc);
00354 char** command_prompt_completion (char *text, int start, int end);
00355 int get_line_from_prompt( void );
00356 void lissom_init_hooks(void);
00357 void process_command_line_args(int argc, char **argv);
00358 void set_filebase(char *commandfilename);
00359 void wrong_usage(const char* filename);
00360 void read_command_file_if_present(string name);
00361
00362
00363
00364
00365
00366
00367
00369 int main(int argc, char **argv)
00370 {
00371 time_t start_time = time(NULL);
00372
00373
00374 lissom_init_hooks();
00375
00376
00377 ipc_notify(IPC_ONE,IPC_SUMMARY,"Execution of %s started %.24s on %s",
00378 argv[0], ctime(&start_time), getenv("HOST") );
00379
00380
00381 ipc_notify(IPC_ONE,IPC_STD,"%dMB (max) required %sfor weight storage",
00382 (int)network_size_megabytes()+1,(NPEs>1 ? "(on each PE) " : ""));
00383
00384 00385
00386 read_command_file_if_present(string(getenv("HOME"))+"/" RCFILENAME);
00387 read_command_file_if_present(RCFILENAME);
00388
00389
00390 process_command_line_args(argc,argv);
00391
00392
00393 if (interactive) {
00394 if (!has_command_file)
00395 ipc_init_logfile(filebase);
00396 cmdparam_changes_verbose=True;
00397 cmddefs_exec_batch(&get_line_from_prompt,"prompt");
00398 }
00399
00400
00401 ipc_exit(IPC_EXIT_NORMAL,"Exited normally");
00402 return 0;
00403 }
00404
00405
00406
00407
00408
00409
00410
00412 void lissom_init_hooks(void)
00413 {
00414
00415 if (check_ind_types(False))
00416 ipc_exit(0,"Need to add definitions to ind_types.c for this architecture.");
00417
00418 ipc_init();
00419
00420
00421 setvbuf( stdout, NULL, _IONBF , 0);
00422
00423 #ifdef USE_READLINE_LIBRARY
00424 rl_attempted_completion_function = (CPPFunction *)command_prompt_completion;
00425 #endif
00426
00427 CMD_DOC(help,NULL,0,"%s [<options>]",
00428 "Try:\n\n"
00429
00430 " help parameters for general help using parameters and constants\n"
00431 " help parameters list for a concise list of the available parameters\n"
00432 " help parameters doc for help on all parameters\n"
00433 " help constants list for a concise list of the available constants\n"
00434 " help constants doc for help on all constants\n"
00435
00436 " help commands for general help using commands\n"
00437 " help commands list for a concise list of the available commands\n"
00438 " help commands doc for help on all commands\n"
00439
00440 " help usage for help on the command-line options\n"
00441 " help version for the date and number of this version of LISSOM\n"
00442
00443 " help <name> for help with a specific parameter, constant,\n"
00444 " or command");
00445
00446
00447 CMD_DOC(make_doc,NULL,0,"%s [<filename>]",
00448 "Create a file with the specified name containing all the help information\n"
00449 "available. It is currently formatted as an ASCII document.");
00450
00451
00452 globals_init_hook();
00453 file_io_init_hook();
00454 analyze_init_hook();
00455 kernel_init_hook();
00456
00457 ppm_init_hook();
00458 #ifndef NO_TILT
00459 tilt_init_hook();
00460 #endif
00461 binarysave_init_hook();
00462 cmdparam_init_hook();
00463
00464
00465 cmddefs_define_command_doc
00466 ("hook","%s <hook_location> <iteration_specifier> <command> [<arguments>]",
00467 "This command allows you to specify that any other command should be\n"
00468 "executed at a specified iteration or iterations.\n\n"
00469
00470 "The <command> and its <arguments> may be any valid command and any\n"
00471 "arguments that it accepts. Any command arguments are evaluated when the\n"
00472 "command is run, not when the hook is first defined.\n\n"
00473
00474 "The <iteration_specifier> should be of the (recursive) form:\n\n"
00475
00476 " <start_iteration>[-<end_iteration>[%<step>]][,<iteration_specifier>]\n\n"
00477
00478 "Each of the first three quantities may be a <term> as defined by the command\n"
00479 "`set', which means that any compound expressions must be parenthesized. For\n"
00480 "example, the <iteration_specifier> can be:\n\n"
00481
00482 " a single iteration (e.g. `1000'),\n"
00483 " a range of iterations (e.g. `1-1000'), \n"
00484 " a range with a stepsize (e.g. `1-1000%%10'), or\n"
00485 " a list of any of these (e.g. `1,10,100-200%%100,7,50-52,(tend-2)-tend').\n\n"
00486
00487 "In the first case, the command is executed only once, at iteration 1000,\n"
00488 "in the second it is executed 1000 times, once per iteration, in the third,\n"
00489 "it is executed 100 times, at iterations 10, 20, etc. (all those evenly\n"
00490 "divisible by 10), and in the last one it is executed at iterations 1,7,\n"
00491 "10,50,51,52,100,200,19998,19999, and 20000, assuming tend==20000. Note\n"
00492 "that the <iteration_specifier> must not contain any spaces.\n\n"
00493
00494 "The <hook_location> specifies where in the code the hook is checked\n"
00495 "for (and executed at the appropriate time.) Currently hooks can be\n"
00496 "inserted at the following locations within an iteration of the training\n"
00497 "or testing commands:\n\n"
00498
00499 " before_input: At the start of the training iteration, before input,\n"
00500 " activation, settling, or learning. Useful for setting parameters,\n"
00501 " loading a saved state, etc.\n\n"
00502
00503 " after_learning: At the end of the training iteration, after input,\n"
00504 " activation, settling, and learning. Useful for saving state,\n"
00505 " plotting, analyzing the activity, etc.\n\n"
00506
00507 "At a given hook_location and iteration, all the hooks that apply\n"
00508 "are executed in the order of their start_iteration and (if those\n"
00509 "match) the order in which they were defined.\n\n"
00510
00511 "Hooks can also be defined to execute multiple times within a given\n"
00512 "specified iteration or iterations(s) using the following hooklist:\n\n"
00513
00514 " after_presentation: After any input has been presented to the\n"
00515 " network subsequent to the original training or testing for an\n"
00516 " iteration. Useful primarily in conjunction with commands that\n"
00517 " present or modify input or network activation without advancing\n"
00518 " the iteration number, such as input_draw and input_present. For\n"
00519 " instance, such commands can be used to graph or analyze the\n"
00520 " response to a set of different inputs at periodic times during\n"
00521 " training without disrupting the network or the iteration numbers.\n\n"
00522
00523 "Examples:\n\n"
00524
00525 " hook before_input 501 set exc_rad=9 delta=0.12 beta=0.67\n"
00526 " hook before_input 1001 set exc_rad=6 delta=0.15 beta=0.65\n\n"
00527
00528 "These could be part of a training schedule that gradually reduces the\n"
00529 "excitation radius while increasing the slope of the sigmoid.\n\n"
00530
00531 " hook after_learning 1-100%%2 plot_activity\n"
00532 " hook after_learning 1000 plot_activity\n\n"
00533
00534 " hook after_learning 10000 kill_connections 0.0001\n\n"
00535
00536 "The top two specify 101 iterations at which the input and activity\n"
00537 "should be plotted. The next specifies that inhibitory weights smaller\n"
00538 "than 0.0001 should be pruned at iteration 10000.\n\n"
00539
00540 " hook after_presentation 1 analyze_portions\n"
00541 " hook after_learning 1 for f=0 f<PI f=f+PI/18 input_present_object \"\" Input_Gaussian f\n\n"
00542
00543 "The second line presents a variety of stimuli at iteration 1,\n"
00544 "while the first analyzes each presentation.");
00545
00546 cmddefs_exec_str("uninit_network");
00547 }
00548
00549
00550
00551
00552
00553
00554
00556 void wrong_usage(const char* filename)
00557 {
00558 if (AMPARENTPE)
00559 fprintf(stdout,usage,filename);
00560 ipc_exit(IPC_EXIT_WRONG_USAGE,"Wrong usage");
00561 }
00562
00563
00564
00566 void read_command_file_if_present(string name)
00567 {
00568 cmdparam_changes_verbose=network_initialized;
00569 FILE *file=fopen(name.c_str(),"r");
00570 if (file) {
00571 ipc_notify(IPC_ONE,IPC_STD,"Processing command file %s", name.c_str());
00572 fclose(file);
00573 if (cmddefs_exec_file(name.c_str()))
00574 ipc_abort(IPC_EXIT_FILE_PROBLEM,"Problem with command file %s",name.c_str());
00575 }
00576 }
00577
00578
00580 #define nextargis(string) (!strcmp(argv[nextarg],string) && nextarg++)
00581 #define argsleft (argc-nextarg)
00582
00589 void process_command_line_args(int argc, char **argv)
00590 {
00591 int force_interactive=Uninitialized;
00592 interactive=False;
00593 int nextarg=1;
00594
00595 while (nextarg<argc) {
00596
00597 if (nextargis("--help") || nextargis("-h"))
00598 fprintf(stdout,usage,argv[0]);
00599
00600 else if (nextargis("--batch")) interactive=force_interactive=False;
00601 else if (nextargis("--interactive")) interactive=force_interactive=True;
00602 else if (nextargis("--remote")) running_remotely=True;
00603 else if (nextargis("--display")) display=1;
00604 else if (nextargis("--verbose")) ipc_msg_level+=2;
00605 else if (nextargis("--quiet")) ipc_msg_level-=2;
00606
00607 else if (nextargis("--filebase")) {
00608 if (argsleft < 1)
00609 wrong_usage(argv[0]);
00610 else
00611 snprintf(filebase, MAXFILENAMELENGTH, "%s", argv[nextarg++]);
00612 }
00613
00614 else if (nextargis("--command")) {
00615 if (argsleft < 1)
00616 wrong_usage(argv[0]);
00617 else {
00618 ipc_init_logfile(filebase);
00619 cmddefs_exec_str(argv[nextarg++]);
00620 }
00621 }
00622
00623 else if (nextargis("--set")) {
00624 if (argsleft < 2)
00625 wrong_usage(argv[0]);
00626 else {
00627 cmdparam_set(argv[nextarg],argv[nextarg+1]);
00628 nextarg+=2;
00629 }
00630 }
00631
00632 else if (nextargis("--train")) {
00633 ipc_init_logfile(filebase);
00634 cmddefs_exec_str("training");
00635 interactive=False;
00636 }
00637
00638 else if (nextargis("--test")) {
00639 ipc_init_logfile(filebase);
00640 cmddefs_exec_str("testing");
00641 interactive=False;
00642 }
00643
00644 else {
00645 if (!strncmp(argv[nextarg],"--",2)) {
00646 if (nextargis("--file"));
00647 else
00648 wrong_usage(argv[0]);
00649 }
00650
00651 if (argsleft < 1)
00652 wrong_usage(argv[0]);
00653 else {
00654 if (!has_command_file) {
00655 has_command_file=True;
00656 set_filebase(argv[nextarg]);
00657 ipc_init_logfile(filebase);
00658 }
00659 00660
00661 cmdparam_changes_verbose=network_initialized;
00662
00663
00664 if (cmddefs_exec_file(argv[nextarg]))
00665 ipc_abort(IPC_EXIT_FILE_PROBLEM,"Problem with command file %s",
00666 argv[nextarg]);
00667 cmdparam_changes_verbose=True;
00668 }
00669
00670 nextarg++;
00671 }
00672 }
00673
00674
00675 if (force_interactive == Uninitialized && !network_initialized)
00676 interactive=True;
00677 }
00678 #undef argsleft
00679 #undef nextargis
00680
00681
00682
00687 void set_filebase(char *commandfilename)
00688 {
00689 snprintf(filebase, MAXFILENAMELENGTH, "%s", commandfilename);
00690 {
00691 char *extension= strrchr(filebase,'.');
00692 if (extension && !strncmp(".param", extension, MAXFILENAMELENGTH))
00693 filebase[extension-filebase]='\0';
00694 }
00695 }
00696
00697
00698
00700 int get_line_from_prompt( void )
00701 {
00702 char prompt[MAX_PROMPT_CHARS];
00703 char *lineptr=NULL;
00704
00705 snprintf(prompt, MAX_PROMPT_CHARS, "lissom.t%d.p%d.c%d> ",iteration,presentation,command_num_called);
00706
00707 #ifdef USE_READLINE_LIBRARY
00708 lineptr= readline(prompt);
00709 if (lineptr) {
00710 if (*lineptr) add_history(lineptr);
00711 strncpy(cmddefs_line_buffer,lineptr,CMD_MAX_LINE_LENGTH+1);
00712 free(lineptr);
00713 lineptr=cmddefs_line_buffer;
00714 }
00715 else
00716 fprintf(stdout,"\n");
00717 #else
00718 fprintf(stdout,prompt);
00719 lineptr = fgets(cmddefs_line_buffer,CMD_MAX_LINE_LENGTH+1,stdin);
00720 #endif
00721
00722 return (lineptr==NULL);
00723 }
00724
00725
00726
00727 #ifdef USE_READLINE_LIBRARY
00728 char ** command_prompt_completion (char *text, int start, int end)
00729 {
00730 (void)end;
00731
00732
00733 return (start==0 ?
00734 completion_matches(text, cmddefs_completion_generator) :
00735 completion_matches(text, params_completion_generator) );
00736 }
00737 #endif
00738
00739
00740
00741 #define COMPAREARG(arg,string) (argc>(arg) && !strcmp(argv[arg],string))
00742 cmdstat cmd_help( CMD_ARGS )
00743 {
00744 if (AMPARENTPE) {
00745
00746
00747 if (COMPAREARG(0,"parameters")) {
00748 if (COMPAREARG(1,"list")) params_print_parameters(stdout);
00749 else if (COMPAREARG(1,"doc")) params_print_parameters_doc(stdout);
00750 else fprintf(stdout,param_help_string);
00751 }
00752
00753
00754 if (COMPAREARG(0,"constants")) {
00755 if (COMPAREARG(1,"list")) params_print_constants(stdout);
00756 else if (COMPAREARG(1,"doc")) params_print_constants_doc(stdout);
00757 else fprintf(stdout,param_help_string);
00758 }
00759
00760
00761 else if (COMPAREARG(0,"commands")) {
00762 if (COMPAREARG(1,"list")) cmddefs_print_all(stdout);
00763 else if (COMPAREARG(1,"doc")) cmddefs_print_all_doc(stdout);
00764 else fprintf(stdout,cmd_help_string);
00765 }
00766
00767
00768 else if (COMPAREARG(0,"files")) fprintf(stdout,file_types_string,"lissom");
00769 else if (COMPAREARG(0,"usage")) fprintf(stdout,usage,"lissom");
00770 else if (COMPAREARG(0,"version")) {
00771 if (AMPARENTPE)
00772 fprintf(stdout,"This is version %s of LISSOM, compiled on %s at %s.\n",
00773 lissom_version,__DATE__, __TIME__);
00774 }
00775
00776
00777 else if (argc>0 && cmdparams_print_doc(stdout, argv[0]));
00778
00779
00780 else
00781 cmddefs_print_doc(stdout,"help");
00782 }
00783
00784 return CMD_NO_ERROR;
00785 }
00786 #undef COMPARE_ARG
00787
00789 #define NEW_SECTION(name) \
00790 fprintf(file,"\nSECTION: " #name "\n\n")
00791
00793 #define NEW_SUBSECTION(name) \
00794 fprintf(file,"\nSUBSECTION: " #name "\n\n")
00795
00797 cmdstat cmd_make_doc( CMD_ARGS )
00798 {
00799 const char *filename=(argc>0 ? cmds(argv[0]) : "USERDOC");
00800
00801 if (AMPARENTPE) {
00802 FILE *file;
00803 if ((file=fopen(filename,"w+"))==NULL){
00804 ipc_notify(IPC_ALL,IPC_ERROR,"Could not open output file %s", filename);
00805 return CMD_FILE_ERROR;
00806 }
00807
00808 fprintf(file,title_string,lissom_version,__DATE__, __TIME__);
00809
00810 NEW_SECTION(INTRODUCTION);
00811 fprintf(file,intro_string);
00812
00813 NEW_SECTION(USAGE);
00814 fprintf(file,usage,"lissom");
00815
00816 NEW_SECTION(PARAMETERS);
00817 fprintf(file,param_help_string);
00818 fprintf(file,"\nList of valid parameters:\n\n");
00819 params_print_parameters(file);
00820
00821 NEW_SUBSECTION(PARAMETER DOCUMENTATION);
00822 params_print_parameters_doc(file);
00823
00824 NEW_SECTION(CONSTANTS);
00825 fprintf(file,"\nList of valid constants:\n\n");
00826 params_print_constants(file);
00827
00828 NEW_SUBSECTION(CONSTANT DOCUMENTATION);
00829 params_print_constants_doc(file);
00830
00831 NEW_SECTION(COMMANDS);
00832 fprintf(file,cmd_help_string);
00833 fprintf(file,"\nList of valid commands:\n\n");
00834 cmddefs_print_all(file);
00835
00836 NEW_SUBSECTION(COMMAND DOCUMENTATION);
00837 cmddefs_print_all_doc(file);
00838
00839 NEW_SECTION(FILES);
00840 fprintf(file,file_types_string,"lissom");
00841
00842 fclose(file);
00843 }
00844
00845 ipc_notify(IPC_ONE,IPC_STD,"Created documentation file %s",filename);
00846
00847 return CMD_NO_ERROR;
00848 }
00849 #undef NEW_SECTION
00850 #undef NEW_SUBSECTION
00851