aboutsummaryrefslogblamecommitdiff
path: root/5.12.c
blob: 5c66060c47fa3a88087f33a6192a5b3d9f726833 (plain) (tree)
































































































































































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

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

int stops[MAXSTOPS];
int stop_position, m, n;

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

int 
main(int argc, char **argv)
{
  char flag;
  int detab_bool = 0, entab_bool = 0, mnloop_bool = 0;

  while (--argc > 0 && (**++argv == '-' || **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 :
          if (isdigit(flag)) {
            if (*(*argv - 1) == '+')
              for (mnloop_bool = 1; isdigit(**argv); (*argv)++)
                n = n * 10 + (**argv) - '0';
            else if (*(*argv - 1) == '-')
              for (mnloop_bool = 1; isdigit(**argv); (*argv)++)
                m = m * 10 + (**argv) - '0'; 
            
            if(mnloop_bool) {
              (*argv)--;
              mnloop_bool = 0;
            }
          } 

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

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

  return 0;
}

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

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

  while((input = getchar()) != EOF)
    switch(input) {
      case ' ' :
        space++;
        count++;
        break;
      case '\n' :
        count = 0;
        break;
      default :
        if (count >= m)
          stops[stop_position] = m;

        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 :
        if (count++ >= m)
          stops[stop_position] = n;

        putchar(input);
        break;
    }
}