Browse code

Make Control+Shift+F1 use the manpage relevant to the current language

Dario Rodriguez authored on 24/09/2025 10:48:32
Showing 1 changed files
... ...
@@ -22,13 +22,6 @@
22 22
 #define PLUGINNAME "prototypes"
23 23
 #define MAXINDEXDATALEN 1024
24 24
 
25
-typedef enum protolang_t {
26
-        protolang_undefined=-1,
27
-        protolang_c=0,
28
-        protolang_tcl,
29
-        protolang_end,
30
-} protolang_t;
31
-
32 25
 typedef struct protoindex_t {
33 26
         int nentries;
34 27
         const char **index;
... ...
@@ -232,16 +225,8 @@ redata_prototypes_get(redata_t *redata, long pos)
232 225
         } status;
233 226
         if(redata==NULL || pos<0 || (cproto=cproto_getplugin(redata))==NULL)
234 227
                 return(NULL); /* sanity check failed */
235
-        if(cproto->lastprotolang==protolang_undefined) {
236
-                char linebuf[1024];
237
-                if(redata_line_getstartstr(redata,0,linebuf,sizeof(linebuf))!=0)
238
-                        return(NULL); /* couldn't detect file type using first line */
239
-                if(linebuf[0]=='#' && (mystrstr(linebuf,"tclsh")!=NULL || mystrstr(linebuf,"wish")!=NULL || mystrstr(linebuf,"expect")!=NULL))
240
-                        cproto->lastprotolang=protolang_tcl;
241
-                else
242
-                        cproto->lastprotolang=protolang_c;
243
-                cproto->lastpos=-1;
244
-        }
228
+        if(cproto->lastprotolang==protolang_undefined)
229
+                redata_prototypes_detectlang(redata);
245 230
         protoindex=cproto->protoindexes+cproto->lastprotolang;
246 231
         if(pos==cproto->lastpos)
247 232
                 return((cproto->lastindex!=-1)?(protoindex->values[cproto->lastindex]):NULL);
... ...
@@ -339,8 +324,22 @@ redata_prototypes_get(redata_t *redata, long pos)
339 324
         return(NULL);
340 325
 }
341 326
 
342
-
343
-
327
+protolang_t
328
+redata_prototypes_detectlang(redata_t *redata)
329
+{
330
+        cproto_t *cproto;
331
+        char linebuf[1024];
332
+        if(redata==NULL || (cproto=cproto_getplugin(redata))==NULL)
333
+                return(protolang_undefined); /* sanity check failed */
334
+        if(redata_line_getstartstr(redata,0,linebuf,sizeof(linebuf))!=0)
335
+                return(protolang_undefined); /* couldn't detect file type using first line */
336
+        if(linebuf[0]=='#' && (mystrstr(linebuf,"tclsh")!=NULL || mystrstr(linebuf,"wish")!=NULL || mystrstr(linebuf,"expect")!=NULL))
337
+                cproto->lastprotolang=protolang_tcl;
338
+        else
339
+                cproto->lastprotolang=protolang_c;
340
+        cproto->lastpos=-1;
341
+        return(cproto->lastprotolang);
342
+}
344 343
 
345 344
 static int
346 345
 cproto_buffer_inv(cproto_t *cproto)
Browse code

add tcl language support for the hinter (uses tcl hinter instead of C hinter if first line starts with # and has tclsh, wish or expect)

Dario Rodriguez authored on 21/02/2022 19:05:43
Showing 1 changed files
... ...
@@ -17,17 +17,30 @@
17 17
 #include "re_data.h"
18 18
 #include "re_plugin_prototypes.h"
19 19
 #include "prototypes_c89_posix.h"
20
+#include "prototypes_tcl.h"
20 21
 
21 22
 #define PLUGINNAME "prototypes"
22 23
 #define MAXINDEXDATALEN 1024
23 24
 
25
+typedef enum protolang_t {
26
+        protolang_undefined=-1,
27
+        protolang_c=0,
28
+        protolang_tcl,
29
+        protolang_end,
30
+} protolang_t;
24 31
 
25
-typedef struct cproto_t {
32
+typedef struct protoindex_t {
26 33
         int nentries;
27 34
         const char **index;
28 35
         const char **values;
36
+} protoindex_t;
37
+
38
+typedef struct cproto_t {
39
+        int sizeprotoindexes;
40
+        protoindex_t *protoindexes;
29 41
         long lastpos;
30 42
         int lastindex;
43
+        protolang_t lastprotolang;
31 44
         int sizebuffer;
32 45
         int usedbuffer;
33 46
         char buffer[MAXINDEXDATALEN];
... ...
@@ -35,45 +48,21 @@ typedef struct cproto_t {
35 48
 
36 49
 static int redata_prototypes_add_or_unadd(redata_t *redata, redata_plugin_t *slot, undo_t *undo, int is_unadd);
37 50
 static int redata_prototypes_postload(redata_t *redata, redata_plugin_t *slot,char *filename);
51
+static cproto_t *cproto_init(void);
52
+static void cproto_free(cproto_t *cproto);
38 53
 static cproto_t *cproto_getplugin(redata_t *redata);
39 54
 static int cproto_buffer_inv(cproto_t *cproto);
55
+const char *mystrstr(char *heystack, char *needle);
40 56
 static int cproto_buffer_getindex(cproto_t *cproto);
41 57
 
42 58
 int
43 59
 redata_prototypes_register(redata_t *redata, redata_plugin_t *slot)
44 60
 {
45 61
         cproto_t *cproto;
46
-        const char *ptr;
47
-        int n;
48 62
         if(redata==NULL || slot==NULL)
49 63
                 return(-1);
50
-        if((cproto=malloc(sizeof(cproto_t)))==NULL)
51
-                return(-1); /* insufficient memory */
52
-        memset(cproto,0,sizeof(cproto_t));
53
-        /* by default, we use C89/POSIX hints */
54
-        cproto->nentries=SIZE_PROTOTYPES_C89_POSIX;
55
-        if((cproto->index=malloc(sizeof(char *)*cproto->nentries))==NULL
56
-          || (cproto->values=malloc(sizeof(char *)*cproto->nentries))==NULL) {
57
-                if(cproto->index!=NULL)
58
-                        free(cproto->index),cproto->index=NULL;
64
+        if((cproto=cproto_init())==NULL)
59 65
                 return(-1); /* insufficient memory */
60
-        }
61
-        memset(cproto->index,0,sizeof(char *)*cproto->nentries);
62
-        memset(cproto->values,0,sizeof(char *)*cproto->nentries);
63
-        for(n=0,ptr=index_prototypes_c89_posix
64
-          ;n<cproto->nentries
65
-          ;n++,ptr+=strlen(ptr)+1) {
66
-                cproto->index[n]=ptr;
67
-        }
68
-        for(n=0,ptr=values_prototypes_c89_posix
69
-          ;n<cproto->nentries
70
-          ;n++,ptr+=strlen(ptr)+1) {
71
-                cproto->values[n]=ptr;
72
-        }
73
-        cproto->lastpos=-1;
74
-        cproto->lastindex=-1;
75
-        cproto->usedbuffer=0;
76
-        cproto->sizebuffer=sizeof(cproto->buffer);
77 66
         strncpy(slot->name,PLUGINNAME,sizeof(slot->name));
78 67
         slot->name[sizeof(slot->name)-1]='\0';
79 68
         slot->unregister=redata_prototypes_unregister;
... ...
@@ -89,12 +78,7 @@ redata_prototypes_unregister(redata_t *redata, redata_plugin_t *slot,char *filen
89 78
         cproto_t *cproto=(cproto_t *) ((slot!=NULL)?(slot->userptr):NULL);
90 79
         if(redata==NULL || slot==NULL || cproto==NULL)
91 80
                 return(-1);
92
-        if(cproto->index!=NULL)
93
-               free(cproto->index),cproto->index=NULL;
94
-        if(cproto->values!=NULL)
95
-               free(cproto->values),cproto->values=NULL;
96
-        if(slot->userptr!=NULL)
97
-                free(slot->userptr),slot->userptr=NULL;
81
+        cproto_free(cproto),cproto=NULL,slot->userptr=NULL;
98 82
         return(0);
99 83
 
100 84
 }
... ...
@@ -108,6 +92,7 @@ redata_prototypes_add_or_unadd(redata_t *redata, redata_plugin_t *slot, undo_t *
108 92
                 return(-1); /* sanity check failed */
109 93
         cproto->lastpos=-1;
110 94
         cproto->lastindex=-1;
95
+        cproto->lastprotolang=protolang_undefined;
111 96
         return(0);
112 97
 }
113 98
 
... ...
@@ -118,6 +103,81 @@ redata_prototypes_postload(redata_t *redata, redata_plugin_t *slot,char *filenam
118 103
         return(-1);
119 104
 }
120 105
 
106
+static cproto_t *
107
+cproto_init(void)
108
+{
109
+        int i;
110
+        cproto_t *cproto;
111
+        protoindex_t *protoindex;
112
+        const char *ptrindex,*ptrvalues;
113
+        int n;
114
+        if((cproto=malloc(sizeof(cproto_t)))==NULL)
115
+                return(NULL); /* insuf. mem. */
116
+        memset(cproto,0,sizeof(cproto_t));
117
+        /* initialize protoindexes */
118
+        if((cproto->protoindexes=malloc(sizeof(protoindex_t)*protolang_end))==NULL) {
119
+                cproto_free(cproto),cproto=NULL;
120
+                return(NULL); /* insuf. mem. */
121
+        }
122
+        memset(cproto->protoindexes,0,sizeof(protoindex_t)*protolang_end);
123
+        cproto->sizeprotoindexes=protolang_end;
124
+        for(i=0;i<protolang_end;i++) {
125
+                protoindex=cproto->protoindexes+i;
126
+                if(i==protolang_c) {
127
+                        protoindex->nentries=SIZE_PROTOTYPES_C89_POSIX;
128
+                        ptrindex=index_prototypes_c89_posix;
129
+                        ptrvalues=values_prototypes_c89_posix;
130
+                } else if(i==protolang_tcl) {
131
+                        protoindex->nentries=SIZE_PROTOTYPES_TCL;
132
+                        ptrindex=index_prototypes_tcl;
133
+                        ptrvalues=values_prototypes_tcl;
134
+                } else {
135
+                        cproto_free(cproto),cproto=NULL;
136
+                        return(NULL); /* internal error, unknown protolang */
137
+                }
138
+                if((protoindex->index=malloc(sizeof(char *)*protoindex->nentries))==NULL
139
+                  || (protoindex->values=malloc(sizeof(char *)*protoindex->nentries))==NULL) {
140
+                        cproto_free(cproto),cproto=NULL;
141
+                        return(NULL); /* insufficient memory */
142
+                }
143
+                memset(protoindex->index,0,sizeof(char *)*protoindex->nentries);
144
+                memset(protoindex->values,0,sizeof(char *)*protoindex->nentries);
145
+                for(n=0;n<protoindex->nentries
146
+                  ;n++,ptrindex+=strlen(ptrindex)+1,ptrvalues+=strlen(ptrvalues)+1) {
147
+                        protoindex->index[n]=ptrindex;
148
+                        protoindex->values[n]=ptrvalues;
149
+                }
150
+        }
151
+        /* init caches */
152
+        cproto->lastpos=-1;
153
+        cproto->lastindex=-1;
154
+        cproto->lastprotolang=protolang_undefined;
155
+        cproto->usedbuffer=0;
156
+        cproto->sizebuffer=sizeof(cproto->buffer);
157
+        return(cproto);
158
+}
159
+
160
+static void
161
+cproto_free(cproto_t *cproto)
162
+{
163
+        int i;
164
+        if(cproto==NULL)
165
+                return;
166
+        if(cproto->protoindexes!=NULL) {
167
+                protoindex_t *protoindex;
168
+                for(i=0;i<cproto->sizeprotoindexes;i++) {
169
+                        protoindex=cproto->protoindexes+i;
170
+                        if(protoindex->index!=NULL)
171
+                                free(protoindex->index),protoindex->index=NULL;
172
+                        if(protoindex->values!=NULL)
173
+                                free(protoindex->values),protoindex->values=NULL;
174
+                }
175
+                free(cproto->protoindexes),cproto->protoindexes=NULL;
176
+        }
177
+        free(cproto),cproto=NULL;
178
+        return;
179
+}
180
+
121 181
 static cproto_t *
122 182
 cproto_getplugin(redata_t *redata)
123 183
 {
... ...
@@ -137,6 +197,20 @@ cproto_getplugin(redata_t *redata)
137 197
         return(cproto);
138 198
 }
139 199
 
200
+const char *
201
+mystrstr(char *haystack, char *needle)
202
+{
203
+        char *ptr;
204
+        int l;
205
+        if(needle[0]=='\0')
206
+                return(haystack);
207
+        l=strlen(needle);
208
+        for(ptr=strchr(haystack,needle[0]);ptr!=NULL;ptr=strchr(ptr+1,needle[0])) {
209
+                if(memcmp(ptr,needle,l)==0)
210
+                        return(ptr);
211
+        }
212
+        return(NULL);
213
+}
140 214
 
141 215
 const char *
142 216
 redata_prototypes_get(redata_t *redata, long pos)
... ...
@@ -146,6 +220,7 @@ redata_prototypes_get(redata_t *redata, long pos)
146 220
         long chunkstartpos;
147 221
         rechunk_t *chunk;
148 222
         cproto_t *cproto;
223
+        protoindex_t *protoindex;
149 224
         char c;
150 225
         int ntry;
151 226
         enum {
... ...
@@ -157,8 +232,19 @@ redata_prototypes_get(redata_t *redata, long pos)
157 232
         } status;
158 233
         if(redata==NULL || pos<0 || (cproto=cproto_getplugin(redata))==NULL)
159 234
                 return(NULL); /* sanity check failed */
235
+        if(cproto->lastprotolang==protolang_undefined) {
236
+                char linebuf[1024];
237
+                if(redata_line_getstartstr(redata,0,linebuf,sizeof(linebuf))!=0)
238
+                        return(NULL); /* couldn't detect file type using first line */
239
+                if(linebuf[0]=='#' && (mystrstr(linebuf,"tclsh")!=NULL || mystrstr(linebuf,"wish")!=NULL || mystrstr(linebuf,"expect")!=NULL))
240
+                        cproto->lastprotolang=protolang_tcl;
241
+                else
242
+                        cproto->lastprotolang=protolang_c;
243
+                cproto->lastpos=-1;
244
+        }
245
+        protoindex=cproto->protoindexes+cproto->lastprotolang;
160 246
         if(pos==cproto->lastpos)
161
-                return((cproto->lastindex!=-1)?(cproto->values[cproto->lastindex]):NULL);
247
+                return((cproto->lastindex!=-1)?(protoindex->values[cproto->lastindex]):NULL);
162 248
         if(redata_getposptr(redata,pos,&savednumchunk,&savedoffset)!=0)
163 249
                 return(NULL); /* couldn't get pos */
164 250
         cproto->lastpos=pos;
... ...
@@ -224,12 +310,12 @@ redata_prototypes_get(redata_t *redata, long pos)
224 310
                                                         cproto_buffer_inv(cproto);
225 311
                                                         /* search string */
226 312
                                                         if((cproto->lastindex=cproto_buffer_getindex(cproto))!=-1)
227
-                                                                return(cproto->values[cproto->lastindex]);
313
+                                                                return(protoindex->values[cproto->lastindex]);
228 314
                                                 }
229 315
                                                 cproto->usedbuffer=0;
230 316
                                                 status=searching_nameend;
231 317
                                                 continue;
232
-                                        } else if(!((c>='A' && c<='Z') || (c>='a' && c<='z') || (c>='0' && c<='9') || c=='_')) {
318
+                                        } else if(!((c>='A' && c<='Z') || (c>='a' && c<='z') || (c>='0' && c<='9') || c=='_' || (cproto->lastprotolang==protolang_tcl && c==' '))) {
233 319
                                                 status=searching_ended;
234 320
                                                 break;
235 321
                                         } else {
... ...
@@ -240,10 +326,14 @@ redata_prototypes_get(redata_t *redata, long pos)
240 326
                         }
241 327
                 }
242 328
                 if((status==searching_nameend || status==searching_ended) && cproto->usedbuffer>0) {
329
+                        /* trim spaces leading to word (for tcl) */
330
+                        while(cproto->usedbuffer>0 && cproto->buffer[cproto->usedbuffer-1]==' ')
331
+                                cproto->usedbuffer--;
332
+                        /* put the string in the correct order */
243 333
                         cproto_buffer_inv(cproto);
244 334
                         /* search string */
245 335
                         if((cproto->lastindex=cproto_buffer_getindex(cproto))!=-1)
246
-                                return(cproto->values[cproto->lastindex]);
336
+                                return(protoindex->values[cproto->lastindex]);
247 337
                 }
248 338
         }
249 339
         return(NULL);
... ...
@@ -277,13 +367,14 @@ cproto_buffer_getindex(cproto_t *cproto)
277 367
 {
278 368
 #warning TODO use qsearch()
279 369
         int i;
370
+        protoindex_t *protoindex;
280 371
         if(cproto==NULL)
281 372
                 return(-1);
282 373
         cproto->buffer[cproto->usedbuffer]='\0';
283
-        for(i=0;i<cproto->nentries;i++) {
284
-                if(strcmp(cproto->index[i],cproto->buffer)==0) {
374
+        protoindex=cproto->protoindexes+cproto->lastprotolang;
375
+        for(i=0;i<protoindex->nentries;i++) {
376
+                if(strcmp(protoindex->index[i],cproto->buffer)==0)
285 377
                         return(i);
286
-                }
287 378
         }
288 379
         return(-1);
289 380
 }
Browse code

Update author email

Dario Rodriguez authored on 07/01/2022 17:57:32
Showing 1 changed files
... ...
@@ -5,7 +5,7 @@
5 5
  *
6 6
  * re_data plugin to support showing common prototypes hints.
7 7
  *
8
- * Author: Dario Rodriguez dario@softhome.net
8
+ * Author: Dario Rodriguez antartica@whereismybit.com
9 9
  * This program is licensed under the terms of GNU GPL v2.1+
10 10
  */
11 11
 
Browse code

bugfix: was not showing prototypes hints if the cursor was in the space after the last character of the line

Dario Rodriguez authored on 25/04/2021 10:31:35
Showing 1 changed files
... ...
@@ -197,7 +197,7 @@ redata_prototypes_get(redata_t *redata, long pos)
197 197
                         chunk=redata->chunks[numchunk];
198 198
                         for(;offset>=0;offset--) {
199 199
                                 c=chunk->data[offset];
200
-                                if(c=='\n') {
200
+                                if(c=='\n' && !(numchunk==savednumchunk && offset==savedoffset)) {
201 201
                                         status=searching_ended;
202 202
                                         break;
203 203
                                 }
Browse code

fix plugins not being called on undo

Dario Rodriguez authored on 01/12/2020 21:24:22
Showing 1 changed files
... ...
@@ -33,8 +33,6 @@ typedef struct cproto_t {
33 33
         char buffer[MAXINDEXDATALEN];
34 34
 } cproto_t;
35 35
 
36
-static int redata_prototypes_add(redata_t *redata, redata_plugin_t *slot, undo_t *undo);
37
-static int redata_prototypes_unadd(redata_t *redata, redata_plugin_t *slot, undo_t *undo);
38 36
 static int redata_prototypes_add_or_unadd(redata_t *redata, redata_plugin_t *slot, undo_t *undo, int is_unadd);
39 37
 static int redata_prototypes_postload(redata_t *redata, redata_plugin_t *slot,char *filename);
40 38
 static cproto_t *cproto_getplugin(redata_t *redata);
... ...
@@ -80,8 +78,7 @@ redata_prototypes_register(redata_t *redata, redata_plugin_t *slot)
80 78
         slot->name[sizeof(slot->name)-1]='\0';
81 79
         slot->unregister=redata_prototypes_unregister;
82 80
         slot->postload=redata_prototypes_postload;
83
-        slot->add=redata_prototypes_add;
84
-        slot->unadd=redata_prototypes_unadd;
81
+        slot->add_or_unadd=redata_prototypes_add_or_unadd;
85 82
         slot->userptr=cproto;
86 83
         return(0);
87 84
 }
... ...
@@ -102,19 +99,6 @@ redata_prototypes_unregister(redata_t *redata, redata_plugin_t *slot,char *filen
102 99
 
103 100
 }
104 101
 
105
-static int
106
-redata_prototypes_add(redata_t *redata, redata_plugin_t *slot, undo_t *undo)
107
-{
108
-        return(redata_prototypes_add_or_unadd(redata, slot, undo, 0));
109
-}
110
-
111
-static int
112
-redata_prototypes_unadd(redata_t *redata, redata_plugin_t *slot, undo_t *undo)
113
-{
114
-        return(redata_prototypes_add_or_unadd(redata, slot, undo, 1));
115
-}
116
-
117
-
118 102
 static int
119 103
 redata_prototypes_add_or_unadd(redata_t *redata, redata_plugin_t *slot, undo_t *undo, int is_unadd)
120 104
 {
Browse code

Implement show hint of related prototype (for now only for common C/POSIX functions)

Dario Rodriguez authored on 31/10/2020 21:29:27
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,305 @@
1
+/*
2
+ * re_plugin_prototypes.c
3
+ *
4
+ * A programmers editor
5
+ *
6
+ * re_data plugin to support showing common prototypes hints.
7
+ *
8
+ * Author: Dario Rodriguez dario@softhome.net
9
+ * This program is licensed under the terms of GNU GPL v2.1+
10
+ */
11
+
12
+#include <stdio.h>
13
+#include <stdlib.h>
14
+#include <unistd.h>
15
+#include <string.h>
16
+
17
+#include "re_data.h"
18
+#include "re_plugin_prototypes.h"
19
+#include "prototypes_c89_posix.h"
20
+
21
+#define PLUGINNAME "prototypes"
22
+#define MAXINDEXDATALEN 1024
23
+
24
+
25
+typedef struct cproto_t {
26
+        int nentries;
27
+        const char **index;
28
+        const char **values;
29
+        long lastpos;
30
+        int lastindex;
31
+        int sizebuffer;
32
+        int usedbuffer;
33
+        char buffer[MAXINDEXDATALEN];
34
+} cproto_t;
35
+
36
+static int redata_prototypes_add(redata_t *redata, redata_plugin_t *slot, undo_t *undo);
37
+static int redata_prototypes_unadd(redata_t *redata, redata_plugin_t *slot, undo_t *undo);
38
+static int redata_prototypes_add_or_unadd(redata_t *redata, redata_plugin_t *slot, undo_t *undo, int is_unadd);
39
+static int redata_prototypes_postload(redata_t *redata, redata_plugin_t *slot,char *filename);
40
+static cproto_t *cproto_getplugin(redata_t *redata);
41
+static int cproto_buffer_inv(cproto_t *cproto);
42
+static int cproto_buffer_getindex(cproto_t *cproto);
43
+
44
+int
45
+redata_prototypes_register(redata_t *redata, redata_plugin_t *slot)
46
+{
47
+        cproto_t *cproto;
48
+        const char *ptr;
49
+        int n;
50
+        if(redata==NULL || slot==NULL)
51
+                return(-1);
52
+        if((cproto=malloc(sizeof(cproto_t)))==NULL)
53
+                return(-1); /* insufficient memory */
54
+        memset(cproto,0,sizeof(cproto_t));
55
+        /* by default, we use C89/POSIX hints */
56
+        cproto->nentries=SIZE_PROTOTYPES_C89_POSIX;
57
+        if((cproto->index=malloc(sizeof(char *)*cproto->nentries))==NULL
58
+          || (cproto->values=malloc(sizeof(char *)*cproto->nentries))==NULL) {
59
+                if(cproto->index!=NULL)
60
+                        free(cproto->index),cproto->index=NULL;
61
+                return(-1); /* insufficient memory */
62
+        }
63
+        memset(cproto->index,0,sizeof(char *)*cproto->nentries);
64
+        memset(cproto->values,0,sizeof(char *)*cproto->nentries);
65
+        for(n=0,ptr=index_prototypes_c89_posix
66
+          ;n<cproto->nentries
67
+          ;n++,ptr+=strlen(ptr)+1) {
68
+                cproto->index[n]=ptr;
69
+        }
70
+        for(n=0,ptr=values_prototypes_c89_posix
71
+          ;n<cproto->nentries
72
+          ;n++,ptr+=strlen(ptr)+1) {
73
+                cproto->values[n]=ptr;
74
+        }
75
+        cproto->lastpos=-1;
76
+        cproto->lastindex=-1;
77
+        cproto->usedbuffer=0;
78
+        cproto->sizebuffer=sizeof(cproto->buffer);
79
+        strncpy(slot->name,PLUGINNAME,sizeof(slot->name));
80
+        slot->name[sizeof(slot->name)-1]='\0';
81
+        slot->unregister=redata_prototypes_unregister;
82
+        slot->postload=redata_prototypes_postload;
83
+        slot->add=redata_prototypes_add;
84
+        slot->unadd=redata_prototypes_unadd;
85
+        slot->userptr=cproto;
86
+        return(0);
87
+}
88
+
89
+int
90
+redata_prototypes_unregister(redata_t *redata, redata_plugin_t *slot,char *filename)
91
+{
92
+        cproto_t *cproto=(cproto_t *) ((slot!=NULL)?(slot->userptr):NULL);
93
+        if(redata==NULL || slot==NULL || cproto==NULL)
94
+                return(-1);
95
+        if(cproto->index!=NULL)
96
+               free(cproto->index),cproto->index=NULL;
97
+        if(cproto->values!=NULL)
98
+               free(cproto->values),cproto->values=NULL;
99
+        if(slot->userptr!=NULL)
100
+                free(slot->userptr),slot->userptr=NULL;
101
+        return(0);
102
+
103
+}
104
+
105
+static int
106
+redata_prototypes_add(redata_t *redata, redata_plugin_t *slot, undo_t *undo)
107
+{
108
+        return(redata_prototypes_add_or_unadd(redata, slot, undo, 0));
109
+}
110
+
111
+static int
112
+redata_prototypes_unadd(redata_t *redata, redata_plugin_t *slot, undo_t *undo)
113
+{
114
+        return(redata_prototypes_add_or_unadd(redata, slot, undo, 1));
115
+}
116
+
117
+
118
+static int
119
+redata_prototypes_add_or_unadd(redata_t *redata, redata_plugin_t *slot, undo_t *undo, int is_unadd)
120
+{
121
+        /* reset the cache */
122
+        cproto_t *cproto=(cproto_t *) ((slot!=NULL)?(slot->userptr):NULL);
123
+        if(redata==NULL || slot==NULL || cproto==NULL || undo==NULL || slot->active==0)
124
+                return(-1); /* sanity check failed */
125
+        cproto->lastpos=-1;
126
+        cproto->lastindex=-1;
127
+        return(0);
128
+}
129
+
130
+static int
131
+redata_prototypes_postload(redata_t *redata, redata_plugin_t *slot,char *filename)
132
+{
133
+#warning XXX TODO: get the language from the filename
134
+        return(-1);
135
+}
136
+
137
+static cproto_t *
138
+cproto_getplugin(redata_t *redata)
139
+{
140
+        cproto_t *cproto;
141
+        int i;
142
+        if(redata==NULL)
143
+                return(NULL); /* sanity check failed */
144
+        for(i=0;i<redata->sizeplugins;i++) {
145
+                if(strcmp(redata->plugins[i].name,PLUGINNAME)==0)
146
+                        break;
147
+        }
148
+        if(i>=redata->sizeplugins || redata->plugins[i].active==0)
149
+                return(NULL); /* plugin not found or nor active */
150
+        cproto=(cproto_t *) (redata->plugins[i].userptr);
151
+        if(cproto==NULL)
152
+                return(NULL); /* internal error */
153
+        return(cproto);
154
+}
155
+
156
+
157
+const char *
158
+redata_prototypes_get(redata_t *redata, long pos)
159
+{
160
+        int numchunk,savednumchunk;
161
+        int offset,savedoffset;
162
+        long chunkstartpos;
163
+        rechunk_t *chunk;
164
+        cproto_t *cproto;
165
+        char c;
166
+        int ntry;
167
+        enum {
168
+                searching_forward,
169
+                searching_paren,
170
+                searching_name,
171
+                searching_nameend,
172
+                searching_ended,
173
+        } status;
174
+        if(redata==NULL || pos<0 || (cproto=cproto_getplugin(redata))==NULL)
175
+                return(NULL); /* sanity check failed */
176
+        if(pos==cproto->lastpos)
177
+                return((cproto->lastindex!=-1)?(cproto->values[cproto->lastindex]):NULL);
178
+        if(redata_getposptr(redata,pos,&savednumchunk,&savedoffset)!=0)
179
+                return(NULL); /* couldn't get pos */
180
+        cproto->lastpos=pos;
181
+        cproto->lastindex=-1;
182
+        /* FIRST  TRY: check if current word is in index */
183
+        /* SECOND TRY: check if word before the last '( is in index */
184
+        for(ntry=0;ntry<2;ntry++) {
185
+                numchunk=savednumchunk;
186
+                offset=savedoffset;
187
+                chunkstartpos=pos-offset;
188
+                status=(ntry==0)?searching_forward:searching_paren;
189
+                cproto->usedbuffer=0;
190
+                /* search forward for current word end */
191
+                if(ntry==0) {
192
+                        for(;status==searching_forward && numchunk<redata->sizechunks
193
+                          ;chunkstartpos+=chunk->useddata,numchunk++,offset=0) {
194
+                                chunk=redata->chunks[numchunk];
195
+                                for(;offset<chunk->useddata;offset++) {
196
+                                        c=chunk->data[offset];
197
+                                        if(!((c>='A' && c<='Z') || (c>='a' && c<='z') || (c>='0' && c<='9') || c=='_')) {
198
+                                                status=searching_name;
199
+                                                break;
200
+                                        }
201
+                                }
202
+                                if(status!=searching_forward)
203
+                                        break;
204
+                        }
205
+                }
206
+                if(ntry==0 && status!=searching_name)
207
+                        continue;
208
+                /* search backwards for prototype info */
209
+                for(;numchunk>=0 && status!=searching_ended
210
+                  ;numchunk--
211
+                  ,offset=(numchunk>=0)?redata->chunks[numchunk]->useddata-1:0
212
+                  ,chunkstartpos-=(numchunk>=0)?redata->chunks[numchunk]->useddata:0) {
213
+                        chunk=redata->chunks[numchunk];
214
+                        for(;offset>=0;offset--) {
215
+                                c=chunk->data[offset];
216
+                                if(c=='\n') {
217
+                                        status=searching_ended;
218
+                                        break;
219
+                                }
220
+                                if(status==searching_paren) {
221
+                                        if(c=='(') {
222
+                                                status=searching_name;
223
+                                                continue;
224
+
225
+                                        }
226
+                                } else if(status==searching_name) {
227
+                                        if(c==')') {
228
+                                                status=searching_paren;
229
+                                                continue;
230
+                                        }
231
+                                        if((c>='A' && c<='Z') || (c>='a' && c<='z') || (c>='0' && c<='9') || c=='_') {
232
+                                                cproto->usedbuffer=0;
233
+                                                cproto->buffer[(cproto->usedbuffer++)]=c;
234
+                                                status=searching_nameend;
235
+                                        }
236
+                                } else { /* status==searching_nameend */
237
+                                        if(c=='(') {
238
+                                                if(cproto->usedbuffer>0) {
239
+                                                        /* if we had a hit, return that */
240
+                                                        cproto_buffer_inv(cproto);
241
+                                                        /* search string */
242
+                                                        if((cproto->lastindex=cproto_buffer_getindex(cproto))!=-1)
243
+                                                                return(cproto->values[cproto->lastindex]);
244
+                                                }
245
+                                                cproto->usedbuffer=0;
246
+                                                status=searching_nameend;
247
+                                                continue;
248
+                                        } else if(!((c>='A' && c<='Z') || (c>='a' && c<='z') || (c>='0' && c<='9') || c=='_')) {
249
+                                                status=searching_ended;
250
+                                                break;
251
+                                        } else {
252
+                                                if((cproto->usedbuffer+1)<cproto->sizebuffer)
253
+                                                        cproto->buffer[(cproto->usedbuffer++)]=c;
254
+                                        }
255
+                                }
256
+                        }
257
+                }
258
+                if((status==searching_nameend || status==searching_ended) && cproto->usedbuffer>0) {
259
+                        cproto_buffer_inv(cproto);
260
+                        /* search string */
261
+                        if((cproto->lastindex=cproto_buffer_getindex(cproto))!=-1)
262
+                                return(cproto->values[cproto->lastindex]);
263
+                }
264
+        }
265
+        return(NULL);
266
+}
267
+
268
+
269
+
270
+
271
+static int
272
+cproto_buffer_inv(cproto_t *cproto)
273
+{
274
+        int i,l,l2;
275
+        char c;
276
+        if(cproto==NULL)
277
+                return(-1);
278
+        /* terminate string */
279
+        cproto->buffer[cproto->usedbuffer]='\0';
280
+        /* invert string */
281
+        l=cproto->usedbuffer;
282
+        l2=l>>1;
283
+        for(i=0;i<l2;i++) {
284
+                c=cproto->buffer[i];
285
+                cproto->buffer[i]=cproto->buffer[l-1-i];
286
+                cproto->buffer[l-1-i]=c;
287
+        }
288
+        return(0);
289
+}
290
+
291
+static int
292
+cproto_buffer_getindex(cproto_t *cproto)
293
+{
294
+#warning TODO use qsearch()
295
+        int i;
296
+        if(cproto==NULL)
297
+                return(-1);
298
+        cproto->buffer[cproto->usedbuffer]='\0';
299
+        for(i=0;i<cproto->nentries;i++) {
300
+                if(strcmp(cproto->index[i],cproto->buffer)==0) {
301
+                        return(i);
302
+                }
303
+        }
304
+        return(-1);
305
+}