Ignore all generated/compiled files
[gwave-svn.git] / remote / repllib.c
blob8a2fdeff5d1515178d3ec10c21045412d9db9842
1 /* Key routines extracted from:
2 * scwmrepl.c,v 1.19 2000/01/22 21:13:16 gjb Exp $
3 * Copyright (C) 1997-2000, Maciej Stachowiak and Greg J. Badros
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software; see the file COPYING.GPL. If not, write to
17 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307 USA
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <glib.h>
30 #include <X11/X.h>
31 #include <X11/Xlib.h>
32 #include <xgexec.h>
34 #ifdef HAVE_READLINE
35 #include <readline/readline.h>
36 #ifdef HAVE_HISTORY
37 #include <readline/history.h>
38 #endif /* HAVE_HISTORY */
39 #endif /* HAVE_READLINE */
41 #ifdef HAVE_READLINE
42 char *scwm_complete(const char *text, int state)
44 static char *result=NULL;
45 static char *last=NULL;
46 static char *completions[1024];
48 extern Display *display;
49 extern Window w;
51 if (!state) {
52 char *szSymbol;
53 char *query, *output, *error;
54 unsigned n;
56 if (!last || strcmp(last,text)!=0) {
57 if (last) {
58 g_free(last);
60 last=strdup(text);
61 if (result) {
62 g_free(result);
63 output = NULL;
65 query = malloc(strlen(text)+30);
66 sprintf(query,"(apropos-internal \"^%s\")",text);
67 result = xgexec_exec_full(display, w, query, &output, &error);
68 if (error) {
69 if (strlen(error) > 0)
70 fprintf(stderr,"Got error querying apropos-internal for completion: %s",error);
71 g_free(error);
72 error = NULL;
74 if (output) {
75 g_free(output);
76 output = NULL;
78 free(query);
79 query = NULL;
82 /* result is something like "(documentation documentation-debug doc-files)" */
83 szSymbol = strtok(result+1," \t)");
84 n=0;
85 while (n<1023 && szSymbol) {
86 completions[n++] = strdup(szSymbol);
87 szSymbol = strtok(NULL," \t)");
89 completions[n]=NULL;
91 return completions[state];
94 void init_readline()
96 rl_completion_entry_function = scwm_complete;
98 #endif
100 int appending_fgets(char **sofar)
102 #ifdef HAVE_READLINE
103 char *buffer;
104 unsigned pos,len;
106 buffer=readline("gwave> ");
107 if (buffer==NULL) {
108 return 0;
110 len=strlen(buffer);
111 #if HAVE_HISTORY
112 if (len>0) {
113 add_history(buffer);
115 #endif
116 pos=strlen(*sofar);
117 *sofar=g_realloc(*sofar,pos+len+2);
118 strncpy(*sofar+pos,buffer,len);
119 (*sofar)[pos+len]='\n';
120 (*sofar)[pos+len+1]=0;
121 #else
122 char buffer [512];
124 fputs("gwave> ", stdout);
125 do {
126 fgets(buffer, 512, stdin);
127 if (strlen(buffer)==0) {
128 return 0;
130 *sofar=g_realloc(*sofar,strlen(*sofar)+strlen(buffer)+1);
131 strcat(*sofar,buffer);
132 } while (buffer[strlen(buffer)-1]!='\n');
133 #endif
135 return 1;
138 int check_balance(char *expr) {
139 /* If you think _this_ is hairy, try doing it for C statements. */
140 int i;
141 int end;
142 int non_whitespace_p=0;
143 int paren_count=0;
144 int prev_separator=1;
145 int quote_wait=0;
147 end=strlen(expr);
148 i=0;
149 while (i<end) {
150 switch(expr[i]) {
151 case ';' :
152 /* skip till newline. */
153 do {
154 i++;
155 } while (expr[i]!='\n' && i<end);
156 break;
157 case ' ':
158 case '\n':
159 case '\t':
160 case '\r':
161 if (non_whitespace_p && paren_count==0 && !quote_wait) {
162 return i;
163 } else {
164 prev_separator=1;
165 i++;
167 break;
168 case '\"' :
169 if (non_whitespace_p && paren_count==0 &&
170 !quote_wait) {
171 return i;
172 } else {
173 /* skip past ", ignoring \" */
174 do {
175 i++;
176 if (i < end && expr[i]=='\\') {
177 i++;
179 } while (i < end && expr[i]!='\"');
180 i++;
181 if (paren_count==0) {
182 if (i < end) {
183 return i;
184 } else {
185 return 0;
187 } else {
188 prev_separator=1;
189 non_whitespace_p=1;
190 quote_wait=0;
193 break;
194 case '#' :
195 if (non_whitespace_p && paren_count==0 &&
196 !quote_wait) {
197 return i;
198 } else {
199 if (prev_separator && i+1<end && expr[i+1]=='{') {
200 /* skip past }#, ignoring \} */
201 do {
202 i++;
203 if (i < end && expr[i]=='\\') {
204 i++;
206 } while (i < end && !(expr[i]=='}' && i+1<end
207 && expr[i+1]=='#'));
208 i+=2;
209 if (paren_count==0) {
210 if (i < end) {
211 return i;
212 } else {
213 return 0;
215 } else {
216 prev_separator=1;
217 non_whitespace_p=1;
218 quote_wait=0;
220 /* MS:FIXME:: Handle #\) properly! */
221 } else {
222 prev_separator=0;
223 quote_wait=0;
224 non_whitespace_p=1;
225 i++;
228 break;
229 case '(' :
230 if (non_whitespace_p && paren_count==0 &&!quote_wait) {
231 return i;
232 } else {
233 i++;
234 paren_count++;
235 non_whitespace_p=1;
236 prev_separator=1;
237 quote_wait=0;
239 break;
240 case ')' :
241 paren_count--;
242 if (non_whitespace_p && paren_count==0) {
243 return i+1;
244 } else {
245 i++;
246 non_whitespace_p=1;
247 prev_separator=1;
248 quote_wait=0;
250 break;
251 case '\'' :
252 if (prev_separator) {
253 non_whitespace_p=1;
254 quote_wait=1;
255 prev_separator=1;
256 i++;
257 } else {
258 non_whitespace_p=1;
259 prev_separator=0;
260 i++;
262 break;
263 default :
264 prev_separator=0;
265 quote_wait=0;
266 non_whitespace_p=1;
267 i++;
268 break;
271 return 0;
274 char *split_at(char **to_split, int i) {
275 char *out;
276 char *ret;
278 out=strdup((*to_split)+i);
280 (*to_split)[i]=0;
281 ret=strdup(*to_split);
282 free(*to_split);
283 *to_split=out;
284 return ret;