summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2009-10-16 00:36:04 +0800
committerpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2009-10-16 00:36:04 +0800
commitb6045ce80ccdf122cc3e945d4a6cf0c4401f5d4e (patch)
tree872e4cd339c84999f86f5c358f5ef57a676799be
parentbe144dd41da38df6162074dcb74186a759ab1726 (diff)
downloadpttbbs-b6045ce80ccdf122cc3e945d4a6cf0c4401f5d4e.tar
pttbbs-b6045ce80ccdf122cc3e945d4a6cf0c4401f5d4e.tar.gz
pttbbs-b6045ce80ccdf122cc3e945d4a6cf0c4401f5d4e.tar.bz2
pttbbs-b6045ce80ccdf122cc3e945d4a6cf0c4401f5d4e.tar.lz
pttbbs-b6045ce80ccdf122cc3e945d4a6cf0c4401f5d4e.tar.xz
pttbbs-b6045ce80ccdf122cc3e945d4a6cf0c4401f5d4e.tar.zst
pttbbs-b6045ce80ccdf122cc3e945d4a6cf0c4401f5d4e.zip
* use vgetstring() with callbacks to implement generalcomplete.
git-svn-id: http://opensvn.csie.org/pttbbs/trunk@4937 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
-rw-r--r--pttbbs/mbbsd/name.c166
1 files changed, 160 insertions, 6 deletions
diff --git a/pttbbs/mbbsd/name.c b/pttbbs/mbbsd/name.c
index d4cef005..8ed2138b 100644
--- a/pttbbs/mbbsd/name.c
+++ b/pttbbs/mbbsd/name.c
@@ -1,7 +1,8 @@
/* $Id$ */
#include "bbs.h"
-#define MORE_MSG "按空白鍵可列出更多項目"
+#define COMPLETE_MORE_MSG "按空白鍵可列出更多項目"
+#define COMPLETE_LIST_TITLE "相關資訊一覽表"
void
ToggleVector(struct Vector *list, int *recipient, const char *listfile, const char *msg)
@@ -100,11 +101,11 @@ nc_cb_peek(int key, VGET_RUNTIME *prt, void *instance)
move(2, 0);
clrtobot();
- printdash("相關資訊一覽表", 0);
+ printdash(COMPLETE_LIST_TITLE, 0);
nc_int->idx = ShowVector(&nc_int->sublist, 3, 0, NULL, nc_int->idx);
if (nc_int->idx < Vector_length(&nc_int->sublist))
- vshowmsg(MORE_MSG);
+ vshowmsg(COMPLETE_MORE_MSG);
return VGETCB_NEXT;
break;
@@ -168,7 +169,6 @@ usercomplete(const char *prompt, char *data)
struct Vector namelist;
Vector_init_const(&namelist, SHM->userid[0], MAX_USERS, IDLEN+1);
-
namecomplete2(&namelist, prompt, data);
}
@@ -234,12 +234,166 @@ gnc_complete(char *data, int *start, int *end,
return count;
}
+typedef struct {
+ int start, end, nmemb, ptr;
+ int morelist;
+ int clearbot; // YEA if screen was dirty
+ gnc_comp_func compar;
+ gnc_perm_func permission;
+ gnc_getname_func getname;
+} generalcomplete_int;
+
+static int
+gnc_cb_data(int key, VGET_RUNTIME *prt, void *instance)
+{
+ generalcomplete_int *gc_int = (generalcomplete_int*) instance;
+ char *data = prt->buf;
+ int ret = VGETCB_NEXT; // reject by default
+ int i;
+ gc_int->morelist = -1;
+
+ assert(prt->icurr+1 < prt->len);
+ // try to add character
+ data[prt->icurr] = key;
+ data[prt->icurr+1]= 0;
+ if (gnc_findbound(data, &gc_int->start, &gc_int->end, gc_int->nmemb, gc_int->compar) >= 0)
+ {
+ // verify permission
+ for (i = gc_int->start; i <= gc_int->end; ++i)
+ if ((*gc_int->permission)(i))
+ break;
+ // found something? accept it
+ if (i != gc_int->end + 1)
+ ret = VGETCB_NONE;
+ }
+ // restore data buffer
+ data[prt->icurr]= 0;
+ return ret;
+}
+
+static int
+gnc_cb_peek(int key, VGET_RUNTIME *prt, void *instance)
+{
+ generalcomplete_int *gc_int = (generalcomplete_int*) instance;
+ char *data = prt->buf;
+
+ switch(key) {
+ case KEY_BS: // backspace
+ gc_int->morelist = -1;
+ break;
+
+ case ' ': // render complete page
+ assert(prt->icurr == prt->iend);
+ if (gc_int->morelist == -1)
+ {
+ int i;
+ char *first;
+ if (gnc_findbound(data, &gc_int->start, &gc_int->end,
+ gc_int->nmemb, gc_int->compar) == -1)
+ return VGETCB_NEXT;
+
+ i = gnc_complete (data, &gc_int->start, &gc_int->end,
+ gc_int->permission, gc_int->getname);
+ if (i == 1) {
+ prt->iend = prt->icurr = strlen(data);
+ return VGETCB_NEXT;
+ }
+ first = (*gc_int->getname)(gc_int->start);
+ i = prt->icurr;
+ while (first[i] && (*gc_int->compar)(gc_int->end, first, i + 1) == 0) {
+ data[i] = first[i];
+ ++i;
+ }
+ data[i] = '\0';
+ prt->iend = prt->icurr = i;
+ gc_int->morelist = gc_int->start;
+ } else if (gc_int->morelist > gc_int->end)
+ return VGETCB_NEXT;
+
+ // rendef list
+ gc_int->clearbot = YEA;
+ move(2, 0);
+ clrtobot();
+ printdash(COMPLETE_LIST_TITLE, 0);
+ {
+ int col = 0, i = 0;
+ int len = prt->len;
+ while (len + col < t_columns-1) {
+ for (i = 0; gc_int->morelist <= gc_int->end && i < p_lines; ++gc_int->morelist) {
+ if ((*gc_int->permission)(gc_int->morelist)) {
+ move(3 + i, col);
+ prints("%s ", (*gc_int->getname)(gc_int->morelist));
+ ++i;
+ }
+ }
+ col += len + 2;
+ }
+ }
+ if (gc_int->morelist != gc_int->end + 1) {
+ vshowmsg(COMPLETE_MORE_MSG);
+ }
+ return VGETCB_NEXT;
+ }
+ return VGETCB_NONE;
+}
+
int
generalnamecomplete(const char *prompt, char *data, int len, size_t nmemb,
gnc_comp_func compar, gnc_perm_func permission,
gnc_getname_func getname)
{
+ generalcomplete_int gc_int = {
+ .start = 0,
+ .end = nmemb-1,
+ .nmemb = nmemb,
+ .morelist = -1,
+ .clearbot = NA,
+ .compar = compar,
+ .permission = permission,
+ .getname = getname,
+ };
+ const VGET_CALLBACKS vcb = {
+ .peek = gnc_cb_peek,
+ .data = gnc_cb_data,
+ };
+ int ret = -1;
+
+ outs(prompt);
+ clrtoeol();
+
+ // init vector
+ ret = vgetstring(data, len, VGET_NO_NAV_EDIT, NULL, &vcb, &gc_int);
+ outc('\n');
+
+ // vgetstring() return string length, but namecomplete needs to return
+ // the index of input string.
+
+ if (ret < 1)
+ {
+ data[0] = '\0';
+ return -1;
+ }
+
+ gnc_findbound(data, &gc_int.start, &gc_int.end, nmemb, compar);
+ if (gnc_complete(data, &gc_int.start, &gc_int.end, permission, getname) == 1 ||
+ (*compar)(gc_int.start, data, len) == 0)
+ {
+ strlcpy(data, (*getname)(gc_int.start), len);
+ ret = gc_int.start;
+ } else {
+ data[0] = '\0';
+ ret = -1;
+ }
+
+ return ret;
+}
+
+int
+generalnamecomplete_old(const char *prompt, char *data, int len, size_t nmemb,
+ gnc_comp_func compar, gnc_perm_func permission,
+ gnc_getname_func getname)
+{
int x, y, origx, scrx, ch, i, morelist = -1, col, ret = -1;
int start, end, ptr;
int clearbot = NA;
@@ -310,7 +464,7 @@ generalnamecomplete(const char *prompt, char *data, int len, size_t nmemb,
clearbot = YEA;
move(2, 0);
clrtobot();
- printdash("相關資訊一覽表", 0);
+ printdash(COMPLETE_LIST_TITLE, 0);
col = 0;
while (len + col < t_columns-1) {
@@ -325,7 +479,7 @@ generalnamecomplete(const char *prompt, char *data, int len, size_t nmemb,
col += len + 2;
}
if (morelist != end + 1) {
- vshowmsg(MORE_MSG);
+ vshowmsg(COMPLETE_MORE_MSG);
}
continue;