~ubuntu-branches/ubuntu/maverick/uim/maverick

« back to all changes in this revision

Viewing changes to uim/mana.c

  • Committer: Bazaar Package Importer
  • Author(s): Masahito Omote
  • Date: 2006-11-23 15:10:53 UTC
  • mfrom: (3.1.8 edgy)
  • Revision ID: james.westby@ubuntu.com-20061123151053-q42sk1lvks41xpfx
Tags: 1:1.2.1-9
uim-gtk2.0.postinst: Don't call update-gtk-immodules on purge.
(closes: Bug#398530)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
  Copyright (c) 2003-2006 uim Project http://uim.freedesktop.org/
 
4
 
 
5
  All rights reserved.
 
6
 
 
7
  Redistribution and use in source and binary forms, with or without
 
8
  modification, are permitted provided that the following conditions
 
9
  are met:
 
10
 
 
11
  1. Redistributions of source code must retain the above copyright
 
12
     notice, this list of conditions and the following disclaimer.
 
13
  2. Redistributions in binary form must reproduce the above copyright
 
14
     notice, this list of conditions and the following disclaimer in the
 
15
     documentation and/or other materials provided with the distribution.
 
16
  3. Neither the name of authors nor the names of its contributors
 
17
     may be used to endorse or promote products derived from this software
 
18
     without specific prior written permission.
 
19
 
 
20
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
 
21
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
22
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
23
  ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
 
24
  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
25
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
26
  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
27
  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
28
  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
29
  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
30
  SUCH DAMAGE.
 
31
*/
 
32
 
 
33
#ifdef HAVE_CONFIG_H
 
34
#include <config.h>
 
35
#endif
 
36
#include <errno.h>
 
37
#include <signal.h>
 
38
#ifdef HAVE_STRING_H
 
39
#include <string.h>
 
40
#endif
 
41
#ifdef HAVE_STDLIB_H
 
42
#include <stdlib.h>
 
43
#endif
 
44
#ifdef HAVE_FCNTL_H
 
45
#include <fcntl.h>
 
46
#endif
 
47
 
 
48
#include "uim.h"
 
49
#include "uim-scm.h"
 
50
#include "plugin.h"
 
51
 
 
52
#define MANA_COMMAND "mana"
 
53
 
 
54
static FILE *mana_r;
 
55
static FILE *mana_w;
 
56
static int mana_pid;
 
57
 
 
58
static char *mana_ipc_send_command(int *pid, FILE **read_fp, FILE **write_fp, const char *str);
 
59
static uim_lisp mana_init(void);
 
60
static uim_lisp mana_eval(uim_lisp buf_);
 
61
static uim_lisp eucjp_string_length(uim_lisp str_);
 
62
 
 
63
#ifdef DEBUG
 
64
static FILE *log;
 
65
#endif
 
66
 
 
67
static char *
 
68
mana_ipc_send_command(int *pid,
 
69
                     FILE **read_fp, FILE **write_fp,
 
70
                     const char *str)
 
71
{
 
72
  char *tmp = strdup("");
 
73
  char buf[8192];
 
74
 
 
75
  struct sigaction act, oact;
 
76
 
 
77
  act.sa_handler = SIG_IGN;
 
78
  sigemptyset(&act.sa_mask);
 
79
  act.sa_flags = 0;
 
80
 
 
81
  sigaction(SIGPIPE, &act, &oact);
 
82
 
 
83
  fputs(str, *write_fp);
 
84
 
 
85
 again:
 
86
  if (fflush(*write_fp) != 0) {
 
87
    switch (errno) {
 
88
    case EINTR:
 
89
      goto again;
 
90
    case EPIPE:
 
91
 
 
92
      while (!feof(*read_fp)) {
 
93
        fgets(buf, sizeof(buf), *read_fp);
 
94
        if (buf != NULL) {
 
95
          if (strcmp(buf, "err") == 0)
 
96
            fprintf(stderr, "mana not found\n");
 
97
          else
 
98
            fprintf(stderr, "%s", buf);
 
99
        }
 
100
      }
 
101
 
 
102
      *pid = 0;
 
103
      fclose(*read_fp);
 
104
      fclose(*write_fp);
 
105
      *read_fp = NULL;
 
106
      *write_fp = NULL;
 
107
 
 
108
      sigaction(SIGPIPE, &oact, NULL);
 
109
      free(tmp);
 
110
 
 
111
      return NULL;
 
112
    default:
 
113
      sigaction(SIGPIPE, &oact, NULL);
 
114
      free(tmp);
 
115
      return NULL;
 
116
    }
 
117
  }
 
118
 
 
119
  sigaction(SIGPIPE, &oact, NULL);
 
120
 
 
121
  if (feof(*read_fp)) {
 
122
    *pid = 0;
 
123
    fclose(*read_fp);
 
124
    fclose(*write_fp);
 
125
    *read_fp = NULL;
 
126
    *write_fp = NULL;
 
127
    free(tmp);
 
128
    return NULL;
 
129
  }
 
130
 
 
131
  while (fgets (buf, sizeof(buf), *read_fp) != NULL) {
 
132
 
 
133
    tmp = realloc(tmp, strlen(tmp) + strlen(buf) + 1);
 
134
    strcat(tmp, buf);
 
135
 
 
136
    if (strchr( buf, '\n' )) {
 
137
      break;
 
138
    }
 
139
  }
 
140
 
 
141
  return tmp;
 
142
 
 
143
}
 
144
 
 
145
static uim_lisp
 
146
mana_init(void)
 
147
{
 
148
  char buf[100];
 
149
  int fd;
 
150
  int fl;
 
151
 
 
152
  if (mana_pid == 0)
 
153
    mana_pid = uim_ipc_open_command(0, &mana_r, &mana_w, MANA_COMMAND);
 
154
 
 
155
  if (mana_pid == 0)
 
156
    return uim_scm_f();
 
157
 
 
158
  fd = fileno(mana_r);
 
159
  fl = fcntl(fd, F_GETFL);
 
160
  fcntl(fd, F_SETFL, fl | O_NONBLOCK);
 
161
  fgets(buf, sizeof(buf), mana_r);
 
162
  fcntl(fd, F_SETFL, fl);
 
163
 
 
164
  if (feof(mana_r)) {
 
165
    mana_pid = 0;
 
166
    fclose(mana_r);
 
167
    fclose(mana_w);
 
168
    mana_r = mana_w = NULL;
 
169
    fprintf(stderr, "mana not found\n");
 
170
    return uim_scm_f();
 
171
  }
 
172
  
 
173
  if (ferror(mana_r))
 
174
    clearerr(mana_r);
 
175
 
 
176
#ifdef DEBUG
 
177
  log = fopen("mana.log", "w");
 
178
#endif
 
179
 
 
180
  return uim_scm_t();
 
181
}
 
182
 
 
183
static uim_lisp
 
184
mana_eval(uim_lisp buf_)
 
185
{
 
186
  const char *buf = uim_scm_refer_c_str(buf_);
 
187
  char *ret_buf;
 
188
  char *eval_buf;
 
189
  uim_lisp ret;
 
190
 
 
191
  if (mana_pid == 0)
 
192
    return uim_scm_f();
 
193
 
 
194
  ret_buf = mana_ipc_send_command(&mana_pid, &mana_r, &mana_w, buf);
 
195
 
 
196
  if (ret_buf == NULL)
 
197
    return uim_scm_f();
 
198
 
 
199
#ifdef DEBUG
 
200
  fputs(buf, log);
 
201
  fputs(ret_buf, log);
 
202
  fflush(log);
 
203
#endif
 
204
 
 
205
  eval_buf = malloc(strlen("'") + strlen(ret_buf) + 1);
 
206
  sprintf(eval_buf, "'%s", ret_buf);
 
207
  ret = uim_scm_eval_c_string(eval_buf);
 
208
  free(ret_buf);
 
209
  free(eval_buf);
 
210
 
 
211
  return ret;
 
212
}
 
213
 
 
214
static uim_lisp
 
215
eucjp_string_length(uim_lisp str_)
 
216
{
 
217
  const unsigned char *str = (const unsigned char *)uim_scm_refer_c_str(str_);
 
218
  int len = strlen((const char *)str);
 
219
 
 
220
  int ascii = 0;
 
221
  int mbyte = 0;
 
222
 
 
223
  int i;
 
224
 
 
225
  for (i = 0; i < len; i++) {
 
226
    if (str[i] < 0x80)
 
227
      ascii++;
 
228
    else
 
229
      mbyte++;
 
230
  }
 
231
 
 
232
  return uim_scm_make_int(ascii + (mbyte / 2));
 
233
}
 
234
 
 
235
void
 
236
uim_plugin_instance_init(void)
 
237
{
 
238
  uim_scm_init_subr_0("mana-lib-init", mana_init);
 
239
  uim_scm_init_subr_1("mana-lib-eval", mana_eval);
 
240
  uim_scm_init_subr_1("mana-lib-eucjp-string-length", eucjp_string_length);
 
241
}
 
242
 
 
243
void
 
244
uim_plugin_instance_quit(void)
 
245
{
 
246
  if (mana_pid != 0) {
 
247
    mana_ipc_send_command(&mana_pid, &mana_r, &mana_w, "(quit)\n");
 
248
    mana_pid = 0;
 
249
  }
 
250
}