// read configurations
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifndef __GNUC__
# ifdef HAVE_ALLOCA_H
# include <alloca.h>
# endif
#endif
#include "jmode.h"
#define DEFKEYATOM
#include "keyatom.h"
class CAtom {
public:
char *name;
std::list<atom_t> bound;
};
struct ConfHook {
char *name;
void (*fn)(char *);
};
//遅いのでだれか書きかえて
static std::list<atom_t> atom_list;
static std::list<ConfHook> hook_list;
bool read_a_conf_file(char *fn);
static atom_t
find_atom_by_name(char *s)
{
std::list<atom_t>::iterator i;
for (i = atom_list.begin(); i != atom_list.end(); i++) {
if (!strcmp((*i)->name, s)) {
return *i;
}
}
return 0;
}
static atom_t
make_atom_by_name(char *name)
{
atom_t n;
n = new CAtom();
n->name = strdup(name);
atom_list.push_back(n);
return n;
}
void
add_conf_hook(char *name, void (*fn)(char *))
{
ConfHook c;
c.name = strdup(name);
c.fn = fn;
hook_list.push_back(c);
}
atom_t
get_atom_by_name(char *name)
{
atom_t a;
a = find_atom_by_name(name);
if (a) {
return a;
}
return make_atom_by_name(name);
}
void
bind_atom(atom_t from, atom_t to)
{
std::list<atom_t>::iterator i;
for (i = to->bound.begin(); i != to->bound.end(); i++) {
if (from == *i) {
return ;
}
}
to->bound.push_back(from);
}
void
unbind_atom(atom_t from, atom_t to)
{
std::list<atom_t>::iterator i;
for (i = to->bound.begin(); i != to->bound.end(); i++) {
to->bound.erase(i);
return ;
}
}
bool
is_bind_to(atom_t from, atom_t to)
{
std::list<atom_t>::iterator i;
for (i = to->bound.begin(); i != to->bound.end(); i++) {
if (*i == from) {
return true;
}
}
return false;
}
char *
get_atom_name(atom_t a)
{
if (!a) {
return 0;
}
return a->name;
}
void
bind_str_to_atom(char *s, atom_t a)
{
atom_t x = get_atom_by_name(s);
bind_atom(x, a);
}
void
bind_str_to_str(char *s, char *d)
{
atom_t x, y;
x = get_atom_by_name(s);
y = get_atom_by_name(d);
bind_atom(x, y);
}
atom_t
get_bound_atoms(atom_t to, atom_t c)
{
std::list<atom_t>::iterator i;
if (!to) {
return 0;
}
i = to->bound.begin();
if (!c) {
if (i == to->bound.end()) {
return 0;
}
return (*i);
}
for (; i != to->bound.end(); i++) {
if ((*i) == c) {
i ++;
if (i == to->bound.end()) {
return 0;
}
return *i;
}
}
return 0;
}
int
nr_bound_atoms(atom_t to)
{
if (!to) {
return 0;
}
return to->bound.size();
}
void
init_default_atoms()
{
A_env = get_atom_by_name("env");
A_delete_back = get_atom_by_name("delete_back");
A_delete_here = get_atom_by_name("delete_here");
A_go_up = get_atom_by_name("go_up");
A_go_down = get_atom_by_name("go_down");
A_go_left = get_atom_by_name("go_left");
A_go_right = get_atom_by_name("go_right");
A_cancel = get_atom_by_name("cancel");
A_return = get_atom_by_name("return");
A_go_line_head = get_atom_by_name("go_line_head");
A_go_line_end = get_atom_by_name("go_line_end");
A_delete_right = get_atom_by_name("delete_right");
A_next_candidate = get_atom_by_name("next_candidate");
A_prev_candidate = get_atom_by_name("prev_candidate");
A_page_up = get_atom_by_name("page_up");
A_page_down = get_atom_by_name("page_down");
A_hira_mode = get_atom_by_name("hira_mode");
A_commit = get_atom_by_name("commit");
A_latin_mode = get_atom_by_name("latin_mode");
A_do_conv = get_atom_by_name("do_conv");
}
void
parse_conf(char *buf)
{
char buf0[256], buf1[256], buf2[256];
int c;
c = sscanf(buf,"%s %s %s", buf0, buf1, buf2);
if (c < 1) {
return ;
}
if (!strcmp("bind", buf0)) {
if (c < 3) {
return ;
}
bind_str_to_str(buf2, buf1);
return ;
}
if (!strcmp("include", buf0)) {
bool r;
if (c < 2) {
return ;
}
r = read_a_conf_file(buf1);
if (!r) {
printf("Failed to include file %s\n", buf1);
}
return ;
}
std::list<ConfHook>::iterator it;
for (it = hook_list.begin(); it != hook_list.end(); it++) {
if (!strcmp((*it).name, buf0)) {
char *b;
b = &buf[strlen(buf0)];
while(strchr(" \t", *b)) {
b++;
}
(*it).fn(b);
}
}
}
static FILE *
open_conf_file(char *fn)
{
if (fn[0] == '/') {
return fopen(fn, "r");
}
char *p;
p = (char *)alloca(strlen(CONF_DIR) + strlen(fn) + 10);
sprintf(p, "%s/%s", CONF_DIR, fn);
return fopen(p, "r");
}
bool
read_a_conf_file(char *fn)
{
FILE *fp;
fp = open_conf_file(fn);
if (!fp) {
return false;
}
char buf[256];
while (fgets(buf, 256, fp)) {
if (buf[0] != '#') {
parse_conf(buf);
}
}
fclose(fp);
return true;
}
void
read_conf_file()
{
char *fn;
fn = (char *)alloca(strlen(homedir)+strlen(PACKAGE)+
strlen(CONF_DIR)+20);
fn[0] = 0;
strcat(fn, homedir);
strcat(fn, "/."PACKAGE);
if (read_a_conf_file(fn)) {
return ;
}
if (!read_a_conf_file("jmode-default.conf")) {
printf("failed to open %s\n", fn);
return ;
}
}
/*
* Local variables:
* c-indent-level: 4
* c-basic-offset: 4
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1