💾 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
⬅️ Previous capture (2023-01-29)
-=-=-=-=-=-=-
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