cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

path_ops.c (4078B)


      1// This is free and unencumbered software released into the public domain.
      2// For more information, please refer to <https://unlicense.org>
      3// bbbbbr 2020
      4
      5#include <stdio.h>
      6#include <string.h>
      7#include <stdbool.h>
      8#include "common.h"
      9#include "path_ops.h"
     10
     11const char kExtensionSeparator = '.';
     12const char kPathSeparator =
     13
     14#ifdef _WIN32
     15  #ifndef _WIN32
     16     #define __WIN32__
     17  #endif
     18#endif
     19
     20#ifdef __WIN32__
     21                            '\\';
     22#else
     23                            '/';
     24#endif
     25
     26const char kPathSeparator_unix = '/';
     27
     28
     29void filename_replace_extension(char * filename, char * new_ext, size_t maxlen) {
     30
     31    // Use a temp work string in case out and in filename are the same pointer
     32    char temp[MAX_FILE_STR];
     33    char ext_sep[2] = {'\0'}; // default to empty string
     34
     35    // Add leading . to path if needed
     36    if (new_ext[0] != kExtensionSeparator) {
     37        ext_sep[0] = kExtensionSeparator;
     38        ext_sep[1] = '\0';
     39    }
     40
     41    // Strip extension from filename, append new extension
     42    filename_remove_extension(filename);
     43    snprintf(temp, maxlen, "%s%s%s", filename, ext_sep, new_ext);
     44    snprintf(filename, maxlen, "%s", temp);
     45}
     46
     47
     48void filename_replace_path(char * filename, char * new_path, size_t maxlen) {
     49
     50    // Use a temp work string in case out and in filename are the same pointer
     51    char temp[MAX_FILE_STR];
     52    char path_sep[2] = {'\0'}; // default to empty string
     53
     54    // Add trailing slash to path if needed (Windows needs both for when running under linix like env)
     55#ifdef __WIN32__
     56    if (((new_path[(strlen(new_path)-1)] != kPathSeparator)) &&
     57       ((new_path[(strlen(new_path)-1)] != kPathSeparator_unix)))
     58#else
     59    if ((new_path[(strlen(new_path)-1)] != kPathSeparator))
     60#endif
     61    {
     62        path_sep[0] = kPathSeparator;
     63        path_sep[1] = '\0';
     64    }
     65
     66    // Strip path from path+filename, pre-pend new path
     67    snprintf(temp, maxlen, "%s%s%s", new_path, path_sep, get_filename_from_path(filename));
     68    snprintf(filename, maxlen, "%s", temp);
     69}
     70
     71
     72const char * get_filename_from_path(const char * path)
     73{
     74    size_t i;
     75
     76    // Returns string starting at last occurrance of path separator char
     77    for(i = strlen(path) - 1; i; i--) {
     78
     79    // Add trailing slash to path if needed (Windows needs both for when running under linix like env)
     80    #ifdef __WIN32__
     81        if ((path[i] == kPathSeparator) || (path[i] == kPathSeparator_unix))
     82    #else
     83        if (path[i] == kPathSeparator)
     84    #endif
     85        {
     86            return &path[i+1];
     87        }
     88    }
     89    return path;
     90}
     91
     92
     93void filename_remove_extension(char * path)
     94{
     95    char * last_ext;
     96    char * last_slash;
     97
     98    // Find the last path separator if present
     99    // Starting from here ensures that no path ".." characters
    100    // get mistaken as extension delimiters.
    101    last_slash = strrchr (path, kExtensionSeparator);
    102    if (!last_slash)
    103        last_slash = path;
    104
    105    // Then check to see if there is an extension (starting with the last occurance of '.')
    106    // (tries to remove *all* trailing extensions backward until the last slash)
    107    last_ext = strrchr (last_slash, kExtensionSeparator);
    108    while (last_ext) {
    109        if (last_ext != NULL) {
    110            // If an extension is found then overwrite it with a string terminator
    111            *last_ext = '\0';
    112        }
    113        last_ext = strrchr (last_slash, kExtensionSeparator);
    114    }
    115}
    116
    117
    118bool get_path_without_filename(const char * path, char * path_only, uint32_t str_max)
    119{
    120    size_t i;
    121
    122   if (strlen(path) + 1 > str_max)
    123        return false;
    124
    125   for(i = strlen(path) - 1; i; i--) {
    126
    127    // Add trailing slash to path if needed (Windows needs both for when running under linix like env)
    128    #ifdef __WIN32__
    129        if ((path[i] == kPathSeparator) || (path[i] == kPathSeparator_unix))
    130    #else
    131        if (path[i] == kPathSeparator)
    132    #endif
    133        {
    134            memcpy(path_only, path, i+1 );
    135            path_only[i+1] = '\0';
    136            return true;
    137        }
    138    }
    139
    140    // memcpy(path_only, path, strlen(path));
    141    // No separater found, so no path
    142    path_only[0] = '\0';
    143    return true;
    144}
    145