slang.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  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. static struct slang_header *slang_find(struct slang_header *, char *);
  19. static int slangtypetoi(char *);
  20. #include "slang_text.c"
  21. #include "slang_multitext.c"
  22. #include "slang_ids.c"
  23. #ifndef SLANG_NOTYPES
  24. #include "slang_types.c"
  25. #endif
  26. #include "slang_duration.c"
  27. #ifndef SLANG_NOFACTS
  28. #include "slang_facts_places.c"
  29. #include "slang_facts.c"
  30. #endif
  31. #include "slang_chanlang.c"
  32. struct slang_header {
  33. struct slang_header *next;
  34. char *lang;
  35. char *desc;
  36. struct slang_id *ids;
  37. #ifndef SLANG_NOTYPES
  38. struct slang_type *types;
  39. #endif
  40. #ifndef SLANG_NOFACTS
  41. struct slang_facts *facts;
  42. #endif
  43. struct slang_duration *durations;
  44. };
  45. static void slang_glob_init()
  46. {
  47. glob_slang_cmd_list = NULL;
  48. }
  49. /*
  50. static int slang_glob_expmem()
  51. {
  52. return slang_commands_list_expmem(glob_slang_cmd_list);
  53. }
  54. */
  55. static void slang_glob_free()
  56. {
  57. slang_commands_list_free(glob_slang_cmd_list);
  58. glob_slang_cmd_list = NULL;
  59. }
  60. static struct slang_header *slang_create(struct slang_header *list, char *lang, char *desc)
  61. {
  62. struct slang_header *nslang, *l;
  63. Assert(lang);
  64. debug2("Creating language '%s' starting by %d", lang, (int) list);
  65. for (nslang = list; nslang; nslang = nslang->next)
  66. if (!strcasecmp(nslang->lang, lang))
  67. return list;
  68. nslang = nmalloc(sizeof(struct slang_header));
  69. nslang->next = NULL;
  70. nslang->desc = NULL;
  71. nslang->lang = nmalloc(strlen(lang) + 1);
  72. strcpy(nslang->lang, lang);
  73. nslang->desc = nmalloc(strlen(desc) + 1);
  74. strcpy(nslang->desc, desc);
  75. nslang->ids = NULL;
  76. #ifndef SLANG_NOTYPES
  77. nslang->types = NULL;
  78. #endif
  79. #ifndef SLANG_NOFACTS
  80. nslang->facts = NULL;
  81. #endif
  82. nslang->durations = NULL;
  83. for (l = list; l && l->next; l = l->next);
  84. if (l)
  85. l->next = nslang;
  86. else {
  87. Assert(!list);
  88. list = nslang;
  89. }
  90. return list;
  91. }
  92. /*
  93. static int slang_expmem(struct slang_header *what)
  94. {
  95. int size = 0;
  96. while (what) {
  97. size += sizeof(struct slang_header);
  98. size += strlen(what->lang) + 1;
  99. size += strlen(what->desc) + 1;
  100. size += slang_id_expmem(what->ids);
  101. #ifndef SLANG_NOTYPES
  102. size += slang_type_expmem(what->types);
  103. #endif
  104. #ifndef SLANG_NOFACTS
  105. size += slang_facts_expmem(what->facts);
  106. #endif
  107. size += slang_duration_expmem(what->durations);
  108. what = what->next;
  109. }
  110. return size;
  111. }
  112. */
  113. static void slang_free(struct slang_header *what)
  114. {
  115. struct slang_header *next;
  116. while (what) {
  117. next = what->next;
  118. slang_id_free(what->ids);
  119. #ifndef SLANG_NOTYPES
  120. slang_type_free(what->types);
  121. #endif
  122. #ifndef SLANG_NOFACTS
  123. slang_facts_free(what->facts);
  124. #endif
  125. slang_duration_free(what->durations);
  126. nfree(what->lang);
  127. nfree(what->desc);
  128. nfree(what);
  129. what = next;
  130. }
  131. }
  132. static int slang_load(struct slang_header *slang, char *filename)
  133. {
  134. FILE *f;
  135. char *buffer, *s;
  136. char *cmd, *sid, *strtol_ret;
  137. #ifndef SLANG_NOTYPES
  138. char *type;
  139. #endif
  140. int line, id, iplace, itype;
  141. Assert(slang);
  142. putlog(LOG_MISC, "*", "Loading language \"%s\" from %s...", slang->lang, filename);
  143. f = fopen(filename, "r");
  144. if (!f) {
  145. putlog(LOG_MISC, "*", "Couldn't open slangfile \"%s\"!", filename);
  146. return 0;
  147. }
  148. buffer = nmalloc(2000);
  149. line = 0;
  150. while (!feof(f)) {
  151. s = buffer;
  152. if (fgets(s, 2000, f)) {
  153. line++;
  154. // at first, kill those stupid line feeds and carriage returns...
  155. if (s[strlen(s) - 1] == '\n')
  156. s[strlen(s) - 1] = 0;
  157. if (s[strlen(s) - 1] == '\r')
  158. s[strlen(s) - 1] = 0;
  159. if (!s[0])
  160. continue;
  161. cmd = newsplit(&s);
  162. if (!strcasecmp(cmd, "T")) {
  163. #ifndef SLANG_NOTYPES
  164. type = newsplit(&s);
  165. slang->types = slang_type_add(slang->types, type, s);
  166. #endif
  167. } else if (!strcasecmp(cmd, "D")) {
  168. sid = newsplit(&s);
  169. id = strtol(sid, &strtol_ret, 10);
  170. if (strtol_ret == sid) {
  171. putlog(LOG_MISC, "*", "ERROR in slangfile \"%s\", line %d: %s is not a valid "
  172. "duration index!", filename, line, sid);
  173. continue;
  174. }
  175. slang->durations = slang_duration_add(slang->durations, id, s);
  176. } else if (!strcasecmp(cmd, "F")) {
  177. itype = typetoi(newsplit(&s));
  178. iplace = atoi(newsplit(&s));
  179. slang->facts = slang_facts_add(slang->facts, itype, iplace, s);
  180. } else {
  181. id = strtol(cmd, &strtol_ret, 10);
  182. if (strtol_ret == cmd)
  183. continue;
  184. slang->ids = slang_id_add(slang->ids, id, s);
  185. }
  186. }
  187. }
  188. fclose(f);
  189. nfree(buffer);
  190. return 1;
  191. }
  192. static struct slang_header *slang_find(struct slang_header *where, char *language)
  193. {
  194. struct slang_header *slang = NULL;
  195. // at first, search for the specified language
  196. for (slang = where; slang; slang = slang->next)
  197. if (!strcasecmp(slang->lang, language))
  198. return slang;
  199. // oops... language seems to be invalid. Let's find the default.
  200. Assert(default_slang);
  201. for (slang = where; slang; slang = slang->next)
  202. if (!strcasecmp(slang->lang, default_slang))
  203. return slang;
  204. // default_slang wasn't found either? *sigh*
  205. // Let's return the first known language then.
  206. return where;
  207. }
  208. #ifndef SLANG_NOVALIDATE
  209. /* slang_valid():
  210. * check if the given language is a valid one
  211. */
  212. static int slang_valid(struct slang_header *where, char *language)
  213. {
  214. struct slang_header *slang = NULL;
  215. for (slang = where; slang; slang = slang->next)
  216. if (!strcasecmp(slang->lang, language))
  217. return 1;
  218. return 0;
  219. }
  220. #endif
  221. static char getslang_error[12];
  222. static char *getslang(int id)
  223. {
  224. char *text;
  225. if (!glob_slang) {
  226. putlog(LOG_MISC, "*", "Stats warning: no language selected. (getslang())");
  227. return "NOLANG";
  228. }
  229. text = slang_id_get(glob_slang->ids, id);
  230. if (!text) {
  231. snprintf(getslang_error, sizeof(getslang_error), "SLANG%d", id);
  232. return getslang_error;
  233. }
  234. return text;
  235. }
  236. static char *getdur(int idx)
  237. {
  238. char *text;
  239. Assert((idx >= 0) && (idx < DURATIONS));
  240. if (!glob_slang) {
  241. putlog(LOG_MISC, "*", "Stats warning: no language selected. (getdur())");
  242. return "NOLANG";
  243. }
  244. text = slang_duration_get(glob_slang->durations, idx);
  245. if (!text) {
  246. snprintf(getslang_error, sizeof(getslang_error), "DUR%d", idx);
  247. return getslang_error;
  248. }
  249. return text;
  250. }
  251. #ifndef SLANG_NOTYPES
  252. static char *getslangtype(char *type)
  253. {
  254. char *stype;
  255. if (!glob_slang) {
  256. putlog(LOG_MISC, "*", "Stats warning: no language selected. (getslangtype())");
  257. return "NOLANG";
  258. }
  259. stype = slang_type_get(glob_slang->types, type);
  260. if (stype)
  261. return stype;
  262. else
  263. return type;
  264. }
  265. static int slangtypetoi(char *slangtype)
  266. {
  267. char *type;
  268. if (!glob_slang) {
  269. putlog(LOG_MISC, "*", "Stats warning: no language selected. (slangtypetoi())");
  270. return T_ERROR;
  271. }
  272. type = slang_type_slang2type(glob_slang->types, slangtype);
  273. if (type) {
  274. debug1("type: %s", type);
  275. return typetoi(type);
  276. } else
  277. return typetoi(slangtype);
  278. }
  279. #endif
  280. #ifndef SLANG_NOGETALL
  281. static char *getslang_first(int id)
  282. {
  283. char *text;
  284. if (!glob_slang) {
  285. putlog(LOG_MISC, "*", "Stats warning: no language selected. (getslang_first())");
  286. return "NOLANG";
  287. }
  288. text = slang_id_get_first(glob_slang->ids, id);
  289. if (!text) {
  290. snprintf(getslang_error, sizeof(getslang_error), "SLANG%d", id);
  291. return getslang_error;
  292. }
  293. return text;
  294. }
  295. static char *getslang_next()
  296. {
  297. if (!glob_slang) {
  298. return NULL;
  299. }
  300. return slang_id_get_next();
  301. }
  302. #endif
  303. #ifndef SLANG_NOFACTS
  304. static int selectfirstfact()
  305. {
  306. if (!glob_slang) {
  307. debug0("getfirstfact(): no language selected!");
  308. return 0;
  309. }
  310. if (!glob_slang->facts)
  311. return 0;
  312. else
  313. return slang_facts_selectfirst(glob_slang->facts);
  314. }
  315. static int selectnextfact()
  316. {
  317. return slang_facts_selectnext();
  318. }
  319. /*static char *getfirstfact()
  320. {
  321. return slang_facts_getfirst();
  322. }
  323. static char *getnextfact()
  324. {
  325. return slang_facts_getnext();
  326. }*/
  327. static char *getfact(int place)
  328. {
  329. return slang_facts_get(place);
  330. }
  331. #endif