static struct textline *alloc_line() { register struct textline *p; /* kmwang: For badident */ extern BOOL IsRealSysop; if (IsRealSysop) { if (total_num_of_line > 8192) /* lthuang: debug */ { indigestion(3); abort_bbs(0); } } else if (total_num_of_line > 2048) /* lthuang: debug */ { indigestion(3); abort_bbs(0); } p = (struct textline *) malloc(sizeof(*p)); if (p == NULL) { indigestion(13); abort_bbs(0); } p->next = NULL; p->prev = NULL; p->data[0] = '\0'; p->len = 0; total_num_of_line++; return p; }
static void insert_char(register int ch) { register int i; register char *s; register struct textline *p = currline; register BOOL wordwrap = TRUE; if (currpnt > p->len) { indigestion(1); return; } for (i = p->len; i >= currpnt; i--) p->data[i + 1] = p->data[i]; p->data[currpnt++] = ch; p->len++; if (p->len < WRAPMARGIN) return; s = p->data + (p->len - 1); while (s != p->data && *s == ' ') s--; while (s != p->data && *s != ' ') s--; if (s == p->data) { wordwrap = FALSE; s = p->data + (p->len - 2); } split(p, (s - p->data) + 1); p = p->next; if (wordwrap && p->len >= 1) { i = p->len; if (p->data[i - 1] != ' ') { p->data[i] = ' '; p->data[i + 1] = '\0'; p->len++; } } while (!join(p)) { p = p->next; if (p == NULL) { indigestion(2); break; } } }
struct textline * alloc_line() { register struct textline *p; p = (struct textline *) malloc(sizeof(*p)); if (p == NULL) { indigestion(13); abort_bbs(0); } p->next = NULL; p->prev = NULL; p->data[0] = '\0'; p->len = 0; p->attr = 0; /* for copy/paste */ return p; }
/* * join connects 'line' and the next line. It returns true if: * * 1) lines were joined and one was deleted * 2) lines could not be joined * 3) next line is empty * * returns false if: * * 1) Some of the joined line wrapped */ static int join(register struct textline *line) { register int ovfl; if (!line->next) return TRUE; if (*killsp(line->next->data) == '\0') return TRUE; ovfl = line->len + line->next->len - WRAPMARGIN; if (ovfl < 0) { strcat(line->data, line->next->data); line->len += line->next->len; delete_line(line->next); return TRUE; } else { register char *s; register struct textline *p = line->next; s = p->data + p->len - ovfl - 1; while (s != p->data && *s == ' ') s--; while (s != p->data && *s != ' ') s--; if (s == p->data) return TRUE; split(p, (s - p->data) + 1); /* indicate one of the two line are longer than WRAPMARGIN */ if (line->len + p->len >= WRAPMARGIN) { indigestion(0); return TRUE; } join(line); /* ? */ p = line->next; if (p->len >= 1 && p->len + 1 < WRAPMARGIN) /* ? */ { if (p->data[p->len - 1] != ' ') { strcat(p->data, " "); p->len++; } } return FALSE; } }
static void join_currline() { struct textline *p = currline; while (!join(p)) { p = p->next; if (p == NULL) { indigestion(2); abort_bbs(0); } } redraw_everything = TRUE; }
static void delete_char() { register int i; if (currline->len == 0) return; if (currpnt >= currline->len) { indigestion(1); return; } for (i = currpnt; i != currline->len; i++) currline->data[i] = currline->data[i + 1]; currline->len--; }
static void backup_file(register char *bakfile) { register FILE *fp; register struct textline *p; if ((fp = fopen(bakfile, "w")) == NULL) { indigestion(5); abort_bbs(0); } for (p = firstline; p != NULL; p = p->next) { if (p == lastline && p->data[0] == '\0') break; fprintf(fp, "%s\n", p->data); } fclose(fp); chmod(bakfile, 0600); /* lthuang */ }
/* * read text from file into editor buffer */ static void read_file(const char *filename) { register int fd; unsigned char ch; vedit_init(); if ((fd = open(filename, O_RDONLY)) < 0) { if ((fd = open(filename, O_WRONLY | O_CREAT, 0644)) > 0) { close(fd); return; } indigestion(4); abort_bbs(0); } while (read(fd, &ch, 1) > 0) { if (ch == '\t') { do { insert_char(' '); } while (currpnt & 0x7); } #if defined(BIT8) else if (isprint2(ch)) #else else if (isprint(ch)) #endif insert_char(ch); else if (ch == '\n') split(currline, currpnt); } close(fd); }
int vedit(const char *filename, const char *saveheader, char *bname) { int ch, foo; int lastcharindent = -1; BOOL firstkey = TRUE; char bakfile[PATHLEN]; int old_rows = t_lines, old_columns = t_columns; sethomefile(bakfile, curuser.userid, UFNAME_EDIT); if ((saveheader || uinfo.mode == EDITPLAN || uinfo.mode == EDITBMWEL) && isfile(bakfile) /* lthuang */ #ifdef GUEST && strcmp(curuser.userid, GUEST) #endif ) { clear(); outs(_msg_edit_8); if (getkey() != '2') mycp(bakfile, filename); } if (!isfile(filename)) unlink(bakfile); if (saveheader) do_article_sig(filename); read_file(filename); top_of_win = firstline; currline = firstline; curr_window_line = 0; currpnt = 0; ansi_mode = FALSE; clear(); display_buffer(); move(curr_window_line, currpnt); while ((ch = getkey()) != EOF) { if (firstkey) { firstkey = FALSE; show_help_msg(); } if (talkrequest) /* lthuang */ { backup_file(bakfile); talkreply(); pressreturn(); ch = CTRL('G'); /* redraw screen */ } else if (msqrequest) /* lthuang */ { msqrequest = FALSE; msq_reply(); #if 0 ch = CTRL('G'); #endif } if (old_rows != t_lines || old_columns != t_columns) { static const char *msg_resized = "[1;34;47m螢幕大小已改變, 按(Ctrl-G)回到頁首![m"; old_rows = t_lines; old_columns = t_columns; top_of_win = firstline; currline = top_of_win; curr_window_line = 0; currpnt = 0; shift = 0; redraw_everything = TRUE; move(t_lines / 2, (t_columns - strlen(msg_resized)) / 2); outs(msg_resized); while (getkey() != CTRL('G')); } else if (ch < 0x100 && isprint2(ch)) { insert_char(ch); lastcharindent = -1; } else switch (ch) { case KEY_UP: if (lastcharindent == -1) lastcharindent = currpnt; if (!currline->prev) { bell(); break; } curr_window_line--; currline = currline->prev; currpnt = (currline->len > lastcharindent) ? lastcharindent : currline->len; break; case KEY_DOWN: if (lastcharindent == -1) lastcharindent = currpnt; if (!currline->next) { bell(); break; } curr_window_line++; currline = currline->next; currpnt = (currline->len > lastcharindent) ? lastcharindent : currline->len; break; default: lastcharindent = -1; switch (ch) { case CTRL('T'): top_of_win = back_line(lastline, b_lines - 2); currline = lastline; curr_window_line = getlineno(); currpnt = 0; redraw_everything = TRUE; break; case CTRL('S'): top_of_win = firstline; currline = top_of_win; curr_window_line = 0; currpnt = 0; redraw_everything = TRUE; break; case '\t': do { insert_char(' '); } while (currpnt & 0x7); break; case CTRL('U'): case CTRL('V'): insert_char(0x1b); break; case CTRL('C'): insert_char(0x1b); insert_char('['); insert_char('m'); break; case KEY_RIGHT: case CTRL('F'): if (currline->len == currpnt) { if (!currline->next) bell(); else { currpnt = 0; curr_window_line++; currline = currline->next; } } else currpnt++; break; case KEY_LEFT: case CTRL('B'): if (currpnt == 0) { if (!currline->prev) bell(); else { currline = currline->prev; currpnt = currline->len; curr_window_line--; } } else currpnt--; break; case CTRL('G'): clear(); redraw_everything = TRUE; break; case CTRL('Z'): vedit_help(); break; case KEY_PGUP: case CTRL('P'): top_of_win = back_line(top_of_win, b_lines - 2); currline = top_of_win; currpnt = 0; curr_window_line = 0; redraw_everything = TRUE; break; case KEY_PGDN: case CTRL('N'): top_of_win = forward_line(top_of_win, b_lines - 2); currline = top_of_win; currpnt = 0; curr_window_line = 0; redraw_everything = TRUE; break; case KEY_HOME: case CTRL('A'): currpnt = 0; break; case KEY_END: case CTRL('E'): currpnt = currline->len; break; case CTRL('R'): #if 0 backup_file(bakfile); #endif msq_reply(); #if 0 redraw_everything = TRUE; /* lthuang */ #endif break; case CTRL('Q'): ansi_mode = TRUE; display_buffer(); pressreturn(); ansi_mode = FALSE; display_buffer(); break; case CTRL('X'): case CTRL('W'): backup_file(bakfile); clear(); foo = write_file(filename, saveheader, bname); if (foo == BACKUP_EDITING) return foo; else if (foo != KEEP_EDITING) { unlink(bakfile); return foo; } redraw_everything = TRUE; /* lthuang */ break; case '\r': case '\n': split(currline, currpnt); /* lthuang: reduce the times of backup */ if (total_num_of_line % 7 == 0) backup_file(bakfile); break; case '\177': case CTRL('H'): if (currpnt == 0) { if (!currline->prev) { bell(); break; } curr_window_line--; currline = currline->prev; currpnt = currline->len; if (*killsp(currline->next->data) == '\0') { delete_line(currline->next); redraw_everything = TRUE; } else { join_currline(); } if (curr_window_line == -1) { curr_window_line = 0; top_of_win = currline; rscroll(); } break; } currpnt--; delete_char(); break; case CTRL('D'): if (currline->len == currpnt) join_currline(); else delete_char(); break; case CTRL('Y'): currpnt = 0; currline->len = 0; delete_currline(); break; case CTRL('K'): if (currline->len == 0) delete_currline(); else if (currline->len == currpnt) join_currline(); else { currline->len = currpnt; currline->data[currpnt] = '\0'; } break; default: break; } break; } if (curr_window_line == -1) { curr_window_line = 0; if (!top_of_win->prev) { indigestion(6); bell(); } else { top_of_win = top_of_win->prev; rscroll(); } } if (curr_window_line == t_lines - 1) { curr_window_line = t_lines - 2; if (!top_of_win->next) { indigestion(7); bell(); } else { top_of_win = top_of_win->next; scroll(); } } /* lthuang: 99/07 */ if (currpnt - shift >= t_columns - 1) { shift = (currpnt / (t_columns - 1)) * (t_columns - 1) - 1; redraw_everything = TRUE; } else if (currpnt - shift < 0) { shift = 0; redraw_everything = TRUE; } if (redraw_everything) { display_buffer(); redraw_everything = FALSE; } else { move(curr_window_line, 0); clrtoeol(); /* lthuang */ vedit_outs(currline->data); } move(curr_window_line, currpnt - shift); /* lthuang: 99/07 */ } if (uinfo.mode == POSTING || uinfo.mode == SMAIL) unlink(filename); return ABORT_EDITING; }