cscg22-gearboy

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

path_ops.c (2951B)


      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 "common.h"
      8
      9const char kExtensionSeparator = '.';
     10const char kPathSeparator =
     11
     12#ifdef _WIN32
     13  #ifndef _WIN32
     14     #define __WIN32__
     15  #endif
     16#endif
     17
     18#ifdef __WIN32__
     19                            '\\';
     20#else
     21                            '/';
     22#endif
     23
     24
     25static const char * get_filename_from_path(const char * path);
     26static void filename_remove_extension(char * path);
     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
     55    if ((new_path[(strlen(new_path)-1)] != kPathSeparator)) {
     56        path_sep[0] = kPathSeparator;
     57        path_sep[1] = '\0';
     58    }
     59
     60    // Strip path from path+filename, pre-pend new path
     61    snprintf(temp, maxlen, "%s%s%s", new_path, path_sep, get_filename_from_path(filename));
     62    snprintf(filename, maxlen, "%s", temp);
     63}
     64
     65
     66static const char * get_filename_from_path(const char * path)
     67{
     68    size_t i;
     69
     70    // Returns string starting at last occurrance of path separator char
     71    for(i = strlen(path) - 1; i; i--) {
     72        if (path[i] == kPathSeparator) {
     73            return &path[i+1];
     74        }
     75    }
     76    return path;
     77}
     78
     79
     80static void filename_remove_extension(char * path)
     81{
     82    char * last_ext;
     83    char * last_slash;
     84
     85    // Find the last path separator if present
     86    // Starting from here ensures that no path ".." characters
     87    // get mistaken as extension delimiters.
     88    last_slash = strrchr (path, kExtensionSeparator);
     89    if (!last_slash)
     90        last_slash = path;
     91
     92    // Then check to see if there is an extension (starting with the last occurance of '.')
     93    // (tries to remove *all* trailing extensions backward until the last slash)
     94    last_ext = strrchr (last_slash, kExtensionSeparator);
     95    while (last_ext) {
     96        if (last_ext != NULL) {
     97            // If an extension is found then overwrite it with a string terminator
     98            *last_ext = '\0';
     99        }
    100        last_ext = strrchr (last_slash, kExtensionSeparator);
    101    }
    102}
    103