Add tools to the Workbench Tools menu
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.

io.c 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. ToolsMenu - Add tools to the Workbench Tools menu
  3. Copyright (C) 2015, 2018 Kim Fastrup Larsen
  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 ver-
  7. sion 3 of the License, or (at your option) any later version.
  8. This program is distributed in the hope that it will be use-
  9. ful, but WITHOUT ANY WARRANTY; without even the implied war-
  10. ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. See the GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public Li-
  13. cense along with this program. If not, see
  14. <http://www.gnu.org/licenses/>.
  15. The author can be contacted on <kimflarsen@hotmail.com>
  16. */
  17. #include <exec/memory.h>
  18. #include <clib/dos_protos.h>
  19. #include <clib/exec_protos.h>
  20. #include <clib/icon_protos.h>
  21. #ifdef USE_PRAGMAS
  22. #include <proto/dos.h>
  23. #include <proto/exec.h>
  24. #include <proto/icon.h>
  25. #endif
  26. #include <string.h>
  27. #include "common.h"
  28. #include "cx.h"
  29. #include "io.h"
  30. #define DEF_BEGIN '\xab' /* Left double angle quote */
  31. #define DEF_END '\xbb' /* Right double angle quote */
  32. typedef void Disk_object_f(struct DiskObject *, char *);
  33. static void with_disk_object(Disk_object_f *f, BPTR dir, char *filename)
  34. {
  35. BPTR old_dir = CurrentDir(dir);
  36. struct DiskObject *disk_obj = GetDiskObject(filename);
  37. if (disk_obj != NULL) {
  38. (*f)(disk_obj, filename);
  39. FreeDiskObject(disk_obj);
  40. }
  41. CurrentDir(old_dir);
  42. }
  43. static void read_definitions(struct DiskObject *disk_obj, char *filename)
  44. {
  45. char **tt, *def_end;
  46. for (tt = disk_obj->do_ToolTypes; *tt != NULL; ++tt)
  47. /* Identify the tool types that are menu item definitions and create
  48. menu items from them. */
  49. if (**tt == DEF_BEGIN && (def_end = strchr(*tt, DEF_END)) != NULL &&
  50. *(def_end + 1) == ' ') {
  51. /* Temporarily insert terminator to facilitate string copy. */
  52. *def_end = '\0';
  53. cx_add_tool(*tt + 1, def_end + 2);
  54. /* Restore original char to leave string "untouched". */
  55. *def_end = DEF_END;
  56. }
  57. }
  58. /* Count the number of tool types that are not menu item definitions. */
  59. static int non_defs(char **tt)
  60. {
  61. int result = 0;
  62. for ( ; *tt != NULL; ++tt)
  63. if (**tt != DEF_BEGIN)
  64. ++result;
  65. return result;
  66. }
  67. /* Create a tool type for a menu item definition. */
  68. static char *create_def(Tool *t)
  69. {
  70. char *def;
  71. size_t name_len = strlen(t->node.ln_Name);
  72. /* Allocate space for name, path, two delimiters, a space, and
  73. string terminator */
  74. def = AllocVec(name_len + strlen(t->path) + 4, 0);
  75. if (def != NULL) {
  76. def[0] = DEF_BEGIN;
  77. strcpy(def + 1, t->node.ln_Name);
  78. def[name_len + 1] = DEF_END;
  79. def[name_len + 2] = ' ';
  80. strcpy(def + name_len + 3, t->path);
  81. }
  82. return def;
  83. }
  84. /* Create a tool type for every menu item in the tools list. */
  85. static Bool create_defs(char **tt)
  86. {
  87. struct Node *n;
  88. for (n = tools->lh_Head; n->ln_Succ != NULL; n = n->ln_Succ)
  89. if ((*(tt++) = create_def((Tool *) n)) == NULL)
  90. return NO;
  91. return YES;
  92. }
  93. /* Copy over those tool types that are not menu item definitions. */
  94. static void copy_non_defs(char **new_tt, char **old_tt)
  95. {
  96. for ( ; *old_tt != NULL; ++old_tt)
  97. if (**old_tt != DEF_BEGIN)
  98. *(new_tt++) = *old_tt;
  99. }
  100. static void free_tool_types(char **tt)
  101. {
  102. char **i;
  103. for (i = tt ; *i != NULL; ++i)
  104. if (**i == DEF_BEGIN)
  105. FreeVec(*i);
  106. FreeVec(tt);
  107. }
  108. static void write_definitions(struct DiskObject *disk_obj, char *filename)
  109. {
  110. int tools_size = length_of(tools);
  111. char **old_tool_types = disk_obj->do_ToolTypes;
  112. int size = tools_size + non_defs(old_tool_types) + 1;
  113. char **new_tool_types = AllocVec(sizeof(char *) * size, MEMF_CLEAR);
  114. if (new_tool_types == NULL)
  115. return;
  116. if (!create_defs(new_tool_types))
  117. goto write_definitions_exit;
  118. copy_non_defs(new_tool_types + tools_size, old_tool_types);
  119. disk_obj->do_ToolTypes = new_tool_types;
  120. PutDiskObject(filename, disk_obj);
  121. disk_obj->do_ToolTypes = old_tool_types;
  122. write_definitions_exit:
  123. free_tool_types(new_tool_types);
  124. }
  125. void io_read_definitions(BPTR dir, char *filename)
  126. {
  127. with_disk_object(read_definitions, dir, filename);
  128. }
  129. void io_write_definitions(BPTR dir, char *filename)
  130. {
  131. with_disk_object(write_definitions, dir, filename);
  132. }