home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff391.lzh / Eco / eco.c < prev    next >
C/C++ Source or Header  |  1990-10-27  |  14KB  |  354 lines

  1. echo ; /*  Note that this declares an int available externally
  2.  failat 1
  3. ;lc:lc -cuwsf -Heco.sym -O -v -dEXTRA eco.c  ; to generate ecox
  4. ;lc:blink lib:cres.o ecox.o TO ecox LIB lib:lc.lib SD SC ND VERBOSE
  5.  lc:lc -cuwsf -Heco.sym -O -v eco.c          ; to generate eco
  6.  lc:blink lib:cres.o eco.o TO eco LIB lib:lc.lib SD SC ND VERBOSE
  7.  quit
  8. */
  9. /*
  10.  *  Created on 88/10/27             Last mod: 90/04/01
  11.  *
  12.  *  Module:     Eco                 by  Dario de Judicibus -  Rome (Italy)
  13.  *
  14.  *  Purpose:    echoes a string to the console - allowed control sequences
  15.  *              Created from eco. It includes \[...] escape sequences.
  16.  *              ECO is the Italian word for Echo.
  17.  *
  18.  *  Syntax:     eco "string"
  19.  *
  20.  *  ParmList:   string    a sequence of character strings and control
  21.  *                        sequences (CS). Escape character is backslash (\)
  22.  *                        See eco.hlp for CS list. Execute eco.me as demo.
  23.  *                        Double quotes are mandatory if string contains:
  24.  *                          semicolons   (;)
  25.  *                          minor chars  (<)
  26.  *                          major chars  (>)
  27.  *                        Double quotes can be included by escape sequence \q
  28.  *
  29.  *   Author's addresses:  MAIL     Dario de Judicibus
  30.  *                                 via Canton 101
  31.  *                                 I 00144 Roma ITALIA
  32.  *
  33.  *                        E-Mail   SAM Link (+39.6.423233)  Userid 244
  34.  *                                 MC Link (+39.6.4180440)         MC2120
  35.  *
  36.  *  =========================================================================
  37.  *  @Mod |   on   | by  |  reason
  38.  *  -----+--------+-----+----------------------------------------------------
  39.  *  @001 | 871027 | DdJ | Vers 1 Rel 0 Mod 0
  40.  *  @002 | 881002 | DdJ | Vers 2 Rel 0 Mod 0 - Lattice 4.0
  41.  *  @003 | 881017 | DdJ | Vers 2 Rel 1 Mod 0 - \< & \>
  42.  *  @004 | 881027 | DdJ | Vers 3 Rel 0 Mod 0 - \[...]
  43.  *  @005 | 890724 | DdJ | Vers 3 Rel 1 Mod 0 - Lattice 5.02
  44.  *  @006 | 890726 | DdJ | Vers 3 Rel 2 Mod 0 - \W & \D
  45.  *  @007 | 890916 | DdJ | Vers 3 Rel 2 Mod 1 - \{..} & fixed bug in \[..]
  46.  *  @008 | 891125 | DdJ | Vers 3 Rel 2 Mod 2 - Added getenv() (Lattice bug)
  47.  *  @009 | 900111 | DdJ | Vers 3 Rel 3 Mod 0 - pre-comp. include & resident
  48.  *  @010 | 900401 | DdJ | Vers 3 Rel 4 Mod 0 - New command feature
  49.  */
  50.  
  51. /*
  52. **  #include lines collected in ecohdr.c and pre-compiled
  53. */
  54.  
  55.  #ifdef EXTRA
  56. /*
  57. **  I had to add an internal getenv() routine because the Lattice C 5.04
  58. **  one has a bug: the variable content is returned overlayed to the
  59. **  variable file name ENV:vatiable_name.
  60. **  #define getenv GetEnv is used to avoid a Lattice error message
  61. */
  62.  #define ENVSIZE 256
  63.  #define getenv GetEnv
  64.  typedef struct FileHandle FH;
  65.  char *getenv(char *);
  66.  #endif
  67.  void help(void);
  68.  
  69.  #define tohex(c)        (isdigit(c)?((c)&0x0F):(((c)-('7'))&0x0F))
  70.  #ifdef EXTRA
  71.  #define todigit(c)      (isdigit(c)?(((c)-('0'))&0x0F):0)
  72.  #endif
  73.  
  74. /* Help                                                            */
  75.  
  76.  #define HLP_0 "\nECO Vers. 3.40 by Dario de Judicibus - Italy\n\nEscape sequences \\<char>:\n\n"
  77.  #define HLP_1 "Special Chars: Quotes, x__ Hex value (two digits), ? ? character\nColours:       0..3 Foreground 4..7 Background\n"
  78.  #define HLP_2 "Screen:        Home and clear, Clear to end of display\nStyles:        Plain, Bold, Italic, Underscore, Reverse, Default\n"
  79.  #define HLP_3 "Cursor:        Invisible, Visible, Home, (x,y) Cursor positioning\nLine control:  Newline, Carriage Return, no Newline at the end\n"
  80.  #define HLP_4 "Tabs:          Vertical, Horizontal\n"
  81.  #ifdef EXTRA
  82.  #define HLP_A "Variables:     [var..var] where var = {d1..d7,t1..t7,w1..w2,p}\nDelays:        Wait for ENTER, Dx Wait for x seconds\n"
  83.  #define HLP_B "Environment:   {variable} where variable is an ENV: variable\n               $command$ will execute the command from current CLI\n"
  84.  #endif
  85.  #define HLP_X "\nECO ? or ECO \\h for help, ECO \042?\042 or ECO \\? to output ? as first char in list.\n\n"
  86.  
  87. /* Control Sequences Definitions                                   */
  88.  
  89.  #define ESCAPE '\\'            /* Escape character                */
  90.  #define ESC    "\\"            /* Escape character                */
  91.  #define DEF    "\2330;31;40m"  /* Normal                          */
  92.  #define F_0    "\23330m"       /* Foreground 0                    */
  93.  #define F_1    "\23331m"       /* Foreground 1                    */
  94.  #define F_2    "\23332m"       /* Foreground 2                    */
  95.  #define F_3    "\23333m"       /* Foreground 3                    */
  96.  #define B_0    "\23340m"       /* Background 0                    */
  97.  #define B_1    "\23341m"       /* Background 1                    */
  98.  #define B_2    "\23342m"       /* Background 2                    */
  99.  #define B_3    "\23343m"       /* Background 3                    */
  100.  #define S_P    "\2330m"        /* Plain                           */
  101.  #define S_B    "\2331m"        /* Bold                            */
  102.  #define S_I    "\2333m"        /* Italic                          */
  103.  #define S_U    "\2334m"        /* Underscore                      */
  104.  #define S_R    "\2337m"        /* Reverse                         */
  105.  #define VT     "\v"            /* Vertical tab                    */
  106.  #define HT     "\t"            /* Horizontal tab                  */
  107.  #define CRLF   "\n"            /* newline                         */
  108.  #define CR     "\x0D"          /* carriage return -- first column */
  109.  #define HOME   "\233H"         /* home                            */
  110.  #define CLSALL "\233H\233J"    /* home and clear screen           */
  111.  #define CLS    "\233J"         /* clear screen                    */
  112.  #define CUROFF "\2330 p"       /* make cursor invisible           */
  113.  #define CURON  "\233 p"        /* make cursor visible             */
  114.  #define QUOTE  "\x22"
  115.  #define QMARK  "\x3F"
  116.  #define NL     '\0'
  117.  #define NOVALUE (-1)
  118.  
  119.  #define LAST(c)   ((c == '\0')||(c == '\n'))
  120.  #define SKIP(c)   ((c == ' ')||(c == '\t')||(c == '\n'))
  121.  #define INDEX(c) ((((c)<('0'))||((c)>('~')))?NOVALUE:((c)-('0')))
  122.  
  123.  BOOL nostop = FALSE;
  124.  
  125. /*------------------------------------------------------------------------*\
  126.  *     # -> used in table    ! -> used in switch    (blank) -> not used   *
  127.  *                                                                        *
  128.  *     #0  #1  #2  #3  #4  #5  #6  #7   8   9   :   ;  #<   =  #>  #?     *
  129.  *      @   A   B  #C  !D   E   F   G  #H   I   J   K   L   M   N   O     *
  130.  *      P   Q   R   S   T   U   V  !W   X   Y   Z  ![  #\   ]   ^   _     *
  131.  *      `   a  #b  #c  #d   e  #f   g  !h  #i   j   k   l   m  #n   o     *
  132.  *     #p  #q  #r  !s  #t  #u  #v   w  !x   y   z  !{   |   }   ~         *
  133.  *                                                                        *
  134.  *     !(  !$                                                             *
  135. \*------------------------------------------------------------------------*/
  136.  
  137.  char *_table[] =
  138.  {
  139.      F_0,    F_1,    F_2,    F_3,    B_0,    B_1,    B_2,    B_3,
  140.       NL,     NL,     NL,     NL, CUROFF,     NL,  CURON,  QMARK,
  141.       NL,     NL,     NL, CLSALL,     NL,     NL,     NL,     NL,
  142.     HOME,     NL,     NL,     NL,     NL,     NL,     NL,     NL,
  143.       NL,     NL,     NL,     NL,     NL,     NL,     NL,     NL,
  144.       NL,     NL,     NL,     NL,    ESC,     NL,     NL,     NL,
  145.       NL,     NL,    S_B,    CLS,    DEF,     NL,     CR,     NL,
  146.       NL,    S_I,     NL,     NL,     NL,     NL,   CRLF,     NL,
  147.      S_P,  QUOTE,    S_R,     NL,     HT,    S_U,     VT,     NL,
  148.       NL,     NL,     NL,     NL,     NL,     NL,     NL   /* end */
  149.  };
  150.  
  151.  #ifdef EXTRA
  152.  char *weekdays[] =
  153.  {
  154.   "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday",
  155.   "SUN"   ,"MON"   ,"TUE"    ,"WED"      ,"THU"     ,"FRI"   ,"SAT"
  156.  };
  157.  #endif
  158.  
  159. /*
  160.  *  Format text
  161.  */
  162.  
  163.  void _main(line)
  164.  register unsigned char *line;
  165.  {
  166.    BOOL inQuote;
  167.  #ifdef EXTRA
  168.    char *old, *temp, *env, clk[8], h[64];
  169.  #endif
  170.  #ifndef EXTRA
  171.    char *old, *temp, h[10];
  172.  #endif
  173.    UWORD j, index;
  174.  
  175.    echo = Output();
  176.  
  177.    if (!(line)) Exit(RETURN_WARN);/* Must be called from CLI   */
  178.    while (*line != ' ') line++;   /* Skip over command name    */
  179.    temp = line;
  180.    while (SKIP(*temp)) temp++;    /* Skip over leading blanks  */
  181.    if (*temp == '\0')             /* End of line: do just a \n */
  182.    {
  183.      Write(echo,CRLF,1);
  184.      Exit(RETURN_OK);
  185.    }
  186.  
  187.    if (*temp == '?')              /* Help, only if first char  */
  188.    {
  189.      help();
  190.      Exit(RETURN_OK);
  191.    }
  192.    inQuote = (*temp == '"');      /* if the line starts with " */
  193.    line = inQuote?++temp:++line;  /* take just what in quote,  */
  194.                                   /* otherwise get all         */
  195.    old = line;
  196.    temp = (char *)NL;
  197.    while(!LAST(*line))
  198.    {
  199.      if (*line == ESCAPE)
  200.      {
  201.        *line = '\0';
  202.        Write(echo,old,strlen(old));
  203.        switch(*(++line))
  204.        {
  205.          case 'h': help();
  206.                    line++;
  207.                    break;
  208.          case 's': temp = line;
  209.                    nostop = TRUE;
  210.                    line++;
  211.                    break;
  212.          case '(':
  213.                    h[0] = '\233';
  214.                    line++;
  215.                    for (j=1; *line != ')' && !LAST(*line); j++, line++)
  216.                      h[j] = (*line == ',') ? ';' : *line;
  217.                    h[j] = ')'; /* to be sure */
  218.                    h[j++] = 'H'; h[j] = '\0';
  219.                    Write(echo,h,strlen(h));
  220.                    line++;
  221.                    break;
  222.          case 'x': if (isxdigit(line[1]) && isxdigit(line[2]))
  223.                    {
  224.                      h[0] = (tohex(line[1])<<4)|tohex(line[2]);
  225.                      Write(echo,h,1);
  226.                    }
  227.                    line = &line[3];
  228.                    break;
  229.  #ifdef EXTRA
  230.          case '[': for (line++;(*line != ']') && !LAST(*line);line++)
  231.                    {
  232.                      h[0] = '\0';
  233.                      if (*line == 'p')
  234.                      {
  235.                        (VOID)getcd(0,&h[0]);
  236.                      }
  237.                      else if ((*(line+1) != ']') && !LAST(*(line+1)))
  238.                      {
  239.                        getclk(clk);
  240.                        index = 0x07&todigit(*(line+1));
  241.                        if (index) switch(*line)
  242.                        {
  243.                          case 'd': (void)stpdate(h,(int)index,&clk[1]);
  244.                                    break;
  245.                          case 't': (void)stptime(h,(int)index,&clk[4]);
  246.                                    break;
  247.                          case 'w': index = (UWORD)clk[0] + (0x01&index)*7;
  248.                                    (void)strcpy(h,weekdays[index]);
  249.                                    break;
  250.                          default:  break;
  251.                        }
  252.                      }
  253.                      Write(echo,h,strlen(h));
  254.                    }
  255.                    line++;
  256.                    break;
  257.          case '{': for (j=0,line++;(*line != '}') && !LAST(*line);j++,line++)
  258.                    {
  259.                      h[j] = *line;
  260.                    }
  261.                    h[j] = '\0';
  262.                    env = getenv(&h[0]);
  263.                    if (env)
  264.                    {
  265.                      Write(echo,env,strlen(env));
  266.                      (void)free(env);
  267.                    }
  268.                    line++;
  269.                    break;
  270.          case '$': for (j=0,line++;(*line != '$') && !LAST(*line);j++,line++)
  271.                    {
  272.                      h[j] = *line;
  273.                    }
  274.                    h[j] = '\0';
  275.                    Execute(&h[0],NULL,echo);
  276.                    line++;
  277.                    break;
  278.          case 'D': if (isdigit(line[1]))
  279.                    {
  280.                      j = TICKS_PER_SECOND * todigit(line[1]);
  281.                      Delay(j);
  282.                    }
  283.                    line = &line[2];
  284.                    break;
  285.          case 'W': Read(echo,h,63);
  286.                    line++;
  287.                    break;
  288.  #endif
  289.          default:  index = (UWORD)INDEX(*line);
  290.                    if ((index != NOVALUE)&&(_table[index] != NL))
  291.                      Write(echo,_table[index],strlen(_table[index]));
  292.                    line++;
  293.        }
  294.        old = line;
  295.      }
  296.      else
  297.      {
  298.        if (inQuote && (*line == '"'))
  299.          break;
  300.        line++;
  301.      }
  302.    }
  303.    *line = '\0';
  304.    Write(echo,old,strlen(old));
  305.    if (!(nostop && (line == ++temp))) Write(echo,CRLF,1);
  306.    Exit(RETURN_OK);
  307.  }
  308.  
  309.  #ifdef EXTRA
  310. /*
  311. **  This procedure will be deleted as soon as the Lattice one will
  312. **  be fixed.
  313. */
  314.  char *getenv(varname)
  315.    char *varname;
  316.  {
  317.    char *p, *buf = NULL;
  318.    FH *envfh;
  319.  
  320.    if ((buf = calloc(1,ENVSIZE)) != NULL)
  321.    {
  322.      p = strcpy(buf,"ENV:");
  323.      p = strcat(buf,varname);
  324.      if ((envfh = (FH *)Open(buf,MODE_OLDFILE)) != NULL)
  325.      {
  326.        p = memset(buf,'\0',ENVSIZE);
  327.        (void)Read((BPTR)envfh,buf,ENVSIZE);
  328.        Close((BPTR)envfh);
  329.      }
  330.      else
  331.        buf[0] = '\0';
  332.    }
  333.  
  334.    return (buf);
  335.  }
  336.  #endif
  337.  
  338. /*
  339. **  Help
  340. */
  341.  void help()
  342.  {
  343.    Write(echo,HLP_0,strlen(HLP_0));
  344.    Write(echo,HLP_1,strlen(HLP_1));
  345.    Write(echo,HLP_2,strlen(HLP_2));
  346.    Write(echo,HLP_3,strlen(HLP_3));
  347.    Write(echo,HLP_4,strlen(HLP_4));
  348.  #ifdef EXTRA
  349.    Write(echo,HLP_A,strlen(HLP_A));
  350.    Write(echo,HLP_B,strlen(HLP_B));
  351.  #endif
  352.    Write(echo,HLP_X,strlen(HLP_X));
  353.  }
  354.