💾 Archived View for gmi.noulin.net › gitRepositories › preprocessor › file › preprocessor.c.gmi captured on 2024-08-19 at 05:16:48. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-01-29)

-=-=-=-=-=-=-

preprocessor

Log

Files

Refs

LICENSE

preprocessor.c (7798B)

     1 
     2 #include "libsheepyObject.h"
     3 
     4 char *commentConfig = NULL;
     5 char *commentEndConfig = NULL;
     6 
     7 /* -------------------------------------------------------------------------------------
     8  * set comment config
     9  */
    10 internal void setCommentConfig(smallArrayt *input_lines) {
    11   forEachSmallArray(input_lines, L) {
    12     castS(l, L);
    13     if (hasG(l, "generator/pp comment config")) {
    14         smallStringt *lt = trimG(dupG(l));
    15         smallArrayt  *la = splitG(lt, ": generator/pp comment config");
    16         commentConfig    = getNDupG(la, rtChar, 0);
    17         commentEndConfig = trimG(getNDupG(la, rtChar, 1));
    18     }
    19     finishG(l);
    20   }
    21   if (not commentConfig) {
    22     commentConfig = strdup("#");
    23   }
    24 }
    25 
    26 internal smallArrayt *includePass(smallArrayt *input_lines, char *script_path) {
    27   createAllocateSmallArray(lines);
    28 
    29   char *include = catS(commentConfig, ":include");
    30 
    31   // Include files
    32   forEachSmallArray(input_lines, L) {
    33     castS(l, L);
    34     smallStringt *l2 = dupG(l);
    35     lowerG(l2);
    36     if (hasG(l2, include) and hasG(l2, "'")) {
    37       smallArrayt *a = splitG(l, "'");
    38       //putsG(l);
    39       //logVarG(a);
    40       char *file_to_include = catS(script_path, "/", getG(a, rtChar, 1));
    41       //logVarG(file_to_include);
    42       createAllocateSmallArray(file);
    43       readFileG(file, file_to_include);
    44       appendNSmashG(lines, file);
    45       terminateG(a);
    46     }
    47     else {
    48       pushG(lines, l);
    49     }
    50     terminateG(l2);
    51     finishG(l);
    52   }
    53   free(include);
    54   smashG(input_lines);
    55   return lines;
    56 }
    57 
    58 // Search and replace defines
    59 internal smallArrayt *definePass(smallArrayt *input_lines) {
    60   createAllocateSmallArray(lines);
    61 
    62   char *define = catS(commentConfig, ":define ");
    63   char *end    = catS(commentConfig, ":end");
    64   char *ppMark = catS(commentConfig, ":");
    65 
    66   // Assign values to defines
    67   createAllocateSmallDict(defines);
    68   char *status  = NULL;
    69   char *name = NULL;
    70   forEachSmallArray(input_lines, L) {
    71     castS(l, L);
    72     //logVarG(l);
    73     //logVarG(status);
    74     if (eqG(status, "define code")) {
    75       if (startsWithG(l, end)) {
    76         status = "no define";
    77       }
    78       else {
    79         smallArrayt *def = getG(defines, rtSmallArrayt, name);
    80         pushNFreeG(def, dupG(l));
    81         setPG(defines, name, def);
    82       }
    83     }
    84     if (hasG(l, define)) {
    85       smallArrayt *spl = splitG(l, define);
    86       free(name);
    87       name = getNDupG(spl, rtChar, 1);
    88       replaceG(&name, commentEndConfig, "", 1);
    89       terminateG(spl);
    90       createAllocateSmallArray(defineCode);
    91       setNFreeG(defines, name, defineCode);
    92       status = "define code";
    93     }
    94     finishG(l);
    95   }
    96   free(name);
    97   //logVarG(defines);
    98 
    99   // cg: replace define with value.
   100   char *statusDefine = "no define";
   101   forEachSmallArray(input_lines, L) {
   102     castS(l, L);
   103     //logVarG(l);
   104     //logVarG(status);
   105     //logVarG(statusDefine);
   106     if (not startsWithG(l, ppMark)) {
   107       pushG(lines, l);
   108     }
   109     else {
   110       if (eqG(l, ppMark)) {
   111         pushG(lines, l);
   112         finishG(l);
   113         continue;
   114       }
   115       status = "keep line";
   116       char *def = strdup(ssGet(l) + lenG(commentConfig) + 1);
   117       replaceG(&def, commentEndConfig, "", 1);
   118       trimG(&def);
   119       if (hasG(defines, def)) {
   120         status = "remove line";
   121       }
   122       if (not hasG(l, define) and ((not startsWithG(l, end)) or (startsWithG(l, end) and (eqG(statusDefine, "no define")))) and eqG(status, "keep line")) {
   123         pushG(lines, l);
   124       }
   125       if (hasG(defines, def)) {
   126         status = "remove line";
   127         smallArrayt *defCode = getNDupG(defines, rtSmallArrayt, def);
   128         //logVarG(def);
   129         //logVarG(defCode);
   130         appendNSmashG(lines, defCode);
   131       }
   132       if (startsWithG(l, end) and eqG(statusDefine, "define code")) {
   133         statusDefine = "no define";
   134       }
   135       if (startsWithG(l, define)) {
   136         statusDefine = "define code";
   137       }
   138     }
   139     finishG(l);
   140   }
   141   smashG(input_lines);
   142   terminateG(defines);
   143   freeManyS(define, end, ppMark);
   144   //logG(lines);
   145   return lines;
   146 }
   147 
   148 // Search tags
   149 // Process tags
   150 internal smallArrayt *tagPass(smallArrayt *input_lines) {
   151   createAllocateSmallArray(lines);
   152 
   153   char *ppMark = catS(commentConfig, ":");
   154 
   155   // Assign values to tags
   156   createAllocateSmallDict(tags);
   157   forEachSmallArray(input_lines, L) {
   158     castS(l, L);
   159     if (startsWithG(l, ppMark) and hasG(l, "=")) {
   160       smallStringt *l2 = dupG(l);
   161       replaceG(l2, commentEndConfig, "", 0);
   162       delG(l2, 0, lenG(commentConfig)+1);
   163       smallArrayt *spl = splitG(l2, "=");
   164       terminateG(l2);
   165       enumerateSmallArray(spl, T, i) {
   166         castS(t, T);
   167         setPG(spl, i, trimG(t));
   168         finishG(t);
   169       }
   170       char *s = getG(spl, rtChar, 1);
   171       setG(tags, getG(spl, rtChar, 0), s);
   172       terminateG(spl);
   173     }
   174     finishG(l);
   175   }
   176   //logVarG(tags);
   177 
   178   // cg: include or remove lines depending on tag value.
   179   char *status = "no tag";
   180   char *Yes, *No, *changeStatus;
   181   // support for inner tags in else closes
   182   createAllocateSmallArray(innerTags);
   183   forEachSmallArray(input_lines, L) {
   184     castS(l, L);
   185     //logVarG(status);
   186     //logVarG(innerTags);
   187     //logVarG(l);
   188     //put;
   189     if (startsWithG(l, ppMark) and (not hasG(l, "="))) {
   190       smallStringt *tag = dupG(l);
   191       delG(tag, 0, lenG(commentConfig)+1);
   192       replaceG(tag, commentEndConfig, "", 1);
   193       trimG(tag);
   194       if (eqG(tag, "end")) {
   195         delG(innerTags, -1, 0);
   196         status = "no tag";
   197       }
   198       else if (not hasG(l, "generator/pp comment config")) {
   199         if (eqG(tag, "else")) {
   200           if (eqG(status, "keep lines")) {
   201             status = "remove lines";
   202           }
   203           else {
   204             if (lenG(innerTags) > 1) {
   205               if (eqG(getG(innerTags, rtChar, 0), "remove lines")) {
   206                 status = "keep lines";
   207               }
   208             }
   209             else {
   210               status = "keep lines";
   211             }
   212           }
   213         }
   214         else {
   215           if (startsWithG(tag, "not ")) {
   216             delG(tag, 0, 4);
   217             Yes = "remove lines";
   218             No  = "keep lines";
   219           }
   220           else {
   221             Yes = "keep lines";
   222             No  = "remove lines";
   223           }
   224 
   225           if (lenG(innerTags) > 0) {
   226             if (eqG(getG(innerTags, rtChar, 0), "remove lines") and eqG(status, "keep lines")) {
   227                 changeStatus = "yes";
   228             }
   229             else {
   230                 changeStatus = "no";
   231             }
   232           }
   233           else {
   234             changeStatus = "yes";
   235           }
   236           if (eqG(changeStatus, "yes")) {
   237             if (hasG(tags, ssGet(tag))) {
   238               if (eqG(getG(tags, rtChar, ssGet(tag)), "0")) {
   239                 status = No;
   240               }
   241               else {
   242                 status = Yes;
   243               }
   244             }
   245             else {
   246               // tag doesnt exit, same as tag = 0
   247               status = No;
   248             }
   249           }
   250           pushG(innerTags, status);
   251         }
   252       }
   253     }
   254     if (not eqG(status, "remove lines") and not startsWithG(l, ppMark)) {
   255       pushG(lines, l);
   256     }
   257     finishG(l);
   258   }
   259   //logVarG(lines);
   260   terminateG(innerTags);
   261   smashG(input_lines);
   262   terminateG(tags);
   263   free(ppMark);
   264   return lines;
   265 }
   266 
   267 smallArrayt *preprocess(char *filename) {
   268   createAllocateSmallArray(lines);
   269 
   270   if (!fileExists(filename)) {
   271     printf("File not found: %s", filename);
   272   }
   273 
   274   char *dir = shDirnameG(filename);
   275   //logVarG(dir);
   276 
   277   readFileG(lines, filename);
   278 
   279   setCommentConfig(lines);
   280   //logVarG(commentConfig);
   281   //logVarG(commentEndConfig);
   282 
   283   lines = includePass(lines, dir);
   284   lines = definePass(lines);
   285   lines = tagPass(lines);
   286 
   287   free(dir);
   288   freen(commentConfig);
   289   freen(commentEndConfig);
   290   return lines;
   291 }
   292 
   293 bool checkLibsheepyVersionPreprocessor(const char *currentLibsheepyVersion) {
   294   return eqG(currentLibsheepyVersion, LIBSHEEPY_VERSION);
   295 }
   296