home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1169 / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  3.7 KB  |  205 lines

  1. /*
  2.  * Tcl command -- provide a Tcl CLI-command with awk-like command syntax
  3.  *
  4.  * Copyright 1990 Hackercorp
  5.  * Permission to use, copy, modify, and distribute this
  6.  * software and its documentation for any purpose and without
  7.  * fee is hereby granted, provided that the above copyright
  8.  * notice appear in all copies.  Hackercorp makes no
  9.  * representations about the suitability of this software for
  10.  * any purpose.  It is provided "as is" without express or
  11.  * implied warranty.
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <tcl.h>
  17.  
  18. void
  19.         print_result(fp, returnval, result_text)
  20. FILE   *fp;
  21. int     returnval;
  22. char   *result_text;
  23. {
  24.     if (returnval == TCL_OK)
  25.     {
  26.         if (result_text && *result_text != 0)
  27.         {
  28.             fprintf(fp, "%s\n", result_text);
  29.         }
  30.     }
  31.     else
  32.     {
  33.         fprintf(stderr, "%s: %s\n",
  34.               (returnval == TCL_ERROR) ? "Error" : "Bad return code",
  35.             result_text);
  36.     }
  37. }
  38.  
  39. int
  40.         cmdGetEnv(clientData, interp, argc, argv)
  41. ClientData clientData;               /* Not used. */
  42. Tcl_Interp *interp;
  43. int     argc;
  44. int    *argv;
  45. {
  46.     char   *getenv();
  47.  
  48.     if (argc != 2)
  49.     {
  50.         sprintf(interp->result, "wrong # args:  should be \"%.50s name\"",
  51.             argv[0]);
  52.         return TCL_ERROR;
  53.     }
  54.     Tcl_Return(interp, getenv(argv[1]), TCL_STATIC);
  55.     return TCL_OK;
  56. }
  57.  
  58. int
  59.         main(argc, argv)
  60. int     argc;
  61. char  **argv;
  62. {
  63.     Tcl_Interp *interp;
  64.     int     result;
  65.  
  66.     interp = Tcl_CreateInterp();
  67.     Tcl_CreateCommand(interp, "getenv", cmdGetEnv, (ClientData) NULL,
  68.               (void (*)()) NULL);
  69.     stream_init(interp);
  70.  
  71.     /*
  72.      * if no arguments, give the user a Tcl command prompt
  73.      * 
  74.      * if first arg is "-f", the following arg is a file name to do a
  75.      * "source" command on (to get Tcl to load the file)
  76.      * 
  77.      * argv is set to be a list of arguments that follow the filename or an
  78.      * empty string if there are none
  79.      * 
  80.      * if there arguments but there wasn't a -f, they are evaluated as a
  81.      * command by the tcl interpreter
  82.      */
  83.  
  84.     if (argc == 1)
  85.         commandloop(interp, stdin, stdout, 1);
  86.     else if ((argc >= 3) && (strcmp(argv[1], "-f") == 0))
  87.     {
  88.         FILE *fp;
  89.  
  90.         if (argc > 3)
  91.         {
  92.             char   *args;
  93.  
  94.             args = Tcl_Merge(argc - 3, &argv[3]);
  95.             Tcl_SetVar(interp, "argv", args, 1);
  96.             ckfree(args);
  97.         }
  98.  
  99.         fp = fopen(argv[2], "r");
  100.         if(!fp) {
  101.             perror(argv[2]);
  102.         } else {
  103.             commandloop(interp, fp, stdout, 0);
  104.             fclose(fp);
  105.         }
  106.     }
  107.     else
  108.     {
  109.         if (argc > 2)
  110.         {
  111.             char   *args;
  112.  
  113.             args = Tcl_Merge(argc - 2, &argv[2]);
  114.             Tcl_SetVar(interp, "argv", args, 1);
  115.             ckfree(args);
  116.         }
  117.  
  118.         result = Tcl_Eval(interp, argv[1], 0, (char **)NULL);
  119.         print_result(stdout, result, interp->result);
  120.     }
  121.  
  122.     Tcl_DeleteInterp(interp);
  123.     exit(0);
  124. }
  125.  
  126. commandloop(interp, in, out, interactive)
  127. Tcl_Interp *interp;
  128. FILE   *in;
  129. FILE   *out;
  130. int     interactive;
  131. {
  132.     char *cmd;
  133.     char *p;
  134.     register char *p2;
  135.     int     c, i, result;
  136.  
  137.     cmd = (char *)ckalloc(32767);
  138.     while (1)
  139.     {
  140.         if (interactive)
  141.         {
  142.             clearerr(in);
  143.             fputs("% ", out);
  144.             fflush(out);
  145.         }
  146.         p = cmd;
  147.         while (1)
  148.         {
  149.             c = getc(in);
  150.             if (c == EOF)
  151.             {
  152.                 if (p == cmd)
  153.                 {
  154.                     goto endOfFile;
  155.                 }
  156.                 goto gotCommand;
  157.             }
  158.             if (c == '\n')
  159.             {
  160.                 register char *p2;
  161.                 int     parens, brackets, numBytes;
  162.  
  163.                 parens = 0;
  164.                 brackets = 0;
  165.                 for (p2 = cmd; p2 < p; p2++)
  166.                 {
  167.                     switch (*p2)
  168.                     {
  169.                         case '\\':
  170.                         Tcl_Backslash(p2, &numBytes);
  171.                         p2 += numBytes - 1;
  172.                         break;
  173.                         case '{':
  174.                         parens++;
  175.                         break;
  176.                         case '}':
  177.                         parens--;
  178.                         break;
  179.                         case '[':
  180.                         brackets++;
  181.                         break;
  182.                         case ']':
  183.                         brackets--;
  184.                         break;
  185.                     }
  186.                 }
  187.                 if ((parens <= 0) && (brackets <= 0))
  188.                 {
  189.                     goto gotCommand;
  190.                 }
  191.             }
  192.             *p = c;
  193.             p++;
  194.         }
  195. gotCommand:
  196.         *p = 0;
  197.  
  198.         result = Tcl_Eval(interp, cmd, 0, &p);
  199.         if (interactive)
  200.             print_result(out, result, interp->result);
  201.     }
  202. endOfFile:
  203.     ckfree(cmd);
  204. }
  205.