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.

251 lines
7.8KB

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