diff options
author | piaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2008-04-21 23:58:37 +0800 |
---|---|---|
committer | piaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2008-04-21 23:58:37 +0800 |
commit | 88c3dcb1b305a6a5781afb25630b7996cc318ea4 (patch) | |
tree | e38c148e366db2061a24ebdf901a888b8f03bd42 /mbbsd/more.c | |
parent | c431922490f08beb011af18f9ffb72a74b5d3a1c (diff) | |
download | pttbbs-88c3dcb1b305a6a5781afb25630b7996cc318ea4.tar pttbbs-88c3dcb1b305a6a5781afb25630b7996cc318ea4.tar.gz pttbbs-88c3dcb1b305a6a5781afb25630b7996cc318ea4.tar.bz2 pttbbs-88c3dcb1b305a6a5781afb25630b7996cc318ea4.tar.lz pttbbs-88c3dcb1b305a6a5781afb25630b7996cc318ea4.tar.xz pttbbs-88c3dcb1b305a6a5781afb25630b7996cc318ea4.tar.zst pttbbs-88c3dcb1b305a6a5781afb25630b7996cc318ea4.zip |
- (internal) code refine
- change pmore to non-official pager again. Explicitly #define USE_PMORE in pttbbs.conf to use it.
- add mini pager (minimore) as a default replacement of pmore for license issue.
git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@4224 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd/more.c')
-rw-r--r-- | mbbsd/more.c | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/mbbsd/more.c b/mbbsd/more.c index 18244e6b..2a0f5009 100644 --- a/mbbsd/more.c +++ b/mbbsd/more.c @@ -1,6 +1,26 @@ /* $Id$ */ #include "bbs.h" +/* + * more.c + * a mini pager in 130 lines of code, or stub of the huge pager pmore. + * Author: Hung-Te Lin (piaip), April 2008. + * + * Copyright (c) 2008 Hung-Te Lin <piaip@csie.ntu.edu.tw> + * All rights reserved. + * Distributed under BSD license (GPL compatible). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + */ + +#ifdef USE_PMORE /* use new pager: piaip's more. */ int more(const char *fpath, int promptend) { @@ -75,3 +95,138 @@ int more(const char *fpath, int promptend) return r; } +#else // !USE_PMORE + +// minimore: a mini pager in exactly 130 lines +#define PAGER_MAXLINES (2048) +int more(const char *fpath, int promptend) +{ + FILE *fp = fopen(fpath, "rt"); + int lineno = 0, lines = 0, oldlineno = -1; + int i = 0, abort = 0, showall = 0, colorize = 0; + int lpos[PAGER_MAXLINES] = {0}; // line position + char buf [ANSILINELEN]; + + if (!fp) return -1; + clear(); + + if (promptend == NA) { // quick print one page + for (i = 0; i < t_lines-1; i++) + if (!fgets(buf, sizeof(buf), fp)) + break; + else + outs(buf); + fclose(fp); + return 0; + } + // YEA mode: pre-read + while (lines < PAGER_MAXLINES-1 && + fgets(buf, sizeof(buf), fp) != NULL) + lpos[++lines] = ftell(fp); + rewind(fp); + + while (!abort) + { + if (oldlineno != lineno) // seek and print + { + clear(); + showall = 0; + oldlineno = lineno; + fseek(fp, lpos[lineno], SEEK_SET); + + for (i = 0, buf[0] = 0; i < t_lines-1; i++, buf[0] = 0) + { + if (!showall) + { + fgets(buf, sizeof(buf), fp); + if (lineno + i == 0 && + (strncmp(buf, STR_AUTHOR1, strlen(STR_AUTHOR1))==0 || + strncmp(buf, STR_AUTHOR2, strlen(STR_AUTHOR2))==0)) + colorize = 1; + } + + if (!buf[0]) + { + outs("\n"); + showall = 1; + } else { + // dirty code to render heeader + if (colorize && lineno+i < 4 && *buf && + *buf != '\n' && strchr(buf, ':')) + { + char *q1 = strchr(buf, ':'); + int l = t_columns - 2 - strlen(buf); + char *q2 = strstr(buf, STR_POST1); + + chomp(buf); + if (q2 == NULL) q2 = strstr(buf, STR_POST2); + if (q2) { *(q2-1) = 0; q2 = strchr(q2, ':'); } + else q2 = q1; + + *q1++ = 0; *q2++ = 0; + if (q1 == q2) q2 = NULL; + + outs(ANSI_COLOR(34;47) " "); + outs(buf); outs(" " ANSI_COLOR(5)); + outs(q1); prints("%*s", l, ""); q1 += strlen(q1); + + if (q2) { + outs(ANSI_COLOR(0;34;47) " "); outs(q1+1); + outs(" " ANSI_COLOR(5)); outs(q2); + } + outs(ANSI_RESET"\n"); + } else + outs(buf); + } + } + if (lineno + i >= lines) + showall = 1; + + // print prompt bar + snprintf(buf, sizeof(buf), + " ÂsÄý P.%d ", 1 + (lineno / (t_lines-2))); + vs_footer(buf, + " (¡÷¡õ[PgUp][PgDn][Home][End])´å¼Ð²¾°Ê\t(¡ö/q)µ²§ô"); + } + // process key + switch(vkey()) { + case KEY_UP: case 'j': case Ctrl('P'): + if (lineno == 0) abort = READ_PREV; + lineno--; + break; + + case KEY_PGUP: case Ctrl('B'): + if (lineno == 0) abort = READ_PREV; + lineno -= t_lines-2; + break; + + case KEY_PGDN: case Ctrl('F'): case ' ': + case KEY_RIGHT: + if (showall) return READ_NEXT; + lineno += t_lines-2; + break; + + case KEY_DOWN: case 'k': case Ctrl('N'): + if (showall) return READ_NEXT; + lineno++; + break; + case KEY_HOME: case Ctrl('A'): + lineno = 0; + break; + case KEY_END: case Ctrl('E'): + lineno = lines - (t_lines-1); + break; + case KEY_LEFT: case 'q': + abort = -1; + break; + } + if (lineno + (t_lines-1) >= lines) + lineno = lines-(t_lines-1); + if (lineno < 0) + lineno = 0; + } + fclose(fp); + return abort > 0 ? abort : 0; +} + +#endif // !USE_PMORE |