commit d02fafe3b0ab746fb1772c7aec7ee900cc9bcb31
parent aa0ad7d221d7219585c069373bb2d47e430d87ab
Author: Remy Noulin <loader2x@gmail.com>
Date: Sun, 20 May 2018 10:26:58 +0200
preprocessor library
package.yml | 15 +++
pp.txt | 21 ++++
ppCommentConfig.txt | 19 ++++
pp_inc.txt | 3 +
preprocessor.c | 289 ++++++++++++++++++++++++++++++++++++++++++++++++++++
preprocessor.h | 4 +
preprocessorTest.c | 18 ++++
7 files changed, 369 insertions(+)
Diffstat:
7 files changed, 369 insertions(+), 0 deletions(-)
diff --git a/package.yml b/package.yml
@@ -0,0 +1,15 @@
+---
+ name: preprocessor
+ version: 0.0.2
+ description: "simple preprocessor for any type of file"
+ bin: ./preprocessor.c
+ repository:
+ type: git
+ url: git+https://github.com/RemyNoulin/preprocessor.git
+ keywords:
+ - utility
+ author: Remy
+ license: MIT
+ bugs:
+ url: https://github.com/RemyNoulin/preprocessor/issues
+ homepage: https://github.com/RemyNoulin/preprocessor#readme
diff --git a/pp.txt b/pp.txt
@@ -0,0 +1,21 @@
+#:define a
+asd
+asd
+#:end
+
+#:include 'pp_inc.txt'
+
+#:a
+
+#:b=1
+#:c=0
+
+#:b
+wewef
+#:else
+no output
+#:end
+
+#:not c
+c is 0
+#:end
diff --git a/ppCommentConfig.txt b/ppCommentConfig.txt
@@ -0,0 +1,19 @@
+/*: generator/pp comment config */
+
+Define:
+/*:define wefw*/
+wefwef
+/*:end */
+
+/*:include 'pp_inc.txt' */
+
+/*:b=1*/
+
+/*:not b */
+b=0
+/*:else*/
+b=1
+/*:end*/
+
+Copy:
+/*:wefw*/
diff --git a/pp_inc.txt b/pp_inc.txt
@@ -0,0 +1,3 @@
+included txt
+
+line 3
diff --git a/preprocessor.c b/preprocessor.c
@@ -0,0 +1,289 @@
+
+#include "libsheepyObject.h"
+
+char *commentConfig = NULL;
+char *commentEndConfig = NULL;
+
+/* -------------------------------------------------------------------------------------
+ * set comment config
+ */
+internal void setCommentConfig(smallArrayt *input_lines) {
+ forEachSmallArray(input_lines, L) {
+ castS(l, L);
+ if (hasG(l, "generator/pp comment config")) {
+ smallStringt *lt = trimG(dupG(l));
+ smallArrayt *la = splitG(lt, ": generator/pp comment config");
+ commentConfig = getNDupG(la, rtChar, 0);
+ commentEndConfig = trimG(getNDupG(la, rtChar, 1));
+ }
+ finishG(l);
+ }
+ if (not commentConfig) {
+ commentConfig = strdup("#");
+ }
+}
+
+internal smallArrayt *includePass(smallArrayt *input_lines, char *script_path) {
+ createAllocateSmallArray(lines);
+
+ char *include = catS(commentConfig, ":include");
+
+ // Include files
+ forEachSmallArray(input_lines, L) {
+ castS(l, L);
+ smallStringt *l2 = dupG(l);
+ lowerG(l2);
+ if (hasG(l2, include) and hasG(l2, "'")) {
+ smallArrayt *a = splitG(l, "'");
+ //putsG(l);
+ //logVarG(a);
+ char *file_to_include = catS(script_path, "/", getG(a, rtChar, 1));
+ //logVarG(file_to_include);
+ createAllocateSmallArray(file);
+ readFileG(file, file_to_include);
+ appendNSmashG(lines, file);
+ terminateG(a);
+ }
+ else {
+ pushG(lines, l);
+ }
+ terminateG(l2);
+ finishG(l);
+ }
+ free(include);
+ smashG(input_lines);
+ return lines;
+}
+
+// Search and replace defines
+internal smallArrayt *definePass(smallArrayt *input_lines) {
+ createAllocateSmallArray(lines);
+
+ char *define = catS(commentConfig, ":define ");
+ char *end = catS(commentConfig, ":end");
+ char *ppMark = catS(commentConfig, ":");
+
+ // Assign values to defines
+ createAllocateSmallDict(defines);
+ char *status = NULL;
+ char *name = NULL;
+ forEachSmallArray(input_lines, L) {
+ castS(l, L);
+ //logVarG(l);
+ //logVarG(status);
+ if (eqG(status, "define code")) {
+ if (startsWithG(l, end)) {
+ status = "no define";
+ }
+ else {
+ smallArrayt *def = getG(defines, rtSmallArrayt, name);
+ pushNFreeG(def, dupG(l));
+ setPG(defines, name, def);
+ }
+ }
+ if (hasG(l, define)) {
+ smallArrayt *spl = splitG(l, define);
+ free(name);
+ name = getNDupG(spl, rtChar, 1);
+ replaceG(&name, commentEndConfig, "", 1);
+ terminateG(spl);
+ createAllocateSmallArray(defineCode);
+ setNFreeG(defines, name, defineCode);
+ status = "define code";
+ }
+ finishG(l);
+ }
+ free(name);
+ //logVarG(defines);
+
+ // cg: replace define with value.
+ char *statusDefine = "no define";
+ forEachSmallArray(input_lines, L) {
+ castS(l, L);
+ //logVarG(l);
+ //logVarG(status);
+ //logVarG(statusDefine);
+ if (not startsWithG(l, ppMark)) {
+ pushG(lines, l);
+ }
+ else {
+ if (eqG(l, ppMark)) {
+ pushG(lines, l);
+ finishG(l);
+ continue;
+ }
+ status = "keep line";
+ char *def = strdup(ssGet(l) + lenG(commentConfig) + 1);
+ replaceG(&def, commentEndConfig, "", 1);
+ trimG(&def);
+ if (hasG(defines, def)) {
+ status = "remove line";
+ }
+ if (not hasG(l, define) and ((not startsWithG(l, end)) or (startsWithG(l, end) and (eqG(statusDefine, "no define")))) and eqG(status, "keep line")) {
+ pushG(lines, l);
+ }
+ if (hasG(defines, def)) {
+ status = "remove line";
+ smallArrayt *defCode = getNDupG(defines, rtSmallArrayt, def);
+ //logVarG(def);
+ //logVarG(defCode);
+ appendNSmashG(lines, defCode);
+ }
+ if (startsWithG(l, end) and eqG(statusDefine, "define code")) {
+ statusDefine = "no define";
+ }
+ if (startsWithG(l, define)) {
+ statusDefine = "define code";
+ }
+ }
+ finishG(l);
+ }
+ smashG(input_lines);
+ terminateG(defines);
+ freeManyS(define, end, ppMark);
+ //logG(lines);
+ return lines;
+}
+
+// Search tags
+// Process tags
+internal smallArrayt *tagPass(smallArrayt *input_lines) {
+ createAllocateSmallArray(lines);
+
+ char *ppMark = catS(commentConfig, ":");
+
+ // Assign values to tags
+ createAllocateSmallDict(tags);
+ forEachSmallArray(input_lines, L) {
+ castS(l, L);
+ if (startsWithG(l, ppMark) and hasG(l, "=")) {
+ smallStringt *l2 = dupG(l);
+ replaceG(l2, commentEndConfig, "", 0);
+ delG(l2, 0, lenG(commentConfig)+1);
+ smallArrayt *spl = splitG(l2, "=");
+ terminateG(l2);
+ enumerateSmallArray(spl, T, i) {
+ castS(t, T);
+ setPG(spl, i, trimG(t));
+ finishG(t);
+ }
+ char *s = getG(spl, rtChar, 1);
+ setG(tags, getG(spl, rtChar, 0), s);
+ terminateG(spl);
+ }
+ finishG(l);
+ }
+ //logVarG(tags);
+
+ // cg: include or remove lines depending on tag value.
+ char *status = "no tag";
+ char *yes, *no, *changeStatus;
+ // support for inner tags in else closes
+ createAllocateSmallArray(innerTags);
+ forEachSmallArray(input_lines, L) {
+ castS(l, L);
+ //logVarG(status);
+ //logVarG(innerTags);
+ //logVarG(l);
+ //put;
+ if (startsWithG(l, ppMark) and (not hasG(l, "="))) {
+ smallStringt *tag = dupG(l);
+ delG(tag, 0, lenG(commentConfig)+1);
+ replaceG(tag, commentEndConfig, "", 1);
+ trimG(tag);
+ if (eqG(tag, "end")) {
+ delG(innerTags, -1, 0);
+ status = "no tag";
+ }
+ else if (not hasG(l, "generator/pp comment config")) {
+ if (eqG(tag, "else")) {
+ if (eqG(status, "keep lines")) {
+ status = "remove lines";
+ }
+ else {
+ if (lenG(innerTags) > 1) {
+ if (eqG(getG(innerTags, rtChar, 0), "remove lines")) {
+ status = "keep lines";
+ }
+ }
+ else {
+ status = "keep lines";
+ }
+ }
+ }
+ else {
+ if (startsWithG(tag, "not ")) {
+ delG(tag, 0, 4);
+ yes = "remove lines";
+ no = "keep lines";
+ }
+ else {
+ yes = "keep lines";
+ no = "remove lines";
+ }
+
+ if (lenG(innerTags) > 0) {
+ if (eqG(getG(innerTags, rtChar, 0), "remove lines") and eqG(status, "keep lines")) {
+ changeStatus = "yes";
+ }
+ else {
+ changeStatus = "no";
+ }
+ }
+ else {
+ changeStatus = "yes";
+ }
+ if (eqG(changeStatus, "yes")) {
+ if (hasG(tags, ssGet(tag))) {
+ if (eqG(getG(tags, rtChar, ssGet(tag)), "0")) {
+ status = no;
+ }
+ else {
+ status = yes;
+ }
+ }
+ else {
+ // tag doesnt exit, same as tag = 0
+ status = no;
+ }
+ }
+ pushG(innerTags, status);
+ }
+ }
+ }
+ if (not eqG(status, "remove lines") and not startsWithG(l, ppMark)) {
+ pushG(lines, l);
+ }
+ finishG(l);
+ }
+ //logVarG(lines);
+ terminateG(innerTags);
+ smashG(input_lines);
+ terminateG(tags);
+ free(ppMark);
+ return lines;
+}
+
+smallArrayt *preprocess(char *filename) {
+ createAllocateSmallArray(lines);
+
+ if (!fileExists(filename)) {
+ printf("File not found: %s", filename);
+ }
+
+ char *dir = shDirnameG(filename);
+ //logVarG(dir);
+
+ readFileG(lines, filename);
+
+ setCommentConfig(lines);
+ //logVarG(commentConfig);
+ //logVarG(commentEndConfig);
+
+ lines = includePass(lines, dir);
+ lines = definePass(lines);
+ lines = tagPass(lines);
+
+ freeManyS(dir, commentConfig, commentEndConfig);
+ return lines;
+}
diff --git a/preprocessor.h b/preprocessor.h
@@ -0,0 +1,4 @@
+
+#include "libsheepyObject.h"
+
+smallArrayt *preprocess(char *filename);
diff --git a/preprocessorTest.c b/preprocessorTest.c
@@ -0,0 +1,18 @@
+#! /usr/bin/env sheepy
+
+#include "libsheepyObject.h"
+#include "preprocessor.h"
+
+int main(int ARGC, char** ARGV) {
+
+ smallArrayt *a;
+ puts(BLD WHT "pp.txt" RST);
+ a = preprocess("pp.txt");
+ logG(a);
+ terminateG(a);
+
+ puts(BLD WHT "ppCommentConfig.txt" RST);
+ a = preprocess("ppCommentConfig.txt");
+ logG(a);
+ terminateG(a);
+}