ToolsMenu/io.c

163 рядки
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);
}