home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c070 / 4.ddi / TOOLS.4 / TCTSRC1.EXE / HLOPEN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-31  |  6.7 KB  |  256 lines

  1. /**
  2. *
  3. * Name        HLOPEN -- Open a help database and construct its index
  4. *              in memory.
  5. *
  6. * Synopsis    result = hlopen(pdatabase_path);
  7. *
  8. *        int result           Error code indicating success or
  9. *                       failure of the operation.
  10. *        const char           The name of the help database to
  11. *              *pdatabase_path  open.
  12. *
  13. * Description    This function accepts a pointer to a string which
  14. *        contains the name of a help database constructed with
  15. *        BUILDHLP, copies that string into the global variable
  16. *        b_help_path, constructs an in memory index of the help
  17. *        records contained in the file, and places a pointer to
  18. *        the root of the index in the global variable
  19. *        b_phelp_index.
  20. *
  21. *        If pdatabase path is NIL or points to the NUL string
  22. *        ("\0") then the pathname of the previously opened
  23. *        database is used (if there was one).  If no database
  24. *        was previously open, HL_NO_PATH is returned.
  25. *
  26. *        If b_phelp_index already points to a database index,
  27. *        the entire index is freed before the new index is built.
  28. *
  29. *        An error occurs if the given pathname does not exist, if
  30. *        there are not enough file handles to open the database,
  31. *        if the path does not point to a valid help database, or
  32. *        if there is not enough memory to construct the index.
  33. *
  34. * Returns    result        Error code. Possible values are:
  35. *                HL_NO_ERROR    Operation successful.
  36. *                HL_NO_PATH    Pathname does not exist.
  37. *                HL_NO_HANDLES    Not enough file handles.
  38. *                HL_BAD_DATABASE Specified file is not
  39. *                        a valid help file.
  40. *                HL_NO_MEMORY    Insufficient memory.
  41. *                HL_VER_MISMATCH Database version is
  42. *                        incorrect.
  43. *                HL_SYSTEM    Internal error.
  44. *
  45. *        b_phelp_index    Pointer to newly constructed help index,
  46. *                or NIL if failure.
  47. *
  48. *        b_help_path    Pathname of database whose index is
  49. *                currently constructed.
  50. *
  51. *
  52. * Version    6.00 (C)Copyright Blaise Computing Inc.  1989
  53. *
  54. **/
  55.  
  56. #include <fcntl.h>
  57. #include <sys\types.h>
  58. #include <sys\stat.h>
  59. #include <io.h>
  60. #include <errno.h>
  61. #include <bhelp.h>
  62. #include <bfiles.h>
  63.  
  64.  
  65. HL_INDEX_NODE *b_phelp_index = NIL;
  66. char           b_help_path[MAX_FLEN] = {'\0'};
  67.  
  68. #define close_error(error)                        \
  69.     {                                \
  70.         close(help_fd);                        \
  71.         b_help_path[0] = '\0';                                  \
  72.         hlfrindx(b_phelp_index);                    \
  73.         hlerror(error);                        \
  74.         return(b_wnerr);                        \
  75.     }
  76.  
  77. static void cdecl insert_index(HL_INDEX_NODE **, HL_INDEX_NODE    *);
  78.  
  79.  
  80. int hlopen(pdatabase_path)
  81. const char *pdatabase_path;
  82. {
  83.     int         help_fd;
  84.     int         name_index = 0;
  85.     int         bytes_read;
  86.     unsigned long   file_size;
  87.     HL_FILE_HEADER  file_header;
  88.     HL_INDEX_NODE  *pnew_node;
  89.  
  90.     errno = 0;
  91.  
  92.     if ((pdatabase_path == NIL) || (*pdatabase_path == '\0'))
  93.     pdatabase_path = b_help_path;
  94.  
  95.         /* Try to open and read the help database.        */
  96.     help_fd = open(pdatabase_path, O_RDONLY | O_BINARY);
  97.     if (help_fd == -1)
  98.     {
  99.     switch (errno)
  100.     {
  101.     case EACCES:
  102.         hlerror(HL_BAD_DATABASE);
  103.  
  104.     case EMFILE:
  105.         hlerror(HL_NO_HANDLES);
  106.  
  107.     case ENOENT:
  108.         hlerror(HL_NO_PATH);
  109.  
  110.     default:
  111.         hlerror(HL_SYSTEM);
  112.     }
  113.  
  114.     return(b_wnerr);
  115.     }
  116.  
  117.         /* Now that the database has been opened, copy the  */
  118.         /* pathname into b_help_path.                */
  119.     if (pdatabase_path != b_help_path)
  120.     if (flnorm(pdatabase_path, b_help_path, &name_index) != 0)
  121.     {
  122.         strncpy(b_help_path, pdatabase_path, sizeof(b_help_path));
  123.         b_help_path[sizeof(b_help_path) - 1] = '\0';
  124.     }
  125.  
  126.     if (b_phelp_index != NIL)
  127.     {
  128.     hlfrindx(b_phelp_index);
  129.     b_phelp_index = NIL;
  130.     }
  131.  
  132.     file_size = lseek(help_fd, 0, SEEK_END);
  133.     lseek(help_fd, 0, SEEK_SET);
  134.  
  135.     if ((read(help_fd, &file_header,
  136.           sizeof(file_header)) != sizeof(file_header)) ||
  137.     (file_size < file_header.file_size)           ||
  138.     (file_header.index_offset > file_size)           ||
  139.     ((file_header.index_offset != 0) &&
  140.      (file_header.index_offset < sizeof(file_header))) ||
  141.     (strncmp(file_header.file_sign, HL_FILE_SIGN,
  142.          strlen(HL_FILE_SIGN)) != 0))
  143.     {
  144.     close_error(HL_BAD_DATABASE);
  145.     }
  146.  
  147.     if (file_header.version != HL_VERSION)
  148.     {
  149.     close_error(HL_VER_MISMATCH);
  150.     }
  151.  
  152.     if (lseek(help_fd, file_header.index_offset, SEEK_SET) == 0)
  153.     {
  154.     close(help_fd);
  155.     return(HL_NO_ERROR);
  156.     }
  157.  
  158.         /* Now begin reading the database index.        */
  159.     do
  160.     {
  161.     pnew_node = calloc(sizeof(HL_INDEX_NODE), 1);
  162.     if (pnew_node == NIL)
  163.     {
  164.         close_error(HL_NO_MEMORY);
  165.     }
  166.  
  167.     bytes_read = read(help_fd, &(pnew_node->index_data),
  168.               sizeof(pnew_node->index_data));
  169.  
  170.     if (pnew_node->index_data.description_len != 0)
  171.     {
  172.         pnew_node->pdescription =
  173.         malloc(pnew_node->index_data.description_len + 1);
  174.  
  175.         if (pnew_node->pdescription == NIL)
  176.         {
  177.         close_error(HL_NO_MEMORY);
  178.         }
  179.  
  180.         bytes_read += read(help_fd, pnew_node->pdescription,
  181.                    pnew_node->index_data.description_len);
  182.     }
  183.     else
  184.         pnew_node->pdescription = NIL;
  185.  
  186.     if (bytes_read != 0)
  187.     {
  188.         if (bytes_read != (sizeof(pnew_node->index_data) +
  189.                    pnew_node->index_data.description_len))
  190.         {
  191.         close_error(HL_BAD_DATABASE);
  192.         }
  193.         else
  194.         {
  195.            hlpas2c(pnew_node->index_data.id_string,
  196.             pnew_node->index_data.id_string,
  197.             sizeof(pnew_node->index_data.id_string));
  198.  
  199.         pnew_node->pdescription[
  200.             pnew_node->index_data.description_len] = '\0';
  201.         insert_index(&b_phelp_index, pnew_node);
  202.         }
  203.         lseek(help_fd, pnew_node->index_data.next_index,
  204.           SEEK_SET);
  205.     }
  206.     }
  207.     while ((pnew_node->index_data.next_index != 0) &&
  208.        (bytes_read != 0));
  209.  
  210.     close(help_fd);
  211.  
  212.     return(HL_NO_ERROR);
  213. }
  214.  
  215.  
  216. /**
  217. *
  218. * Name        INSERT_INDEX  Insert a help index node into the given
  219. *                  help index subtree.
  220. *
  221. * Synopsis    insert_index(ppindex_node, pnew_node);
  222. *
  223. *        HL_INDEX_NODE *ppindex_node Pointer to pointer to
  224. *                        subtree into which the new
  225. *                        node is to be inserted.
  226. *        HL_INDEX_NODE *pnew_node    Pointer to the new help
  227. *                        index node to insert.
  228. *
  229. * Description    This function accepts a pointer to a pointer to a help
  230. *        index subtree and a pointer to a new help index node
  231. *        and inserts the given node into the subtree.  If
  232. *        *ppindex_node is NIL, *ppindex node is set to pnew_node.
  233. *
  234. * Returns    *ppindex_node    If NIL, it is set to pnew_node.
  235. *
  236. **/
  237.  
  238. void insert_index(ppindex_node, pnew_node)
  239. HL_INDEX_NODE **ppindex_node;
  240. HL_INDEX_NODE  *pnew_node;
  241. {
  242.     if (*ppindex_node == NIL)
  243.     {
  244.     *ppindex_node = pnew_node;
  245.     return;
  246.     }
  247.  
  248.     if (strcmp(pnew_node->index_data.id_string,
  249.           (*ppindex_node)->index_data.id_string) <= 0)
  250.     insert_index(&((*ppindex_node)->pleft), pnew_node);
  251.     else
  252.     insert_index(&((*ppindex_node)->pright), pnew_node);
  253.  
  254.     return;
  255. }
  256.