[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
lynx-dev (patch) local directory output - add partial mode
From: |
Leonid Pauzner |
Subject: |
lynx-dev (patch) local directory output - add partial mode |
Date: |
Sun, 4 Apr 1999 00:14:23 +0400 (MSD) |
* Reading of long local directories now benefits from partial mode and fully
interruptable. Split out print_local_dir() function from HTLoadFile(). - LP
Comments:
1) it should not be overhead from HTDisplayPartial() in a tiny loop and
only minore overhead from HTCheckForInterrupt() - invoked once a 1/10 second.
can be more optimized by a lines counter.
2) it was found that reading of local directory consists of two phases:
while stat() loop and actual printing of sorted output, so being interrupted
at first stage we got nonobvious loss of entries - original directory
is not sorted.
3) was found a bug: CTRACE macro in HTUtils.h -
#define CTRACE if(TRACE)fprintf
may serve a bad joke when happen without { and } in a tiny if:
if()
CTRACE(...);
else
something;
diff -u -d old/htfile.c ./htfile.c
--- old/htfile.c Wed Mar 31 00:43:48 1999
+++ ./htfile.c Sat Apr 3 23:08:14 1999
@@ -516,6 +516,8 @@
}
#endif /* LY_FIND_LEAKS */
+extern void HTDisplayPartial NOARGS;
+
/* Send README file.
** -----------------
**
@@ -565,6 +567,7 @@
#endif /* NOTDEFINED */
}
END(HTML_PRE);
+ HTDisplayPartial();
fclose(fp);
}
}
@@ -1463,6 +1466,333 @@
return(need_parent_link);
}
+PRIVATE int print_local_dir ARGS5(
+ DIR *, dp,
+ char *, localname,
+ HTParentAnchor *, anchor,
+ HTFormat, format_out,
+ HTStream *, sink)
+{
+ HTStructured *target; /* HTML object */
+ HTStructuredClass targetClass;
+ STRUCT_DIRENT * dirbuf;
+ char *logical = NULL;
+ char *pathname = NULL;
+ char *tail = NULL;
+ BOOL present[HTML_A_ATTRIBUTES];
+ char * tmpfilename = NULL;
+ BOOL need_parent_link = FALSE;
+ struct stat file_info;
+ int status;
+
+ CTRACE(tfp, "print_local_dir() started\n");
+
+ logical = HTAnchor_address((HTAnchor*)anchor);
+ pathname = HTParse(logical, "",
+ PARSE_PATH + PARSE_PUNCTUATION);
+
+ if (!strcmp(pathname,"/")) {
+ /*
+ ** Root path.
+ */
+ StrAllocCopy (tail, "/foo/..");
+ } else {
+ char *p = strrchr(pathname, '/'); /* find last slash */
+
+ if (!p) {
+ /*
+ ** This probably should not happen,
+ ** but be prepared if it does. - KW
+ */
+ StrAllocCopy (tail, "/foo/..");
+ } else {
+ /*
+ ** Take slash off the beginning.
+ */
+ StrAllocCopy(tail, (p + 1));
+ }
+ }
+ FREE(pathname);
+
+ if (UCLYhndl_HTFile_for_unspec >= 0) {
+ HTAnchor_setUCInfoStage(anchor,
+ UCLYhndl_HTFile_for_unspec,
+ UCT_STAGE_PARSER,
+ UCT_SETBY_DEFAULT);
+ }
+
+ target = HTML_new(anchor, format_out, sink);
+ targetClass = *target->isa; /* Copy routine entry points */
+
+ { int i;
+ for (i = 0; i < HTML_A_ATTRIBUTES; i++)
+ present[i] = (i == HTML_A_HREF);
+ }
+
+ /*
+ ** The need_parent_link flag will be set if an
+ ** "Up to <parent>" link was not created for a
+ ** readable parent in HTDirTitles() because
+ ** LONG_LIST is defined and NO_PARENT_DIR_REFERENCE
+ ** is not defined so that need we to create the
+ ** link via an LYListFmtParse() call. - FM
+ */
+ need_parent_link = HTDirTitles(target,
+ (HTAnchor *)anchor, FALSE);
+
+#ifdef DIRED_SUPPORT
+ if (strncmp(anchor->address, "lynxcgi:", 8)) {
+ HTAnchor_setFormat((HTParentAnchor *) anchor, WWW_DIRED);
+ lynx_edit_mode = TRUE;
+ }
+#endif /* DIRED_SUPPORT */
+ if (HTDirReadme == HT_DIR_README_TOP)
+ do_readme(target, localname);
+
+
+ {
+ HTBTree * bt = HTBTree_new((HTComparer)strcmp);
+ int num_of_entries = 0; /* counter, currently not used
*/
+
+ _HTProgress (gettext("Reading directory..."));
+ status = HT_LOADED; /* assume we don't get interrupted */
+ while ((dirbuf = readdir(dp)) != NULL) {
+ /*
+ ** While there are directory entries to be read...
+ */
+ char * dirname = NULL;
+
+#ifndef DOSPATH
+ if (dirbuf->d_ino == 0)
+ /*
+ ** If the entry is not being used, skip it.
+ */
+ continue;
+#endif
+ /*
+ ** Skip self, parent if handled in HTDirTitles()
+ ** or if NO_PARENT_DIR_REFERENCE is not defined,
+ ** and any dot files if no_dotfiles is set or
+ ** show_dotfiles is not set. - FM
+ */
+ if (!strcmp(dirbuf->d_name, ".") /* self */ ||
+ (!strcmp(dirbuf->d_name, "..") /* parent */ &&
+ need_parent_link == FALSE) ||
+ ((strcmp(dirbuf->d_name, "..")) &&
+ (dirbuf->d_name[0] == '.' &&
+ (no_dotfiles || !show_dotfiles))))
+ continue;
+
+ StrAllocCopy(tmpfilename, localname);
+ if (strcmp(localname, "/"))
+ /*
+ ** If filename is not root directory.
+ */
+ StrAllocCat(tmpfilename, "/");
+
+ StrAllocCat(tmpfilename, dirbuf->d_name);
+ stat(tmpfilename, &file_info);
+ if (S_ISDIR(file_info.st_mode))
+#ifndef DIRED_SUPPORT
+ HTSprintf0(&dirname, "D%s",dirbuf->d_name);
+ else
+ HTSprintf0(&dirname, "F%s",dirbuf->d_name);
+ /* D & F to have first directories, then files */
+#else
+ {
+ if (dir_list_style == MIXED_STYLE)
+ HTSprintf0(&dirname, " %s/", dirbuf->d_name);
+ else if (!strcmp(dirbuf->d_name, ".."))
+ HTSprintf0(&dirname, "A%s", dirbuf->d_name);
+ else
+ HTSprintf0(&dirname, "D%s", dirbuf->d_name);
+ }
+ else if (dir_list_style == MIXED_STYLE)
+ HTSprintf0(&dirname, " %s", dirbuf->d_name);
+ else if (dir_list_style == FILES_FIRST)
+ HTSprintf0(&dirname, "C%s", dirbuf->d_name);
+ /* C & D to have first files, then directories */
+ else
+ HTSprintf0(&dirname, "F%s", dirbuf->d_name);
+#endif /* !DIRED_SUPPORT */
+ /*
+ ** Sort dirname in the tree bt.
+ */
+ HTBTree_add(bt, dirname);
+
+ num_of_entries++;
+ if (HTCheckForInterrupt()) {
+ status = HT_PARTIAL_CONTENT;
+ break;
+ }
+
+ } /* end while directory entries left to read */
+
+ if (status != HT_PARTIAL_CONTENT)
+ _HTProgress (gettext("OK"));
+ else
+ CTRACE(tfp, "Reading the directory interrupred by
user\n");
+
+
+ /*
+ ** Run through tree printing out in order.
+ */
+ {
+ HTBTElement * next_element = HTBTree_next(bt,NULL);
+ /* pick up the first element of the list */
+ char state;
+ /* I for initial (.. file),
+ D for directory file,
+ F for file */
+
+#ifdef DIRED_SUPPORT
+ char test;
+#endif /* DIRED_SUPPORT */
+ state = 'I';
+
+ while (next_element != NULL) {
+ char *entry, *file_extra;
+
+ StrAllocCopy(tmpfilename,localname);
+ if (strcmp(localname, "/"))
+ /*
+ ** If filename is not root directory.
+ */
+ StrAllocCat(tmpfilename, "/");
+
+ StrAllocCat(tmpfilename,
+ (char *)HTBTree_object(next_element)+1);
+ /*
+ ** Append the current entry's filename
+ ** to the path.
+ */
+ HTSimplify(tmpfilename);
+ /*
+ ** Output the directory entry.
+ */
+ if (strcmp((char *)
+ (HTBTree_object(next_element)), "D..") &&
+ strcmp((char *)
+ (HTBTree_object(next_element)), "A.."))
+ {
+#ifdef DIRED_SUPPORT
+ test = (*(char *)(HTBTree_object(next_element))
+ == 'D' ? 'D' : 'F');
+ if (state != test) {
+#ifndef LONG_LIST
+ if (dir_list_style == FILES_FIRST) {
+ if (state == 'F')
+ END(HTML_DIR);
+ } else if (dir_list_style != MIXED_STYLE)
+ if (state == 'D')
+ END(HTML_DIR);
+#endif /* !LONG_LIST */
+ state =
+ (*(char *)(HTBTree_object(next_element))
+ == 'D' ? 'D' : 'F');
+ START(HTML_H2);
+ if (dir_list_style != MIXED_STYLE) {
+ START(HTML_EM);
+ PUTS(state == 'D'
+ ? LABEL_SUBDIRECTORIES
+ : LABEL_FILES);
+ END(HTML_EM);
+ }
+ END(HTML_H2);
+#ifndef LONG_LIST
+ START(HTML_DIR);
+#endif /* !LONG_LIST */
+ }
+#else
+ if (state != *(char *)(HTBTree_object(
+ next_element))) {
+#ifndef LONG_LIST
+ if (state == 'D')
+ END(HTML_DIR);
+#endif /* !LONG_LIST */
+ state =
+ (*(char *)(HTBTree_object(next_element))
+ == 'D' ? 'D' : 'F');
+ START(HTML_H2);
+ START(HTML_EM);
+ PUTS(state == 'D'
+ ? LABEL_SUBDIRECTORIES
+ : LABEL_FILES);
+ END(HTML_EM);
+ END(HTML_H2);
+#ifndef LONG_LIST
+ START(HTML_DIR);
+#endif /* !LONG_LIST */
+ }
+#endif /* DIRED_SUPPORT */
+#ifndef LONG_LIST
+ START(HTML_LI);
+#endif /* !LONG_LIST */
+ }
+ entry = (char*)HTBTree_object(next_element)+1;
+ file_extra = NULL;
+
+#ifdef LONG_LIST
+ LYListFmtParse(list_format, tmpfilename, target,
+ entry, tail);
+#else
+ HTDirEntry(target, tail, entry);
+ PUTS(entry);
+ END(HTML_A);
+ if (file_extra) {
+ PUTS(file_extra);
+ FREE(file_extra);
+ }
+ MAYBE_END(HTML_LI);
+#endif /* LONG_LIST */
+
+ next_element = HTBTree_next(bt, next_element);
+ /* pick up the next element of the list;
+ if none, return NULL*/
+
+ /* num_of_entries, num_of_entries_partial... */
+ /* HTReadProgress...(bytes, 0); */
+ HTDisplayPartial();
+
+ if (HTCheckForInterrupt()) {
+ _HTProgress (TRANSFER_INTERRUPTED);
+ status = HT_PARTIAL_CONTENT;
+ break;
+ }
+
+ } /* end while next_element */
+
+ if (status == HT_LOADED) {
+ if (state == 'I') {
+ START(HTML_P);
+ PUTS("Empty Directory");
+ }
+#ifndef LONG_LIST
+ else
+ END(HTML_DIR);
+#endif /* !LONG_LIST */
+ }
+ } /* printing out the tree in order done */
+
+ closedir(dp);
+ FREE(logical);
+ FREE(tmpfilename);
+ FREE(tail);
+ HTBTreeAndObject_free(bt);
+
+ if (status == HT_LOADED) {
+ if (HTDirReadme == HT_DIR_README_BOTTOM)
+ do_readme(target, localname);
+ FREE_TARGET;
+ } else {
+ ABORT_TARGET;
+ }
+ }
+ return status; /* document loaded, maybe partial */
+}
+
+
+
/* Load a document.
** ----------------
**
@@ -1931,16 +2261,7 @@
/*
** If localname is a directory.
*/
- HTStructured *target; /* HTML object */
- HTStructuredClass targetClass;
DIR *dp;
- STRUCT_DIRENT * dirbuf;
- char *logical = NULL;
- char *pathname = NULL;
- char *tail = NULL;
- BOOL present[HTML_A_ATTRIBUTES];
- char * tmpfilename = NULL;
- BOOL need_parent_link = FALSE;
struct stat file_info;
CTRACE(tfp, "%s is a directory\n", localname);
@@ -1983,288 +2304,14 @@
/*
** Directory access is allowed and possible.
*/
- logical = HTAnchor_address((HTAnchor*)anchor);
- pathname = HTParse(logical, "",
- PARSE_PATH + PARSE_PUNCTUATION);
-
- if (!strcmp(pathname,"/")) {
- /*
- ** Root path.
- */
- StrAllocCopy (tail, "/foo/..");
- } else {
- char *p = strrchr(pathname, '/'); /* find last slash */
-
- if (!p) {
- /*
- ** This probably should not happen,
- ** but be prepared if it does. - KW
- */
- StrAllocCopy (tail, "/foo/..");
- } else {
- /*
- ** Take slash off the beginning.
- */
- StrAllocCopy(tail, (p + 1));
- }
- }
- FREE(pathname);
-
- if (UCLYhndl_HTFile_for_unspec >= 0) {
- HTAnchor_setUCInfoStage(anchor,
- UCLYhndl_HTFile_for_unspec,
- UCT_STAGE_PARSER,
- UCT_SETBY_DEFAULT);
- }
-
- target = HTML_new(anchor, format_out, sink);
- targetClass = *target->isa; /* Copy routine entry points */
-
- { int i;
- for (i = 0; i < HTML_A_ATTRIBUTES; i++)
- present[i] = (i == HTML_A_HREF);
- }
-
- /*
- ** The need_parent_link flag will be set if an
- ** "Up to <parent>" link was not created for a
- ** readable parent in HTDirTitles() because
- ** LONG_LIST is defined and NO_PARENT_DIR_REFERENCE
- ** is not defined so that need we to create the
- ** link via an LYListFmtParse() call. - FM
- */
- need_parent_link = HTDirTitles(target,
- (HTAnchor *)anchor, FALSE);
-
-#ifdef DIRED_SUPPORT
- if (strncmp(anchor->address, "lynxcgi:", 8)) {
- HTAnchor_setFormat((HTParentAnchor *) anchor, WWW_DIRED);
- lynx_edit_mode = TRUE;
- }
-#endif /* DIRED_SUPPORT */
- if (HTDirReadme == HT_DIR_README_TOP)
- do_readme(target, localname);
- {
- HTBTree * bt = HTBTree_new((HTComparer)strcmp);
-
- status = HT_LOADED; /* assume we don't get interrupted */
- while ((dirbuf = readdir(dp)) != NULL) {
- /*
- ** While there are directory entries to be read...
- */
- char * dirname = NULL;
-
-#ifndef DOSPATH
- if (dirbuf->d_ino == 0)
- /*
- ** If the entry is not being used, skip it.
- */
- continue;
-#endif
- /*
- ** Skip self, parent if handled in HTDirTitles()
- ** or if NO_PARENT_DIR_REFERENCE is not defined,
- ** and any dot files if no_dotfiles is set or
- ** show_dotfiles is not set. - FM
- */
- if (!strcmp(dirbuf->d_name, ".") /* self */ ||
- (!strcmp(dirbuf->d_name, "..") /* parent */ &&
- need_parent_link == FALSE) ||
- ((strcmp(dirbuf->d_name, "..")) &&
- (dirbuf->d_name[0] == '.' &&
- (no_dotfiles || !show_dotfiles))))
- continue;
-
- StrAllocCopy(tmpfilename, localname);
- if (strcmp(localname, "/"))
- /*
- ** If filename is not root directory.
- */
- StrAllocCat(tmpfilename, "/");
-
- StrAllocCat(tmpfilename, dirbuf->d_name);
- stat(tmpfilename, &file_info);
- if (S_ISDIR(file_info.st_mode))
-#ifndef DIRED_SUPPORT
- HTSprintf0(&dirname, "D%s",dirbuf->d_name);
- else
- HTSprintf0(&dirname, "F%s",dirbuf->d_name);
- /* D & F to have first directories, then files */
-#else
- {
- if (dir_list_style == MIXED_STYLE)
- HTSprintf0(&dirname, " %s/", dirbuf->d_name);
- else if (!strcmp(dirbuf->d_name, ".."))
- HTSprintf0(&dirname, "A%s", dirbuf->d_name);
- else
- HTSprintf0(&dirname, "D%s", dirbuf->d_name);
- }
- else if (dir_list_style == MIXED_STYLE)
- HTSprintf0(&dirname, " %s", dirbuf->d_name);
- else if (dir_list_style == FILES_FIRST)
- HTSprintf0(&dirname, "C%s", dirbuf->d_name);
- /* C & D to have first files, then directories */
- else
- HTSprintf0(&dirname, "F%s", dirbuf->d_name);
-#endif /* !DIRED_SUPPORT */
- /*
- ** Sort dirname in the tree bt.
- */
- HTBTree_add(bt, dirname);
- }
-
- /*
- ** Run through tree printing out in order.
- */
- {
- HTBTElement * next_element = HTBTree_next(bt,NULL);
- /* pick up the first element of the list */
- char state;
- /* I for initial (.. file),
- D for directory file,
- F for file */
-
-#ifdef DIRED_SUPPORT
- char test;
-#endif /* DIRED_SUPPORT */
- state = 'I';
-
- while (next_element != NULL) {
- char *entry, *file_extra;
-
- if (HTCheckForInterrupt()) {
- _HTProgress ("Data transfer interrupted.");
- status = HT_PARTIAL_CONTENT;
- break;
- }
- StrAllocCopy(tmpfilename,localname);
- if (strcmp(localname, "/"))
- /*
- ** If filename is not root directory.
- */
- StrAllocCat(tmpfilename, "/");
-
- StrAllocCat(tmpfilename,
- (char *)HTBTree_object(next_element)+1);
- /*
- ** Append the current entry's filename
- ** to the path.
- */
- HTSimplify(tmpfilename);
- /*
- ** Output the directory entry.
- */
- if (strcmp((char *)
- (HTBTree_object(next_element)), "D..") &&
- strcmp((char *)
- (HTBTree_object(next_element)), "A.."))
- {
-#ifdef DIRED_SUPPORT
- test = (*(char *)(HTBTree_object(next_element))
- == 'D' ? 'D' : 'F');
- if (state != test) {
-#ifndef LONG_LIST
- if (dir_list_style == FILES_FIRST) {
- if (state == 'F')
- END(HTML_DIR);
- } else if (dir_list_style != MIXED_STYLE)
- if (state == 'D')
- END(HTML_DIR);
-#endif /* !LONG_LIST */
- state =
- (*(char *)(HTBTree_object(next_element))
- == 'D' ? 'D' : 'F');
- START(HTML_H2);
- if (dir_list_style != MIXED_STYLE) {
- START(HTML_EM);
- PUTS(state == 'D'
- ? LABEL_SUBDIRECTORIES
- : LABEL_FILES);
- END(HTML_EM);
- }
- END(HTML_H2);
-#ifndef LONG_LIST
- START(HTML_DIR);
-#endif /* !LONG_LIST */
- }
-#else
- if (state != *(char *)(HTBTree_object(
- next_element))) {
-#ifndef LONG_LIST
- if (state == 'D')
- END(HTML_DIR);
-#endif /* !LONG_LIST */
- state =
- (*(char *)(HTBTree_object(next_element))
- == 'D' ? 'D' : 'F');
- START(HTML_H2);
- START(HTML_EM);
- PUTS(state == 'D'
- ? LABEL_SUBDIRECTORIES
- : LABEL_FILES);
- END(HTML_EM);
- END(HTML_H2);
-#ifndef LONG_LIST
- START(HTML_DIR);
-#endif /* !LONG_LIST */
- }
-#endif /* DIRED_SUPPORT */
-#ifndef LONG_LIST
- START(HTML_LI);
-#endif /* !LONG_LIST */
- }
- entry = (char*)HTBTree_object(next_element)+1;
- file_extra = NULL;
-
-#ifdef LONG_LIST
- LYListFmtParse(list_format, tmpfilename, target,
- entry, tail);
-#else
- HTDirEntry(target, tail, entry);
- PUTS(entry);
- END(HTML_A);
- if (file_extra) {
- PUTS(file_extra);
- FREE(file_extra);
- }
- MAYBE_END(HTML_LI);
-#endif /* LONG_LIST */
-
- next_element = HTBTree_next(bt, next_element);
- /* pick up the next element of the list;
- if none, return NULL*/
- }
- if (status == HT_LOADED) {
- if (state == 'I') {
- START(HTML_P);
- PUTS("Empty Directory");
- }
-#ifndef LONG_LIST
- else
- END(HTML_DIR);
-#endif /* !LONG_LIST */
- }
- }
- /* end while directory entries left to read */
- closedir(dp);
- FREE(logical);
- FREE(tmpfilename);
- FREE(tail);
- HTBTreeAndObject_free(bt);
- if (status == HT_LOADED) {
- if (HTDirReadme == HT_DIR_README_BOTTOM)
- do_readme(target, localname);
- FREE_TARGET;
- } else {
- ABORT_TARGET;
- }
- FREE(localname);
- FREE(nodename);
- return status; /* document loaded, maybe partial */
- }
+ status = print_local_dir(dp, localname,
+ anchor, format_out, sink);
+ FREE(localname);
+ FREE(nodename);
+ return status; /* document loaded, maybe partial */
- } /* end if localname is directory */
+ } /* end if localname is a directory */
} /* end if file stat worked */
diff -u -d old/htformat.c ./htformat.c
--- old/htformat.c Wed Mar 31 00:43:48 1999
+++ ./htformat.c Sat Apr 3 23:28:46 1999
@@ -478,11 +478,12 @@
** -------------------------------------------
**
** Repaint the page only when necessary.
+** This is a traverse call for HText_pageDispaly() - it works!.
**
*/
-#ifdef DISP_PARTIAL
-PRIVATE void HTDisplayPartial NOARGS
+PUBLIC void HTDisplayPartial NOARGS
{
+#ifdef DISP_PARTIAL
if (display_partial) {
/*
** HText_getNumOfLines() = "current" number of lines received
@@ -517,10 +518,10 @@
HText_pageDisplay(Newline_partial, "");
}
}
+#else /* nothing */
+#endif /* DISP_PARTIAL */
}
-#else
-#define HTDisplayPartial() /*nothing*/
-#endif
+
/* Push data from a socket down a stream
** -------------------------------------
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- lynx-dev (patch) local directory output - add partial mode,
Leonid Pauzner <=