home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / z / zsh220.zip / zsh2.2 / src / text.c < prev    next >
C/C++ Source or Header  |  1992-05-07  |  9KB  |  466 lines

  1. /*
  2.  *
  3.  * text.c - textual representations of syntax trees
  4.  *
  5.  * This file is part of zsh, the Z shell.
  6.  *
  7.  * This software is Copyright 1992 by Paul Falstad
  8.  *
  9.  * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  10.  * use this software as long as: there is no monetary profit gained
  11.  * specifically from the use or reproduction of this software, it is not
  12.  * sold, rented, traded or otherwise marketed, and this copyright notice is
  13.  * included prominently in any copy made. 
  14.  *
  15.  * The author make no claims as to the fitness or correctness of this software
  16.  * for any use whatsoever, and it is provided as is. Any use of this software
  17.  * is at the user's own risk. 
  18.  *
  19.  */
  20.  
  21. #include "zsh.h"
  22.  
  23. static char *tptr,*tbuf,*tlim;
  24. static int tsiz,tindent,tnewlins;
  25.  
  26. /* add a character to the text buffer */
  27.  
  28. void taddchr(c) /**/
  29. int c;
  30. {
  31.     *tptr++ = c;
  32.     if (tptr == tlim) {
  33.         if (!tbuf) { tptr--; return; }
  34.         tbuf = realloc(tbuf,tsiz *= 2);
  35.         tlim = tbuf+tsiz;
  36.         tptr = tbuf+tsiz/2;
  37.     }
  38. }
  39.  
  40. /* add a string to the text buffer */
  41.  
  42. void taddstr(s) /**/
  43. char *s;
  44. {
  45. int sl = strlen(s);
  46.  
  47.     while (tptr+sl >= tlim) {
  48.         int x = tptr-tbuf;
  49.  
  50.         if (!tbuf) return;
  51.         tbuf = realloc(tbuf,tsiz *= 2);
  52.         tlim = tbuf+tsiz;
  53.         tptr = tbuf+x;
  54.     }
  55.     strcpy(tptr,s);
  56.     tptr += sl;
  57. }
  58.  
  59. /* add an integer to the text buffer */
  60.  
  61. void taddint(x) /**/
  62. int x;
  63. {
  64. char buf[10];
  65.  
  66.     sprintf(buf,"%d",x);
  67.     taddstr(buf);
  68. }
  69.  
  70. /* add a newline, or something equivalent, to the text buffer */
  71.  
  72. void taddnl() /**/
  73. {
  74. int t0;
  75.  
  76.     if (tnewlins)
  77.         {
  78.         taddchr('\n');
  79.         for (t0 = 0; t0 != tindent; t0++)
  80.             taddchr('\t');
  81.         }
  82.     else
  83.         taddstr("; ");
  84. }
  85.  
  86. /* get a permanent textual representation of n */
  87.  
  88. char *getpermtext(n) /**/
  89. struct node *n;
  90. {
  91.     tnewlins = 1;
  92.     tbuf = zalloc(tsiz = 32);
  93.     tptr = tbuf;
  94.     tlim = tbuf+tsiz;
  95.     tindent = 1;
  96.     gettext2(n);
  97.     *tptr = '\0';
  98.     untokenize(tbuf);
  99.     return tbuf;
  100. }
  101.  
  102. /* get a representation of n in a job text buffer */
  103.  
  104. char *getjobtext(n) /**/
  105. struct node *n;
  106. {
  107. static char jbuf[JOBTEXTSIZE];
  108.  
  109.     tnewlins = 0;
  110.     tbuf = NULL;
  111.     tptr = jbuf;
  112.     tlim = tptr+JOBTEXTSIZE-1;
  113.     tindent = 1;
  114.     gettext2(n);
  115.     *tptr = '\0';
  116.     untokenize(jbuf);
  117.     return jbuf;
  118. }
  119.  
  120. #define gt2(X) gettext2((struct node *) (X))
  121.  
  122. /*
  123.     "gettext2" or "type checking and how to avoid it"
  124.     an epic function by Paul Falstad
  125. */
  126.  
  127. #define _Cond(X) ((Cond) (X))
  128. #define _Cmd(X) ((Cmd) (X))
  129. #define _Pline(X) ((Pline) (X))
  130. #define _Sublist(X) ((Sublist) (X))
  131. #define _List(X) ((List) (X))
  132. #define _casecmd(X) ((struct casecmd *) (X))
  133. #define _ifcmd(X) ((struct ifcmd *) (X))
  134. #define _whilecmd(X) ((struct whilecmd *) (X))
  135.  
  136. void gettext2(n) /**/
  137. struct node *n;
  138. {
  139. Cmd nn;
  140. Cond nm;
  141.  
  142.     if (!n)
  143.         return;
  144.     switch (n->type)
  145.         {
  146.         case N_LIST:
  147.             gt2(_List(n)->left);
  148.             if (_List(n)->type == ASYNC)
  149.                 taddstr(" &");
  150.             simplifyright(_List(n));
  151.             if (_List(n)->right)
  152.                 {
  153.                 if (tnewlins)
  154.                     taddnl();
  155.                 else
  156.                     taddstr((_List(n)->type == ASYNC) ? " " : "; ");
  157.                 gt2(_List(n)->right);
  158.                 }
  159.             break;
  160.         case N_SUBLIST:
  161.             if (_Sublist(n)->flags & PFLAG_NOT)
  162.                 taddstr("! ");
  163.             if (_Sublist(n)->flags & PFLAG_COPROC)
  164.                 taddstr("coproc ");
  165.             gt2(_Sublist(n)->left);
  166.             if (_Sublist(n)->right)
  167.                 {
  168.                 taddstr((_Sublist(n)->type == ORNEXT) ? " || " : " && ");
  169.                 gt2(_Sublist(n)->right);
  170.                 }
  171.             break;
  172.         case N_PLINE:
  173.             gt2(_Pline(n)->left);
  174.             if (_Pline(n)->type == PIPE)
  175.                 {
  176.                 taddstr(" | ");
  177.                 gt2(_Pline(n)->right);
  178.                 }
  179.             break;
  180.         case N_CMD:
  181.             nn = _Cmd(n);
  182.             if (nn->flags & CFLAG_EXEC)
  183.                 taddstr("exec ");
  184.             if (nn->flags & CFLAG_COMMAND)
  185.                 taddstr("command ");
  186.             switch (nn->type)
  187.                 {
  188.                 case SIMPLE:
  189.                     getsimptext(nn);
  190.                     break;
  191.                 case SUBSH:
  192.                     taddstr("( ");
  193.                     tindent++;
  194.                     gt2(nn->u.list);
  195.                     tindent--;
  196.                     taddstr(" )");
  197.                     break;
  198.                 case ZCTIME:
  199.                     taddstr("time ");
  200.                     tindent++;
  201.                     gt2(nn->u.pline);
  202.                     tindent--;
  203.                     break;
  204.                 case FUNCDEF:
  205.                     taddlist(nn->args);
  206.                     taddstr(" () {");
  207.                     tindent++;
  208.                     taddnl();
  209.                     gt2(nn->u.list);
  210.                     tindent--;
  211.                     taddnl();
  212.                     taddstr("}");
  213.                     break;
  214.                 case CURSH:
  215.                     taddstr("{ ");
  216.                     tindent++;
  217.                     gt2(nn->u.list);
  218.                     tindent--;
  219.                     taddstr(" }");
  220.                     break;
  221.                 case CFOR:
  222.                 case CSELECT:
  223.                     taddstr((nn->type == CFOR) ? "for " : "select ");
  224.                     taddstr(nn->u.forcmd->name);
  225.                     if (nn->u.forcmd->inflag)
  226.                         {
  227.                         taddstr(" in ");
  228.                         taddlist(nn->args);
  229.                         }
  230.                     taddnl();
  231.                     taddstr("do");
  232.                     tindent++;
  233.                     taddnl();
  234.                     gt2(nn->u.forcmd->list);
  235.                     taddnl();
  236.                     tindent--;
  237.                     taddstr("done");
  238.                     break;
  239.                 case CIF:
  240.                     gt2(nn->u.ifcmd);
  241.                     taddstr("fi");
  242.                     break;
  243.                 case CCASE:
  244.                     taddstr("case ");
  245.                     taddlist(nn->args);
  246.                     taddstr(" in");
  247.                     tindent++;
  248.                     taddnl();
  249.                     gt2(nn->u.casecmd);
  250.                     tindent--;
  251.                     if (tnewlins)
  252.                         taddnl();
  253.                     else
  254.                         taddchr(' ');
  255.                     taddstr("esac");
  256.                     break;
  257.                 case COND:
  258.                     taddstr("[[ ");
  259.                     gt2(nn->u.cond);
  260.                     taddstr(" ]]");
  261.                     break;
  262.                 case CREPEAT:
  263.                     taddstr("repeat ");
  264.                     taddlist(nn->args);
  265.                     taddnl();
  266.                     taddstr("do");
  267.                     tindent++;
  268.                     taddnl();
  269.                     gt2(nn->u.list);
  270.                     tindent--;
  271.                     taddnl();
  272.                     taddstr("done");
  273.                     break;
  274.                 case CWHILE:
  275.                     gt2(nn->u.whilecmd);
  276.                     break;
  277.                 }
  278.             getredirs(nn);
  279.             break;
  280.         case N_COND:
  281.             nm = _Cond(n);
  282.             switch (nm->type)
  283.                 {
  284.                 case COND_NOT:
  285.                     taddstr("! ");
  286.                     gt2(nm->left);
  287.                     break;
  288.                 case COND_AND:
  289.                     taddstr("( ");
  290.                     gt2(nm->left);
  291.                     taddstr(" && ");
  292.                     gt2(nm->right);
  293.                     taddstr(" )");
  294.                     break;
  295.                 case COND_OR:
  296.                     taddstr("( ");
  297.                     gt2(nm->left);
  298.                     taddstr(" || ");
  299.                     gt2(nm->right);
  300.                     taddstr(" )");
  301.                     break;
  302.                 default:
  303.                     {
  304.                     static char *c1[] = {
  305.                         " = "," != "," < "," > "," -nt "," -ot "," -ef "," -eq ",
  306.                         " -ne "," -lt "," -gt "," -le "," -ge "
  307.                         };
  308.                     if (nm->right)
  309.                         taddstr(nm->left);
  310.                     if (nm->type <= COND_GE)
  311.                         taddstr(c1[nm->type-COND_STREQ]);
  312.                     else
  313.                         {
  314.                         char c2[5];
  315.                         c2[0] = ' '; c2[1] = '-';
  316.                         c2[2] = nm->type;
  317.                         c2[3] = ' '; c2[4] = '\0';
  318.                         taddstr(c2);
  319.                         }
  320.                     taddstr((nm->right) ? nm->right : nm->left);
  321.                     }
  322.                     break;
  323.                 }
  324.             break;
  325.         case N_CASE:
  326.             taddstr(_casecmd(n)->pat);
  327.             taddstr(") ");
  328.             tindent++;
  329.             gt2(_casecmd(n)->list);
  330.             tindent--;
  331.             taddstr(";;");
  332.             if (tnewlins)
  333.                 taddnl();
  334.             else
  335.                 taddchr(' ');
  336.             gt2(_casecmd(n)->next);
  337.             break;
  338.         case N_IF:
  339.             if (_ifcmd(n)->ifl)
  340.                 {
  341.                 taddstr("if ");
  342.                 tindent++;
  343.                 gt2(_ifcmd(n)->ifl);
  344.                 tindent--;
  345.                 taddnl();
  346.                 taddstr("then");
  347.                 }
  348.             else
  349.                 taddchr('e');
  350.             tindent++;
  351.             taddnl();
  352.             gt2(_ifcmd(n)->thenl);
  353.             tindent--;
  354.             taddnl();
  355.             if (_ifcmd(n)->next)
  356.                 {
  357.                 taddstr("els");
  358.                 gt2(_ifcmd(n)->next);
  359.                 }
  360.             break;
  361.         case N_WHILE:
  362.             taddstr((_whilecmd(n)->cond) ? "until " : "while ");
  363.             tindent++;
  364.             gt2(_whilecmd(n)->cont);
  365.             tindent--;
  366.             taddnl();
  367.             taddstr("do");
  368.             tindent++;
  369.             taddnl();
  370.             gt2(_whilecmd(n)->loop);
  371.             tindent--;
  372.             taddnl();
  373.             taddstr("done");
  374.             break;
  375.         }
  376. }
  377.  
  378. void getsimptext(cmd) /**/
  379. Cmd cmd;
  380. {
  381. Lknode n;
  382.  
  383.     for (n = firstnode(cmd->vars); n; incnode(n))
  384.         {
  385.         struct varasg *v = getdata(n);
  386.  
  387.         taddstr(v->name);
  388.         taddchr('=');
  389.         if ((v->type & PMTYPE) == PMFLAG_A)
  390.             {
  391.             taddchr('(');
  392.             taddlist(v->arr);
  393.             taddstr(") ");
  394.             }
  395.         else
  396.             {
  397.             taddstr(v->str);
  398.             taddchr(' ');
  399.             }
  400.         }
  401.     taddlist(cmd->args);
  402. }
  403.  
  404. void getredirs(cmd) /**/
  405. Cmd cmd;
  406. {
  407. Lknode n;
  408. static char *fstr[] = {
  409.     ">",">!",">>",">>!",">&",">&!",">>&",">>&!","<","<<",
  410.     "<<-","<<<","<&",">&-","..",".."
  411.     };
  412.  
  413.     taddchr(' ');
  414.     for (n = firstnode(cmd->redir); n; incnode(n))
  415.         {
  416.         struct redir *f = getdata(n);
  417.  
  418.         switch(f->type)
  419.             {
  420.             case WRITE: case WRITENOW: case APP: case APPNOW: case READ:
  421.             case HERESTR:
  422.                 if (f->fd1 != ((f->type == READ) ? 0 : 1))
  423.                     taddchr('0'+f->fd1);
  424.                 taddstr(fstr[f->type]);
  425.                 taddchr(' ');
  426.                 taddstr(f->name);
  427.                 taddchr(' ');
  428.                 break;
  429.             case MERGE: case MERGEOUT:
  430.                 if (f->fd1 != ((f->type == MERGEOUT) ? 1 : 0))
  431.                     taddchr('0'+f->fd1);
  432.                 taddstr(fstr[f->type]);
  433.                 taddchr(' ');
  434.                 taddint(f->fd2);
  435.                 taddchr(' ');
  436.                 break;
  437.             case CLOSE:
  438.                 taddchr(f->fd1+'0');
  439.                 taddstr(">&- ");
  440.                 break;
  441.             case INPIPE:
  442.             case OUTPIPE:
  443.                 if (f->fd1 != ((f->type == INPIPE) ? 0 : 1))
  444.                     taddchr('0'+f->fd1);
  445.                 taddstr((f->type == INPIPE) ? "< " : "> ");
  446.                 taddstr(f->name);
  447.                 taddchr(' ');
  448.                 break;
  449.             }
  450.         }
  451.     tptr--;
  452. }
  453.  
  454. void taddlist(l) /**/
  455. Lklist l;
  456. {
  457. Lknode n;
  458.  
  459.     for (n = firstnode(l); n; incnode(n))
  460.         {
  461.         taddstr(getdata(n));
  462.         taddchr(' ');
  463.         }
  464.     tptr--;
  465. }
  466.