Advertisement
Guest User

Untitled

a guest
Feb 18th, 2020
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.99 KB | None | 0 0
  1. /*==================================================================
  2.  *
  3.  *               University College Dublin
  4.  *          COMP20020 - Unix Programming
  5.  *
  6.  * File Name    :   assign1-18442024.c
  7.  *
  8.  * Description  :   program to carry out user controlled head and tail operations on a file read from stdin
  9.  *                  checklist:
  10.  *                      getopt working coorectly
  11.  *                      default 10 lines working correctly
  12.  *                      -n K lines function working correctly
  13.  *                      -h program description working correctly
  14.  *                      -V print version version info working correctly
  15.  *                      -e/-o options working correctly
  16.  *                      read from stdin if no recognisable file is supplied
  17.  *                      all functions work form both supplied files and std input files
  18.  *
  19.  *
  20.  * Author       :   Matthew Murnaghan
  21.  *
  22.  * Date         :   16-02-20
  23.  *
  24.  *==================================================================*/
  25.  
  26. #include <stdlib.h>
  27. #include <stdio.h>
  28. #include <getopt.h>     // include relevant libraries
  29. #include <string.h>
  30. #include <stdbool.h>
  31.  
  32. #define READONLY "r"    // defined for use in file opening
  33. #define HEADERSIZE 10
  34. #define TAILSIZE 10
  35. #define MAXLINE_LENGTH 180  // defines max line length, can be changed to suit file, use for printing a seperating line between stdin input and stdin output file
  36. #define DEBUG 0   // defined to enable optional debug mode for analysis                                                                           // see line 130
  37. #define MAX_ARGUEMENTS 5
  38.  
  39. int main(int argc, char **argv)
  40. {
  41.     int K, lines = 0, ctr = 1, evenOdd = 2, option, i;       // declares int values for later use
  42.     char *line;                                                                                  // declares pointer to line foe use in getline fucntion
  43.     char head[] = "head", tail[] = "tail", V[] = "V", h[] = "h";                                 // declares char arrays for later use
  44.     char usage[] = "Error - Input format must be: { head | tail } [OPTION ] . . . [ FILE ]\n\n"; // declares generic usage error message
  45.     char optlist[] = "List of options for this program -->-n (int) K--returns int value K lines of read file\n-V-- returns version info\n-h-- returns help message\n-o-- returns odd lines of file\n-e-- returns even lines of file";
  46.     bool headMode = false, tailMode = false, fsupplied = true, optsupplied = false;              // declares booleans for condition checking
  47.     size_t len = 0;                                                                              // delcares size_t for use in get line for correct memory allocation
  48.     FILE *fpin, *tmpFile;                                                                        //declares needed file pointers
  49.     if (DEBUG)
  50.         printf("argc = %d\n\n", argc);
  51.     if (DEBUG)
  52.         for (i = 0; i < argc; i++)
  53.         {
  54.             printf("argv %d = %s \n", i, argv[i]);  // prints all arguments to the function
  55.         }
  56.     if (argc > MAX_ARGUEMENTS)
  57.     {
  58.         printf("Error - arguments for this program must not exceed 5\n");   // Prints specific error message if user exceeds max number of arguements
  59.         exit(2);
  60.     }
  61.     for (i = 1; i < argc; i++)  // checks all arguments to see of -h or -V is present
  62.     {
  63.         if (strcmp(argv[i], "-h") ==0 || strcmp(argv[i], "-H") == 0)
  64.         {
  65.             if (DEBUG)
  66.             {
  67.                 printf("%d\n", strcmp(argv[i], "-h"));
  68.                 printf("-h present - optsupplied = true\n");
  69.             }
  70.             optsupplied = true; // sets optsupplied to true for comparison check. if optsupplied == true
  71.         }
  72.             if (strcmp(argv[i], "-V") == 0 || strcmp(argv[i], "-v") == 0)
  73.         {
  74.             if (DEBUG)
  75.                 printf("-V present - optsupplied = true\n");
  76.             optsupplied = true;
  77.         }
  78.     }                                      
  79.     if (argc<2)
  80.     {
  81.         printf("%sMust provide at least 2 arguements\n", usage);
  82.         exit(2);
  83.     }
  84.     if (DEBUG)
  85.     {
  86.         printf("optsupplied false\n");
  87.     }
  88.     if (optsupplied == false)
  89.     {
  90.         if ((strncmp(head, argv[1], 4)) == 0)
  91.         {
  92.             if (DEBUG)
  93.                 printf("headmode\n");
  94.             headMode = true;
  95.         }
  96.         else if ((strncmp(tail, argv[1], 4)) == 0)
  97.         {
  98.             if (DEBUG)
  99.                 printf("tailemode\n");
  100.             tailMode = true; // printf("head/tail check\n");
  101.         }
  102.     }
  103.     if (optsupplied == false) // checks to make sure h option hasnt been triggered before attempting to open a file.
  104.     {
  105.         if ((fpin = fopen(argv[argc - 1], READONLY)) == NULL)
  106.         {
  107.             fsupplied = false;
  108.             printf("No File provided or file not recognised\n\nOpening temp file from stdin:\nTo end file input: user input --> \"Ctrl + D\"\n");
  109.             fpin = stdin;
  110.             tmpFile = tmpfile();
  111.             if (tmpFile == NULL)
  112.             {
  113.                 printf("Temp file failed to open \n");
  114.                 exit(EXIT_FAILURE);
  115.             }
  116.             while ((getline(&line, &len, fpin)) != EOF)
  117.             {
  118.                 fputs(line, tmpFile);
  119.                 lines++;
  120.             }
  121.             if (DEBUG)
  122.                 printf("lines %d\n", lines);
  123.             fpin = tmpFile;
  124.         }
  125.         if (DEBUG)
  126.         {
  127.             printf("%d\n", fsupplied);
  128.             printf("file opened\n");
  129.         }
  130.         if (DEBUG)
  131.             printf("lines %d\n", lines);
  132.         if (fsupplied == false)
  133.         {
  134.             for (i = 0; i < MAXLINE_LENGTH; i++)
  135.                 fputs("-", stdout);
  136.  
  137.             fputs("\n", stdout);
  138.             fseek(fpin, 0, SEEK_SET);
  139.         }  
  140.     }
  141.     if (DEBUG)
  142.         printf("start of while loop\n");
  143.  
  144.     while ((option = getopt(argc, argv, "hvn:eo")) != -1 || argc < 4)
  145.     {
  146.         switch (option)
  147.         {
  148.         case 'o':
  149.             if (argc > 4)
  150.             {
  151.                 printf("Error - even odd option requires no integer input\n");
  152.                 exit(2);
  153.             }
  154.             while ((getline(&line, &len, fpin)) != EOF)
  155.             {
  156.                 if (evenOdd % 2 == 0) /* code */
  157.                 {
  158.                     fputs(line, stdout);
  159.                 }
  160.                 evenOdd++;
  161.             }
  162.             exit(EXIT_SUCCESS);
  163.             {
  164.                 fputs(usage, stdout);
  165.                 exit(2);  
  166.             {
  167.                 fputs(usage, stdout);
  168.                 exit(2);
  169.             }
  170.             }
  171.  
  172.         case 'e':
  173.             if (argc > 4)
  174.             {
  175.                 printf("Error - even odd option requires no integer input\n");
  176.                 exit(2);
  177.             }
  178.             evenOdd = 1;
  179.             while ((getline(&line, &len, fpin)) != EOF)
  180.             {
  181.                 if (evenOdd % 2 == 0)
  182.                 {
  183.                     fputs(line, stdout);
  184.                 }
  185.                 evenOdd++;
  186.             }
  187.             exit(EXIT_SUCCESS);
  188.  
  189.         case 'V':
  190.             if (optsupplied == true && argc>2)
  191.             {
  192.                 printf("Error -V option requires only 2 inputs\n");
  193.                 exit(2);
  194.             }
  195.             printf("Version info:\n\tProgram Author: Matthew Murnaghan\n\tStudent email: \tmatthew.murnaghan@ucdconnect.ie\n\tstudent number: 18442024\n");
  196.             exit(EXIT_SUCCESS);
  197.  
  198.         case 'n':
  199.             lines = 0;
  200.             K = atoi(optarg);
  201.             if (DEBUG)
  202.                 printf("%d\n", K);
  203.             if (headMode == true)
  204.             {
  205.                 for (ctr = 0; ctr < K; ctr++)
  206.                 {
  207.                     (getline(&line, &len, fpin));
  208.                     fputs(line, stdout);
  209.                 }
  210.             }
  211.             else if (tailMode == true)
  212.             {
  213.                 if (DEBUG)
  214.                     printf("tailmode - before while\n");
  215.                 while ((getline(&line, &len, fpin)) != EOF)
  216.                 {
  217.                     lines++;
  218.                 }
  219.                 if (DEBUG)
  220.                     printf("after while\nlines = %d\n", lines);
  221.                 fseek(fpin, 0, SEEK_SET);
  222.                 while ((getline(&line, &len, fpin)) != EOF)
  223.                 {
  224.                     if (ctr > lines - K)
  225.                         fputs(line, stdout);
  226.  
  227.                     ctr++;
  228.                 }
  229.                 fputs("\n", stdout);
  230.             }
  231.             exit(EXIT_SUCCESS);
  232.  
  233.         case 'h':
  234.             if (optsupplied == true && argc>2)
  235.             {
  236.                 printf("Error -h option requires only 2 inputs\n");
  237.                
  238.                 exit(2);
  239.             }
  240.             fputs("\nThis is a program to print a user specified amount of lines from the head or tail of a file\n", stdout);
  241.             fputs("Input format must be: { head | tail } [OPTION ] . . . [ FILE ]\n\n", stdout);
  242.             printf("%s\n", optlist);
  243.             exit(EXIT_SUCCESS);
  244.  
  245.         default:
  246.             if (DEBUG)
  247.                 printf("default\n");
  248.             if (headMode == true)
  249.             {
  250.                 if (DEBUG)
  251.                     printf("forloop\n");
  252.                 if (lines < HEADERSIZE && fsupplied == false) //this part is used for when no file is supplied and the default case should trigger
  253.                 {
  254.                     if (DEBUG)
  255.                         printf("ctr = %d\n", ctr);
  256.                     for (ctr = 0; ctr < lines; ctr++)
  257.                     {
  258.                         (getline(&line, &len, fpin));
  259.                         fputs(line, stdout);
  260.                     }
  261.                 }
  262.                 else
  263.                 {
  264.                     lines = 0;
  265.                     for (ctr = 0; ctr < HEADERSIZE; ctr++) // this part is for when a file is supplied
  266.                     {
  267.                         (getline(&line, &len, fpin));
  268.                         fputs(line, stdout);
  269.                     }
  270.                     if (DEBUG)
  271.                         printf("past forloop\n");
  272.                 }
  273.             }
  274.             else if (tailMode == true)
  275.             {
  276.                 if (DEBUG)
  277.                     printf("tail mode - before while\n");
  278.                 while ((getline(&line, &len, fpin)) != EOF)
  279.                 {
  280.                     lines++;
  281.                 }
  282.                 if (DEBUG)
  283.                     printf("after while\nlines =%d\n", lines);
  284.                 fseek(fpin, 0, SEEK_SET);
  285.                 while ((getline(&line, &len, fpin)) != EOF)
  286.                 {
  287.                     if (ctr > lines - TAILSIZE)
  288.                         fputs(line, stdout);
  289.  
  290.                     ctr++;
  291.                 }
  292.                 fputs("\n", stdout);
  293.             }
  294.             else
  295.             {
  296.                 printf("%s", usage);
  297.                 exit(2);
  298.             }
  299.             exit(EXIT_SUCCESS);
  300.         }
  301.     }
  302.     if (headMode)
  303.     {
  304.         fclose(fpin);
  305.         free(line);
  306.         free(tmpFile);
  307.     }
  308.     exit(EXIT_SUCCESS);
  309. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement