Пример #1
0
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;
}
Пример #2
0
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;
		}
	}
}
Пример #3
0
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;
}
Пример #4
0
/*
 * 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;
	}
}
Пример #5
0
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;
}
Пример #6
0
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--;
}
Пример #7
0
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 */
}
Пример #8
0
/*
 * 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);
}
Пример #9
0
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 = "螢幕大小已改變, 按(Ctrl-G)回到頁首!";

			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;
}