SHARE
TWEET

Untitled

a guest May 23rd, 2019 61 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <sys/types.h>
  4. #include <fcntl.h>
  5. #include <sys/stat.h>
  6. #include <unistd.h>
  7. #include <regex.h>
  8. #include <signal.h>
  9. #include <sys/mman.h>
  10. #include <string.h>
  11.  
  12. #define CORRECT_NUMBER_OF_ARGUMENTS 2
  13. #define MAX_COUNT_OF_STRINGS 100
  14. #define MAX_SIZE_OF_FILENAME BUFSIZ
  15. #define MAX_SIZE_OF_REQUEST BUFSIZ
  16. #define OPEN_FAILURE -1
  17. #define CLOSE_FAILURE -1
  18. #define WRITE_FAILURE -1
  19. #define READ_FAILURUE -1
  20. #define LSEEK_FAILURE -1
  21. #define READ_CONTINUES 0
  22. #define END_OF_WORKING 0
  23. #define CONTINUE_WORK 1
  24. #define END_OF_STRING '\n'
  25. #define PATTERN_OF_REQUEST "^[1-9][0-9]{0,}$"
  26. #define PATTERN_OF_EXIT "^\s{0,}0"
  27. #define REGEX_SUCCESS 0
  28. #define PRINT_STRING_ERROR 0
  29. #define PRINT_STRING_SUCCESS 1
  30. #define PROCESS_REQUEST_FAILURE -1
  31. #define MAKE_TABLE_FAILURE 0
  32. #define MAKE_TABLE_SUCCESS 1
  33. #define TIME_WAIT 5
  34. #define ALARM 1
  35. #define EMPTY_STRING 1
  36. #define PROCESS_UI_FAILURE 0
  37. #define PROCESS_UI_SUCCESS 1
  38. #define MUNMAP_FAILURE -1
  39. #define FINISH_MUNMAP_FAILURE 0
  40. #define FINISH_MUNMAP_SUCCESS 1
  41.  
  42. typedef struct Table
  43. {
  44.     off_t offset;
  45.     int length;
  46. }Table;
  47.  
  48. int Signal = NULL;
  49. char *mappedFile = NULL;
  50. size_t fileLength = 0;
  51.  
  52. void checkArgs(int argc, char* argv, int* fileDesc)
  53. {
  54.     char filename[MAX_SIZE_OF_FILENAME];
  55.     if (argc != CORRECT_NUMBER_OF_ARGUMENTS)
  56.     {
  57.         printf("Please, print the filename:\n");
  58.         scanf("%s", filename);
  59.         argv = filename;
  60.     }
  61.     *fileDesc = open(argv, O_RDONLY);
  62.     while (*fileDesc == OPEN_FAILURE)
  63.     {
  64.         perror("Incorrect name of file");
  65.         printf("Please, print the filename:\n");
  66.         scanf("%s", filename);
  67.         *fileDesc = open(filename, O_RDONLY);
  68.     }
  69. }
  70.  
  71. int makeTable(Table* table, int* tableIndex)
  72. {
  73.     int code;
  74.  
  75.     *tableIndex = 0;
  76.     size_t iter;
  77.     for (iter = 0; iter < fileLength; iter++)
  78.     {
  79.         if (mappedFile[iter] != END_OF_STRING)
  80.         {
  81.             ++table[*tableIndex].length;
  82.             continue;
  83.         }
  84.         ++*tableIndex;
  85.         if (*tableIndex > MAX_COUNT_OF_STRINGS)
  86.         {
  87.             fprintf(stderr, "File is too big. Prog got first 100 strings.\n");
  88.             return MAKE_TABLE_SUCCESS;
  89.         }
  90.         table[*tableIndex].offset = table[*tableIndex - 1].offset + table[*tableIndex - 1].length + 1;
  91.     }
  92.     if (code == READ_FAILURUE)
  93.     {
  94.         perror("Reading file error");
  95.         return MAKE_TABLE_FAILURE;
  96.     }
  97.     return MAKE_TABLE_SUCCESS;
  98. }
  99.  
  100. void printString(int stringNumb, Table* table)
  101. {
  102.     char symb;
  103.     off_t iter;
  104.     for (iter = table[stringNumb - 1].offset; iter < table[stringNumb - 1].offset + table[stringNumb - 1].length; iter++)
  105.     {
  106.         printf("%c", mappedFile[iter]);
  107.     }
  108.     printf("\n");
  109. }
  110.  
  111. int processRequest(Table* table, int stringsCount, char* request)
  112. {
  113.     regex_t regexexit, regexrequest;
  114.     int code;
  115.     char error[512];
  116.     code = regcomp(&regexexit, PATTERN_OF_EXIT, REG_EXTENDED);
  117.     if (code != REGEX_SUCCESS) {
  118.         perror("regex error");
  119.         regerror(code, &regexexit, error, sizeof(error));
  120.         return PROCESS_REQUEST_FAILURE;
  121.     }
  122.     code = regcomp(&regexrequest, PATTERN_OF_REQUEST, REG_EXTENDED);
  123.     if (code != REGEX_SUCCESS) {
  124.         perror("regex error");
  125.         regerror(code, &regexrequest, error, sizeof(error));
  126.         return PROCESS_REQUEST_FAILURE;
  127.     }
  128.  
  129.     regmatch_t pm;
  130.     code = regexec(&regexexit, request, 0, &pm, 0);
  131.     if (code == REGEX_SUCCESS)
  132.     {
  133.         return END_OF_WORKING;
  134.     }
  135.     code = regexec(&regexrequest, request, 0, &pm, 0);
  136.     if (code != REGEX_SUCCESS)
  137.     {
  138.         fprintf(stderr, "Incorrect request!\n");
  139.         return CONTINUE_WORK;
  140.     }
  141.  
  142.     int stringNumb = atoi(request);
  143.     if (stringNumb > stringsCount)
  144.     {
  145.         printf("File has only %d strings!\n", stringsCount);
  146.         printf("Try again\n");
  147.         return CONTINUE_WORK;
  148.     }
  149.     printString(stringNumb, table);
  150.     return CONTINUE_WORK;
  151. }
  152.  
  153. int printAllStrings()
  154. {
  155.     printf("Too long to wait. All file: \n");
  156.     char symb;
  157.     off_t iter;
  158.     for (iter = 0; iter < fileLength; iter++)
  159.     {
  160.         printf("%c", mappedFile[iter]);
  161.     }
  162. }
  163.  
  164. void endWork()
  165. {
  166.     Signal = ALARM;
  167. }
  168.  
  169. void *mapFile(int *fileDesc)
  170. {
  171.     off_t filesize = lseek(*fileDesc, 0, SEEK_END);
  172.     if (filesize == LSEEK_FAILURE)
  173.     {
  174.         perror("Reading file error");
  175.         return NULL;
  176.     }
  177.  
  178.     fileLength = (size_t)filesize;
  179.     char *mappedfile = mmap(NULL, fileLength, PROT_READ, MAP_PRIVATE, *fileDesc, 0);
  180.     if (mappedFile == MAP_FAILED)
  181.     {
  182.         perror("Mapping error");
  183.         return NULL;
  184.     }
  185.  
  186.     close(*fileDesc);
  187.  
  188.     return mappedfile;
  189. }
  190.  
  191. int processUserInput(Table* table, int stringsCount)
  192. {
  193.     char request[MAX_SIZE_OF_REQUEST];
  194.     int code;
  195.     code = CONTINUE_WORK;
  196.     if (signal(SIGALRM, endWork) == SIG_ERR)
  197.     {
  198.         perror("Signal seting error");
  199.         return PROCESS_UI_FAILURE;
  200.     }
  201.     while (code != END_OF_WORKING)
  202.     {
  203.         printf("Print the number of string in 5 seconds(0 for exit)\n");
  204.         alarm(TIME_WAIT);
  205.         if (fgets(request, MAX_SIZE_OF_REQUEST, stdin) == EOF)
  206.         {
  207.             fprintf(stderr, "Reading request error\nTry again\n");
  208.             continue;
  209.         }
  210.         if (Signal == ALARM)
  211.         {
  212.             break;
  213.         }
  214.         if (strlen(request) == EMPTY_STRING)
  215.         {
  216.             continue;
  217.         }
  218.         request[strlen(request) - 1] = '\0';
  219.         code = processRequest(table, stringsCount, request);
  220.         if (code == PROCESS_REQUEST_FAILURE)
  221.         {
  222.             perror("Processing request error");
  223.             return PROCESS_UI_FAILURE;
  224.         }
  225.     }
  226.     if (Signal == ALARM)
  227.     {
  228.         if (printAllStrings() == PRINT_STRING_ERROR)
  229.         {
  230.             fprintf(stderr, "Printing all strings error\n");
  231.             return PROCESS_UI_FAILURE;
  232.         }
  233.     }
  234.     return PROCESS_UI_SUCCESS;
  235. }
  236.  
  237. int finishmap()
  238. {
  239.     int code;
  240.     if (code = munmap(mappedFile, fileLength) == MUNMAP_FAILURE)
  241.     {
  242.         perror("Releasing resources error");
  243.         return FINISH_MUNMAP_FAILURE;
  244.     }
  245.     return FINISH_MUNMAP_SUCCESS;
  246. }
  247.  
  248. int main(int argc, char *argv[])
  249. {
  250.     int fileDesc;
  251.     checkArgs(argc, argv[1], &fileDesc);
  252.  
  253.     mappedFile = mapFile(&fileDesc);
  254.     if (mappedFile == NULL)
  255.     {
  256.         return EXIT_FAILURE;
  257.     }
  258.  
  259.     Table table[MAX_COUNT_OF_STRINGS] = { 0, 0 };
  260.     int stringsCount;
  261.     int code;
  262.     code = makeTable(table, &stringsCount);
  263.     if (code == MAKE_TABLE_FAILURE)
  264.     {
  265.         return EXIT_FAILURE;
  266.     }
  267.  
  268.     if (processUserInput(table, stringsCount) == PROCESS_UI_FAILURE)
  269.     {
  270.         fprintf(stderr, "ProcessUserInput error\n");
  271.         if (code = finishmap() == FINISH_MUNMAP_FAILURE)//обработка ошибки
  272.         {
  273.             return EXIT_FAILURE;
  274.         }
  275.         return EXIT_FAILURE;
  276.     }
  277.  
  278.     if (code = finishmap() == FINISH_MUNMAP_FAILURE)
  279.     {
  280.         return EXIT_FAILURE;
  281.     }
  282.  
  283.     return EXIT_SUCCESS;
  284. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top