Advertisement
Guest User

Untitled

a guest
May 23rd, 2019
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.23 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement