/* ToolsMenu - Add tools to the Workbench Tools menu Copyright (C) 2015, 2018 Kim Fastrup Larsen This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either ver- sion 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be use- ful, but WITHOUT ANY WARRANTY; without even the implied war- ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public Li- cense along with this program. If not, see . The author can be contacted on */ #include #include #include #include #ifdef USE_PRAGMAS #include #include #include #endif #include #include "common.h" #include "cx.h" #include "io.h" #define DEF_BEGIN '\xab' /* Left double angle quote */ #define DEF_END '\xbb' /* Right double angle quote */ typedef void Disk_object_f(struct DiskObject *, char *); static void with_disk_object(Disk_object_f *f, BPTR dir, char *filename) { BPTR old_dir = CurrentDir(dir); struct DiskObject *disk_obj = GetDiskObject(filename); if (disk_obj != NULL) { (*f)(disk_obj, filename); FreeDiskObject(disk_obj); } CurrentDir(old_dir); } static void read_definitions(struct DiskObject *disk_obj, char *filename) { char **tt, *def_end; for (tt = disk_obj->do_ToolTypes; *tt != NULL; ++tt) /* Identify the tool types that are menu item definitions and create menu items from them. */ if (**tt == DEF_BEGIN && (def_end = strchr(*tt, DEF_END)) != NULL && *(def_end + 1) == ' ') { /* Temporarily insert terminator to facilitate string copy. */ *def_end = '\0'; cx_add_tool(*tt + 1, def_end + 2); /* Restore original char to leave string "untouched". */ *def_end = DEF_END; } } /* Count the number of tool types that are not menu item definitions. */ static int non_defs(char **tt) { int result = 0; for ( ; *tt != NULL; ++tt) if (**tt != DEF_BEGIN) ++result; return result; } /* Create a tool type for a menu item definition. */ static char *create_def(Tool *t) { char *def; size_t name_len = strlen(t->node.ln_Name); /* Allocate space for name, path, two delimiters, a space, and string terminator */ def = AllocVec(name_len + strlen(t->path) + 4, 0); if (def != NULL) { def[0] = DEF_BEGIN; strcpy(def + 1, t->node.ln_Name); def[name_len + 1] = DEF_END; def[name_len + 2] = ' '; strcpy(def + name_len + 3, t->path); } return def; } /* Create a tool type for every menu item in the tools list. */ static Bool create_defs(char **tt) { struct Node *n; for (n = tools->lh_Head; n->ln_Succ != NULL; n = n->ln_Succ) if ((*(tt++) = create_def((Tool *) n)) == NULL) return NO; return YES; } /* Copy over those tool types that are not menu item definitions. */ static void copy_non_defs(char **new_tt, char **old_tt) { for ( ; *old_tt != NULL; ++old_tt) if (**old_tt != DEF_BEGIN) *(new_tt++) = *old_tt; } static void free_tool_types(char **tt) { char **i; for (i = tt ; *i != NULL; ++i) if (**i == DEF_BEGIN) FreeVec(*i); FreeVec(tt); } static void write_definitions(struct DiskObject *disk_obj, char *filename) { int tools_size = length_of(tools); char **old_tool_types = disk_obj->do_ToolTypes; int size = tools_size + non_defs(old_tool_types) + 1; char **new_tool_types = AllocVec(sizeof(char *) * size, MEMF_CLEAR); if (new_tool_types == NULL) return; if (!create_defs(new_tool_types)) goto write_definitions_exit; copy_non_defs(new_tool_types + tools_size, old_tool_types); disk_obj->do_ToolTypes = new_tool_types; PutDiskObject(filename, disk_obj); disk_obj->do_ToolTypes = old_tool_types; write_definitions_exit: free_tool_types(new_tool_types); } void io_read_definitions(BPTR dir, char *filename) { with_disk_object(read_definitions, dir, filename); } void io_write_definitions(BPTR dir, char *filename) { with_disk_object(write_definitions, dir, filename); }