URI: 
       lex.c - 9base - revived minimalist port of Plan 9 userland to Unix
  HTML git clone git://git.suckless.org/9base
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       lex.c (2505B)
       ---
            1 #include        "mk.h"
            2 
            3 static        int        bquote(Biobuf*, Bufblock*);
            4 
            5 /*
            6  *        Assemble a line skipping blank lines, comments, and eliding
            7  *        escaped newlines
            8  */
            9 int
           10 assline(Biobuf *bp, Bufblock *buf)
           11 {
           12         int c;
           13         int lastc;
           14 
           15         buf->current=buf->start;
           16         while ((c = nextrune(bp, 1)) >= 0){
           17                 switch(c)
           18                 {
           19                 case '\r':                /* consumes CRs for Win95 */
           20                         continue;
           21                 case '\n':
           22                         if (buf->current != buf->start) {
           23                                 insert(buf, 0);
           24                                 return 1;
           25                         }
           26                         break;                /* skip empty lines */
           27                 case '\\':
           28                 case '\'':
           29                 case '"':
           30                         rinsert(buf, c);
           31                         if (shellt->escapetoken(bp, buf, 1, c) == 0)
           32                                 Exit();
           33                         break;
           34                 case '`':
           35                         if (bquote(bp, buf) == 0)
           36                                 Exit();
           37                         break;
           38                 case '#':
           39                         lastc = '#';
           40                         while ((c = Bgetc(bp)) != '\n') {
           41                                 if (c < 0)
           42                                         goto eof;
           43                                 if(c != '\r')
           44                                         lastc = c;
           45                         }
           46                         mkinline++;
           47                         if (lastc == '\\')
           48                                 break;                /* propagate escaped newlines??*/
           49                         if (buf->current != buf->start) {
           50                                 insert(buf, 0);
           51                                 return 1;
           52                         }
           53                         break;
           54                 default:
           55                         rinsert(buf, c);
           56                         break;
           57                 }
           58         }
           59 eof:
           60         insert(buf, 0);
           61         return *buf->start != 0;
           62 }
           63 
           64 /*
           65  *        assemble a back-quoted shell command into a buffer
           66  */
           67 static int
           68 bquote(Biobuf *bp, Bufblock *buf)
           69 {
           70         int c, line, term;
           71         int start;
           72 
           73         line = mkinline;
           74         while((c = Bgetrune(bp)) == ' ' || c == '\t')
           75                         ;
           76         if(c == '{'){
           77                 term = '}';                /* rc style */
           78                 while((c = Bgetrune(bp)) == ' ' || c == '\t')
           79                         ;
           80         } else
           81                 term = '`';                /* sh style */
           82 
           83         start = buf->current-buf->start;
           84         for(;c > 0; c = nextrune(bp, 0)){
           85                 if(c == term){
           86                         insert(buf, '\n');
           87                         insert(buf,0);
           88                         buf->current = buf->start+start;
           89                         execinit();
           90                         execsh(0, buf->current, buf, envy, shellt, shellcmd);
           91                         return 1;
           92                 }
           93                 if(c == '\n')
           94                         break;
           95                 if(c == '\'' || c == '"' || c == '\\'){
           96                         insert(buf, c);
           97                         if(!shellt->escapetoken(bp, buf, 1, c))
           98                                 return 0;
           99                         continue;
          100                 }
          101                 rinsert(buf, c);
          102         }
          103         SYNERR(line);
          104         fprint(2, "missing closing %c after `\n", term);
          105         return 0;
          106 }
          107 
          108 /*
          109  *        get next character stripping escaped newlines
          110  *        the flag specifies whether escaped newlines are to be elided or
          111  *        replaced with a blank.
          112  */
          113 int
          114 nextrune(Biobuf *bp, int elide)
          115 {
          116         int c, c2;
          117         static int savec;
          118 
          119         if(savec){
          120                 c = savec;
          121                 savec = 0;
          122                 return c;
          123         }
          124 
          125         for (;;) {
          126                 c = Bgetrune(bp);
          127                 if (c == '\\') {
          128                         c2 = Bgetrune(bp);
          129                         if(c2 == '\r'){
          130                                 savec = c2;
          131                                 c2 = Bgetrune(bp);
          132                         }
          133                         if (c2 == '\n') {
          134                                 savec = 0;
          135                                 mkinline++;
          136                                 if (elide)
          137                                         continue;
          138                                 return ' ';
          139                         }
          140                         Bungetrune(bp);
          141                 }
          142                 if (c == '\n')
          143                         mkinline++;
          144                 return c;
          145         }
          146 }