163 rindas
4.4 KiB
C
Executable File
163 rindas
4.4 KiB
C
Executable File
/*
|
|
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);
|
|
}
|