source: trunk/src/testing/src/fsConsole.cpp @ 4

Revision 4, 22.3 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1/******************************************************************************
2 * SAGE - Scalable Adaptive Graphics Environment
3 *
4 * Module: fsConsole.cpp - a UI console to control the Free Space Manager
5 * Author : Luc Renambot, Byungil Jeong
6 *
7 * Copyright (C) 2004 Electronic Visualization Laboratory,
8 * University of Illinois at Chicago
9 *
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are met:
14 *
15 *  * Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions and the following disclaimer.
17 *  * Redistributions in binary form must reproduce the above
18 *    copyright notice, this list of conditions and the following disclaimer
19 *    in the documentation and/or other materials provided with the distribution.
20 *  * Neither the name of the University of Illinois at Chicago nor
21 *    the names of its contributors may be used to endorse or promote
22 *    products derived from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 *
36 * Direct questions, comments etc about SAGE to sage_users@listserv.uic.edu or
37 * http://www.evl.uic.edu/cavern/forum/
38 *
39 *****************************************************************************/
40
41#include "suil.h"
42#include "misc.h"
43#include <pthread.h>
44
45#include <stdio.h>
46#include <stdlib.h>
47#include <string.h>
48
49#include <readline/readline.h>
50#include <readline/history.h>
51
52#if defined(SAGE_NETLOG)
53#include "nl_log.h"
54#endif
55
56// SAGE object
57suil uiLib;
58
59// Application list
60typedef struct _application_t
61{
62   char *name;
63   int   id;
64   FILE *log;
65} application_t;
66
67application_t *Applications[64];
68FILE *playback;
69
70// When non-zero, this means the user is done using this program.
71int done;
72bool zeroPerf;
73char execArg[256];
74int noRecv, noSend, dispX, dispY, rendX, wholeX, intval = 0;
75
76// A static variable for holding the line.
77static char *line_read = (char *)NULL;
78static char current_command[256];
79static char exec_arg[256];
80
81// The names of functions that actually do the work
82int com_help     (char *arg);
83int com_exit     (char *arg);
84int com_exec     (char *arg);
85int com_move     (char *arg);
86int com_resize   (char *arg);
87int com_bg       (char *arg);
88int com_depth    (char *arg);
89int com_perf     (char *arg);
90int com_zeroperf (char *arg);
91int com_stopperf (char *arg);
92int com_kill     (char *arg);
93int com_shutdown (char *arg);
94int com_admin    (char *arg);
95int com_rate     (char *arg);
96int com_intval   (char *arg);
97int com_ptr      (char *arg);
98int com_share    (char *arg);
99
100
101
102// A structure which contains information on the commands
103// this program can understand.
104
105typedef struct {
106   const char *name;                   // User printable name of the function.
107   rl_icpfunc_t *func;           // Function to call to do the job.
108   const char *doc;                    // Documentation for this function.
109} COMMAND;
110
111//###
112COMMAND commands[] = {
113
114   { "exec",     com_exec,
115     "Execute an application: <exec app_name config_num (init_x init_y)>" },
116   { "move",     com_move,
117     "Move the window of an application: <move app_id dx dy>" },
118   { "resize",   com_resize,
119     "Resize the window of an application: <resize app_id left right bottom top>" },
120   { "bg",       com_bg,
121     "Change background color: <bg red green blue>" },
122   { "depth",    com_depth,
123     "Change z-order of the windows: <depth #_of_change app_id1 zVal1 ...>" },
124   { "perf",     com_perf,
125     "Request performance information: <perf app_id report_period(sec)>" },
126   { "stopperf", com_stopperf,
127     "Stop performance information report: <stopperf app_id>" },
128   { "zeroperf", com_zeroperf,
129     "set performance numbers zero: <zeroperf>" },
130   { "kill",     com_kill,
131     "Kill an application: <kill app_id>" },
132   { "shutdown", com_shutdown,
133     "Shutdown SAGE: <shutdown>" },
134   { "admin",    com_admin,
135     "Get administrative information and status: <admin>" },
136
137   { "ptr", com_ptr, "Move the pointer: <move dx dy>" },
138
139   { "help", com_help, "Display this text: <help>" },
140   { "exit", com_exit, "Quit the console: <exit>" },
141   { "quit", com_exit, "Quit the console: <quit>" },
142   { "rate", com_rate, "change the frame rate of apps: <rate app_id frame_rate>" },
143   { "intval", com_intval, "change the pause interval of the udp stream : <intval app_id interval>" },
144   { "share", com_share, "sharing app to another fsManager : <share app_id fs_IP fs_port>" },
145   { "?",    com_help, "Synonym for help: <?>" },
146
147   { (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL }
148};
149//###
150
151
152// Functions locally defined
153void*  readThread(void *args);
154char*  dupstr (char *s);
155char*  rl_gets (const char *prompt);
156char*  command_generator (const char * text, int state);
157char** fileman_completion (const char * text, int start, int end);
158char*  stripwhite (char *thestring);
159int    execute_line (char *line);
160
161COMMAND* find_command (char *name);
162
163////////////////////////////////////////////////////////////////////////////////
164
165
166void* readThread(void *args)
167{
168   suil *uiLib = (suil *)args;
169   int timestep = 1;
170
171   while (1)
172   {
173      sageMessage msg;
174
175      msg.init(READ_BUF_SIZE);
176      uiLib->rcvMessageBlk(msg);
177
178      if (msg.getCode() == APP_INFO_RETURN)
179      {
180         char appname[256], cmd[256];
181         int ret;
182         int appID, left, right, bottom, top, sailID, zValue;
183
184         ret = sscanf((char*)msg.getData(), "%s %d %d %d %d %d %d %d",
185                        appname, &appID, &left, &right, &bottom, &top, &sailID, &zValue);
186
187         if (ret != 8)
188               fprintf(stderr, "Something wrong, got only %d fields\n", ret);
189         else
190         {
191            if (Applications[appID] == NULL)
192            {
193               Applications[appID] = (application_t*)malloc(sizeof(application_t));
194               Applications[appID]->id   = appID;
195               Applications[appID]->name = strdup(appname);
196 
197               // Get local time
198               time_t local = time(NULL);
199               struct tm *current = localtime( & local );
200
201               // Create a file for each application
202               char fn[256];
203               memset(fn, 0, 256);
204
205                char *sageDir = getenv("SAGE_DIRECTORY");
206                if (!sageDir) {
207                        sage::printLog("fsConsole: cannot find the environment variable SAGE_DIRECTORY");
208                        return NULL;
209                }
210
211                data_path path;
212                std::string found = path.get_file("log");
213                if (found.empty()) {
214                        sage::printLog("fsConsole: cannot find the directory [%s]", "log");
215                        return NULL;
216                }
217                const char *logPath = found.c_str();
218                       
219                    /*
220                    if (noRecv == 0) {
221                       sprintf(fn, "log/%s-%d-%d-%d-%d-%d-%d.log", // year-month-day hour-minute-second
222                            Applications[appID]->name,
223                            current->tm_year, current->tm_mon, current->tm_mday,
224                            current->tm_hour, current->tm_min, current->tm_sec);
225                    }
226                    else {   
227                        sprintf(fn, "log/%s-r%d-s%d-%dx%d-i%d.log", Applications[appID]->name,
228                              noRecv, noSend, dispX, dispY, intval);
229                    }         
230                    */
231
232                sprintf(fn, "%s/%s-%s.log", logPath, Applications[appID]->name, execArg);
233                sage::printLog("fsConsole: opening [%s] log file", fn);
234               Applications[appID]->log = fopen(fn, "w+");
235                   
236               if (noRecv > 0) {
237                  fprintf(Applications[appID]->log,
238                           "%s rcv %d send %d dispRes %d %d rendRes %d %d whole %d %d int %d\n",
239                           Applications[appID]->name,
240                           noRecv, noSend, dispX, dispY, rendX, dispY, wholeX, dispY, intval);
241               }     
242
243#if defined(SAGE_NETLOG)
244               memset(fn, 0, 256);
245               sprintf(fn, "log/%s-%d-%d-%d-%d-%d-%d.nlg", // year-month-day hour-minute-second
246               Applications[appID]->name,
247                           current->tm_year, current->tm_mon, current->tm_mday,
248                           current->tm_hour, current->tm_min, current->tm_sec);
249               NL_logger_module( Applications[appID]->name, fn, NL_LVL_INFO, NL_TYPE_APP, "" );
250#endif
251
252               memset(cmd, 0, 256);
253               sprintf(cmd, "%d", appID);
254               uiLib->sendMessage(STOP_PERF_INFO, cmd);
255                   
256               memset(cmd, 0, 256);
257               sprintf(cmd, "%d %d", appID, 1); // every second
258               uiLib->sendMessage(PERF_INFO_REQ, cmd);                   
259            }
260         }
261      }
262       
263      else if (msg.getCode() == UI_APP_SHUTDOWN)
264      {
265         int ret;
266         int appID;
267
268         ret = sscanf((char*)msg.getData(), "%d", &appID);
269         if (ret != 1)
270               fprintf(stderr, "Something wrong, got only %d fields\n", ret);
271         else
272         {
273            if (Applications[appID]->log)
274            {
275               fprintf(stderr, "Closing log file for application [%s]\n", Applications[appID]->name);
276               fclose(Applications[appID]->log);
277            }
278         }
279           
280      }
281       
282      else if (msg.getCode() == UI_PERF_INFO)
283      {
284         char appname[256], cmd[256];
285         int ret;
286         int appID, dispNodes, renderNodes, numStreamR;
287         float dispBandWidth, dispFrameRate, renderBandWidth, renderFrameRate, packetLoss;
288
289         ret = sscanf((char*)msg.getData(), "%d\nDisplay %f %f %f %d\nRendering %f %f %d",
290                        &appID,
291                        &dispBandWidth, &dispFrameRate, &packetLoss, &dispNodes,
292                        &renderBandWidth, &renderFrameRate, &renderNodes);
293
294         if (ret != 8)
295               fprintf(stderr, "Something wrong, got only %d fields\n", ret);
296         else
297         {
298            if (zeroPerf) {
299               fprintf(Applications[appID]->log, "%d 0.0 0.0 0.0 0.0 %d %d %s\n", timestep, dispNodes, renderNodes, exec_arg);
300            }
301            else {         
302               fprintf(Applications[appID]->log, "%d %f %f %f %f %f %d %d %s\n",
303                        timestep, dispBandWidth, dispFrameRate, packetLoss, renderBandWidth,
304                        renderFrameRate, dispNodes, renderNodes, exec_arg);
305            }
306                       
307            fflush(Applications[appID]->log);
308               
309#if defined(SAGE_NETLOG)
310            NL_flush = 1;
311            NL_write( Applications[appID]->name, NL_LVL_INFO, "display", "bandwidth=d framerate=d", dispBandWidth, dispFrameRate);
312            NL_write( Applications[appID]->name, NL_LVL_INFO, "render",  "bandwidth=d framerate=d", renderBandWidth, renderFrameRate);
313#endif
314
315            timestep += 1;
316         }
317      }
318
319      else
320      {
321         fprintf(stdout, "\n\tMessage: %d\n\t[%s]\n", msg.getCode(), (char *)msg.getData());
322      }
323
324   }
325
326   return NULL;
327}
328
329
330
331char *dupstr (const char *s)
332{
333   char *r;
334
335   r = (char*)malloc (strlen (s) + 1);
336   strcpy (r, s);
337   return (r);
338}
339
340// Read a string, and return a pointer to it.
341// Returns NULL on EOF.
342char *rl_gets (const char *prompt)
343{
344  /* If the buffer has already been allocated,
345     return the memory to the free pool. */
346   if (line_read)
347   {
348      free (line_read);
349      line_read = (char *)NULL;
350   }
351
352  /* Get a line from the user. */
353   line_read = readline (prompt);
354
355  /* If the line has any text in it,
356     save it on the history. */
357   if (line_read && *line_read) add_history (line_read);
358
359   return (line_read);
360}
361
362// Generator function for command completion.  STATE lets us
363//   know whether to start from scratch; without any state
364//   (i.e. STATE == 0), then we start at the top of the list.
365char*
366command_generator (const char * text, int state)
367{
368   static int list_index, len;
369   const char *name;
370
371        /* If this is a new word to complete, initialize now.  This
372           includes saving the length of TEXT for efficiency, and
373           initializing the index variable to 0. */
374   if (!state)
375   {
376      list_index = 0;
377      len = strlen (text);
378   }
379
380        /* Return the next name which partially matches from the
381           command list. */
382   while (name = commands[list_index].name)
383   {
384      list_index++;
385
386      if (strncmp (name, text, len) == 0)
387      {
388         memset(current_command, 0, 256);
389         strcpy(current_command, name);
390         return dupstr(name);
391      }
392   }
393
394        /* If no names matched, then return NULL. */
395   return ((char *)NULL);
396}
397
398// Attempt to complete on the contents of TEXT.  START and END
399//   bound the region of rl_line_buffer that contains the word to
400//   complete.  TEXT is the word to complete.  We can use the entire
401//   contents of rl_line_buffer in case we want to do some simple
402//   parsing.  Returnthe array of matches, or NULL if there aren't any.
403char**
404fileman_completion (const char * text, int start, int end)
405{
406   char **matches;
407   
408   matches = (char **)NULL;
409
410        /* If this word is at the start of the line, then it is a command
411           to complete.  Otherwise it is the name of a file in the current
412           directory. */
413   if (start == 0)
414   {
415      matches = rl_completion_matches (text, command_generator);
416   }
417   else
418   {
419      // If match found, display the corresponding documentation
420      COMMAND *cm = find_command(current_command);
421      if (cm)
422      {
423         matches = (char**)malloc(3*sizeof(char*));
424         matches[0] = dupstr("");
425         matches[1] = dupstr(cm->doc);
426         matches[2] = NULL;
427      }
428   }
429   
430   return (matches);
431}
432
433// Look up NAME as the name of a command, and return a pointer to that
434//   command.  Return a NULL pointer if NAME isn't a command name.
435COMMAND *find_command (char *name)
436{
437   register int i;
438
439   for (i = 0; commands[i].name; i++)
440      if (strcmp (name, commands[i].name) == 0)
441      return (&commands[i]);
442
443   return ((COMMAND *)NULL);
444}
445
446// Strip whitespace from the start and end of STRING.  Return a pointer
447//   into STRING.
448char* stripwhite (char *thestring)
449{
450   register char *s, *t;
451
452   for (s = thestring; whitespace (*s); s++)
453      ;
454   
455   if (*s == 0)
456      return (s);
457
458   t = s + strlen (s) - 1;
459   while (t > s && whitespace (*t))
460      t--;
461   *++t = '\0';
462
463   return s;
464}
465
466
467
468// Execute a command line
469int execute_line (char *line)
470{
471   register int i;
472   COMMAND *command;
473   char *word;
474
475        /* Isolate the command word. */
476   i = 0;
477   while (line[i] && whitespace (line[i]))
478      i++;
479   word = line + i;
480
481   while (line[i] && !whitespace (line[i]))
482      i++;
483
484   if (line[i])
485      line[i++] = '\0';
486
487   command = find_command (word);
488
489   if (!command)
490   {
491      fprintf (stderr, "%s: No such command.\n", word);
492      return (-1);
493   }
494
495        /* Get argument to command, if any. */
496   while (whitespace (line[i]))
497      i++;
498
499   word = line + i;
500
501        /* Call the function. */
502   return ((*(command->func)) (word));
503}
504
505
506int
507main(int argc, char **argv)
508{
509   pthread_t thId;   
510   char *line, *s;
511   char com[256];
512
513   zeroPerf = false;
514   
515   // File containing commands
516   playback = NULL;
517   if (argc >= 2)
518   {
519      playback = fopen(argv[1], "r");
520      if (playback == NULL)
521            fprintf(stderr, "Cannot open playback file <%s>\n", argv[1]);   
522   }
523
524   if (argc > 2) {
525      strcpy(execArg, argv[2]);
526   }
527   else
528      strcpy(execArg, "no");
529     
530   if (argc > 8)
531      intval = atoi(argv[8]);   
532   
533   // Setup the completion function
534   rl_attempted_completion_function = fileman_completion;
535   
536   // Clear application list
537   for (int k=0;k<64;k++) Applications[k] = NULL;
538
539   // Connect to SAGE
540   uiLib.init("fsManager.conf");
541   uiLib.connect(NULL);
542   
543   uiLib.sendMessage(SAGE_UI_REG," ");
544
545   // Start the receiving thread
546   if(pthread_create(&thId, 0, readThread, (void*)&uiLib) != 0)
547   {
548      return -1;
549   }
550
551#if defined(SAGE_NETLOG)
552   // Get local time
553   time_t local = time(NULL);
554   struct tm *current = localtime( & local );
555   char fn[256];
556   
557   memset(fn, 0, 256);
558   sprintf(fn, "log/%s-%d-%d-%d-%d-%d-%d.nlg", // year-month-day hour-minute-second
559   "fsConsole",
560            current->tm_year, current->tm_mon, current->tm_mday,
561            current->tm_hour, current->tm_min, current->tm_sec);
562   NL_logger_module( "fsConsole", fn, NL_LVL_INFO, NL_TYPE_APP, "" );
563#endif
564
565        /* Loop reading and executing lines until the user quits. */
566   for ( ; done == 0; )
567   {
568      if (playback && !feof(playback))
569      {
570         memset(com, 0, 256);
571         if ( fgets(com, 256, playback) )
572         {
573            // trailing \n
574            com[ strlen(com)-1 ] = '\0';
575            s = stripwhite (com);
576            int v, pause;   
577            v = sscanf(s, "pause %d", &pause);
578            if (v == 1)
579            {
580               fprintf(stderr, "PB> Pausing %d sec\n", pause);
581               sleep(pause);
582            }
583            else
584                  if (*s)
585            {
586               add_history (s);
587               fprintf(stderr, "PB> Exec <%s>\n", s);
588               execute_line (s);
589            }
590         }
591      }
592      else
593      {
594         line = rl_gets(">>> ");
595       
596         if (!line) break;
597     
598                /* Remove leading and trailing whitespace from the line.
599                   Then, if there is anything left, add it to the history list
600                   and execute it. */
601         s = stripwhite (line);
602     
603         if (*s)
604         {
605            add_history (s);
606            execute_line (s);
607         }
608      }
609   }
610   
611   // Close the command file
612   if (playback != NULL)
613      fclose(playback);
614   
615   return 0;
616}
617
618
619
620
621
622// ****************************************************************
623//                                                                 
624//                               Commands                         
625//                                                                 
626// ****************************************************************
627
628
629int com_exec (char *arg)
630{
631#if defined(SAGE_NETLOG)
632   NL_flush = 1;
633   NL_write( "fsConsole", NL_LVL_INFO, "exec", "arg=s", arg);
634#endif
635   uiLib.sendMessage(EXEC_APP, arg);   
636   strcpy(exec_arg, arg);
637   return 0;
638}
639
640int com_move (char *arg)
641{
642#if defined(SAGE_NETLOG)
643   NL_flush = 1;
644   NL_write( "fsConsole", NL_LVL_INFO, "move", "arg=s", arg);
645#endif
646   uiLib.sendMessage(MOVE_WINDOW, arg);
647   return 0;
648}
649
650int com_ptr (char *arg)
651{
652#if defined(SAGE_NETLOG)
653   NL_flush = 1;
654   NL_write( "fsConsole", NL_LVL_INFO, "ptr", "arg=s", arg);
655#endif
656   uiLib.sendMessage(MOVE_OBJECT, arg);
657   return 0;
658}
659
660int com_resize (char *arg)
661{
662#if defined(SAGE_NETLOG)
663   NL_flush = 1;
664   NL_write( "fsConsole", NL_LVL_INFO, "resize", "arg=s", arg);
665#endif
666   uiLib.sendMessage(RESIZE_WINDOW, arg);
667   return 0;
668}
669
670int com_bg (char *arg)
671{
672#if defined(SAGE_NETLOG)
673   NL_flush = 1;
674   NL_write( "fsConsole", NL_LVL_INFO, "bg", "arg=s", arg);
675#endif
676   uiLib.sendMessage(SAGE_BG_COLOR, arg);
677   return 0;
678}
679
680int com_depth (char *arg)
681{
682#if defined(SAGE_NETLOG)
683   NL_flush = 1;
684   NL_write( "fsConsole", NL_LVL_INFO, "depth", "arg=s", arg);
685#endif
686   uiLib.sendMessage(SAGE_Z_VALUE, arg);
687   return 0;
688}
689
690int com_zeroperf (char *arg)
691{
692   zeroPerf = true;
693   return 0;
694}
695
696int com_rate (char *arg)
697{
698   uiLib.sendMessage(APP_FRAME_RATE, arg);
699   return 0;
700}
701
702int com_intval (char *arg)
703{
704   uiLib.sendMessage(APP_PAUSE_INTV, arg);
705   return 0;
706}
707
708int com_share (char *arg)
709{
710   uiLib.sendMessage(SAGE_APP_SHARE, arg);
711   return 0;
712}
713
714int com_perf (char *arg)
715{
716#if defined(SAGE_NETLOG)
717   NL_flush = 1;
718   NL_write( "fsConsole", NL_LVL_INFO, "perf", "arg=s", arg);
719#endif
720   zeroPerf = false;
721   uiLib.sendMessage(PERF_INFO_REQ, arg);
722   return 0;
723}
724
725int com_stopperf (char *arg)
726{
727#if defined(SAGE_NETLOG)
728   NL_flush = 1;
729   NL_write( "fsConsole", NL_LVL_INFO, "stopperf", "arg=s", arg);
730#endif
731   uiLib.sendMessage(STOP_PERF_INFO, arg);
732   return 0;
733}
734
735int com_kill (char *arg)
736{
737#if defined(SAGE_NETLOG)
738   NL_flush = 1;
739   NL_write( "fsConsole", NL_LVL_INFO, "kill", "arg=s", arg);
740#endif
741   uiLib.sendMessage(SHUTDOWN_APP, arg);
742   return 0;
743}
744
745int com_shutdown (char *arg)
746{
747#if defined(SAGE_NETLOG)
748   //NL_flush = 1;
749   //NL_write( "fsConsole", NL_LVL_INFO, "shutdown", "arg=s", arg);
750#endif
751   // Close all the log files
752   for (int k=0;k<64;k++)
753      if (Applications[k])
754      fclose(Applications[k]->log);
755
756#if defined(SAGE_NETLOG)
757   NL_logger_del();
758#endif
759
760   // Send the message
761   uiLib.sendMessage(SAGE_SHUTDOWN, "shutdown");
762   done = 1;
763   
764   return 0;
765}
766
767int com_admin (char *arg)
768{
769#if defined(SAGE_NETLOG)
770   NL_flush = 1;
771   NL_write( "fsConsole", NL_LVL_INFO, "admin", "arg=s", arg);
772#endif
773   uiLib.sendMessage(SAGE_ADMIN_CHECK, "admin");
774   return 0;
775}
776
777
778// Print out help for ARG, or for all of the commands
779//   if ARG is not present.
780int com_help (char *arg)
781{
782   register int i;
783   int printed = 0;
784
785#if defined(SAGE_NETLOG)
786   NL_flush = 1;
787   NL_write( "fsConsole", NL_LVL_INFO, "help", "arg=s", arg);
788#endif
789
790   for (i = 0; commands[i].name; i++)
791   {
792      if (!*arg || (strcmp (arg, commands[i].name) == 0))
793      {
794         printf ("%-8s\t\t%s.\n", commands[i].name, commands[i].doc);
795         printed++;
796      }
797   }
798
799   if (!printed)
800   {
801      printf ("No commands match `%s'.  Possibilties are:\n", arg);
802
803      for (i = 0; commands[i].name; i++)
804      {
805                /* Print in six columns. */
806         if (printed == 6)
807         {
808            printed = 0;
809            printf ("\n");
810         }
811
812         printf ("%s\t", commands[i].name);
813         printed++;
814      }
815
816      if (printed)
817            printf ("\n");
818   }
819   return (0);
820}
821
822// The user wishes to quit using this program.
823//   Just set DONE non-zero.
824int com_exit (char *arg)
825{
826#if defined(SAGE_NETLOG)
827   NL_flush = 1;
828   NL_write( "fsConsole", NL_LVL_INFO, "exit", "arg=s", arg);
829#endif
830
831   std::cout << "\t Done with SAGE..." << std::endl;
832
833   done = 1;
834   return (0);
835}
Note: See TracBrowser for help on using the repository browser.