git.y1.nz

gbdk-2020

GameBoy Development Kit
download: https://git.y1.nz/archives/gbdk.tar.gz
README | Files | Log | Refs | LICENSE

gbdk-support/lcc/list.c

      1 // list.c
      2 
      3 #include <stdio.h>
      4 #include <stdarg.h>
      5 #include <stdlib.h>
      6 #include <stdbool.h>
      7 #include <string.h>
      8 //#include <assert.h>
      9 //#include <ctype.h>
     10 //#include <signal.h>
     11 
     12 #include "list.h"
     13 
     14 // From lcc.c
     15 extern void *alloc(int);
     16 extern char *strsave(const char *str);
     17 extern char *stringf(const char *fmt, ...);
     18 extern char *path_stripext(char *name);
     19 extern int matches_ext(const char * filename, const char * ext);
     20 extern int verbose;
     21 
     22 
     23 
     24 /* append - append a node with string str onto list, return new list */
     25 List append(char *str, List list) {
     26     List p = alloc(sizeof *p);
     27 
     28     p->str = str;
     29     if (list) {
     30         p->link = list->link;
     31         list->link = p;
     32     }
     33     else
     34         p->link = p;
     35     return p;
     36 }
     37 
     38 
     39 /* find - find 1st occurrence of str in list, return list node or 0 */
     40 List find(char *str, List list) {
     41     List b;
     42 
     43     b = list;
     44     if (b)
     45         do {
     46             if (strcmp(str, b->str) == 0)
     47                 return b;
     48         } while ((b = b->link) != list);
     49         return 0;
     50 }
     51 
     52 
     53 /* path2list - convert a colon- or semicolon-separated list to a list */
     54 List path2list(const char *path) {
     55     List list = NULL;
     56     char sep = ':';
     57 
     58     if (path == NULL)
     59         return NULL;
     60     if (strchr(path, ';'))
     61         sep = ';';
     62     while (*path) {
     63         char *p, buf[512];
     64         p = strchr(path, sep);
     65         if (p) {
     66             size_t len = p - path;
     67             if(len >= sizeof(buf)) len = sizeof(buf)-1;
     68             strncpy(buf, path, len);
     69             buf[len] = '\0';
     70         }
     71         else {
     72             strncpy(buf, path, sizeof(buf));
     73             buf[sizeof(buf)-1] = '\0';
     74         }
     75         if (!find(buf, list))
     76             list = append(strsave(buf), list);
     77         if (p == 0)
     78             break;
     79         path = p + 1;
     80     }
     81     return list;
     82 }
     83 
     84 
     85 // Replace extensions for filenames in a list
     86 void list_rewrite_exts(List list_in, char * ext_match, char * ext_new)
     87 {
     88     char * filepath_old;
     89 
     90     // Iterate through list and replace file extensions
     91     if (list_in) {
     92         List list_t = list_in;
     93         do {
     94             if (list_t->str) {
     95                 // Check to see if filname has desired extension
     96                 if (matches_ext(list_t->str, ext_match)) {
     97 
     98                     // Save a copy to free after re-assignment
     99                     filepath_old = list_t->str;
    100                     // Create a new string with the replaced suffix (stringf() allocs)
    101                     list_t->str = stringf("%s%s", path_stripext(list_t->str), ext_new);
    102                     if (verbose > 0) fprintf(stderr,"lcc: rename link obj (from -autobank): %s -> %s\n", filepath_old, list_t->str);
    103                 }
    104             }
    105             // Move to next list item, exit if start of list is reached
    106             list_t = list_t->link;
    107         } while (list_t != list_in);
    108     }
    109 }
    110 
    111 
    112 // Duplicate items with [ext_match] into new list items with [ext_new]
    113 void list_duplicate_to_new_exts(List list_in, char * ext_match, char * ext_new)
    114 {
    115     // List may have entries appended, cache original start
    116     List list_start = list_in;
    117 
    118     // Iterate through list and replace file extensions
    119     if (list_in) {
    120         List list_t = list_in;
    121         do {
    122             if (list_t->str) {
    123                 // Check to see if filname has desired extension
    124                 if (matches_ext(list_t->str, ext_match)) {
    125                     // Make a copy with the replaced extension into the list
    126                     list_in = append(stringf("%s%s", path_stripext(list_t->str), ext_new), list_in);
    127                     if (verbose > 0) fprintf(stderr,"lcc: add to rmlist (from -autobank): %s -> %s\n", list_t->str, stringf("%s%s", path_stripext(list_t->str), ext_new));
    128                 }
    129             }
    130             // Move to next list item, exit if start of list is reached
    131             list_t = list_t->link;
    132         } while (list_t != list_start);
    133     }
    134 }
    135 
    136 
    137 // Remove all items from a list
    138 List list_remove_all(List list_in) {
    139 
    140     // Well... the custom alloc() used for lists makes it hard to free their memory.
    141     // Instead just set the list to NULL to erase it and let cleanup happen on program exit.
    142     return NULL;
    143 
    144     /*
    145     List list_next;
    146     // Iterate through list and free memory
    147     if (list_in) {
    148         List list_t = list_in->link; // Advance to next item
    149         list_in->link = NULL; // Break list to create a stopping point
    150 
    151         do {
    152             // Copy next link before freeing the current item
    153             list_next = list_t->link;
    154             if (list_t) {
    155                 free(list_t);
    156                 list_t = NULL;
    157             }
    158             // Move to next list item, exit if start of list is reached
    159             list_t = list_next;
    160         } while (list_t && list_t->link);
    161     }
    162     return NULL;
    163     */
    164 }
    165 
    166 
    167 // Copies all items from [list_src] to [list_dest]
    168 // * optionally prefix items from [list_src] with [str_prefix]
    169 // * optionally append() a separate [str_add_before] for each item in [list_src] (use for space separated flags)
    170 List list_add_to_another(List list_dest, List list_src, char * str_prefix, char * str_add_before) {
    171 
    172     if (list_src) {
    173         List list_t = list_src->link; // Start at first list item (list usually points to END)
    174 
    175         // Iterate through [list_src] and copy into to [list_dest], exit once start is reached again
    176         do {
    177             if (list_t->str)
    178                 // Add str_add_before string as a separate item if present
    179                 if (str_add_before)
    180                     list_dest = append( stringf("%s", str_add_before), list_dest);
    181 
    182                 // pre-pend string prefix if present
    183                 if (str_prefix)
    184                     list_dest = append( stringf("%s%s", str_prefix, list_t->str), list_dest);
    185                 else
    186                     list_dest = append( stringf("%s", list_t->str), list_dest);
    187             // Move to next list item
    188             list_t = list_t->link;
    189         } while (list_t != list_src);
    190     }
    191 
    192     return list_dest; // Return updated list
    193 }

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.