edit.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. /******************************************************************************
  2. * This file is part of TinTin++ *
  3. * *
  4. * Copyright (C) 2004-2020 Igor van den Hoven *
  5. * *
  6. * TinTin++ is free software; you can redistribute it and/or modify *
  7. * it under the terms of the GNU General Public License as published by *
  8. * the Free Software Foundation; either version 3 of the License, or *
  9. * (at your option) any later version. *
  10. * *
  11. * This program is distributed in the hope that it will be useful, *
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  14. * GNU General Public License for more details. *
  15. * *
  16. * You should have received a copy of the GNU General Public License *
  17. * along with TinTin++. If not, see https://www.gnu.org/licenses. *
  18. ******************************************************************************/
  19. /******************************************************************************
  20. * T I N T I N + + *
  21. * *
  22. * coded by Igor van den Hoven 2020 *
  23. ******************************************************************************/
  24. #include "tintin.h"
  25. DO_COMMAND(do_edit)
  26. {
  27. int cnt;
  28. arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN);
  29. if (*arg1 == 0)
  30. {
  31. tintin_header(ses, 80, " EDIT OPTIONS ");
  32. for (cnt = 0 ; edit_table[cnt].fun ; cnt++)
  33. {
  34. if (*edit_table[cnt].desc)
  35. {
  36. tintin_printf2(ses, " [%-18s] %s", edit_table[cnt].name, edit_table[cnt].desc);
  37. }
  38. }
  39. tintin_header(ses, 80, "");
  40. }
  41. else
  42. {
  43. for (cnt = 0 ; edit_table[cnt].fun ; cnt++)
  44. {
  45. if (is_abbrev(arg1, edit_table[cnt].name))
  46. {
  47. edit_table[cnt].fun(ses, arg, arg1, arg2);
  48. return ses;
  49. }
  50. }
  51. show_error(ses, LIST_COMMAND, "#ERROR: #EDIT {%s} IS NOT A VALID OPTION.", arg1);
  52. }
  53. return ses;
  54. }
  55. DO_EDIT(edit_create)
  56. {
  57. struct edit_data *edit = gtd->ses->input->edit;
  58. char *pta, *ptn;
  59. int index;
  60. clear_editor(edit);
  61. arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN);
  62. str_cpy(&gtd->ses->input->edit_name, arg1);
  63. index = 0;
  64. while (*arg)
  65. {
  66. arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN);
  67. pta = arg1;
  68. ptn = strchr(pta, '\n');
  69. while (ptn)
  70. {
  71. *ptn++ = 0;
  72. if (*ptn)
  73. {
  74. insert_line(edit, index++, pta);
  75. pta = ptn;
  76. }
  77. ptn = strchr(pta, '\n');
  78. }
  79. insert_line(edit, index++, pta);
  80. }
  81. show_message(ses, LIST_COMMAND, "#EDIT CREATE: CREATED %d LINES.", edit->used);
  82. enable_editor(edit);
  83. return ses;
  84. }
  85. DO_EDIT(edit_load)
  86. {
  87. struct edit_data *edit = gtd->ses->input->edit;
  88. struct listnode *node;
  89. int index;
  90. arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN);
  91. if ((node = search_nest_node_ses(ses, arg1)) == NULL)
  92. {
  93. show_error(ses, LIST_COMMAND, "#EDIT LOAD: VARIABLE {%s} NOT FOUND.", arg1);
  94. return ses;
  95. }
  96. if (node->root == NULL)
  97. {
  98. return edit_create(ses, node->arg1, arg1, arg2);
  99. }
  100. clear_editor(edit);
  101. for (index = 0 ; index < node->root->used ; index++)
  102. {
  103. substitute(ses, node->root->list[index]->arg1, arg2, SUB_ESC);
  104. insert_line(edit, index, arg2);
  105. }
  106. show_message(ses, LIST_COMMAND, "#EDIT LOAD: LOADED %d LINES FROM {%s}.", edit->used, arg1);
  107. enable_editor(edit);
  108. return ses;
  109. }
  110. DO_EDIT(edit_save)
  111. {
  112. struct edit_data *edit = gtd->ses->input->edit;
  113. struct listnode *node;
  114. int index;
  115. arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN);
  116. if (!valid_variable(ses, arg1))
  117. {
  118. show_error(ses, LIST_VARIABLE, "#EDIT SAVE: INVALID VARIABLE NAME {%s}.", arg1);
  119. return ses;
  120. }
  121. node = set_nest_node_ses(ses, arg1, "");
  122. node->root = init_list(gtd->ses, LIST_VARIABLE, LIST_SIZE);
  123. for (index = 0 ; index < edit->used ; index++)
  124. {
  125. substitute(ses, edit->line[index]->str, arg2, SUB_SEC);
  126. create_node_list(node->root, ntos(index), arg2, "", "");
  127. }
  128. show_message(ses, LIST_COMMAND, "#EDIT SAVE: SAVED %d LINES TO {%s}.", edit->used, arg1);
  129. return ses;
  130. }
  131. DO_EDIT(edit_read)
  132. {
  133. struct edit_data *edit = gtd->ses->input->edit;
  134. FILE *file;
  135. int index, size;
  136. arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN);
  137. if (*arg1 == 0)
  138. {
  139. show_error(ses, LIST_COMMAND, "#SYNTAX: #EDIT READ <FILENAME>");
  140. return ses;
  141. }
  142. if ((file = fopen(arg1, "r")) == NULL)
  143. {
  144. show_error(ses, LIST_COMMAND, "#ERROR: #EDIT READ: FILE {%s} NOT FOUND.", arg1);
  145. return ses;
  146. }
  147. clear_editor(edit);
  148. str_cpy(&gtd->ses->input->edit_name, arg1);
  149. index = 0;
  150. size = 0;
  151. while (fread_one_line(&arg2, file))
  152. {
  153. size += str_len(arg2);
  154. insert_line(edit, index++, arg2);
  155. }
  156. show_message(ses, LIST_COMMAND, "#EDIT READ: READ %d LINES FROM {%s}.", edit->used, arg1);
  157. enable_editor(edit);
  158. fclose(file);
  159. return ses;
  160. }
  161. DO_EDIT(edit_write)
  162. {
  163. struct edit_data *edit = gtd->ses->input->edit;
  164. FILE *file;
  165. int index;
  166. arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN);
  167. if (*arg1 == 0)
  168. {
  169. str_cpy(&arg1, gtd->ses->input->edit_name);
  170. }
  171. if ((file = fopen(arg1, "w")) == NULL)
  172. {
  173. show_error(ses, LIST_COMMAND, "#ERROR: #EDIT WRITE: COULDN'T OPEN {%s} TO WRITE.", arg1);
  174. return ses;
  175. }
  176. for (index = 0 ; index < edit->used ; index++)
  177. {
  178. fputs(edit->line[index]->str, file);
  179. putc(ASCII_LF, file);
  180. }
  181. show_message(ses, LIST_COMMAND, "#EDIT WRITE: WROTE %d LINES TO {%s}.", index, arg1);
  182. return ses;
  183. }
  184. DO_EDIT(edit_resume)
  185. {
  186. struct edit_data *edit = gtd->ses->input->edit;
  187. SET_BIT(gtd->ses->input->flags, INPUT_FLAG_EDIT);
  188. if (edit->size == edit->update)
  189. {
  190. insert_line(edit, edit->update, "");
  191. }
  192. inputline_set(edit->line[edit->update]->str, 0);
  193. cursor_redraw_edit(ses, "");
  194. return ses;
  195. }
  196. DO_EDIT(edit_suspend)
  197. {
  198. struct edit_data *edit = gtd->ses->input->edit;
  199. if (!HAS_BIT(gtd->ses->input->flags, INPUT_FLAG_EDIT))
  200. {
  201. tintin_printf2(gtd->ses, "edit_suspend: not currently editing");
  202. return ses;
  203. }
  204. DEL_BIT(gtd->ses->input->flags, INPUT_FLAG_EDIT);
  205. str_cpy(&edit->line[edit->update]->str, gtd->ses->input->buf);
  206. cursor_clear_line(ses, "");
  207. cursor_redraw_edit(ses, "");
  208. return ses;
  209. }
  210. struct edit_data *create_editor(void)
  211. {
  212. return calloc(1, sizeof(struct edit_data));
  213. }
  214. void delete_editor(struct edit_data *edit)
  215. {
  216. if (edit == NULL)
  217. {
  218. tintin_printf2(gtd->ses, "destroy_edit: NULL");
  219. return;
  220. }
  221. clear_editor(edit);
  222. free(edit);
  223. }
  224. void resize_editor(struct edit_data *edit, int size)
  225. {
  226. if (edit->size < size)
  227. {
  228. edit->size = size;
  229. edit->line = (struct row_data **) realloc(edit->line, edit->size * sizeof(struct row_data *));
  230. }
  231. }
  232. void clear_editor(struct edit_data *edit)
  233. {
  234. int index;
  235. edit->update = 0;
  236. for (index = edit->used - 1 ; index >= 0 ; index--)
  237. {
  238. delete_line(edit, index);
  239. }
  240. }
  241. void enable_editor(struct edit_data *edit)
  242. {
  243. char *str1;
  244. int filesize;
  245. SET_BIT(gtd->ses->input->flags, INPUT_FLAG_EDIT);
  246. if (edit->used == 0)
  247. {
  248. create_line(edit, 0, "");
  249. }
  250. inputline_set(edit->line[edit->update]->str, 0);
  251. str1 = str_alloc_stack(0);
  252. filesize = str_save_editor(gtd->ses->input->edit, &str1);
  253. cursor_redraw_edit(gtd->ses, "");
  254. check_all_events(gtd->ses, EVENT_FLAG_INPUT, 0, 4, "STARTED EDITING", gtd->ses->input->edit_name, ntos(edit->used), ntos(filesize), str1);
  255. if (*gtd->ses->input->edit_name)
  256. {
  257. check_all_events(gtd->ses, EVENT_FLAG_INPUT, 1, 4, "STARTED EDITING %s", gtd->ses->input->edit_name, gtd->ses->input->edit_name, ntos(edit->used), ntos(filesize), str1);
  258. }
  259. }
  260. int str_save_editor(struct edit_data *edit, char **str)
  261. {
  262. int index, size;
  263. size = 0;
  264. str_cpy(str, "");
  265. for (index = 0 ; index < edit->used ; index++)
  266. {
  267. str_cat_printf(str, "%s\n", edit->line[index]->str);
  268. size += str_len(edit->line[index]->str);
  269. }
  270. return size;
  271. }
  272. int var_save_editor(struct edit_data *edit, char **str)
  273. {
  274. int index, size;
  275. size = 0;
  276. for (index = 0 ; index < edit->used ; index++)
  277. {
  278. str_cat_printf(str, "{%d}{%s}", index + 1, edit->line[index]->str);
  279. }
  280. return size;
  281. }
  282. void create_line(struct edit_data *edit, int index, char *str)
  283. {
  284. resize_editor(edit, index + 2);
  285. edit->line[index] = (struct row_data *) calloc(1, sizeof(struct row_data));
  286. edit->line[index]->str = str_dup(str);
  287. edit->used++;
  288. }
  289. void delete_line(struct edit_data *edit, int index)
  290. {
  291. str_free(edit->line[index]->str);
  292. free(edit->line[index]);
  293. edit->used--;
  294. }
  295. void insert_line(struct edit_data *edit, int index, char *str)
  296. {
  297. int cnt;
  298. if (index >= edit->used)
  299. {
  300. while (edit->used < index)
  301. {
  302. create_line(edit, edit->used, "");
  303. }
  304. create_line(edit, edit->used, str);
  305. return;
  306. }
  307. resize_editor(edit, edit->used + 2);
  308. for (cnt = edit->used ; cnt > index ; cnt--)
  309. {
  310. edit->line[cnt] = edit->line[cnt - 1];
  311. }
  312. create_line(edit, index, str);
  313. }
  314. void remove_line(struct edit_data *edit, int index)
  315. {
  316. int cnt;
  317. delete_line(edit, index);
  318. for (cnt = index ; cnt < edit->used ; cnt++)
  319. {
  320. edit->line[cnt] = edit->line[cnt + 1];
  321. }
  322. }