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

📄 sflfile.c

📁 短小精悍的C语言标准函数库。提供450个以上的可移植的算法和工具代码。
💻 C
📖 第 1 页 / 共 5 页
字号:
    if no problems occurred, -1 if an error occurred, 1 if the destination
    file already exists.
    ---------------------------------------------------------------------[>]-*/

int
file_copy (
    const char *dest,
    const char *src,
    char mode)
{
    FILE *inf, *outf;
    char *buffer,
         openmode [3] = "??";
    size_t chars_read;                  /*  Amount read from stream          */
    int  feedback = 0;

    ASSERT (dest);
    ASSERT (src);
    if (file_exists (dest))
        return (1);                     /*  Cancel: dest already exists      */

#   if (defined (MSDOS_FILESYSTEM))
    if (system_devicename (dest) || system_devicename (src))
        return (-1);                    /*  Not allowed on device names      */
#   endif
#   if (defined (MSDOS_FILESYSTEM))
    openmode [1] = mode;
#   else
    openmode [1] = 0;
#   endif
    openmode [0] = 'r';
    if ((inf = fopen (src, openmode)) == NULL)
        return (-1);                    /*  Input file not found             */

    if ((buffer = mem_alloc (SHRT_MAX)) == NULL)
        feedback = -1;                  /*  Insufficient memory for buffer   */
    else
      {
        openmode [0] = 'w';
        if ((outf = fopen (dest, openmode)) == NULL)
          {
            mem_free (buffer);
            return (-1);                /*  Could not create output file     */
          }
        while ((chars_read = fread (buffer, 1, SHRT_MAX, inf)) != 0)
            if (fwrite (buffer, 1, chars_read, outf) != chars_read)
              {
                feedback = -1;
                break;
              }
        fclose (outf);
        mem_free (buffer);
      }
    fclose (inf);
    return (feedback);
}


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

    Synopsis: Copies the contents of src onto dest.  If dest does not exist,
    it is created.  Returns 0 if the concatenation operation succeeded, or
    -1 if some error occurred.
    ---------------------------------------------------------------------[>]-*/

int
file_concat (
    const char *src,
    const char *dest)
{
    FILE *inf, *outf;
    char *buffer;
    size_t chars_read;                  /*  Amount read from stream          */
    int  feedback = 0;

    ASSERT (src);
    ASSERT (dest);

#   if (defined (MSDOS_FILESYSTEM))
    if (system_devicename (dest) || system_devicename (src))
        return (-1);                    /*  Not allowed on device names      */
#   endif
    if ((inf = fopen (src, FOPEN_READ_BINARY)) == NULL)
        return (-1);                    /*  Input file not found             */

    if ((buffer = mem_alloc (SHRT_MAX)) == NULL)
        feedback = -1;                  /*  Insufficient memory for buffer   */
    else
      {
        if ((outf = fopen (dest, FOPEN_APPEND_BINARY)) == NULL)
          {
            mem_free (buffer);
            return (-1);                /*  Could not create output file     */
          }
        while ((chars_read = fread (buffer, 1, SHRT_MAX, inf)) != 0)
            if (fwrite (buffer, 1, chars_read, outf) != chars_read)
              {
                feedback = -1;
                break;
              }
        fclose (outf);
        mem_free (buffer);
      }
    fclose (inf);
    return (feedback);
}


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

    Synopsis: Renames a file from oldname to newname.  Returns 0 if okay,
    or -1 if there was an error.  Does not overwrite existing files.
    ---------------------------------------------------------------------[>]-*/

int
file_rename (
    const char *oldname,
    const char *newname)
{
#   if (defined (MSDOS_FILESYSTEM))
    char *dos_newname;
    int   feedback;

    ASSERT (oldname);
    ASSERT (newname);

    if (system_devicename (oldname) || system_devicename (newname))
        return (-1);                    /*  Not allowed on device names      */

    dos_newname = mem_strdup (newname);
    strconvch (dos_newname, '/', '\\');
    feedback = rename (oldname, dos_newname);
    mem_free (dos_newname);
    return (feedback);

#   else
    ASSERT (oldname);
    ASSERT (newname);

    return (rename (oldname, newname));
#   endif
}


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

    Synopsis: Deletes the specified file.  Returns 0 if okay, -1 in case of
    an error.
    ---------------------------------------------------------------------[>]-*/

int
file_delete (
    const char *filename)
{
#if (defined (__VMS__))
    ASSERT (filename);
    return (remove (filename));

#elif (defined (WIN32))
    int
        rc;

    ASSERT (filename);
    if (system_devicename (filename))
        return (-1);                    /*  Not allowed on device names      */

    rc = !DeleteFile (filename);
    if (rc && errno == EACCES)
      {
        /*  Under WinNT and Win95, a delete of a freshly-created file can
         *  sometimes fail with a permission error which passes after a
         *  short delay.  Ugly but it seems to work.
         */
        Sleep (200);
        rc = !DeleteFile (filename);
      }
    return (rc);
#else

    ASSERT (filename);
    return (unlink (filename));
#endif
}


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

    Synopsis: Returns TRUE if the file exists, or FALSE if it does not.
    ---------------------------------------------------------------------[>]-*/

Bool
file_exists (
    const char *filename)
{
    ASSERT (filename);
    return (file_mode (filename) > 0);
}


/*  -------------------------------------------------------------------------
 *  file_mode -- internal
 *
 *  Returns the file mode for the specified file or directory name; returns
 *  0 if the specified file does not exist.
 */

static dbyte
file_mode (const char *filename)
{
#if (defined (WIN32))
    DWORD   dwfa;
    dbyte   mode;

    ASSERT (filename);

    if (system_devicename (filename))
        return (0);                     /*  Not allowed on device names      */
        
    dwfa = GetFileAttributes (filename);
    if (dwfa == 0xffffffff)
        return (0);

    mode = 0;
    if (dwfa & FILE_ATTRIBUTE_DIRECTORY)
        mode |= S_IFDIR;
    else
        mode |= S_IFREG;

    if (!(dwfa & FILE_ATTRIBUTE_HIDDEN))
        mode |= S_IREAD;

    if (!(dwfa & FILE_ATTRIBUTE_READONLY))
        mode |= S_IWRITE;

    if (is_exe_file (filename))
        mode |= S_IEXEC;

    return (mode);

#else
    static struct stat
        stat_buf;

    ASSERT (filename);

#   if (defined (MSDOS_FILESYSTEM))
    /*  Handle simple disk specifiers ourselves, since some compilers cannot
     *  do a 'stat' on these.
     */
    if ( filename [1] == ':'
    && ((filename [2] == '\\' && filename [3] == '\0')
    ||  (filename [2] == '/'  && filename [3] == '\0')
    ||  (filename [2] == '\0')))
        return (S_IFDIR | S_IREAD | S_IWRITE);
#   endif

    if (strnull (filename))
        return (0);
    else
    if (stat ((char *) filename, &stat_buf) == 0)
        return ((dbyte) stat_buf.st_mode);
    else
        return (0);
#endif
}


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

    Synopsis: Scans a user-specified path symbol for a specific file, and
    returns the fully-specified filename.  Also adds an extension if this
    is required.

    The mode argument can be one of: r, w, a, or s for read, write, append,
    or static.  The function tries to locate existing files somewhere on the
    path.  New files are always created in the current directory.  Static
    files are created in the first directory on the path.

    The path argument is only used when more is r, a, or s.  If the path is
    NULL or empty, it is ignored.  Otherwise, the path is translated as an
    environment variable, and cut into a list of directory names.  The path
    is cut up as follows:
    <TABLE>
        MS-DOS    directory names separated by ';'. ;; means current.
        OS/2      directory names separated by ';'. ;; means current.
        Unix      directory names separated by ':'. :: means current.
        VMS       directory names separated by ','. " ", means current.
        Other     single directory name.
    </TABLE>

    When the mode is 'r' or 'a', searches the current directory before
    considering the path value.  When the path cannot be translated, and is
    not null or empty, it is used as a literal value.

    The name argument is the filename with or without extension.  It will
    be prefixed by the path and suffixed by the extension, if required.

    The ext argument is a default or mandatory extension.  If ext starts
    with a dot, it is mandatory and always used.  Otherwise it is used only
    if the name does not already have an extension.  If ext is NULL or empty,
    it is ignored.

    The total length of a name including path, name, extension, and any
    delimiters is FILE_NAME_MAX.  Names are truncated if too long.  The
    maximum size of one directory component is FILE_DIR_MAX chars.

    All parameters are case-sensitive; the precise effect of this depends on
    the system.  On MS-DOS, filenames are always folded to uppercase, but the
    path must be supplied in uppercase correctly.  On UNIX, all parameters are
    case sensitive.  On VMS, path and filenames are folded into uppercase.

    Returns a pointer to a static character array containing the filename; if
    mode is 'r' and the file does not exist, returns NULL.  If the mode is
    'w', 'a', or 's', always returns a valid filename.

    Under VMS, all filenames are handled in POSIX mode, i.e. /disk/path/file
    instead of $disk:[path]file.
    ---------------------------------------------------------------------[>]-*/

char *
file_where (
    char mode,
    const char *path,
    const char *name,
    const char *ext)
{
    const char
        *pathptr;                       /*  End of directory in path         */
    char
        *curdir;
    Bool
        search_curdir = TRUE;           /*  Look in current directory?       */

    ASSERT (name);
    if (ext != NULL && *ext)            /*  Append extension if not null     */
      {                                 /*    to get name + ext into         */
        if (ext [0] == '.')             /*    work_name.                     */
            fixed_extension (work_name, name, ext);
        else
            default_extension (work_name, name, ext);
      }
    else
        strcpy (work_name, name);
#if (NAMEFOLD == TRUE)
    strupc (work_name);                 /*  Fold to uppercase if needed      */
#endif

    if (path != NULL && *path)          /*  Get value of path, or NULL       */
      {
        pathptr = getenv (path);        /*  Translate path symbol            */
        if (pathptr == NULL)
          {
            pathptr = path;             /*  If not found, use literally      */
            search_curdir = FALSE;      /*  Path now takes priority          */
          }
#if (PATHFOLD == TRUE)                  /*  Fold to uppercase if necessary   */
        if (pathptr)
          {
            ASSERT (strlen (pathptr) < PATH_MAX);
            strcpy (path_name, pathptr);
            strupc (path_name);
            pathptr = path_name;        /*  Redirect to uppercase version    */
          }
#endif
      }
    else
        pathptr = NULL;

#if (defined (MSDOS_FILESYSTEM))
    /*  Normalise the path value by changing any slashes to backslashes      */
    if (pathptr)

⌨️ 快捷键说明

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