[Pinfo-devel] r246 - pinfo/branches/cxx/src
Nathanael Nerode
neroden-guest at costa.debian.org
Mon Sep 26 03:42:09 UTC 2005
Author: neroden-guest
Date: 2005-09-26 03:42:08 +0000 (Mon, 26 Sep 2005)
New Revision: 246
Modified:
pinfo/branches/cxx/src/filehandling_functions.cxx
pinfo/branches/cxx/src/filehandling_functions.h
pinfo/branches/cxx/src/manual.cxx
pinfo/branches/cxx/src/printinfo.cxx
pinfo/branches/cxx/src/printinfo.h
pinfo/branches/cxx/src/video.cxx
pinfo/branches/cxx/src/video.h
Log:
Make various routines pass const X & instead of X.
Make most of the functions in manual.cxx static, and topo-sort them
to eliminate forward declarations.
Modified: pinfo/branches/cxx/src/filehandling_functions.cxx
===================================================================
--- pinfo/branches/cxx/src/filehandling_functions.cxx 2005-09-26 03:25:33 UTC (rev 245)
+++ pinfo/branches/cxx/src/filehandling_functions.cxx 2005-09-26 03:42:08 UTC (rev 246)
@@ -358,7 +358,7 @@
}
void
-load_indirect(vector<string> message)
+load_indirect(const vector<string> & message)
{
for (typeof(message.size()) i = 0; i < message.size(); i++) {
/* Find the first colon, but not in position 0 */
@@ -376,7 +376,7 @@
}
void
-load_tag_table(vector<string> message)
+load_tag_table(const vector<string> & message)
{
tag_table.clear();
Modified: pinfo/branches/cxx/src/filehandling_functions.h
===================================================================
--- pinfo/branches/cxx/src/filehandling_functions.h 2005-09-26 03:25:33 UTC (rev 245)
+++ pinfo/branches/cxx/src/filehandling_functions.h 2005-09-26 03:42:08 UTC (rev 246)
@@ -52,9 +52,9 @@
* loads indirect table (from a special node, stored in message, of lines
* length)
*/
-void load_indirect (std::vector<std::string> message);
+void load_indirect (const std::vector<std::string>& message);
/* loads tag table (as above) */
-void load_tag_table (std::vector<std::string> message);
+void load_tag_table (const std::vector<std::string>& message);
/* opens info file */
FILE *openinfo (const std::string filename, int number);
/* opens dir info file */
Modified: pinfo/branches/cxx/src/manual.cxx
===================================================================
--- pinfo/branches/cxx/src/manual.cxx 2005-09-26 03:25:33 UTC (rev 245)
+++ pinfo/branches/cxx/src/manual.cxx 2005-09-26 03:42:08 UTC (rev 246)
@@ -39,31 +39,6 @@
#define FTPSECTION 101
#define MAILSECTION 102
-/* check if a char is a hyphen character */
-int ishyphen(unsigned char ch);
-/* load manual */
-void loadmanual(FILE * id);
-/* handle keyboard */
-int manualwork();
-void rescan_selected(); /* scan for potential link to select on
- viewed manual page */
-/* self explanatory */
-void showmanualscreen();
-/* mvaddstr with bold/italic */
-void mvaddstr_manual(int y, int x, string str);
-/* adds highlights to a painted screen */
-void add_highlights();
-/* strips line of formatting characters */
-void strip_manual(string& buf);
-/*
- * Initialize links in a line . Links are entries of form reference(section),
- * and are stored in `manuallinks' var, described bellow.
- */
-void man_initializelinks(string line, int line_num, int carry);
-bool is_in_manlinks(vector<string> in, string find);
-
-void printmanual(vector<string> message);
-
/* line by line stored manual */
vector<string> manual;
@@ -125,8 +100,19 @@
* $MANWIDTH was changed by pinfo */
static bool manwidthChanged = false;
+/*** START OF FUNCTIONS ***/
+
+/* check if a char is a hyphen character */
+static int
+ishyphen(unsigned char ch)
+{
+ if ((ch == '-') ||(ch == SOFT_HYPHEN))
+ return 1;
+ return 0;
+}
+
/* Set MANWIDTH environment variable as needed */
-void
+static void
check_manwidth(void) {
if ((!getenv("MANWIDTH")) ||(manwidthChanged))
{
@@ -148,24 +134,57 @@
}
}
+/* Cleanse a line of backspaces; overwrites argument. */
+/* Should probably be rewritten to not overwrite argument. */
+static void
+strip_manual(string& buf)
+{
+ /* in general, tmp buffer will hold a line with highlight marks stripped */
+ /* Overwrite as we go. Length will change as we go, too. */
+ for (string::size_type i = 0; i < buf.length(); i++)
+ {
+ /* strip from the line "'_',0x8" -- underline marks */
+ if ((buf[i] == '_') && (buf[i + 1] == 8))
+ buf.erase(i, 2);
+ /* and 0x8 -- overstrike marks */
+ else if ((buf[i + 1] == 8) &&(buf[i + 2] == buf[i]))
+ buf.erase(i, 2);
+ /* else we don't do anything */
+ }
+}
-/* free buffers allocated by current man page */
-void
-manual_free_buffers()
+/*
+ * checks if a construction, which looks like hyperlink, belongs to the allowed
+ * manual sections.
+ */
+static bool
+is_in_manlinks(vector<string> manlinks, string to_find)
{
- /* first free previously allocated memory */
- /* for the manual itself... */
- manual.clear();
- /* ...and for the list of manual hypertext */
- if (manuallinks.size() > 0)
+ /* Normalize case */
+ string to_find_uppercase = string_toupper(to_find);
+ typeof(manlinks.begin()) result_iter;
+ result_iter = std::find(manlinks.begin(), manlinks.end(), to_find_uppercase);
+ return (result_iter != manlinks.end()); /* True if found */
+}
+
+/* scan for some hyperlink, available on current screen */
+static void
+rescan_selected()
+{
+ for (typeof(manuallinks.size()) i = 0; i < manuallinks.size(); i++)
{
- manuallinks.clear();
- selected = -1;
+ if ((manuallinks[i].line >= manualpos) &&
+ (manuallinks[i].line < manualpos +(maxy - 1)))
+ {
+ selected = i;
+ break;
+ }
}
}
+
/* initialize history variables for manual pages. */
-void
+static void
set_initial_history(string name)
{
/* filter trailing spaces */
@@ -195,7 +214,7 @@
}
/* construct man name; take care about carry */
-void
+static void
construct_manualname(string& buf, int which)
{
if (!manuallinks[which].carry) {
@@ -254,246 +273,14 @@
}
}
-/* this is something like main() function for the manual viewer code. */
-int
-handlemanual(string name)
-{
- int return_value;
- struct stat statbuf;
- FILE *id;
-
- string manualname_string; /* Filled by construct_manualname */
-
- if (tmpfilename1 != "")
- {
- unlink(tmpfilename1.c_str());
- }
-
- init_curses();
- getmaxyx(stdscr, maxy, maxx);
- myendwin();
-
- check_manwidth();
-
- if (!plain_apropos) {
- string cmd_string = "man ";
- cmd_string += ManOptions;
- cmd_string += " ";
- cmd_string += name;
- cmd_string += " ";
- cmd_string += StderrRedirection;
- cmd_string += " > ";
- cmd_string += tmpfilename1;
-
- int cmd_result;
- cmd_result = system(cmd_string.c_str());
- if (cmd_result != 0) {
- unlink(tmpfilename1.c_str());
- printf(_("Error: No manual page found\n"));
- plain_apropos = 1; /* Fallback */
- } else {
- id = fopen(tmpfilename1.c_str(), "r");
- }
- }
- if (plain_apropos) {
- plain_apropos = 0;
- if (!use_apropos) {
- return 1;
- }
- printf(_("Calling apropos \n"));
- apropos_tmpfilename = tmpdirname;
- apropos_tmpfilename += "/apropos_result";
- string cmd_string = "apropos ";
- cmd_string += name;
- cmd_string += " > ";
- cmd_string += apropos_tmpfilename;
- if (system(cmd_string.c_str()) != 0) {
- printf(_("Nothing appropriate\n"));
- unlink(apropos_tmpfilename.c_str());
- return 1;
- } else {
- id = fopen(apropos_tmpfilename.c_str(), "r");
- }
- }
-
- init_curses();
-
- set_initial_history(name);
- /* load manual to memory */
- loadmanual(id);
- fclose(id);
- do {
- /* manualwork handles all actions when viewing man page */
- return_value = manualwork();
- /* Return value may specify link to follow */
-
- getmaxyx(stdscr, maxy, maxx);
- check_manwidth();
-
- /* Changing page, so clear regexp */
- regex_is_current = false;
-
- /* -1 is quit key */
- if (return_value != -1)
- {
- if (tmpfilename2 != "")
- {
- unlink(tmpfilename2.c_str());
- }
-
- bool historical = false;
- string cmd_string = "man ";
- cmd_string += ManOptions;
- cmd_string += " ";
- if (return_value == -2) {
- /* key_back was pressed */
- if ( (manualhistory.size() - 2) == 0 && apropos_tmpfilename != "")
- {
- id = fopen(apropos_tmpfilename.c_str(), "r");
- loadmanual(id);
- fclose(id);
- continue;
- }
- if (manualhistory[manualhistory.size() - 2].sect == "") {
- cmd_string += manualhistory[manualhistory.size() - 2].name;
- } else {
- cmd_string += manualhistory[manualhistory.size() - 2].sect;
- cmd_string += " ";
- cmd_string += manualhistory[manualhistory.size() - 2].name;
- }
- manualhistory.pop_back();
- historical = true;
- } else {
- /*
- * key_back was not pressed; and return_value is an offset to
- * manuallinks
- */
- construct_manualname(manualname_string, return_value);
- cmd_string += manuallinks[return_value].section;
- cmd_string += " ";
- cmd_string += manualname_string;
- }
- cmd_string += " ";
- cmd_string += StderrRedirection;
- cmd_string += " > ";
- cmd_string += tmpfilename2;
- system(cmd_string.c_str());
- stat(tmpfilename2.c_str(), &statbuf);
- if (statbuf.st_size > 0) {
- string cmd_string2 = "mv ";
- cmd_string2 += tmpfilename2;
- cmd_string2 += " ";
- cmd_string2 += tmpfilename1;
- /* create tmp file containing man page */
- system(cmd_string2.c_str());
- /* open man page */
- id = fopen(tmpfilename1.c_str(), "r");
- if (id != NULL) {
- manhistory my_hist;
- /* now we create history entry for new page */
- if (!historical)
- {
- /*
- * we can write so since this code applies
- * only when it's not a history call
- */
- my_hist.name = manualname_string;
- my_hist.sect = manuallinks[return_value].section;
- my_hist.pos = 0;
- my_hist.selected = -1;
- manualhistory.push_back(my_hist);
- }
- /* loading manual page and its defaults... */
- loadmanual(id);
- fclose(id);
- } else {
- return_value = -1;
- }
- }
- }
- } while (return_value != -1);
- if (apropos_tmpfilename != "")
- unlink(apropos_tmpfilename.c_str());
- /* raw-manpage for scanning */
- return 0;
-}
-
-void
-/* loads manual from given filedescriptor */
-loadmanual(FILE * id)
-{
- char prevlinechar = 0;
- /* tmp variable, set after reading first nonempty line of input */
- int cutheader = 0;
- int carryflag = 0;
- manualpos = 0;
- manual_free_buffers();
- manual.clear();
- manuallinks.clear();
-
- /* fixed-size buffer, FIXME */
- char tmpline[1024];
-
- /* we read until eof */
- while (!feof(id)) {
- memset(tmpline, '\0', 1024);
- /*
- * it happens sometimes, that the last line is weird
- * and causes sigsegvs by not entering anything to buffer, what
- * confuses strlen
- */
- if (fgets(tmpline, 1024, id) == NULL) {
- strcpy(tmpline, "");
- }
- if (cutheader) {
- if (manual[cutheader] == tmpline) {
- strcpy(tmpline, "\n");
- }
- }
- if (FilterB7) {
- char *filter_pos = index(tmpline, 0xb7);
- if (filter_pos)
- *filter_pos = 'o';
- }
- if ((CutEmptyManLines) &&((tmpline[0]) == '\n') &&
- (prevlinechar == '\n')) {
- ; /* do nothing */
- } else {
- if (CutManHeaders && !cutheader) {
- cutheader = manual.size();
- }
- int manlinelen = strlen(tmpline);
-
- carryflag = 0;
- if ( (manlinelen >= 2)
- && (ishyphen(tmpline[manlinelen - 2]))
- ) {
- carryflag = 1;
- }
- prevlinechar = tmpline[0];
-
- /* temporary variable for determining hypertextuality of fields */
- string tmpstr;
- tmpstr = tmpline;
- strip_manual(tmpstr);
- int line_num = manual.size();
- /* Above depends on link initializing happening right before push_back. */
- man_initializelinks(tmpstr, line_num, carryflag);
-
- string tmpline_str = tmpline;
- manual.push_back(tmpline_str);
- }
- }
-}
-
-bool
+static bool
compare_manuallink(manuallink a, manuallink b)
{
/* Should a sort before b? */
return (a.col < b.col);
}
-void
+static void
sort_manuallinks_from_current_line(
typeof(manuallinks.begin()) startlink,
typeof(manuallinks.begin()) endlink)
@@ -502,7 +289,7 @@
}
/* initializes hyperlinks in manual */
-void
+static void
man_initializelinks(string line, int line_num, int carry)
{
typeof(manuallinks.size()) initialManualLinks = manuallinks.size();
@@ -684,8 +471,386 @@
}
}
+/* loads manual from given filedescriptor */
+static void
+loadmanual(FILE * id)
+{
+ char prevlinechar = 0;
+ /* tmp variable, set after reading first nonempty line of input */
+ int cutheader = 0;
+ int carryflag = 0;
+ manualpos = 0;
+ selected = -1;
+ manual.clear();
+ manuallinks.clear();
+
+ /* fixed-size buffer, FIXME */
+ char tmpline[1024];
+
+ /* we read until eof */
+ while (!feof(id)) {
+ memset(tmpline, '\0', 1024);
+ /*
+ * it happens sometimes, that the last line is weird
+ * and causes sigsegvs by not entering anything to buffer, what
+ * confuses strlen
+ */
+ if (fgets(tmpline, 1024, id) == NULL) {
+ strcpy(tmpline, "");
+ }
+ if (cutheader) {
+ if (manual[cutheader] == tmpline) {
+ strcpy(tmpline, "\n");
+ }
+ }
+ if (FilterB7) {
+ char *filter_pos = index(tmpline, 0xb7);
+ if (filter_pos)
+ *filter_pos = 'o';
+ }
+ if ((CutEmptyManLines) &&((tmpline[0]) == '\n') &&
+ (prevlinechar == '\n')) {
+ ; /* do nothing */
+ } else {
+ if (CutManHeaders && !cutheader) {
+ cutheader = manual.size();
+ }
+ int manlinelen = strlen(tmpline);
+
+ carryflag = 0;
+ if ( (manlinelen >= 2)
+ && (ishyphen(tmpline[manlinelen - 2]))
+ ) {
+ carryflag = 1;
+ }
+ prevlinechar = tmpline[0];
+
+ /* temporary variable for determining hypertextuality of fields */
+ string tmpstr;
+ tmpstr = tmpline;
+ strip_manual(tmpstr);
+ int line_num = manual.size();
+ /* Above depends on link initializing happening right before push_back. */
+ man_initializelinks(tmpstr, line_num, carryflag);
+
+ string tmpline_str = tmpline;
+ manual.push_back(tmpline_str);
+ }
+ }
+}
+
+static void
+printmanual(vector<string> message)
+{
+ /* printer fd */
+ FILE *prnFD;
+ int i;
+
+ prnFD = popen(printutility.c_str(), "w");
+
+ /* scan through all lines */
+ for (i = 0; i < message.size(); i++)
+ {
+ fprintf(prnFD, "\r%s", message[i].c_str());
+ }
+ pclose(prnFD);
+}
+
+/* add hyperobject highlights */
+static void
+add_highlights()
+{
+ /* scan through the visible objects */
+ for (typeof(manuallinks.size()) i = 0; i < manuallinks.size(); i++)
+ {
+ /* if the object is on the current screen */
+ if ((manuallinks[i].line >= manualpos) &&
+ (manuallinks[i].line < manualpos +(lines_visible)))
+ {
+ /* if it's a simple man link */
+ if (manuallinks[i].section_mark < HTTPSECTION)
+ {
+ if (i == selected)
+ attrset(noteselected);
+ else
+ attrset(note);
+
+ /* if it's a link split into two lines */
+ if (manuallinks[i].carry == 1) {
+ int x, y;
+ getyx(stdscr, y, x);
+
+ int ltline = manuallinks[i].line - 1;
+ string tmp_string = manual[ltline];
+
+ strip_manual(tmp_string);
+
+ string::size_type link_begin = tmp_string.length();
+ if (y > 2) {
+ /* skip \n, -, and at least one more character */
+ if (link_begin > 2) {
+ link_begin -= 3;
+ }
+
+ /*
+ * positon link_begin to the beginning of the link to be
+ * highlighted
+ */
+ while ( isalpha(tmp_string[link_begin])
+ || (tmp_string[link_begin] == '.')
+ || (tmp_string[link_begin] == '_')
+ ) {
+ link_begin--;
+ }
+
+ /* Chop off \n */
+ tmp_string.resize(tmp_string.length() - 1);
+ /* Chop off pre-link portion */
+ tmp_string = tmp_string.substr(link_begin);
+
+ if (link_begin > manualcol) {
+ /* OK, link horizontally fits into screen */
+ mvaddstr(manuallinks[i].line - manualpos + 1 - 1,
+ link_begin-manualcol, tmp_string.c_str());
+ } else if (link_begin + tmp_string.length() > manualcol) {
+ /*
+ * we cut here a part of the link, and draw only what's
+ * visible on screen
+ */
+ mvaddstr(manuallinks[i].line - manualpos + 1 - 1,
+ link_begin-manualcol, tmp_string.c_str());
+ }
+ }
+ move(y, x);
+ }
+ }
+ else
+ {
+ if (i == selected)
+ attrset(urlselected);
+ else
+ attrset(url);
+ if (manuallinks[i].carry == 1)
+ {
+ int ltline = manuallinks[i].line + 1;
+ /*
+ * the split part to find is lying down
+ * to the line defined in manlinks(line+1)
+ */
+ string tmp_string = manual[ltline];
+ strip_manual(tmp_string);
+ /* skip spaces */
+ string::size_type wsk_idx = 0;
+ while (isspace(tmp_string[wsk_idx]))
+ wsk_idx++;
+
+ /* find the end of url */
+ string::size_type wskend_idx = findurlend(tmp_string, wsk_idx);
+ string printable_str = tmp_string.substr(wsk_idx, wskend_idx - wsk_idx);
+
+ /* Print */
+ if (wsk_idx < manualcol) {
+ mvaddstr(manuallinks[i].line - manualpos + 2, wsk_idx - manualcol,
+ printable_str.c_str());
+ } else if (wskend_idx < manualcol) {
+ mvaddstr(manuallinks[i].line - manualpos + 2, 0,
+ printable_str.substr(manualcol).c_str());
+ }
+ }
+ }
+ if (manuallinks[i].col>manualcol)
+ mvaddstr(1 + manuallinks[i].line - manualpos,
+ manuallinks[i].col - manualcol, manuallinks[i].name.c_str());
+ else if (manuallinks[i].col+manuallinks[i].name.length()>manualcol)
+ mvaddstr(1 + manuallinks[i].line - manualpos, 0,
+ manuallinks[i].name.substr(manualcol-manuallinks[i].col).c_str());
+ attrset(normal);
+ }
+ }
+}
+
+/*
+ * calculate from which to start displaying of manual line *man. Skip `mancol'
+ * columns. But remember, that *man contains also nonprinteble characters for
+ * boldface etc.
+ */
+static const char*
+getmancolumn(const char* man, int mancol)
+{
+ if (mancol==0) return man;
+ while (mancol>0)
+ { if (*(man+1) == 8) man+=3; else man++; mancol--; }
+ return man;
+}
+
+/* print a manual line */
+static void
+mvaddstr_manual(int y, int x, string my_str)
+{
+ static string strippedline_string;
+ if ((h_regexp.size() > 0) || regex_is_current) {
+ strippedline_string = my_str;
+ strip_manual(strippedline_string);
+ }
+
+ move(y, x);
+ for (int i = 0; i < my_str.length(); i++) {
+ if ((i > 0) &&(i < my_str.length() - 1))
+ {
+ /* handle bold highlight */
+ if ((my_str[i] == 8) &&(my_str[i - 1] == '_'))
+ {
+ attrset(manualbold);
+ addch(my_str[i] & 0xff);
+ addch(my_str[i + 1] & 0xff);
+ attrset(normal);
+ i++;
+ goto label_skip_other;
+ }
+ /*
+ * if it wasn't bold, check italic, before default, unhighlighted
+ * line will be painted. We can do it only if i<my_str.length()-3.
+ */
+ else if (i < my_str.length() - 3)
+ goto label_check_italic;
+ else /* unhighlighted */
+ {
+ addch(my_str[i] & 0xff);
+ goto label_skip_other;
+ }
+ }
+ /* italic highlight */
+ if (i < my_str.length() - 3)
+ {
+label_check_italic:
+ if ((my_str[i + 1] == 8) &&(my_str[i + 2] == my_str[i]))
+ {
+ attrset(manualitalic);
+ addch(my_str[i] & 0xff);
+ i += 2;
+ attrset(normal);
+ }
+ else
+ {
+ addch(my_str[i] & 0xff);
+ }
+ }
+label_skip_other:;
+ }
+#ifdef HAVE_BKGDSET
+ bkgdset(' ' | normal);
+ clrtoeol();
+ bkgdset(0);
+#else
+ myclrtoeol();
+#endif
+ attrset(normal);
+#ifndef ___DONT_USE_REGEXP_SEARCH___
+ if (h_regexp.size() > 0) {
+ regmatch_t pmatch[1];
+
+ /* if it is after search, then we have user defined regexps+
+ a searched regexp to highlight */
+ for (int j = 0; j < h_regexp.size(); j++) {
+ const char* strippedline = strippedline_string.c_str();
+ const char* tmpstr = strippedline;
+ while (!regexec(&h_regexp[j], tmpstr, 1, pmatch, 0)) {
+ int n = pmatch[0].rm_eo - pmatch[0].rm_so;
+ int rx = pmatch[0].rm_so + tmpstr - strippedline;
+ int curY, curX;
+ getyx(stdscr, curY, curX);
+
+ attrset(searchhighlight);
+ string str_to_print;
+ str_to_print.assign(strippedline_string, rx, n);
+ mvaddstr(y, rx, str_to_print.c_str());
+ attrset(normal);
+
+ tmpstr = tmpstr + pmatch[0].rm_eo;
+ move(curY, curX);
+ }
+ }
+ }
+ /* Duplicate code, this time for the interactive search */
+ if (regex_is_current) {
+ regmatch_t pmatch[1];
+ const char* strippedline = strippedline_string.c_str();
+ const char* tmpstr = strippedline;
+ while (!regexec(¤t_regex, tmpstr, 1, pmatch, 0)) {
+ int n = pmatch[0].rm_eo - pmatch[0].rm_so;
+ int rx = pmatch[0].rm_so + tmpstr - strippedline;
+ int curY, curX;
+ getyx(stdscr, curY, curX);
+
+ attrset(searchhighlight);
+ string str_to_print;
+ str_to_print.assign(strippedline_string, rx, n);
+ mvaddstr(y, rx, str_to_print.c_str());
+ attrset(normal);
+
+ tmpstr = tmpstr + pmatch[0].rm_eo;
+ move(curY, curX);
+ }
+ }
+#endif
+}
+
+/* show the currently visible part of manpage */
+static void
+showmanualscreen()
+{
+#ifdef getmaxyx
+ /* refresh maxy, maxx values */
+ getmaxyx(stdscr, maxy, maxx);
+#endif
+ attrset(normal);
+ /* print all visible text lines */
+ for (int i = manualpos;
+ (i < manualpos + (lines_visible)) && (i < manual.size());
+ i++) {
+ int len = manual[i].length();
+ if (len)
+ manual[i][len - 1] = ' ';
+ /* if we have something to display */
+ if (len>manualcol) {
+ string yet_another_tmpstr = getmancolumn(manual[i].c_str(),manualcol);
+ mvaddstr_manual((i - manualpos) + 1, 0, yet_another_tmpstr);
+ }
+ else /* otherwise, just clear the line to eol */
+ {
+ move((i - manualpos) + 1, 0);
+ bkgdset(' ' | normal);
+ clrtoeol();
+ }
+ if (len)
+ manual[i][len - 1] = '\n';
+ }
+#ifdef HAVE_BKGDSET
+ bkgdset(' ' | normal);
+#endif
+ /* and clear to bottom */
+ clrtobot();
+#ifdef HAVE_BKGDSET
+ bkgdset(0);
+#endif
+ attrset(normal);
+ /* add highlights */
+ add_highlights();
+ /* draw bottomline with user informations */
+ attrset(bottomline);
+ mymvhline(0, 0, ' ', maxx);
+ mymvhline(maxy - 1, 0, ' ', maxx);
+ move(maxy - 1, 0);
+ if (((manualpos + maxy) < manual.size()) &&(manual.size() > lines_visible))
+ printw(_("Viewing line %d/%d, %d%%"),(manualpos - 1 + maxy), manual.size(),((manualpos - 1 + maxy) * 100) / manual.size());
+ else
+ printw(_("Viewing line %d/%d, 100%%"), manual.size(), manual.size());
+ move(maxy - 1, 0);
+ attrset(normal);
+}
+
/* viewer function. Handles keyboard actions--main event loop */
-int
+static int
manualwork()
{
/* for user's shell commands */
@@ -1316,367 +1481,168 @@
return -1;
}
-void
-/* scan for some hyperlink, available on current screen */
-rescan_selected()
+/* this is something like main() function for the manual viewer code. */
+int
+handlemanual(string name)
{
- for (typeof(manuallinks.size()) i = 0; i < manuallinks.size(); i++)
+ int return_value;
+ struct stat statbuf;
+ FILE *id;
+
+ string manualname_string; /* Filled by construct_manualname */
+
+ if (tmpfilename1 != "")
{
- if ((manuallinks[i].line >= manualpos) &&
- (manuallinks[i].line < manualpos +(maxy - 1)))
- {
- selected = i;
- break;
- }
+ unlink(tmpfilename1.c_str());
}
-}
-/*
- * calculate from which to start displaying of manual line *man. Skip `mancol'
- * columns. But remember, that *man contains also nonprinteble characters for
- * boldface etc.
- */
-const char* getmancolumn(const char* man, int mancol)
-{
- if (mancol==0) return man;
- while (mancol>0)
- { if (*(man+1) == 8) man+=3; else man++; mancol--; }
- return man;
-}
-
-/* show the currently visible part of manpage */
-void
-showmanualscreen()
-{
-#ifdef getmaxyx
- /* refresh maxy, maxx values */
+ init_curses();
getmaxyx(stdscr, maxy, maxx);
-#endif
- attrset(normal);
- /* print all visible text lines */
- for (int i = manualpos;
- (i < manualpos + (lines_visible)) && (i < manual.size());
- i++) {
- int len = manual[i].length();
- if (len)
- manual[i][len - 1] = ' ';
- /* if we have something to display */
- if (len>manualcol) {
- string yet_another_tmpstr = getmancolumn(manual[i].c_str(),manualcol);
- mvaddstr_manual((i - manualpos) + 1, 0, yet_another_tmpstr);
- }
- else /* otherwise, just clear the line to eol */
- {
- move((i - manualpos) + 1, 0);
- bkgdset(' ' | normal);
- clrtoeol();
- }
- if (len)
- manual[i][len - 1] = '\n';
- }
-#ifdef HAVE_BKGDSET
- bkgdset(' ' | normal);
-#endif
- /* and clear to bottom */
- clrtobot();
-#ifdef HAVE_BKGDSET
- bkgdset(0);
-#endif
- attrset(normal);
- /* add highlights */
- add_highlights();
- /* draw bottomline with user informations */
- attrset(bottomline);
- mymvhline(0, 0, ' ', maxx);
- mymvhline(maxy - 1, 0, ' ', maxx);
- move(maxy - 1, 0);
- if (((manualpos + maxy) < manual.size()) &&(manual.size() > lines_visible))
- printw(_("Viewing line %d/%d, %d%%"),(manualpos - 1 + maxy), manual.size(),((manualpos - 1 + maxy) * 100) / manual.size());
- else
- printw(_("Viewing line %d/%d, 100%%"), manual.size(), manual.size());
- move(maxy - 1, 0);
- attrset(normal);
-}
+ myendwin();
-void
-/* print a manual line */
-mvaddstr_manual(int y, int x, string my_str)
-{
- static string strippedline_string;
- if ((h_regexp.size() > 0) || regex_is_current) {
- strippedline_string = my_str;
- strip_manual(strippedline_string);
- }
+ check_manwidth();
- move(y, x);
- for (int i = 0; i < my_str.length(); i++) {
- if ((i > 0) &&(i < my_str.length() - 1))
- {
- /* handle bold highlight */
- if ((my_str[i] == 8) &&(my_str[i - 1] == '_'))
- {
- attrset(manualbold);
- addch(my_str[i] & 0xff);
- addch(my_str[i + 1] & 0xff);
- attrset(normal);
- i++;
- goto label_skip_other;
- }
- /*
- * if it wasn't bold, check italic, before default, unhighlighted
- * line will be painted. We can do it only if i<my_str.length()-3.
- */
- else if (i < my_str.length() - 3)
- goto label_check_italic;
- else /* unhighlighted */
- {
- addch(my_str[i] & 0xff);
- goto label_skip_other;
- }
+ if (!plain_apropos) {
+ string cmd_string = "man ";
+ cmd_string += ManOptions;
+ cmd_string += " ";
+ cmd_string += name;
+ cmd_string += " ";
+ cmd_string += StderrRedirection;
+ cmd_string += " > ";
+ cmd_string += tmpfilename1;
+
+ int cmd_result;
+ cmd_result = system(cmd_string.c_str());
+ if (cmd_result != 0) {
+ unlink(tmpfilename1.c_str());
+ printf(_("Error: No manual page found\n"));
+ plain_apropos = 1; /* Fallback */
+ } else {
+ id = fopen(tmpfilename1.c_str(), "r");
}
- /* italic highlight */
- if (i < my_str.length() - 3)
- {
-label_check_italic:
- if ((my_str[i + 1] == 8) &&(my_str[i + 2] == my_str[i]))
- {
- attrset(manualitalic);
- addch(my_str[i] & 0xff);
- i += 2;
- attrset(normal);
- }
- else
- {
- addch(my_str[i] & 0xff);
- }
+ }
+ if (plain_apropos) {
+ plain_apropos = 0;
+ if (!use_apropos) {
+ return 1;
}
-label_skip_other:;
+ printf(_("Calling apropos \n"));
+ apropos_tmpfilename = tmpdirname;
+ apropos_tmpfilename += "/apropos_result";
+ string cmd_string = "apropos ";
+ cmd_string += name;
+ cmd_string += " > ";
+ cmd_string += apropos_tmpfilename;
+ if (system(cmd_string.c_str()) != 0) {
+ printf(_("Nothing appropriate\n"));
+ unlink(apropos_tmpfilename.c_str());
+ return 1;
+ } else {
+ id = fopen(apropos_tmpfilename.c_str(), "r");
+ }
}
-#ifdef HAVE_BKGDSET
- bkgdset(' ' | normal);
- clrtoeol();
- bkgdset(0);
-#else
- myclrtoeol();
-#endif
- attrset(normal);
-#ifndef ___DONT_USE_REGEXP_SEARCH___
- if (h_regexp.size() > 0) {
- regmatch_t pmatch[1];
- /* if it is after search, then we have user defined regexps+
- a searched regexp to highlight */
- for (int j = 0; j < h_regexp.size(); j++) {
- const char* strippedline = strippedline_string.c_str();
- const char* tmpstr = strippedline;
- while (!regexec(&h_regexp[j], tmpstr, 1, pmatch, 0)) {
- int n = pmatch[0].rm_eo - pmatch[0].rm_so;
- int rx = pmatch[0].rm_so + tmpstr - strippedline;
- int curY, curX;
- getyx(stdscr, curY, curX);
+ init_curses();
- attrset(searchhighlight);
- string str_to_print;
- str_to_print.assign(strippedline_string, rx, n);
- mvaddstr(y, rx, str_to_print.c_str());
- attrset(normal);
+ set_initial_history(name);
+ /* load manual to memory */
+ loadmanual(id);
+ fclose(id);
+ do {
+ /* manualwork handles all actions when viewing man page */
+ return_value = manualwork();
+ /* Return value may specify link to follow */
- tmpstr = tmpstr + pmatch[0].rm_eo;
- move(curY, curX);
- }
- }
- }
- /* Duplicate code, this time for the interactive search */
- if (regex_is_current) {
- regmatch_t pmatch[1];
- const char* strippedline = strippedline_string.c_str();
- const char* tmpstr = strippedline;
- while (!regexec(¤t_regex, tmpstr, 1, pmatch, 0)) {
- int n = pmatch[0].rm_eo - pmatch[0].rm_so;
- int rx = pmatch[0].rm_so + tmpstr - strippedline;
- int curY, curX;
- getyx(stdscr, curY, curX);
+ getmaxyx(stdscr, maxy, maxx);
+ check_manwidth();
- attrset(searchhighlight);
- string str_to_print;
- str_to_print.assign(strippedline_string, rx, n);
- mvaddstr(y, rx, str_to_print.c_str());
- attrset(normal);
+ /* Changing page, so clear regexp */
+ regex_is_current = false;
- tmpstr = tmpstr + pmatch[0].rm_eo;
- move(curY, curX);
- }
- }
-#endif
-}
-
-/* add hyperobject highlights */
-void
-add_highlights()
-{
- /* scan through the visible objects */
- for (typeof(manuallinks.size()) i = 0; i < manuallinks.size(); i++)
- {
- /* if the object is on the current screen */
- if ((manuallinks[i].line >= manualpos) &&
- (manuallinks[i].line < manualpos +(lines_visible)))
+ /* -1 is quit key */
+ if (return_value != -1)
{
- /* if it's a simple man link */
- if (manuallinks[i].section_mark < HTTPSECTION)
+ if (tmpfilename2 != "")
{
- if (i == selected)
- attrset(noteselected);
- else
- attrset(note);
+ unlink(tmpfilename2.c_str());
+ }
- /* if it's a link split into two lines */
- if (manuallinks[i].carry == 1) {
- int x, y;
- getyx(stdscr, y, x);
-
- int ltline = manuallinks[i].line - 1;
- string tmp_string = manual[ltline];
-
- strip_manual(tmp_string);
-
- string::size_type link_begin = tmp_string.length();
- if (y > 2) {
- /* skip \n, -, and at least one more character */
- if (link_begin > 2) {
- link_begin -= 3;
- }
-
+ bool historical = false;
+ string cmd_string = "man ";
+ cmd_string += ManOptions;
+ cmd_string += " ";
+ if (return_value == -2) {
+ /* key_back was pressed */
+ if ( (manualhistory.size() - 2) == 0 && apropos_tmpfilename != "")
+ {
+ id = fopen(apropos_tmpfilename.c_str(), "r");
+ loadmanual(id);
+ fclose(id);
+ continue;
+ }
+ if (manualhistory[manualhistory.size() - 2].sect == "") {
+ cmd_string += manualhistory[manualhistory.size() - 2].name;
+ } else {
+ cmd_string += manualhistory[manualhistory.size() - 2].sect;
+ cmd_string += " ";
+ cmd_string += manualhistory[manualhistory.size() - 2].name;
+ }
+ manualhistory.pop_back();
+ historical = true;
+ } else {
+ /*
+ * key_back was not pressed; and return_value is an offset to
+ * manuallinks
+ */
+ construct_manualname(manualname_string, return_value);
+ cmd_string += manuallinks[return_value].section;
+ cmd_string += " ";
+ cmd_string += manualname_string;
+ }
+ cmd_string += " ";
+ cmd_string += StderrRedirection;
+ cmd_string += " > ";
+ cmd_string += tmpfilename2;
+ system(cmd_string.c_str());
+ stat(tmpfilename2.c_str(), &statbuf);
+ if (statbuf.st_size > 0) {
+ string cmd_string2 = "mv ";
+ cmd_string2 += tmpfilename2;
+ cmd_string2 += " ";
+ cmd_string2 += tmpfilename1;
+ /* create tmp file containing man page */
+ system(cmd_string2.c_str());
+ /* open man page */
+ id = fopen(tmpfilename1.c_str(), "r");
+ if (id != NULL) {
+ manhistory my_hist;
+ /* now we create history entry for new page */
+ if (!historical)
+ {
/*
- * positon link_begin to the beginning of the link to be
- * highlighted
+ * we can write so since this code applies
+ * only when it's not a history call
*/
- while ( isalpha(tmp_string[link_begin])
- || (tmp_string[link_begin] == '.')
- || (tmp_string[link_begin] == '_')
- ) {
- link_begin--;
- }
-
- /* Chop off \n */
- tmp_string.resize(tmp_string.length() - 1);
- /* Chop off pre-link portion */
- tmp_string = tmp_string.substr(link_begin);
-
- if (link_begin > manualcol) {
- /* OK, link horizontally fits into screen */
- mvaddstr(manuallinks[i].line - manualpos + 1 - 1,
- link_begin-manualcol, tmp_string.c_str());
- } else if (link_begin + tmp_string.length() > manualcol) {
- /*
- * we cut here a part of the link, and draw only what's
- * visible on screen
- */
- mvaddstr(manuallinks[i].line - manualpos + 1 - 1,
- link_begin-manualcol, tmp_string.c_str());
- }
+ my_hist.name = manualname_string;
+ my_hist.sect = manuallinks[return_value].section;
+ my_hist.pos = 0;
+ my_hist.selected = -1;
+ manualhistory.push_back(my_hist);
}
- move(y, x);
+ /* loading manual page and its defaults... */
+ loadmanual(id);
+ fclose(id);
+ } else {
+ return_value = -1;
}
}
- else
- {
- if (i == selected)
- attrset(urlselected);
- else
- attrset(url);
- if (manuallinks[i].carry == 1)
- {
- int ltline = manuallinks[i].line + 1;
- /*
- * the split part to find is lying down
- * to the line defined in manlinks(line+1)
- */
- string tmp_string = manual[ltline];
- strip_manual(tmp_string);
- /* skip spaces */
- string::size_type wsk_idx = 0;
- while (isspace(tmp_string[wsk_idx]))
- wsk_idx++;
-
- /* find the end of url */
- string::size_type wskend_idx = findurlend(tmp_string, wsk_idx);
- string printable_str = tmp_string.substr(wsk_idx, wskend_idx - wsk_idx);
-
- /* Print */
- if (wsk_idx < manualcol) {
- mvaddstr(manuallinks[i].line - manualpos + 2, wsk_idx - manualcol,
- printable_str.c_str());
- } else if (wskend_idx < manualcol) {
- mvaddstr(manuallinks[i].line - manualpos + 2, 0,
- printable_str.substr(manualcol).c_str());
- }
- }
- }
- if (manuallinks[i].col>manualcol)
- mvaddstr(1 + manuallinks[i].line - manualpos,
- manuallinks[i].col - manualcol, manuallinks[i].name.c_str());
- else if (manuallinks[i].col+manuallinks[i].name.length()>manualcol)
- mvaddstr(1 + manuallinks[i].line - manualpos, 0,
- manuallinks[i].name.substr(manualcol-manuallinks[i].col).c_str());
- attrset(normal);
}
- }
+ } while (return_value != -1);
+ if (apropos_tmpfilename != "")
+ unlink(apropos_tmpfilename.c_str());
+ /* raw-manpage for scanning */
+ return 0;
}
-/* Cleanse a line of backspaces; overwrites argument. */
-/* Should probably be rewritten to not overwrite argument. */
-void
-strip_manual(string& buf)
-{
- /* in general, tmp buffer will hold a line with highlight marks stripped */
- /* Overwrite as we go. Length will change as we go, too. */
- for (string::size_type i = 0; i < buf.length(); i++)
- {
- /* strip from the line "'_',0x8" -- underline marks */
- if ((buf[i] == '_') && (buf[i + 1] == 8))
- buf.erase(i, 2);
- /* and 0x8 -- overstrike marks */
- else if ((buf[i + 1] == 8) &&(buf[i + 2] == buf[i]))
- buf.erase(i, 2);
- /* else we don't do anything */
- }
-}
-/*
- * checks if a construction, which looks like hyperlink, belongs to the allowed
- * manual sections.
- */
-bool
-is_in_manlinks(vector<string> manlinks, string to_find)
-{
- /* Normalize case */
- string to_find_uppercase = string_toupper(to_find);
- typeof(manlinks.begin()) result_iter;
- result_iter = std::find(manlinks.begin(), manlinks.end(), to_find_uppercase);
- return (result_iter != manlinks.end()); /* True if found */
-}
-
-void
-printmanual(vector<string> message)
-{
- /* printer fd */
- FILE *prnFD;
- int i;
-
- prnFD = popen(printutility.c_str(), "w");
-
- /* scan through all lines */
- for (i = 0; i < message.size(); i++)
- {
- fprintf(prnFD, "\r%s", message[i].c_str());
- }
- pclose(prnFD);
-}
-
-int
-ishyphen(unsigned char ch)
-{
- if ((ch == '-') ||(ch == SOFT_HYPHEN))
- return 1;
- return 0;
-}
Modified: pinfo/branches/cxx/src/printinfo.cxx
===================================================================
--- pinfo/branches/cxx/src/printinfo.cxx 2005-09-26 03:25:33 UTC (rev 245)
+++ pinfo/branches/cxx/src/printinfo.cxx 2005-09-26 03:42:08 UTC (rev 246)
@@ -32,7 +32,7 @@
* are darker than the rest :)
*/
void
-printnode(const vector<string> message)
+printnode(const vector<string> & message)
{
/* printer fd */
FILE *prnFD;
Modified: pinfo/branches/cxx/src/printinfo.h
===================================================================
--- pinfo/branches/cxx/src/printinfo.h 2005-09-26 03:25:33 UTC (rev 245)
+++ pinfo/branches/cxx/src/printinfo.h 2005-09-26 03:42:08 UTC (rev 246)
@@ -26,6 +26,6 @@
#include <string>
#include <vector>
/* prints node, pointed by `message', of `lines' length. */
-void printnode (const std::vector<std::string> message);
+void printnode (const std::vector<std::string> & message);
#endif
Modified: pinfo/branches/cxx/src/video.cxx
===================================================================
--- pinfo/branches/cxx/src/video.cxx 2005-09-26 03:25:33 UTC (rev 245)
+++ pinfo/branches/cxx/src/video.cxx 2005-09-26 03:42:08 UTC (rev 246)
@@ -104,7 +104,8 @@
* Add all the highlights.
*/
static void
-info_add_highlights(int pos, int cursor, int column, const vector <string> message)
+info_add_highlights(int pos, int cursor, int column,
+ const vector<string> & message)
{
for (typeof(hyperobjects.size()) i = 0; i < hyperobjects.size(); i++) {
if ( (hyperobjects[i].line < pos)
@@ -213,7 +214,7 @@
* Print the entire screen.
*/
void
-showscreen(const vector <string> message, long pos, long cursor, int column)
+showscreen(const vector<string> & message, long pos, long cursor, int column)
{
#ifdef getmaxyx
getmaxyx(stdscr, maxy, maxx);
Modified: pinfo/branches/cxx/src/video.h
===================================================================
--- pinfo/branches/cxx/src/video.h 2005-09-26 03:25:33 UTC (rev 245)
+++ pinfo/branches/cxx/src/video.h 2005-09-26 03:42:08 UTC (rev 246)
@@ -25,7 +25,7 @@
#define __VIDEO_H
#include <string>
/* paints the screen while viewing info file */
-void showscreen (const std::vector<std::string> message, long pos,
+void showscreen (const std::vector<std::string>& message, long pos,
long cursor, int column);
/* prints unselected menu option */
void mvaddstr_menu (int y, int x, char *line, int linenumber);
More information about the Pinfo-devel
mailing list