Download | Plain Text | No Line Numbers


  1. /*
  2.  * Name: mycat
  3.  * Author: Manuel Mausz, 0728348
  4.  * Description: A simplified version of cat
  5.  * Created: 11.03.2009
  6.  * Exercise: 1h A
  7.  */
  8.  
  9. #include <unistd.h>
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <errno.h>
  13. #include <string.h>
  14.  
  15. /* global variables */
  16. char *me; /* name of myself (argv[0]) */
  17. int vflag = 0; /* cmdline option: -v set */
  18. int eflag = 0; /* cmdline option: -e set */
  19. int tflag = 0; /* cmdline option: -t set */
  20.  
  21. /*
  22.  * NAME: scan
  23.  * PURPOSE:
  24.  * reads characters from stream, converts them according the
  25.  * commandline options and print the converted characters on stdout
  26.  *
  27.  * PARAMETERS:
  28.  * FILE *fp ... pointer to a stream to read from
  29.  *
  30.  * RETURN VALUE:
  31.  * void
  32.  *
  33.  * GLOBAL VARS:
  34.  * vflag, eflag, tflag
  35.  */
  36. void scan(FILE *fp)
  37. {
  38. int ch;
  39.  
  40. while((ch = getc(fp)) != EOF)
  41. {
  42. /* eflag: print '$' before '\n' */
  43. if (ch == '\n')
  44. {
  45. if (eflag && putchar('$') == EOF)
  46. break;
  47. }
  48. /* tflag: print '^I' instead of '\t' */
  49. else if (ch == '\t')
  50. {
  51. if (tflag)
  52. {
  53. if (putchar('^') == EOF || putchar('I') == EOF)
  54. break;
  55. continue;
  56. }
  57. }
  58. /* vflag */
  59. else if (vflag)
  60. {
  61. /* 128 <= ch <= 255: print 'M-'.(ch-128) */
  62. if (128 <= ch && ch <= 255)
  63. {
  64. if (putchar('M') == EOF || putchar('-') == EOF)
  65. break;
  66. ch = ch - 128;
  67. }
  68.  
  69. /* 0 <= ch <= 31: print '^'.(ch+'@') */
  70. if (0 <= ch && ch <= 31)
  71. {
  72. if (putchar('^') == EOF || putchar(ch + '@') == EOF)
  73. break;
  74. continue;
  75. }
  76. /* ch == 27: print '^?' */
  77. else if (ch == 127)
  78. {
  79. if (putchar('^') == EOF || putchar('?') == EOF)
  80. break;
  81. continue;
  82. }
  83. }
  84.  
  85. /* print character to stdout */
  86. if (putchar(ch) == EOF)
  87. break;
  88. }
  89. }
  90.  
  91. /*
  92.  * NAME: usage
  93.  * PURPOSE:
  94.  * prints program usage to stderr and terminates with EXIT_FAILURE
  95.  *
  96.  * PARAMETERS:
  97.  * void
  98.  *
  99.  * RETURN VALUE:
  100.  * void
  101.  *
  102.  * GLOBAL VARS:
  103.  * me
  104.  */
  105. static void usage(void)
  106. {
  107. (void) fprintf(stderr, "Usage: %s [-vET]\n", me);
  108. (void) exit(EXIT_FAILURE);
  109. }
  110.  
  111. /*
  112.  * NAME: main
  113.  * PURPOSE:
  114.  * parses commandline options and calls scan()
  115.  *
  116.  * PARAMETERS:
  117.  * standard parameters of main(...)
  118.  *
  119.  * RETURN VALUE:
  120.  * int ... always 0
  121.  *
  122.  * GLOBAL VARS:
  123.  * me, vflag, eflag, tflag
  124.  */
  125. int main(int argc, char *argv[])
  126. {
  127. int opt;
  128.  
  129. me = argv[0];
  130. while ((opt = getopt(argc, argv, "vET")) != -1)
  131. {
  132. switch(opt)
  133. {
  134. case 'v':
  135. vflag = 1;
  136. break;
  137. case 'E':
  138. eflag = 1;
  139. break;
  140. case 'T':
  141. tflag = 1;
  142. break;
  143. default:
  144. (void) usage();
  145. break;
  146. }
  147. }
  148.  
  149. (void) scan(stdin);
  150. return 0;
  151. }
  152.  
  153. /* vim: set et sw=2 ts=2: */
  154.