templates_content.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /*
  2. * Copyright (C) 2000,2001 Florian Sander
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version 2
  7. * of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. /*
  19. static int templates_content_expmem(struct template_content *what)
  20. {
  21. int size = 0;
  22. while (what) {
  23. size += sizeof(struct template_content);
  24. if (what->html)
  25. size += strlen(what->html) + 1;
  26. if (what->charpar1)
  27. size += strlen(what->charpar1) + 1;
  28. size += templates_content_expmem(what->subcontent);
  29. what = what->next;
  30. }
  31. return size;
  32. }
  33. */
  34. static void templates_content_free(struct template_content *what)
  35. {
  36. struct template_content *next;
  37. while (what) {
  38. next = what->next;
  39. if (what->html)
  40. nfree(what->html);
  41. if (what->charpar1)
  42. nfree(what->charpar1);
  43. templates_content_free(what->subcontent);
  44. nfree(what);
  45. what = next;
  46. }
  47. }
  48. #define TEMPLATE_LINE_LENGTH 1024
  49. static struct template_content *templates_content_load(char *filename)
  50. {
  51. FILE *f;
  52. char buf[TEMPLATE_LINE_LENGTH + 1], *contentstring;
  53. struct template_content *content;
  54. Context;
  55. // at first, load the whole file into a buffer
  56. f = fopen(filename, "r");
  57. if (f == NULL) {
  58. putlog(LOG_MISC, "*", "Couldn't open template from %s!", filename);
  59. return NULL;
  60. }
  61. contentstring = nmalloc(1);
  62. contentstring[0] = 0;
  63. while (!feof(f)) {
  64. if (fgets(buf, TEMPLATE_LINE_LENGTH, f)) {
  65. buf[TEMPLATE_LINE_LENGTH] = 0;
  66. contentstring = nrealloc(contentstring, strlen(contentstring) + strlen(buf) + 1);
  67. strcat(contentstring, buf);
  68. }
  69. }
  70. fclose(f);
  71. // now process the content
  72. content = templates_content_parse(contentstring);
  73. nfree(contentstring);
  74. return content;
  75. }
  76. static struct template_content *templates_content_create()
  77. {
  78. struct template_content *newcontent;
  79. newcontent = nmalloc(sizeof(struct template_content));
  80. newcontent->next = NULL;
  81. newcontent->html = NULL;
  82. newcontent->command = NULL;
  83. newcontent->what = 0;
  84. newcontent->charpar1 = NULL;
  85. newcontent->floatpar1 = 0.0;
  86. newcontent->floatpar2 = 0.0;
  87. newcontent->intpar1 = 0;
  88. newcontent->subcontent = NULL;
  89. return newcontent;
  90. }
  91. static struct template_content *templates_content_append(struct template_content *where, struct template_content *what)
  92. {
  93. struct template_content *c;
  94. if (what->next)
  95. debug0("WARNING in templates_content_append(): what->next does exist!");
  96. for (c = where; c && c->next; c = c->next);
  97. if (c)
  98. c->next = what;
  99. else {
  100. Assert(!where);
  101. where = what;
  102. }
  103. return where;
  104. }
  105. /* template_parse_content():
  106. * parse the content and return a pointer to the filled content struct
  107. */
  108. static struct template_content *templates_content_parse(char *buf)
  109. {
  110. char *s, *cmdstart, *cmdend, *cmd, *included_text, *end_tag;
  111. char tag_buf[100];
  112. struct llist_2string *params;
  113. int need_end_tag;
  114. struct template_content *content;
  115. Context;
  116. content = NULL;
  117. while ((s = strstr(buf, "<?"))) {
  118. // initialize variables
  119. need_end_tag = 1;
  120. included_text = cmdstart = cmd = cmdend = end_tag = NULL;
  121. params = NULL;
  122. // cut the tag from the leading text
  123. s[0] = 0;
  124. s += 2;
  125. content = templates_content_addhtml(content, buf);
  126. cmdstart = buf = s;
  127. // and find the end of the tag
  128. cmdend = strstr(cmdstart, "?>");
  129. if (!cmdend) {
  130. putlog(LOG_MISC, "*", "ERROR parsing template: tag not terminated! (%s)", cmdstart);
  131. continue;
  132. }
  133. cmdend[0] = 0;
  134. s = buf = cmdend + 2;
  135. // if the command isn't really a command, but a comment, then
  136. // just skip it.
  137. if (!strncmp(cmdstart, "--", 2))
  138. continue;
  139. // check if we need a seperate end-tag, or if the tag is already terminated
  140. // (following XML-style)
  141. if (cmdstart[strlen(cmdstart) - 1] == '/') {
  142. need_end_tag = 0;
  143. cmdstart[strlen(cmdstart) - 1] = 0;
  144. }
  145. // now get the name of the command.
  146. cmd = newsplit(&cmdstart);
  147. // find the ending tag if needed...
  148. if (need_end_tag) {
  149. included_text = s;
  150. snprintf(tag_buf, sizeof(tag_buf), "<?/%s?>", (cmd[0] == '!') ? cmd + 1 : cmd);
  151. end_tag = strstr(s, tag_buf);
  152. if (!end_tag) {
  153. putlog(LOG_MISC, "*", "ERROR parsing template: end-tag (%s) not found!", tag_buf);
  154. continue;
  155. }
  156. end_tag[0] = 0;
  157. s = buf = end_tag + strlen(tag_buf);
  158. }
  159. // if this is just a comment or an disabled tag, then don't parse or store it all all.
  160. if (!strcmp(cmd, "comment") || (cmd[0] == '!'))
  161. continue;
  162. // parse the parameters
  163. params = templates_content_parseparams(cmdstart);
  164. // and finally add the tag with parameters and included text to
  165. // our template
  166. content = templates_commands_addtocontent(content, cmd, params, included_text);
  167. // now free the params again...
  168. llist_2string_free(params);
  169. }
  170. // append all remaining html code
  171. content = templates_content_addhtml(content, buf);
  172. return content;
  173. }
  174. static struct template_content *templates_content_addhtml(struct template_content *where, char *html)
  175. {
  176. struct template_content *newcontent;
  177. Assert(html);
  178. newcontent = templates_content_create();
  179. newcontent->html = nmalloc(strlen(html) + 1);
  180. strcpy(newcontent->html, html);
  181. where = templates_content_append(where, newcontent);
  182. return where;
  183. }
  184. static struct llist_2string *templates_content_parseparams(char *buf)
  185. {
  186. struct llist_2string *params;
  187. char *name, *value, *s;
  188. Assert(buf);
  189. params = NULL;
  190. while (buf[0]) {
  191. while (buf[0] == ' ')
  192. buf++;
  193. s = buf;
  194. name = csplit(&buf, '=');
  195. if (buf[0] != '"') {
  196. putlog(LOG_MISC, "*", "ERROR parsing parameters: missing '\"'! (%s)", name);
  197. continue;
  198. }
  199. buf++;
  200. value = buf;
  201. while (buf[0]) {
  202. if (buf[0] == '"')
  203. break;
  204. buf++;
  205. }
  206. if (buf[0] != '"') {
  207. putlog(LOG_MISC, "*", "ERROR parsing parameters: missing '\"'! (%s)", name);
  208. continue;
  209. }
  210. buf[0] = 0;
  211. buf++;
  212. params = llist_2string_add(params, name, value);
  213. }
  214. return params;
  215. }
  216. static void templates_content_send(struct template_content *tpc, int idx)
  217. {
  218. for (;tpc; tpc = tpc->next) {
  219. if (tpc->html)
  220. dprintf(idx, "%s", tpc->html);
  221. else if (tpc->command)
  222. tpc->command(idx, tpc);
  223. else
  224. dprintf(idx, "<H1>ERROR: No content!</H1>");
  225. }
  226. }