home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_144 / 2.ddi / CLIBSRC3.ZIP / SEARCHP.CAS < prev    next >
Encoding:
Text File  |  1992-06-10  |  14.0 KB  |  389 lines

  1. /*-----------------------------------------------------------------------*
  2.  * filename - searchp.cas
  3.  *
  4.  * function(s)
  5.  *        CopyUpr      - copy string and convert to upper-case
  6.  *        CheckFile    - build absolute pathname and check existence
  7.  *        __search_env - return an absolute DOS path for the given file name,
  8.  *                       using any path environment variable
  9.  *        __searchpath - return an absolute DOS path for the given file name,
  10.  *                       using PATH environment variable
  11.  *        _searchenv   - search a path environment variable for a file.
  12.  *-----------------------------------------------------------------------*/
  13.  
  14. /*
  15.  *      C/C++ Run Time Library - Version 5.0
  16.  *
  17.  *      Copyright (c) 1987, 1992 by Borland International
  18.  *      All Rights Reserved.
  19.  *
  20.  */
  21.  
  22.  
  23. #pragma inline
  24. #include <asmrules.h>
  25. #include <dir.h>
  26. #include <_dir.h>
  27. #include <direct.h>
  28. #include <dos.h>
  29. #include <_io.h>
  30. #include <string.h>
  31. #include <stdlib.h>
  32.  
  33. static  char    PathFile[MAXPATH];
  34. static  char    drive[MAXDRIVE+1];
  35. static  char    dir[MAXDIR+1];
  36. static  char    fname[MAXFILE+1];
  37. static  char    ext[MAXEXT+1];
  38.  
  39. /*-----------------------------------------------------------------------*
  40.  
  41. Name            CopyUpr - copy string and convert to upper-case
  42.  
  43. Usage           void * pascal near CopyUpr(char *dst, char *src)
  44.  
  45. Description     Copies a string to another, converting all lowercase
  46.                 characters to upper case.
  47.  
  48. Return value    Returns the address of the terminating null byte in "dst".
  49.  
  50. *------------------------------------------------------------------------*/
  51. static void * pascal near CopyUpr(char *dst, char *src)
  52. {
  53.         pushDS_
  54. asm     LDS_    si, src
  55. asm     LES_    di, dst
  56. asm     cld
  57. #if !LDATA
  58. asm     push    ds
  59. asm     pop     es
  60. #endif
  61. Copying:
  62. asm     lodsb
  63. asm     cmp     al, 'a'
  64. asm     jb      Converted
  65. asm     cmp     al, 'z'
  66. asm     ja      Converted
  67. asm     sub     al, 'a' - 'A'
  68. Converted:
  69. asm     stosb
  70. asm     or      al, al
  71. asm     jnz     Copying
  72. asm     dec     di
  73. asm     xchg    ax,di
  74.         popDS_
  75. #pragma warn -sus
  76.         return (void _es *) _AX;
  77. #pragma warn .sus
  78. }
  79.  
  80.  
  81. /*--------------------------------------------------------------------------*
  82.  
  83. Name            _getcurdir - gets current directory for specified drive
  84.  
  85. Usage           int _getcurdir(int drive, char *direc);
  86.  
  87. Prototype in    local
  88.  
  89. Description     _getcurdir gets the name of the current working
  90.                 directory for the named drive.
  91.  
  92.                 drive contains a drive number (0 = default, 1 = A, etc.).
  93.  
  94.                 direc points to an area of memory of length MAXDIR where
  95.                 the directory name will be placed. The null-terminated name
  96.                 does not contain the drive specification and does not begin
  97.                 with a backslash.
  98.  
  99. Return value    _getcurdir returns 0 on success or the DOS error code
  100.                 in the event of error.
  101.  
  102. *---------------------------------------------------------------------------*/
  103. static int pascal _getcurdir(int drive, char *direc)
  104. {
  105.         pushDS_
  106. asm     mov     ah, 047h
  107. asm     mov     dl, drive
  108. asm     LDS_    si, direc
  109. asm     int     021H
  110.         popDS_
  111. asm     jc      getcurdirFailed
  112.         return(0);
  113.  
  114. getcurdirFailed:
  115.         return (_AX);
  116. }
  117.  
  118. /*-----------------------------------------------------------------------*
  119.  
  120. Name            CheckFile - build absolute pathname and check existence
  121.  
  122. Usage           static unsigned pascal near CheckFile(char *pathP, char *driveP,
  123.                                                  char *dirP, char *nameP,
  124.                                                  char *extP, int mode);
  125.  
  126. Description     Builds an absolute pathname with the given components,
  127.                 and then checks for the existence of the given file.
  128.  
  129. Return value    Returns zero if the given file exists, or the DOS error
  130.                 code from _dos_findfirst() if it doesn't exist.
  131.  
  132. *------------------------------------------------------------------------*/
  133. static unsigned pascal near CheckFile(char *pathP, char *driveP, char *dirP,
  134.                                  char *nameP, char *extP, int mode)
  135. {
  136.         register char   *bufP;
  137.         struct   find_t ffbuf;
  138.         unsigned drive, len;
  139.  
  140.         bufP = pathP;
  141.         if (*driveP == '\0')
  142.                 _dos_getdrive(&drive);  /* get drive, 1=A, 2=B, etc. */
  143.         else
  144.                 drive = *driveP & 0x1f; /* convert A(a) to 1, B(b) to 2, etc. */
  145.         *bufP++ = drive + 'A' - 1;
  146.         *bufP++ = ':';
  147.  
  148.         if (*dirP != '\\' && *dirP != '/')
  149.             {
  150.             *bufP++ = '\\';
  151.             if (_getcurdir(drive, bufP) != 0)
  152.                 return (e_pathNotFound);
  153.             len = strlen(bufP);
  154.             if (len != 0)
  155.                 {
  156.                 bufP += len;
  157.                 *bufP++ = '\\';
  158.                 }
  159.             }
  160.  
  161.         bufP = CopyUpr(bufP, dirP);
  162.         if (*(bufP - 1) != '\\' && *(bufP - 1) != '/')
  163.                 *bufP++ = '\\';
  164.  
  165.         bufP = CopyUpr(bufP, nameP);
  166.  
  167.         if (extP)
  168.                 CopyUpr(bufP, extP);
  169.  
  170.         return (_dos_findfirst(pathP, (mode & _PROGRAM) ? 0x27 : 0x37, &ffbuf));
  171. }
  172.  
  173.  
  174. /*-----------------------------------------------------------------------*
  175.  
  176. Name            __search_env - return an absolute DOS path for the given file
  177.                                name.
  178.  
  179. Usage           char    *pascal __searchpath(const char *pathP, int mode,
  180.                                              char *envname);
  181.  
  182. Description     __search_env attempts to locate a file, given by filename.
  183.                 If the value for mode specified is _USEPATH, the directories
  184.                 in the MS-DOS environment variable envname (typically PATH)
  185.                 are searched.  If mode is _STRING, the directories in the
  186.                 string envname are searched.  A pointer to the complete
  187.                 path-name string is returned as the function value.
  188.  
  189.                 The current directory of the current drive is checked first. If
  190.                 the file is not found there and _USEPATH is specified, the
  191.                 environment variable is fetched, and each directory in the
  192.                 variable is searched in turn until the file is found or the
  193.                 path is exhausted.  Similarly, if _STRING is specified,
  194.                 the list of directories pointed to by envname is searched.
  195.  
  196.                 When the file is located, a string is returned containing the
  197.                 full path name. This string can be used in a call to open or
  198.                 exec... to access the file.
  199.  
  200.                 The string returned is located in a static buffer and is
  201.                 destroyed on each subsequent call to __search_env.
  202.  
  203. Return value    A pointer to a filename string is returned if the
  204.                 file is successfully located; otherwise, __search_env returns
  205.                 NULL.
  206.  
  207. *------------------------------------------------------------------------*/
  208. static char *pascal near __search_env(const char *pathP, int mode, char *envname)
  209. {
  210.         register char   *bufP = PathFile;
  211.         register char   *envP = NULL;
  212.                  int    flag;
  213.  
  214.         /*      Preliminary checking            */
  215.         flag = 0;
  216.         if ((pathP != NULL) || (*pathP != 0))
  217.                 flag = _fnsplit(pathP, drive, dir, fname, ext);
  218.         if ((flag & (WILDCARDS + FILENAME)) != FILENAME)
  219.                 return (NULL);
  220.  
  221. /*      If  looking  for  a  program  file,  limit  the  search  if a
  222.         directory or an extension is specified
  223. */
  224.         if (mode & _PROGRAM) {
  225.                 if (flag & DIRECTORY)
  226.                         mode &= ~_USEPATH;
  227.                 if (flag & EXTENSION)
  228.                         mode &= ~_PROGRAM;
  229.         }
  230.  
  231.         /*      Get environment variable (usually "PATH") if allowed      */
  232.         if (mode & _USEPATH)
  233.                 envP = getenv(envname);
  234.         else if (mode & _STRING)
  235.                 envP = envname;
  236.  
  237. /*      Try to locate "pathP" in current  directory, then try in all
  238.         directories specified  by the environment variable and
  239.         return a pointer  to the full path if  found, otherwise NULL
  240.         is returned.
  241. */
  242.         while (1) {
  243.                 unsigned doserr;
  244.  
  245.                 /* Check if the file exists */
  246.                 if ((doserr = CheckFile(bufP, drive, dir, fname, ext, mode)) == 0)
  247.                         break;
  248.  
  249.                 /* If PROGRAM file, try with ".COM" and ".EXE" extension */
  250.                 if ((doserr != e_pathNotFound) && (mode & _PROGRAM)) {
  251.  
  252.                         if ((doserr = CheckFile(bufP, drive, dir, fname, ".COM", mode)) == 0)
  253.                                 break;
  254.                         if (doserr != e_pathNotFound)
  255.                                 if (CheckFile(bufP, drive, dir, fname, ".EXE", mode) == 0)
  256.                                         break;
  257.                 }
  258.  
  259.                 /* Stops if no environment or end of it */
  260.                 if (envP == NULL || *envP == '\0') {
  261.                         bufP = NULL;
  262.                         break;
  263.                 }
  264.  
  265.                 /* Isolate drive name from environment */
  266.                 flag = 0;
  267.                 if (envP[1] == ':') {
  268.                         drive[flag++] = *envP++;
  269.                         drive[flag++] = *envP++;
  270.                 }
  271.                 drive[flag] = 0;
  272.  
  273.                 /* Isolate directory name from environment */
  274.                 for (flag = 0; (dir[flag] = *envP++) != 0; flag++)
  275.                         if (dir[flag] == ';') {
  276.                                 dir[flag] = 0;
  277.                                 envP++;
  278.                                 break;
  279.                         }
  280.                 envP--;         /* point back at '\0' or past ';' */
  281.  
  282.                 /* if only drive specified, set dir to root */
  283.                 if (dir[0] == '\0') {
  284.                   dir[0] = '\\';
  285.                   dir[1] = '\0';
  286.                 }
  287.         }
  288.         return (bufP);
  289. }
  290.  
  291.  
  292. /*-----------------------------------------------------------------------*
  293.  
  294. Name            __searchpath - return an absolute DOS path for the given file
  295.                                name.
  296.  
  297. Usage           char    *pascal __searchpath(const char *pathP, int mode);
  298.  
  299. Prototype in    _dir.h
  300.  
  301. Description     __searchpath attempts to locate a file, given by filename.
  302.                 If the value for mode specified is _USEPATH, the MS-DOS path
  303.                 is searched. A pointer to the complete path-name string is
  304.                 returned as the function value.
  305.  
  306.                 The current directory of the current drive is checked first. If
  307.                 the file is not found there and _USEPATH is specified, the PATH
  308.                 environment variable is fetched, and each directory in the
  309.                 path is searched in turn until the file is found or the path
  310.                 is exhausted.
  311.  
  312.                 When the file is located, a string is returned containing the
  313.                 full path name. This string can be used in a call to open or
  314.                 exec... to access the file.
  315.  
  316.                 The string returned is located in a static buffer and is
  317.                 destroyed on each subsequent call to __searchpath.
  318.  
  319. Return value    A pointer to a filename string is returned if the
  320.                 file is successfully located; otherwise, __searchpath returns
  321.                 NULL.
  322.  
  323. *------------------------------------------------------------------------*/
  324. char    *pascal near __searchpath(const char *pathP, int mode)
  325. {
  326.         return (__search_env(pathP, mode, "PATH"));
  327. }
  328.  
  329. /*-----------------------------------------------------------------------*
  330.  
  331. Name            _searchenv - searches for a file using an enviroment path
  332.  
  333. Usage           void _searchenv(const char *filename, const char *varname,
  334.                                 char *pathname);
  335.  
  336. Prototype in    stdlib.h
  337.  
  338. Description     _searchenv simply calls __search_env to search the current
  339.                 directory and MS DOS environment variable 'varname' for
  340.                 filename.  If found, the complete pathname of the file
  341.                 is copied to the user's buffer pathname.  If the file
  342.                 is not found, an empty string will be stored in pathname.
  343.  
  344. Return value    None.
  345.  
  346. Note            Compatible with Microsoft C.  Not the same as searchpath().
  347. *------------------------------------------------------------------------*/
  348.  
  349. void _searchenv(const char *file, const char *varname, char *pathname)
  350. {
  351.         char *found;
  352.  
  353.         if ((found = __search_env(file, _USEPATH, (char *)varname)) == NULL)
  354.                 *pathname = '\0';       /* not found, store empty string */
  355.         else
  356.                 strcpy(pathname,found); /* found, copy complete pathname */
  357. }
  358.  
  359. /*-----------------------------------------------------------------------*
  360.  
  361. Name            _searchstr - searches for a file using a path string
  362.  
  363. Usage           void _searchstr(const char *filename, const char *ipath,
  364.                                 char *pathname);
  365.  
  366. Prototype in    stdlib.h
  367.  
  368. Description     _searchstr simply calls __search_env to search the current
  369.                 directory and the list of semicolon-separated directories
  370.                 specified by ipath for the file filename.  If found,
  371.                 the complete pathname of the file is copied to the user's
  372.                 buffer pathname.  If the file is not found, an empty string
  373.                 will be stored in pathname.
  374.  
  375. Return value    None.
  376.  
  377. *------------------------------------------------------------------------*/
  378.  
  379. void _searchstr(const char *file, const char *ipath, char *pathname)
  380. {
  381.         char *found;
  382.  
  383.         if ((found = __search_env(file, _STRING, (char *)ipath)) == NULL)
  384.                 *pathname = '\0';       /* not found, store empty string */
  385.         else
  386.                 strcpy(pathname,found); /* found, copy complete pathname */
  387. }
  388.  
  389.