⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sfldir.c

📁 短小精悍的C语言标准函数库。提供450个以上的可移植的算法和工具代码。
💻 C
📖 第 1 页 / 共 4 页
字号:


/*  ---------------------------------------------------------------------[<]-
    Function: get_curdir

    Synopsis: Returns a buffer containing the current working directory.
    This buffer is allocated using the mem_alloc() function and should be
    freed using mem_free() when no longer needed.  Returns NULL if there
    was insufficient memory to allocate the buffer, or if the system does
    not provide the current working directory information.  Under Windows,
    replaces backslash characters by the UNIX-like slash.  Under OpenVMS,
    returns directory name in POSIX format.  Note that the directory name
    always ends in a slash (e.g. 'C:/' or 'C:/subdir/').
    ---------------------------------------------------------------------[>]-*/

char *
get_curdir (void)
{
    char
        *curdir;                        /*  String we get from the OS        */

    curdir = mem_alloc (PATH_MAX + 1);

#if (defined (__UNIX__) || defined (__OS2__))
    getcwd (curdir, PATH_MAX);

#elif (defined (__VMS__))
    getcwd (curdir, PATH_MAX, 0);

#elif (defined (WIN32))
    GetCurrentDirectory (PATH_MAX, curdir);
    strconvch (curdir, '\\', '/');

#elif (defined (MSDOS_FILESYSTEM))
    getcwd (curdir, PATH_MAX);
    strconvch (curdir, '\\', '/');

#else
    strclr (curdir);
#endif

    /*  The directory must always end in a slash                             */
    if (strlast (curdir) != '/')
        strcat (curdir, "/");

    return (curdir);
}


/*  ---------------------------------------------------------------------[<]-
    Function: set_curdir

    Synopsis: Sets the current working directory as specified.  Returns 0
    if the directory path was found; -1 if there was an error.  Under
    Windows, replaces '/' by '\' before changing directory, and switches
    to the specified disk if the path starts with a letter and ':'.  Does
    nothing if the path is NULL or empty.
    ---------------------------------------------------------------------[>]-*/

int
set_curdir (
    const char *path)
{
    int
        feedback = 0;

#if (defined (__UNIX__) || defined (__VMS_XOPEN) || defined (__OS2__))
    if (path && *path)
        feedback = chdir (path);

#elif (defined (MSDOS_FILESYSTEM))
    char
        *copy_path = mem_strdup (path);

    if (path == NULL || *path == '\0')
        return (0);                     /*  Do nothing if path is empty      */

    /*  MS-DOS compilers generally require a two-step process                */
    strconvch (copy_path, '/', '\\');

#   if (defined (WIN32))
    /* The drive letter does not need to be changed separately in Win32.    */
    feedback = !SetCurrentDirectory (copy_path);

#   elif (defined (__TURBOC__))
    feedback = chdir (copy_path);
    if (feedback == 0 && isalpha (path [0]) && path [1] == ':')
        setdisk (toupper (path [0]) - 'A');

#   elif (defined (__LCC__))
    feedback = chdir (copy_path);
    if (feedback == 0 && isalpha (path [0]) && path [1] == ':')
        chdrive (toupper (path [0]) - 'A' + 1);

#   elif (defined (_MSC_VER))
    feedback = _chdir (copy_path);
    if (feedback == 0 && isalpha (path [0]) && path [1] == ':')
        _chdrive (toupper (path [0]) - 'A' + 1);

#   endif
    mem_strfree (&copy_path);
#else
    feedback = -1;
#endif

    return (feedback);
}


/*  ---------------------------------------------------------------------[<]-
    Function: file_matches

    Synopsis: Returns TRUE if the filename matches the pattern.  The pattern
    is a character string that can contain these 'wildcard' characters:
    ---------------------------------------------------------------------[>]-*/

Bool
file_matches (
    const char *filename,
    const char *pattern)
{
    char
        *pattern_ptr,                   /*  Points to pattern                */
        *filename_ptr;                  /*  Points to filename               */

    filename_ptr = (char *) filename;   /*  Start comparing file name        */
    pattern_ptr  = (char *) pattern;    /*  Start comparing file name        */
    FOREVER
      {
        /*  If we came to the end of the pattern and the filename, we have   */
        /*  successful match.                                                */
        if (*pattern_ptr == '\0' && *filename_ptr == '\0')
            return (TRUE);              /*  Have a match                     */

        /*  Otherwise, end of either is a failed match                       */
        if (*pattern_ptr == '\0' || *filename_ptr == '\0')
            return (FALSE);             /*  Match failed                     */

        /*  If the pattern character is '?', then we matched a char          */
        if (*pattern_ptr == '?'
#if (defined (NAMEFOLD))
        ||  toupper (*pattern_ptr) == toupper (*filename_ptr))
#else
        ||  *pattern_ptr == *filename_ptr)
#endif
          {
            pattern_ptr++;
            filename_ptr++;
          }
        else
        /*  If we have a '*', match as much of the filename as we can        */
        if (*pattern_ptr == '*')
          {
            pattern_ptr++;              /*  Try to match following char      */
            while (*filename_ptr && *filename_ptr != *pattern_ptr)
                filename_ptr++;
          }
        else
            return (FALSE);             /*  Match failed                     */
      }
}


/*  ---------------------------------------------------------------------[<]-
    Function: make_dir

    Synopsis: Create a new directory.  Returns 0 if the directory was created;
    -1 if there was an error.  Under Windows and OpenVMS, accepts directory
    names with '/'.  Will create multiple levels of directory if required.
    ---------------------------------------------------------------------[>]-*/

int
make_dir (
    const char *path_to_create)
{
    char
        *path,
        *slash;
    int
        rc = 0;

    path = mem_strdup (path_to_create); /*  Working copy                     */
#if (defined (MSDOS_FILESYSTEM))
    strconvch (path, '/', '\\');

    /*  Handle \\system\drive specially                                      */
    if (strprefixed (path, "\\\\"))     /*  Network drive name?              */
      {
        slash = strchr (path + 2, '\\');
        if (slash)
            slash = strchr (slash + 1, '\\');
      }
    else
#endif
    slash = strchr (path + 1, PATHEND);

    /*  Create each component of directory as required                       */
    FOREVER                             /*  Create any parent directories    */
      {
        if (slash)
            *slash = '\0';              /*  Cut at slash                     */

        if (!file_is_directory (path))
          {
#if (defined (__UNIX__) || defined (__VMS_XOPEN) || defined (__OS2__))
            rc = mkdir (path, 0775);    /*  User RWE Group RWE World RE      */

#elif (defined (WIN32))
            if (CreateDirectory (path, NULL))
                rc = 0;
            else
                rc = -1;

#elif (defined (MSDOS_FILESYSTEM))
#   if (defined (__DJGPP__))
            rc = mkdir (path, 0775);    /*  User RWE Group RWE World RE      */
#   else
            rc = mkdir (path);          /*  Protection?  What's that?        */
#   endif
#else
            rc = -1;                    /*  Not a known system               */
#endif
            if (rc)                     /*  End if error                     */
                break;
          }
        if (slash == NULL)              /*  End if last directory            */
            break;
       *slash = PATHEND;                /*  Restore path name                */
        slash = strchr (slash + 1, PATHEND);
      }
    mem_strfree (&path);
    return (rc);
}


/*  ---------------------------------------------------------------------[<]-
    Function: remove_dir

    Synopsis: remove a directory.  Returns 0 if the directory could be
    removed; -1 if there was an error.  Under MS-DOS and OpenVMS accepts
    a directory name in UNIX format, i.e. containing '/' delimiters.  The
    directory must be empty to be removed.
    ---------------------------------------------------------------------[>]-*/

int
remove_dir (
    const char *path)
{
#if (defined (__UNIX__) || defined (__VMS_XOPEN) || defined (__OS2__))
    /*  Check that directory exists                                          */
    if (!file_is_directory (path))
        return (-1);

    return (rmdir (path));

#elif (defined (MSDOS_FILESYSTEM))
    int
        rc = 0;
    char
        *copy_path;

    /*  Check that directory exists                                          */
    if (!file_is_directory (path))
        return (-1);

    copy_path = mem_strdup (path);
    if (copy_path)
      {
        strconvch (copy_path, '/', '\\');
#   if (defined (WIN32))
        if (RemoveDirectory (copy_path))
            rc = 0;
        else
          {
LPVOID lpMsgBuf;
 
FormatMessage( 
    FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
    NULL,
    GetLastError(),
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
    (LPTSTR) &lpMsgBuf,
    0,
    NULL 
);
coprintf (lpMsgBuf);
           
            rc = -1;
            }
#   else
        rc = rmdir (copy_path);
#   endif
        mem_strfree (&copy_path);
      }
    return (rc);
#else
    return (-1);
#endif
}


/*  ---------------------------------------------------------------------[<]-
    Function: dir_usage

    Synopsis: Calculates the amount of disk space used by a directory, and
    optionally all directories below that.  If the total size is greater
    than 4Gb, returns an unspecified value.  Returns 0 if there was an error.
    ---------------------------------------------------------------------[>]-*/

qbyte
dir_usage (const char *path, Bool recurse)
{
    DIRST
        dir;
    qbyte
        usage = 0;
    char
        *full_dir;

    if (open_dir (&dir, path))
    do
      {
        if ((dir.file_attrs & ATTR_HIDDEN) != 0)
            ;   /*  Do nothing                                               */
        else
        if (recurse
        && (dir.file_attrs & ATTR_SUBDIR) != 0)
          {
            full_dir = locate_path (path, dir.file_name);
            usage += dir_usage (full_dir, TRUE);
            mem_free (full_dir);
          }
        else
            usage += dir.file_size;
      }
    while (read_dir (&dir));
    close_dir (&dir);
    return (usage);
}


/*  ---------------------------------------------------------------------[<]-
    Function: dir_files

    Synopsis: Calculates the number of files in a directory and optionally
    all directories below that.  Excludes directories from the count (thus,
    a directory containing only '.' and '..' contains 0 files.  Returns 0
    if there was an error.  Excludes hidden files.
    ---------------------------------------------------------------------[>]-*/

qbyte
dir_files (const char *path, Bool recurse)
{
    DIRST
        dir;
    qbyte
        files = 0;
    char
        *full_dir;

    if (open_dir (&dir, path))
    do
      {
        if ((dir.file_attrs & ATTR_HIDDEN) != 0)
            ;   /*  Do nothing                                               */
        else
        if (recurse
        && (dir.file_attrs & ATTR_SUBDIR) != 0)
          {
            full_dir = locate_path (path, dir.file_name);
            files += dir_files (full_dir, TRUE);
            mem_free (full_dir);
          }
        else
            files++;
      }
    while (read_dir (&dir));
    close_dir (&dir);
    return (files);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -