Program to generate an xml file based on a provided text file
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

readfile.c 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdbool.h>
  5. #include <ctype.h>
  6. #include <sys/types.h>
  7. #include "main.h"
  8. #include "readfile.h"
  9. #include "encoding.h"
  10. #ifdef __MINGW32__
  11. #include "getline.h"
  12. #endif
  13. /*
  14. * This function reads Biblia.txt, searches for the information in config,
  15. * and stores it into an array of strings to be used later to create the xml.
  16. */
  17. int read_file() {
  18. FILE *file = NULL;
  19. CHAPTER *chapter = NULL;
  20. int start = 0;
  21. int end = 0;
  22. int chapters = 1;
  23. int verse = 0;
  24. int length;
  25. int i = 0;
  26. int k = 0;
  27. int l = 0;
  28. char *line = NULL;
  29. char *temp = NULL;
  30. char **array = NULL;
  31. ssize_t chars = 0;
  32. size_t lines = 0;
  33. size_t j = 0;
  34. size_t new_max = MAX_LINES;
  35. bool matches[3];
  36. matches[0] = false;
  37. matches[1] = false;
  38. matches[2] = false;
  39. char *ch = strtok(config->chapter_numbers, "-");
  40. while (ch != NULL) {
  41. if (i == 0) {
  42. start = atoi(ch);
  43. i++;
  44. }
  45. else {
  46. end = atoi(ch);
  47. }
  48. ch = strtok(NULL, "-");
  49. }
  50. #ifdef DEBUG
  51. printf("Start chapter: %d\nEnd chapter: %d\n", start, end);
  52. #endif
  53. if (end != 0) {
  54. if (start > end) {
  55. printf("Archivo de configuración invalido!");
  56. return 1;
  57. }
  58. else {
  59. chapters = (end - start) + 1;
  60. }
  61. }
  62. #ifdef DEBUG
  63. printf("Chapters: %d\n", chapters);
  64. #endif
  65. book->chapters = chapters;
  66. book->current = -1;
  67. book->chapter = (CHAPTER **) malloc((chapters + 1) * sizeof(CHAPTER *));
  68. i = 0;
  69. file = fopen("Biblia.txt", "r");
  70. if (file == NULL) {
  71. perror("fopen");
  72. return 1;
  73. }
  74. if (!(array = calloc(new_max, sizeof(*array)))) {
  75. fprintf(stderr, "Allocación de memoria falló.");
  76. return 1;
  77. }
  78. while ((chars = getline(&line, &j, file)) != -1) {
  79. while (chars > 0 && (line[chars - 1] == '\n' || line[chars - 1] == '\r' || line[chars - 1] == ' ' || line[chars - 1] == '\t')) {
  80. /* remove whitespace from end of the line */
  81. chars--;
  82. line[chars] = '\0';
  83. }
  84. line[chars] = '\0';
  85. array[lines] = strdup(line);
  86. lines++;
  87. /* not enough memory for more lines, time to allocate more memory */
  88. if (lines == new_max) {
  89. /* faster, but uses more ram while running */
  90. /*new_max = new_max * 2;*/
  91. /* slower, but uses less ram */
  92. new_max = new_max + 100;
  93. char **tmp = realloc(array, new_max * sizeof(*array));
  94. if (!tmp) {
  95. fprintf(stderr, "Reallocación de memoria falló.");
  96. return 1;
  97. }
  98. array = tmp;
  99. }
  100. }
  101. /* free the extra unused memory */
  102. if (new_max > lines) {
  103. char **tmp = realloc(array, lines * sizeof(*array));
  104. if (!tmp) {
  105. fprintf(stderr, "Reallocación de memoria falló.");
  106. return 1;
  107. }
  108. array = tmp;
  109. }
  110. if (file) {
  111. fclose(file);
  112. }
  113. if (line) {
  114. free(line);
  115. }
  116. for (j = 0; j < lines; j++) {
  117. if (array[j] != NULL) {
  118. line = latin_to_utf8(array[j]);
  119. }
  120. if (line != NULL) {
  121. if (strcmp(line, config->bible) == 0) {
  122. /* found the bible */
  123. matches[0] = true;
  124. matches[1] = false;
  125. matches[2] = false;
  126. #ifdef DEBUG
  127. printf("Bible match: %lu -> %s\n", (long) j + 1, line);
  128. #endif
  129. }
  130. if (strcmp(line, config->book) == 0) {
  131. /* found the book */
  132. matches[1] = true;
  133. matches[2] = false;
  134. #ifdef DEBUG
  135. printf("Book match: %lu -> %s\n", (long) j + 1, line);
  136. #endif
  137. }
  138. for (i = start; i <=end; i++) {
  139. length = snprintf(NULL, 0, "%d", i) + strlen(config->chapter);
  140. temp = (char *) malloc((length + 2) * sizeof(char));
  141. snprintf(temp, length + 2, "%s %d", config->chapter, i);
  142. if (strcmp(line, temp) == 0) {
  143. /* found a chapter */
  144. matches[2] = true;
  145. book->current++;
  146. book->chapter[book->current] = (CHAPTER *) malloc(sizeof(CHAPTER));
  147. chapter = book->chapter[book->current];
  148. chapter->chapter = i;
  149. chapter->current = -1;
  150. chapter->verses = 0;
  151. chapter->verse = (char **) malloc(sizeof(char *));
  152. #ifdef DEBUG
  153. printf("Chapter match: %lu -> %s\n", (long) j + 1, line);
  154. #endif
  155. }
  156. free(temp);
  157. }
  158. if (matches[0] == true && matches[1] == true && matches[2] == true) {
  159. /* 3 matches, start getting the verses */
  160. length = snprintf(NULL, 0, "%d", end + 1) + strlen(config->chapter);
  161. temp = (char *) malloc((length + 2) * sizeof(char));
  162. snprintf(temp, length + 2, "%s %d", config->chapter, end + 1);
  163. if (strcmp(line, temp) == 0) {
  164. free(line);
  165. free(temp);
  166. line = NULL;
  167. break;
  168. }
  169. if (temp) {
  170. free(temp);
  171. }
  172. temp = (char *) malloc((strlen(line) + 1) * sizeof(char));
  173. /* If it's a verse, match */
  174. for (i = 0; i <= 2; i++) {
  175. if (line[i] == ' ') {
  176. temp[i] = '\0';
  177. verse = atoi(temp);
  178. if (temp) {
  179. free(temp);
  180. }
  181. l = 0;
  182. temp = (char *) malloc((strlen(line) + 1) * sizeof(char));
  183. for (k = i + 1; k < strlen(line) - 1; (k++)) {
  184. temp[l] = line[k];
  185. l++;
  186. }
  187. temp[l] = '\0';
  188. chapter->current++;
  189. chapter->verses++;
  190. chapter->verse = (char **) realloc(chapter->verse, chapter->verses * sizeof(char *));
  191. chapter->verse[chapter->current] = (char *) malloc((strlen(temp) + 1) * sizeof(char));
  192. memcpy(chapter->verse[chapter->current], temp, strlen(temp) + 1);
  193. if (temp) {
  194. free(temp);
  195. }
  196. break;
  197. }
  198. if (!isdigit(line[i])) {
  199. if (temp) {
  200. free(temp);
  201. }
  202. break;
  203. }
  204. else {
  205. temp[i] = line[i];
  206. }
  207. }
  208. }
  209. if (matches[0] == true && matches[1] == true && matches[2] == true && strcmp(line, "------------------------------------------------------------------------") == 0) {
  210. /* end of a section and we already have 3 matches, no reason to continue */
  211. #ifdef DEBUG
  212. printf("Bible end match: %lu -> %s\n", (long) j + 1, line);
  213. #endif
  214. free(line);
  215. line = NULL;
  216. break;
  217. }
  218. }
  219. free(line);
  220. line = NULL;
  221. }
  222. for (j = 0; j < lines; j++) {
  223. free(array[j]);
  224. }
  225. free(array);
  226. if (matches[0] == false || matches[1] == false || matches[2] == false) {
  227. printf("No pudo encontrar lo solicitado en Biblia.txt!\n");
  228. return 1;
  229. }
  230. return 0;
  231. }