精華區beta SetupBBS 關於我們 聯絡資訊
/*-------------------------------------------------------*/ /* name.c ( NTHU CS MapleBBS Ver 2.36 ) */ /*-------------------------------------------------------*/ /* target : name-complete routines */ /* create : 95/03/29 */ /* update : 95/12/15 */ /*-------------------------------------------------------*/ #include "bbs.h" struct word *toplev = NULL; static struct word *current = NULL; static char *msg_more = "-- More --"; static void FreeNameList() { struct word *p, *temp; for (p = toplev; p; p = temp) { temp = p->next; free(p->word); free(p); } } void CreateNameList() { if (toplev) FreeNameList(); toplev = current = NULL; } void AddNameList(name) char *name; { struct word *node; node = (struct word *) malloc(sizeof(struct word)); node->next = NULL; node->word = (char *) malloc(strlen(name) + 1); strcpy(node->word, name); if (toplev) current = current->next = node; else current = toplev = node; } int RemoveNameList(name) char *name; { struct word *curr, *prev = NULL; for (curr = toplev; curr; curr = curr->next) { if (!strcmp(curr->word, name)) { if (prev == NULL) toplev = curr->next; else prev->next = curr->next; if (curr == current) current = prev; free(curr->word); free(curr); return 1; } prev = curr; } return 0; } int InNameList(name) char *name; { struct word *p; for (p = toplev; p; p = p->next) { if (!strcmp(p->word, name)) return 1; } return 0; } void ShowNameList(row, column, prompt) int row, column; char *prompt; { struct word *p; move(row, column); clrtobot(); outs(prompt); column = 80; for (p = toplev; p; p = p->next) { row = strlen(p->word) + 1; if (column + row > 76) { column = row; outc('\n'); } else { column += row; outc(' '); } outs(p->word); } } void LoadNameList(reciper, listfile, msg) int *reciper; char *listfile, *msg; { FILE *fp; char genbuf[200]; if (fp = fopen(listfile, "r")) { while (fgets(genbuf, STRLEN, fp)) { strtok(genbuf, str_space); if (!InNameList(genbuf)) { AddNameList(genbuf); (*reciper)++; } } fclose(fp); ShowNameList(3, 0, msg); } } /* woju */ void ToggleNameList(reciper, listfile, msg) int *reciper; char *listfile, *msg; { FILE *fp; char genbuf[200]; if (fp = fopen(listfile, "r")) { while (fgets(genbuf, STRLEN, fp)) { strtok(genbuf, str_space); if (!InNameList(genbuf)) { AddNameList(genbuf); (*reciper)++; } else { RemoveNameList(genbuf); (*reciper)--; } } fclose(fp); ShowNameList(3, 0, msg); } } void SaveNameList(listfile) char *listfile; { FILE *fp; struct word *p; if (fp = fopen(listfile, "w")) { for (p = toplev; p; p = p->next) fprintf(fp, "%s\n", p->word); fclose(fp); } } static int NumInList(list) register struct word *list; { register int i; for (i = 0; list; i++) list = list->next; return i; } #if 0 void ApplyToNameList(fptr) int ((*fptr) ()); { struct word *p; for (p = toplev; p; p = p->next) (*fptr) (p->word); } #endif int chkstr(otag, tag, name) char *otag, *tag, *name; { char ch, *oname = name; while (*tag) { ch = *name++; if (*tag != chartoupper(ch)) return 0; tag++; } if (*tag && *name == '\0') strcpy(otag, oname); return 1; } static struct word * GetSubList(tag, list) register char *tag; register struct word *list; { struct word *wlist, *wcurr; char tagbuf[STRLEN]; int n; wlist = wcurr = NULL; for (n = 0; tag[n]; n++) { tagbuf[n] = chartoupper(tag[n]); } tagbuf[n] = '\0'; while (list) { if (chkstr(tag, tagbuf, list->word)) { register struct word *node; node = (struct word *) malloc(sizeof(struct word)); node->word = list->word; node->next = NULL; if (wlist) wcurr->next = node; else wlist = node; wcurr = node; } list = list->next; } return wlist; } static void ClearSubList(list) struct word *list; { struct word *tmp_list; while (list) { tmp_list = list->next; free(list); list = tmp_list; } } static int MaxLen(list, count) struct word *list; { int len = strlen(list->word); int t; while (list && count) { if ((t = strlen(list->word)) > len) len = t; list = list->next; count--; } return len; } void namecomplete(prompt, data) char *prompt, *data; { char *temp; struct word *cwlist, *morelist; int x, y, origx, origy; int ch; int count = 0; int clearbot = NA; if (toplev == NULL) AddNameList(""); cwlist = GetSubList("", toplev); morelist = NULL; temp = data; outs(prompt); clrtoeol(); getyx(&y, &x); getyx(&origy, &origx); standout(); prints("%*s", IDLEN + 1, ""); standend(); move(y, x); refresh(); while ((ch = igetch()) != EOF) { if (ch == '\n' || ch == '\r') { *temp = '\0'; outc('\n'); if (NumInList(cwlist) == 1) strcpy(data, cwlist->word); ClearSubList(cwlist); break; } if (ch == ' ') { int col, len; if (NumInList(cwlist) == 1) { strcpy(data, cwlist->word); move(y, x); outs(data + count); count = strlen(data); temp = data + count; getyx(&y, &x); continue; } clearbot = YEA; col = 0; if (!morelist) morelist = cwlist; len = MaxLen(morelist, p_lines); move(2, 0); clrtobot(); printdash("相關資訊一覽表"); while (len + col < 80) { int i; for (i = p_lines; (morelist) && (i > 0); i--) { move(3 + (p_lines - i), col); outs(morelist->word); morelist = morelist->next; } col += len + 2; if (!morelist) break; len = MaxLen(morelist, p_lines); } if (morelist) { move(b_lines, 0); outs(msg_more); } move(y, x); continue; } if (ch == '\177' || ch == '\010') { if (temp == data) continue; temp--; count--; *temp = '\0'; ClearSubList(cwlist); cwlist = GetSubList(data, toplev); morelist = NULL; x--; move(y, x); outc(' '); move(y, x); continue; } if (count < STRLEN) { struct word *node; *temp++ = ch; count++; *temp = '\0'; node = GetSubList(data, cwlist); if (node == NULL) { temp--; *temp = '\0'; count--; continue; } ClearSubList(cwlist); cwlist = node; morelist = NULL; move(y, x); outc(ch); x++; } } if (ch == EOF) longjmp(byebye, -1); outc('\n'); refresh(); if (clearbot) { move(2, 0); clrtobot(); } if (*data) { move(origy, origx); outs(data); outc('\n'); } } /* ---------------------------------------------------- */ /* name complete for user ID */ /* ---------------------------------------------------- */ static int UserMaxLen(cwlist, cwnum, morenum, count) char cwlist[][IDLEN + 1]; int cwnum, morenum, count; { int len, max = 0; while (count-- > 0 && morenum < cwnum) { len = strlen(cwlist[morenum++]); if (len > max) max = len; } return max; } static int UserSubArray(cwbuf, cwlist, cwnum, key, pos) char cwbuf[][IDLEN + 1]; char cwlist[][IDLEN + 1]; int cwnum, key, pos; { int key2, num = 0; int n, ch; key = chartoupper(key); if (key >= 'A' && key <= 'Z') { key2 = key | 0x20; } else { key2 = key ; } for (n = 0; n < cwnum; n++) { ch = cwlist[n][pos]; if (ch == key || ch == key2) { strcpy(cwbuf[num++], cwlist[n]); } } return num; } void usercomplete(prompt, data) char *prompt, *data; { char *temp; char *u_namearray(); char *cwbuf, *cwlist; int cwnum, x, y, origx, origy; int clearbot = NA, count = 0, morenum = 0; char ch; cwbuf = (char *) malloc(MAXUSERS * (IDLEN + 1)); cwlist = u_namearray(cwbuf, &cwnum, ""); temp = data; outs(prompt); clrtoeol(); getyx(&y, &x); getyx(&origy, &origx); standout(); prints("%*s", IDLEN + 1, ""); standend(); move(y, x); while ((ch = igetch()) != EOF) { if (ch == '\n' || ch == '\r') { int i; char *ptr; *temp = '\0'; outc('\n'); ptr = cwlist; for (i = 0; i < cwnum; i++) { if (ci_strncmp(data, ptr, IDLEN + 1) == 0) strcpy(data, ptr); ptr += IDLEN + 1; } break; } else if (ch == ' ') { int col, len; if (cwnum == 1) { strcpy(data, cwlist); move(y, x); outs(data + count); count = strlen(data); temp = data + count; getyx(&y, &x); continue; } clearbot = YEA; col = 0; len = UserMaxLen(cwlist, cwnum, morenum, p_lines); move(2, 0); clrtobot(); printdash("使用者代號一覽表"); while (len + col < 79) { int i; for (i = 0; morenum < cwnum && i < p_lines; i++) { move(3 + i, col); prints("%s ", cwlist + (IDLEN + 1) * morenum++); } col += len + 2; if (morenum >= cwnum) break; len = UserMaxLen(cwlist, cwnum, morenum, p_lines); } if (morenum < cwnum) { move(b_lines, 0); outs(msg_more); } else { morenum = 0; } move(y, x); continue; } else if (ch == '\177' || ch == '\010') { if (temp == data) continue; temp--; count--; *temp = '\0'; cwlist = u_namearray(cwbuf, &cwnum, data); morenum = 0; x--; move(y, x); outc(' '); move(y, x); continue; } else if (count < STRLEN) { int n; *temp++ = ch; *temp = '\0'; n = UserSubArray(cwbuf, cwlist, cwnum, ch, count); if (n == 0) { temp--; *temp = '\0'; continue; } cwlist = cwbuf; count++; cwnum = n; morenum = 0; move(y, x); outc(ch); x++; } } free(cwbuf); if (ch == EOF) longjmp(byebye, -1); outc('\n'); refresh(); if (clearbot) { move(2, 0); clrtobot(); } if (*data) { move(origy, origx); outs(data); outc('\n'); } }