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

📄 sflfile.c

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

        if ((length)
        && (dest [length - 1] != PATHEND))
            dest [length++] = PATHEND;  /*  Add path-to-filename delimiter   */

        dest [length] = '\0';
        strcat (dest, name);
        add_extension (dest, dest, ext);
      }
    else
      {
        if (ext)
            add_extension (dest, name, ext);
        else
            strcpy (dest, name);
      }

    return (pathptr);
}


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

    Synopsis: Cycles the file: if the file already exists, renames the
    existing file.  This function tries to rename the file using the date
    of creation of the file; if this fails because an existing file had the
    same name, generates a guaranteed unique file name.  Returns TRUE if
    the cycle operation succeeded, or FALSE if it failed (e.g. due to a
    protection problem).  The how argument must be one of:
    <TABLE>
    CYCLE_ALWAYS        Cycle file unconditionally
    CYCLE_HOURLY        Cycle file if hour has changed
    CYCLE_DAILY         Cycle file if day has changed
    CYCLE_WEEKLY        Cycle file if week has changed
    CYCLE_MONTHLY       Cycle file if month has changed
    CYCLE_NEVER         Don't cycle the file
    </TABLE>
    ---------------------------------------------------------------------[>]-*/

Bool
file_cycle (
    const char *filename,
    int how)
{
    long
        file_date;                      /*  Datestamp of file                */
    char
        *point,
        *insert_at;                     /*  Where we start messing name      */
    int
        unique_nbr;                     /*  To generate a unique name        */

    ASSERT (filename);

    /*  If no cycling needed, do nothing                                     */
    if (!file_cycle_needed (filename, how))
        return (TRUE);                  /*  No errors, nothing in fact       */

    file_date = timer_to_date (get_file_time (filename));
    strcpy (full_name, filename);
    point = strrchr (full_name, '.');
    if (point)
      {
        strcpy (work_name, point);      /*  Save extension, if any           */
        *point = '\0';                  /*    and truncate original name     */
      }
    else
        strclr (work_name);

    /*  We leave up to 2 original letters of the filename, then stick-in     */
    /*  the 6-digit timestamp.                                               */
    insert_at = strrchr (full_name, '/');
#if (defined (MSDOS_FILESYSTEM))
    if (!insert_at)
        insert_at = strrchr (full_name, '\\');
#endif
    if (insert_at)
        insert_at++;                    /*  Bump past slash, if found        */
    else
        insert_at = full_name;

    if (*insert_at)                     /*  Bump insert_at twice, to leave   */
        insert_at++;                    /*    up to 2 letters before we      */
    if (*insert_at)                     /*    stick-in the date stamp        */
        insert_at++;

    /*  Format new name for file and make sure it does not already exist     */
    sprintf (insert_at, "%06d", (int) (file_date % 1000000L));
    strcat  (insert_at, work_name);
    if (file_exists (full_name))
      {
        point = strrchr (full_name, '.') + 1;
        for (unique_nbr = 0; unique_nbr < 1000; unique_nbr++)
          {
            sprintf (point, "%03d", unique_nbr);
            if (!file_exists (full_name))
                break;
          }
      }
    if (file_exists (full_name))
        return (FALSE);                 /*  We give up!                      */

    if (file_rename (filename, full_name))
        return (FALSE);                 /*  No permission                    */
    else
        return (TRUE);                  /*  Okay, it worked                  */
}


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

    Synopsis: Checks whether the file should be cycled or not.  Returns
    TRUE if the file needs to be cycled, FALSE if not.  The how argument
    must be one of:
    <TABLE>
    CYCLE_ALWAYS        Cycle file unconditionally
    CYCLE_HOURLY        Cycle file if hour has changed
    CYCLE_DAILY         Cycle file if day has changed
    CYCLE_WEEKLY        Cycle file if week has changed
    CYCLE_MONTHLY       Cycle file if month has changed
    CYCLE_NEVER         Don't cycle the file
    </TABLE>
    If the specified file does not exist or is not accessible, returns
    FALSE.
    ---------------------------------------------------------------------[>]-*/

Bool
file_cycle_needed (
    const char *filename,
    int how)
{
    long
        curr_time,                      /*  Current time                     */
        curr_date,                      /*  Current date                     */
        file_date,                      /*  Timestamp of file                */
        file_time;                      /*  Datestamp of file                */
    Bool
        cycle;                          /*  Do we want to cycle the file?    */

    ASSERT (filename);
    if (!file_exists (filename))        /*  Not found - nothing more to do   */
        return (FALSE);

    file_time = timer_to_time (get_file_time (filename));
    file_date = timer_to_date (get_file_time (filename));
    curr_time = time_now ();
    curr_date = date_now ();

    switch (how)
      {
        case CYCLE_ALWAYS:
            cycle = TRUE;
            break;
        case CYCLE_HOURLY:
            cycle = GET_HOUR (file_time) != GET_HOUR (curr_time);
            break;
        case CYCLE_DAILY:
            cycle = GET_DAY (file_date) != GET_DAY (curr_date);
            break;
        case CYCLE_WEEKLY:
            cycle = week_of_year (file_date) != week_of_year (curr_date);
            break;
        case CYCLE_MONTHLY:
            cycle = GET_MONTH (file_date) != GET_MONTH (curr_date);
            break;
        case CYCLE_NEVER:
            cycle = FALSE;
            break;
        default:
            cycle = FALSE;
      }
    return (cycle);
}


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

    Synopsis: Returns TRUE if the file has changed since it was last read.
    The calling program must supply the date and time of the file as it
    was read.  If the file is not present or accessible, returns FALSE.
    ---------------------------------------------------------------------[>]-*/

Bool
file_has_changed (
    const char *filename,
    long old_date,
    long old_time)
{
    long
        file_date,                      /*  Timestamp of file                */
        file_time;                      /*  Datestamp of file                */

    ASSERT (filename);
    if (!file_exists (filename))        /*  Not found - nothing more to do   */
        return (FALSE);

    file_time = timer_to_time (get_file_time (filename));
    file_date = timer_to_date (get_file_time (filename));
    if (file_date  > old_date
    || (file_date == old_date && file_time > old_time))
        return (TRUE);
    else
        return (FALSE);
}


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

    Synopsis: Handles system-specific case of extending a file that may not
    be in a valid state for such an operation. Returns TRUE if the extend
    can go ahead; returns FALSE if the extend cannot be permitted.

    Under MS-DOS and Windows, if the last byte in the file is Ctrl-Z (26)
    the file is truncated by 1 position to remove this character.
    ---------------------------------------------------------------------[>]-*/

Bool
safe_to_extend (
    const char *filename)
{
#if (defined (MSDOS_FILESYSTEM))
    int  handle;                        /*  Opened file handle               */
    char endoffile;                     /*  Last character in file           */

    ASSERT (filename);

    if (system_devicename (filename))
        return (FALSE);                 /*  Not allowed on device names      */

    handle = open (filename, O_RDWR + O_BINARY, S_IREAD | S_IWRITE);
    if (handle)                         /*  If not found, ignore             */
      {
        lseek (handle, -1, SEEK_END);
        read  (handle, &endoffile, 1);
        if (endoffile == 26)
            chsize (handle, filelength (handle) - 1);

        close (handle);
      }
#endif
    return (TRUE);
}


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

    Synopsis: Copies src to dest and adds ext if necessary.  Returns dest.
    Dest must be large enough for a fully-formatted filename; define it as
    char [FILE_NAME_MAX + 1].  The ext argument can start with or without
    a dot. If ext is null or empty, does nothing.
    ---------------------------------------------------------------------[>]-*/

char *
default_extension (
    char *dest,
    const char *src,
    const char *ext)
{
    int len, i;
    char *ptr;

    ASSERT (dest);
    ASSERT (src);

    if (dest != src)                    /*  Copy src to dest if not same     */
        strcpy (dest, src);

    if (ext != NULL && *ext != 0)
      {
        len = strlen (dest);
        for (i = len - 1, ptr = dest + i; i >= 0; i--, ptr--)
            if (*ptr == '\\' || *ptr == '/' || *ptr == '.')
                break;

        if (i < 0 || *ptr != '.')
          {
            if (*ext != '.')
              {
                dest [len++] = '.';
                dest [len] = '\0';
              }
            strcat (dest + len, ext);
          }
      }
    return (dest);
}


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

    Synopsis: Copies src to dest and enforces ext extension.  Returns dest.
    Dest must be large enough for a fully-formatted filename; define it as
    char [FILE_NAME_MAX + 1].  The ext argument can start with or without
    a dot.  If ext is null or empty, does nothing.
    ---------------------------------------------------------------------[>]-*/

char *
fixed_extension (
    char *dest,
    const char *src,
    const char *ext)
{
    ASSERT (dest);
    ASSERT (src);

    if (dest != src)                    /*  Copy src to dest if not same     */
        strcpy (dest, src);

    strip_extension (dest);
    return (default_extension (dest, dest, ext));
}


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

    Synopsis: Removes dot and extension from the name, if any was present.
    If the name contained multiple extensions, removes the last one only.
    Returns name.
    ---------------------------------------------------------------------[>]-*/

char *
strip_extension (
    char *name)
{
    char *dot, *slash;

    ASSERT (name);

    dot   = strrchr (name, '.');        /*  Find dot in name, if any         */
    slash = strrchr (name, '\\');       /*  Find last slash (DOS or Unix)    */
    if (slash == NULL)
        slash = strrchr (name, '/');
    if (dot > slash)
        *dot = 0;                       /*  If we had a dot, truncate name   */

    return (name);
}


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

    Synopsis: Copies src to dest and adds ext if necessary.  If extension
    starts with "." then it will be added, in place of any existing extension.
    If extension does not start with "." it will be added only if there is
    no existing extension.  If ext is null or empty, just copies src into
    dest if required.
    Dest must be large enough for a fully-formatted filename; define it as
    char [FILE_NAME_MAX + 1].
    ---------------------------------------------------------------------[>]-*/

char *
add_extension (
    char *dest,
    const char *src,
    const char *ext)
{
    char
        *result;

    ASSERT (dest);
    ASSERT (src);
    if (!src || !dest)
        return (NULL);

    if (!ext || *ext == '\0')
      {
        if (dest != src)                /*  Copy src to dest if not same     */

⌨️ 快捷键说明

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