aboutsummaryrefslogblamecommitdiff
path: root/5.11.c
blob: 7f2fbf63238560604f327b4b9d44a5a9808e9652 (plain) (tree)



































































































































                                                                              
#include <stdio.h>
#include <ctype.h>

#define DEFTAB 8
#define MAXSTOPS 65
#define ON 1

int stops[MAXSTOPS];
int stop_position, detab_bool, entab_bool;

void entab(void);
void detab(void);

int 
main(int argc, char **argv)
{
  int flag;
  while (--argc > 0 && **++argv == '-')
    while((flag = *++*argv))
      switch (flag) {
        case 'e' :
          entab_bool = ON;
          break;
        case 'd' :
          detab_bool = ON;
          break;
        case 's' :
          if(*++*argv != '=')
            argc = -1;
          else 
            (*argv)++;

          if (**argv == '\0')
            argc = -1;

          while (isdigit(**argv)) {
            if (stop_position > MAXSTOPS)
              argc = -1;

            stops[stop_position] = stops[stop_position] * 10 + (**argv) - '0';
            (*argv)++;
            if (**argv == ',') {
              (*argv)++;
              if(isdigit(**argv) && stop_position < MAXSTOPS)
                stop_position++;
            }
          }
          stop_position++;

          (*argv)--;
          break;
        default :
          argc = -1;
          printf("Err: illigal option %c\n", flag);
          break;
      }

  if (argc || !entab_bool ^ detab_bool)
    printf("Usage: tab (-e || -d) -s=s1,s2,s3,...,s%d\n", MAXSTOPS-1);
  else if(entab_bool)
    entab();
  else if (detab_bool)
    detab();

  return 0;
}

void 
entab(void)
{
 char input;
 int space, stop_now;

  space = 0;
  stop_now = 0;
  stops[stop_position] = DEFTAB; 

  while((input = getchar()) != EOF)
    switch(input) {
      case ' ' :
        space++;
        break;
      default :
        while (space/stops[stop_now]) {
          space -= stops[stop_now];

          putchar('\t');

          if (stop_now < stop_position)
            stop_now++;
        }

        while (space) {
          putchar(' ');
          space--;
        }

        putchar(input);
        break;
    }
}

void 
detab(void)
{
  char input; 
  int count, space, stop_now;

  count = 0;
  stop_now = 0;
  stops[stop_position] = DEFTAB; 

  while ((input = getchar()) != EOF)
    switch (input) {
      case '\n' :
        count = 0;
        putchar('\n');
        break;
      case '\t' :
        space = stops[stop_now] - count%stops[stop_now];
        count += space;
        while (space--)
          putchar(' ');
        if (stop_now < stop_position)
          stop_now++;
        break;
      default :
        count++;
        putchar(input);
        break;
    }
}