home *** CD-ROM | disk | FTP | other *** search
- /**
- *
- * Name HLLOOKUP -- Look up and read the help record for a given
- * ID string from the specified help database.
- *
- * Synopsis result = hllookup(pdatabase_path, pid_string, offset,
- * phelp_win, pptext, ptext_length,
- * option);
- *
- * int result Error code indicating success or
- * failure of the operation.
- * const char The name of the help database to
- * *pdatabase_path search.
- * const char The help ID string to search for.
- * *pid_string
- * unsigned long offset If pid_string is NIL or points to
- * the NUL string ('\0'), this is the
- * absolute offset of the help record
- * in the help database.
- * HL_WINDOW *phelp_win Pointer to a help window structure
- * to be filled in from the database.
- * char **pptext Pointer to the returned pointer to
- * the buffer which is allocated for
- * the help window's text (read from
- * the database).
- * int *ptext_length Pointer to the returned length of
- * the text contained in **pptext.
- * int option The format that the window's text
- * is to be returned in. One of the
- * following values:
- * HL_CHARS_ONLY: Return the text as
- * characters only.
- * HL_CHAR_ATTR: Return the text as
- * character attribute pairs.
- * HL_COMPRESSED: Return text in
- * comressed format.
- *
- * Description This function will construct the specified database's
- * index in memory (if it is not already built), search for
- * the specified string, and read in the data associated
- * with the given ID string, if it can be found. If
- * pid_string is NIL or points to the NUL string ('\0'),
- * then offset contains the absolute file offset of the
- * help record within the specified database. The
- * characteristics of the help record's window will be
- * copied into *phelp_win, which must be preallocated. The
- * memory for the window's text will be allocated (a
- * pointer to which is returned in *pptext), and the size
- * of the allocated space is returned in *ptext_length.
- *
- * If b_phelp_index already points to a database index,
- * the entire index is freed before the new index is built.
- *
- * An error occurs if the given pathname does not exist, if
- * there are not enough file handles to open the database,
- * if the path does not point to a valid help database, or
- * if there is not enough memory for the index or the help
- * text.
- *
- * Returns result Error code. Possible values are:
- * HL_NO_ERROR Operation successful.
- * HL_NO_PATH Pathname does not exist.
- * HL_NO_HANDLES Not enough file handles.
- * HL_BAD_DATABASE Specified file is not
- * a valid help file.
- * HL_NO_MEMORY Insufficient memory.
- * HL_NOT_FOUND Id is not in database.
- * HL_VER_MISMATCH Database version is
- * incorrect.
- * HL_SYSTEM Internal error.
- *
- * b_phelp_index Pointer to help index (possibly newly
- * constructed), or NIL if unable to
- * construct index.
- *
- * b_help_path Pathname of database whose index is
- * currently constructed.
- *
- *
- * Version 6.00 (C)Copyright Blaise Computing Inc. 1989
- *
- **/
- #include <stdlib.h>
- #include <fcntl.h>
- #include <sys\types.h>
- #include <sys\stat.h>
- #include <io.h>
- #include <errno.h>
- #include <bhelp.h>
- #include <bstrings.h>
- #include <bfiles.h>
-
-
- #define close_error(error) {close(help_fd); hlerror(error);}
-
-
- static HL_INDEX_NODE *search_index(HL_INDEX_NODE *, char *);
-
-
- int hllookup(pdatabase_path, pid_string, offset, phelp_win, pptext,
- ptext_length, option)
- const char *pdatabase_path;
- const char *pid_string;
- unsigned long offset;
- HL_WINDOW *phelp_win;
- char **pptext;
- int *ptext_length;
- int option;
- {
- int error;
- HL_INDEX_NODE *pindex_node;
- HL_RECORD_DATA record_data;
- extern int errno;
- int help_fd;
- int buffer_index;
- const char *ppath;
- char *puncompressed_text;
- char *pchars_only_text;
- int uncompressed_size;
- int chars_only_size;
- char uppercase_id[HL_ID_SIZE];
- char normalized_path[MAX_FLEN];
- int name_index;
- unsigned long search_offset;
- int id_specified = 0;
-
- errno = 0;
-
- if (flnorm(pdatabase_path, normalized_path, &name_index) != 0)
- ppath = pdatabase_path;
- else
- ppath = normalized_path;
-
- /* First check to see if we need to build the index.*/
- if (strcmp(ppath, b_help_path) != 0)
- {
- hlclose();
- error = hlopen(ppath);
- if (error != HL_NO_ERROR)
- return(error);
- }
-
- /* Now search the index if necessary. */
- if ((pid_string != NIL) && (*pid_string != '\0'))
- {
- id_specified = 1;
-
- strncpy(uppercase_id, pid_string, HL_ID_SIZE - 1);
- uppercase_id[HL_ID_SIZE - 1] = '\0';
- stpcvt(uppercase_id, RLWHITE | RTWHITE | TOUP);
-
- pindex_node = search_index(b_phelp_index, uppercase_id);
- if (pindex_node == NIL)
- hlerror(HL_NOT_FOUND);
-
- search_offset = pindex_node->index_data.help_record;
- }
- else
- search_offset = offset;
-
- /* The index has been found, so open the file and */
- /* read the data. */
- help_fd = open(ppath, O_RDONLY | O_BINARY);
- if (help_fd == -1)
- switch (errno)
- {
- case EACCES:
- hlerror(HL_BAD_DATABASE);
-
- case EMFILE:
- hlerror(HL_NO_HANDLES);
-
- case ENOENT:
- hlerror(HL_NO_PATH);
-
- default:
- hlerror(HL_SYSTEM);
- }
-
- if (lseek(help_fd, search_offset, SEEK_SET) != search_offset)
- close_error(HL_BAD_DATABASE);
-
- /* First, read the record header and window data. */
- if ((read(help_fd, &record_data, sizeof(HL_RECORD_DATA)) !=
- sizeof(HL_RECORD_DATA)) ||
- (record_data.record_sign.type != HL_WINDOW_RECORD) ||
- (record_data.record_sign.length != sizeof(HL_RECORD_DATA)))
- {
- close_error(HL_BAD_DATABASE);
- }
-
- hlpas2c(record_data.id_string, record_data.id_string,
- sizeof(record_data.id_string));
-
- if (id_specified &&
- (strcmp(record_data.id_string, uppercase_id) != 0))
- {
- close_error(HL_BAD_DATABASE);
- }
-
- /* Convert the help record from disk format to */
- /* memory format. */
- *phelp_win = *((HL_WINDOW *) &record_data.view_top);
- phelp_win->view_top--;
- phelp_win->view_left--;
- phelp_win->view_bottom--;
- phelp_win->view_right--;
- phelp_win->origin_row--;
- phelp_win->origin_col--;
-
- /* Now read in the help window's text. */
- *pptext = malloc(record_data.image_length);
- if (*pptext == NIL)
- close_error(HL_NO_MEMORY);
-
- if (read(help_fd, *pptext, record_data.image_length) !=
- record_data.image_length)
- {
- close_error(HL_BAD_DATABASE);
- }
-
- /* Now check to see if the window has a title. */
- if (record_data.title_length != 0)
- {
- phelp_win->pwindow_title = malloc(record_data.title_length + 1);
- if (phelp_win->pwindow_title == NIL)
- close_error(HL_NO_MEMORY);
-
- if (read(help_fd, phelp_win->pwindow_title,
- record_data.title_length) != record_data.title_length)
- close_error(HL_BAD_DATABASE);
-
- phelp_win->pwindow_title[record_data.title_length] = '\0';
- }
- else
- phelp_win->pwindow_title = NIL;
-
- /* Now check to see how the text should be returned.*/
- switch(option)
- {
- case HL_COMPRESSED:
- *ptext_length = record_data.image_length;
- break;
-
- case HL_CHAR_ATTR:
- case HL_CHARS_ONLY:
- uncompressed_size = *((int *) ((*pptext) + 2));
- puncompressed_text = malloc(uncompressed_size);
- if (puncompressed_text == NIL)
- close_error(HL_NO_MEMORY);
- if (utunsqz(*pptext, puncompressed_text,
- record_data.image_length, uncompressed_size) !=
- uncompressed_size)
- {
- free(puncompressed_text);
- close_error(HL_BAD_DATABASE);
- }
-
- if (option == HL_CHAR_ATTR)
- {
- free(*pptext);
- *pptext = puncompressed_text;
- *ptext_length = uncompressed_size;
- }
- else
- {
- chars_only_size = uncompressed_size / 2;
- pchars_only_text = malloc(chars_only_size);
- if (pchars_only_text == NIL)
- {
- free(puncompressed_text);
- close_error(HL_NO_MEMORY);
- }
- for (buffer_index = 0; buffer_index < chars_only_size;
- buffer_index++)
- {
- pchars_only_text[buffer_index] =
- puncompressed_text[buffer_index * 2];
- }
- free(*pptext);
- *pptext = pchars_only_text;
- free(puncompressed_text);
- *ptext_length = chars_only_size;
- }
- break;
-
- default:
- return(HL_SYSTEM);
- }
-
- return(HL_NO_ERROR);
- }
-
-
- /**
- *
- * Name SEARCH_INDEX -- Recursively search a help index tree for
- * a specified ID string.
- *
- * Synopsis pindex_node = search_index(pindex_root, pid_string);
- *
- * HL_INDEX_NODE *pindex_node Pointer to found index node,
- * or NIL if ID is not in the
- * index.
- * HL_INDEX_NODE *pindex_root Pointer to root of subtree
- * to search.
- * char *pid_string The help ID string to search
- * for.
- *
- * Description This function will recursively search the specified
- * help index subtree for the given id string. The return
- * value is a pointer to the help index node for the ID,
- * or NIL if the ID cannot be found in the subtree.
- *
- * Returns pindex_node Found index node or NIL if ID does not
- * exist.
- *
- **/
-
- HL_INDEX_NODE *search_index(pindex_root, pid_string)
- HL_INDEX_NODE *pindex_root;
- char *pid_string;
- {
- int result;
-
- if (pindex_root == NIL)
- return(NIL);
-
- result = strcmp(pid_string, pindex_root->index_data.id_string);
-
- if (result == 0)
- return(pindex_root);
-
- if (result < 0)
- return(search_index(pindex_root->pleft, pid_string));
-
- return(search_index(pindex_root->pright, pid_string));
- }