|
- /*
- 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
- <http://www.gnu.org/licenses/>.
-
- The author can be contacted on <kimflarsen@hotmail.com>
- */
-
- #include <exec/memory.h>
-
- #include <clib/dos_protos.h>
- #include <clib/exec_protos.h>
- #include <clib/icon_protos.h>
-
- #ifdef USE_PRAGMAS
- #include <proto/dos.h>
- #include <proto/exec.h>
- #include <proto/icon.h>
- #endif
-
- #include <string.h>
-
- #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);
- }
|