tword.c - plan9port - [fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port
Log
Files
Refs
README
LICENSE
---
tword.c (2715B)
---
     1 #include        "mk.h"
     2 
     3 static        Word        *nextword(char**);
     4 
     5 Word*
     6 newword(char *s)
     7 {
     8         Word *w;
     9 
    10         w = (Word *)Malloc(sizeof(Word));
    11         w->s = strdup(s);
    12         w->next = 0;
    13         return(w);
    14 }
    15 
    16 Word *
    17 stow(char *s)
    18 {
    19         Word *head, *w, *new;
    20 
    21         w = head = 0;
    22         while(*s){
    23                 new = nextword(&s);
    24                 if(new == 0)
    25                         break;
    26                 if (w)
    27                         w->next = new;
    28                 else
    29                         head = w = new;
    30                 while(w->next)
    31                         w = w->next;
    32 
    33         }
    34         if (!head)
    35                 head = newword("");
    36         return(head);
    37 }
    38 
    39 char *
    40 wtos(Word *w, int sep)
    41 {
    42         Bufblock *buf;
    43         char *cp;
    44 
    45         buf = newbuf();
    46         for(; w; w = w->next){
    47                 for(cp = w->s; *cp; cp++)
    48                         insert(buf, *cp);
    49                 if(w->next)
    50                         insert(buf, sep);
    51         }
    52         insert(buf, 0);
    53         cp = strdup(buf->start);
    54         freebuf(buf);
    55         return(cp);
    56 }
    57 
    58 Word*
    59 wdup(Word *w)
    60 {
    61         Word *v, *new, *base;
    62 
    63         v = base = 0;
    64         while(w){
    65                 new = newword(w->s);
    66                 if(v)
    67                         v->next = new;
    68                 else
    69                         base = new;
    70                 v = new;
    71                 w = w->next;
    72         }
    73         return base;
    74 }
    75 
    76 void
    77 delword(Word *w)
    78 {
    79         Word *v;
    80 
    81         while(v = w){
    82                 w = w->next;
    83                 if(v->s)
    84                         free(v->s);
    85                 free(v);
    86         }
    87 }
    88 
    89 /*
    90  *        break out a word from a string handling quotes, executions,
    91  *        and variable expansions.
    92  */
    93 static Word*
    94 nextword(char **s)
    95 {
    96         Bufblock *b;
    97         Word *head, *tail, *w;
    98         Rune r;
    99         char *cp;
   100         int empty;
   101 
   102         cp = *s;
   103         b = newbuf();
   104 restart:
   105         head = tail = 0;
   106         while(*cp == ' ' || *cp == '\t')                /* leading white space */
   107                 cp++;
   108         empty = 1;
   109         while(*cp){
   110                 cp += chartorune(&r, cp);
   111                 switch(r)
   112                 {
   113                 case ' ':
   114                 case '\t':
   115                 case '\n':
   116                         goto out;
   117                 case '\\':
   118                 case '\'':
   119                 case '"':
   120                         empty = 0;
   121                         cp = shellt->expandquote(cp, r, b);
   122                         if(cp == 0){
   123                                 fprint(2, "missing closing quote: %s\n", *s);
   124                                 Exit();
   125                         }
   126                         break;
   127                 case '$':
   128                         w = varsub(&cp);
   129                         if(w == 0){
   130                                 if(empty)
   131                                         goto restart;
   132                                 break;
   133                         }
   134                         empty = 0;
   135                         if(b->current != b->start){
   136                                 bufcpy(b, w->s, strlen(w->s));
   137                                 insert(b, 0);
   138                                 free(w->s);
   139                                 w->s = strdup(b->start);
   140                                 b->current = b->start;
   141                         }
   142                         if(head){
   143                                 bufcpy(b, tail->s, strlen(tail->s));
   144                                 bufcpy(b, w->s, strlen(w->s));
   145                                 insert(b, 0);
   146                                 free(tail->s);
   147                                 tail->s = strdup(b->start);
   148                                 tail->next = w->next;
   149                                 free(w->s);
   150                                 free(w);
   151                                 b->current = b->start;
   152                         } else
   153                                 tail = head = w;
   154                         while(tail->next)
   155                                 tail = tail->next;
   156                         break;
   157                 default:
   158                         empty = 0;
   159                         rinsert(b, r);
   160                         break;
   161                 }
   162         }
   163 out:
   164         *s = cp;
   165         if(b->current != b->start){
   166                 if(head){
   167                         cp = b->current;
   168                         bufcpy(b, tail->s, strlen(tail->s));
   169                         bufcpy(b, b->start, cp-b->start);
   170                         insert(b, 0);
   171                         free(tail->s);
   172                         tail->s = strdup(cp);
   173                 } else {
   174                         insert(b, 0);
   175                         head = newword(b->start);
   176                 }
   177         }
   178         freebuf(b);
   179         return head;
   180 }
   181 
   182 void
   183 dumpw(char *s, Word *w)
   184 {
   185         Bprint(&bout, "%s", s);
   186         for(; w; w = w->next)
   187                 Bprint(&bout, " '%s'", w->s);
   188         Bputc(&bout, '\n');
   189 }