Download | Plain Text | Line Numbers


/*
 * Name:         mycat
 * Author:       Manuel Mausz, 0728348
 * Description:  A simplified version of cat
 * Created:      11.03.2009
 * Exercise:     1h A
 */
 
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
 
/* global variables */
char *me;      /* name of myself (argv[0]) */
int vflag = 0; /* cmdline option: -v set */
int eflag = 0; /* cmdline option: -e set */
int tflag = 0; /* cmdline option: -t set */
 
/*
 * NAME: scan
 * PURPOSE:
 * reads characters from stream, converts them according the
 * commandline options and print the converted characters on stdout
 *
 * PARAMETERS:
 * FILE *fp ... pointer to a stream to read from
 *
 * RETURN VALUE:
 * void
 *
 * GLOBAL VARS:
 * vflag, eflag, tflag
 */
void scan(FILE *fp)
{
  int ch;
 
  while((ch = getc(fp)) != EOF)
  {
    /* eflag: print '$' before '\n' */
    if (ch == '\n')
    {
      if (eflag && putchar('$') == EOF)
        break;
    }
    /* tflag: print '^I' instead of '\t' */
    else if (ch == '\t')
    {
      if (tflag)
      {
        if (putchar('^') == EOF || putchar('I') == EOF)
          break;
        continue;
      }
    }
    /* vflag */
    else if (vflag)
    {
      /* 128 <= ch <= 255: print 'M-'.(ch-128) */
      if (128 <= ch && ch <= 255)
      {
        if (putchar('M') == EOF || putchar('-') == EOF)
          break;
        ch = ch - 128;
      }
 
      /* 0 <= ch <= 31: print '^'.(ch+'@') */
      if (0 <= ch && ch <= 31)
      {
        if (putchar('^') == EOF || putchar(ch + '@') == EOF)
          break;
        continue;
      }
      /* ch == 27: print '^?' */
      else if (ch == 127)
      {
        if (putchar('^') == EOF || putchar('?') == EOF)
          break;
        continue;
      }
    }
 
    /* print character to stdout */
    if (putchar(ch) == EOF)
      break;
  }
}
 
/*
 * NAME: usage
 * PURPOSE:
 * prints program usage to stderr and terminates with EXIT_FAILURE
 *
 * PARAMETERS:
 * void
 *
 * RETURN VALUE:
 * void
 *
 * GLOBAL VARS:
 * me
 */
static void usage(void)
{
  (void) fprintf(stderr, "Usage: %s [-vET]\n", me);
  (void) exit(EXIT_FAILURE);
}
 
/*
 * NAME: main
 * PURPOSE:
 * parses commandline options and calls scan()
 *
 * PARAMETERS:
 * standard parameters of main(...)
 *
 * RETURN VALUE:
 * int ... always 0
 *
 * GLOBAL VARS:
 * me, vflag, eflag, tflag
 */
int main(int argc, char *argv[])
{
  int opt;
 
  me = argv[0];
  while ((opt = getopt(argc, argv, "vET")) != -1)
  {
    switch(opt)
    {
      case 'v':
        vflag = 1;
        break;
      case 'E':
        eflag = 1;
        break;
      case 'T':
        tflag = 1;
        break;
      default:
        (void) usage();
        break;
    }
  }
 
  (void) scan(stdin);
  return 0;
}
 
/* vim: set et sw=2 ts=2: */