picolisp

Unnamed repository; edit this file to name it for gitweb.
git clone https://logand.com/git/picolisp.git/
Log | Files | Refs | README | LICENSE

balance.c (2056B)


      1 /* balance.c
      2  * 06jul05abu
      3  */
      4 
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <unistd.h>
      8 #include <string.h>
      9 #include <errno.h>
     10 #include <signal.h>
     11 #include <sys/wait.h>
     12 
     13 int Len, Siz;
     14 char *Line, **Data;
     15 
     16 static void giveup(char *msg) {
     17    fprintf(stderr, "balance: %s\n", msg);
     18    exit(1);
     19 }
     20 
     21 static char *getLine(FILE *fp) {
     22 	int i, c;
     23    char *s;
     24 
     25    i = 0;
     26    while ((c = getc_unlocked(fp)) != '\n') {
     27       if (c == EOF)
     28          return NULL;
     29       Line[i] = c;
     30       if (++i == Len  &&  !(Line = realloc(Line, Len *= 2)))
     31          giveup("No memory");
     32    }
     33    Line[i] = '\0';
     34    if (!(s = strdup(Line)))
     35       giveup("No memory");
     36    return s;
     37 }
     38 
     39 static void balance(char **data, int len) {
     40    if (len) {
     41       int n = (len + 1) / 2;
     42       char **p = data + n - 1;
     43 
     44       printf("%s\n", *p);
     45       balance(data, n - 1);
     46       balance(p + 1, len - n);
     47    }
     48 }
     49 
     50 // balance [-<cmd> [<arg> ..]]
     51 // balance [<file>]
     52 int main(int ac, char *av[]) {
     53    int cnt;
     54    char *s;
     55    pid_t pid = 0;
     56    FILE *fp = stdin;
     57 
     58    if (ac > 1) {
     59       if (*av[1] == '-') {
     60          int pfd[2];
     61 
     62          if (pipe(pfd) < 0)
     63             giveup("Pipe error\n");
     64          if ((pid = fork()) == 0) {
     65             close(pfd[0]);
     66             if (pfd[1] != STDOUT_FILENO)
     67                dup2(pfd[1], STDOUT_FILENO),  close(pfd[1]);
     68             execvp(av[1]+1, av+1);
     69          }
     70          if (pid < 0)
     71             giveup("Fork error\n");
     72          close(pfd[1]);
     73          if (!(fp = fdopen(pfd[0], "r")))
     74             giveup("Pipe open error\n");
     75       }
     76       else if (!(fp = fopen(av[1], "r")))
     77          giveup("File open error\n");
     78    }
     79    Line = malloc(Len = 4096);
     80    Data = malloc((Siz = 4096) * sizeof(char*));
     81    for (cnt = 0;  s = getLine(fp);  ++cnt) {
     82       if (cnt == Siz  &&  !(Data = realloc(Data, (Siz *= 2) * sizeof(char*))))
     83          giveup("No memory");
     84       Data[cnt] = s;
     85    }
     86    if (pid) {
     87       fclose(fp);
     88       while (waitpid(pid, NULL, 0) < 0)
     89          if (errno != EINTR)
     90             giveup("Pipe close error\n");
     91    }
     92    balance(Data, cnt);
     93    return 0;
     94 }