Advertisement
Guest User

ProjectXV4 - easyd source

a guest
Jan 16th, 2015
269
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 6.45 KB | None | 0 0
  1. // https://github.com/BaussProjects/ProjectXV4/
  2. // Compile with dmd
  3. import std.stdio;
  4. import std.file;
  5. alias fwrite = std.file.write;
  6. import std.array : replace, split, join;
  7. import std.algorithm : canFind, endsWith, startsWith, stripLeft;
  8.  
  9. void main(string[] args) {
  10.     // removes the compile folder ...
  11.     foreach (string name; dirEntries("cmpl", SpanMode.depth)) {
  12.         remove(name);
  13.     }
  14.  
  15.     rmdirRecurse("dsrc");
  16.     mkdir("dsrc");
  17.    
  18.     string[] cmd = ["dmd"];
  19.     string[] cmd2;
  20.     string[] excludes;
  21.     string[] extensions;
  22.     string buildPath;
  23.     bool makeDSource = false;
  24.     bool useReports = false;
  25.    
  26.     string makeFixedPath(string p) {
  27.         string opath = split(thisExePath(), "\\easyd")[0];
  28.         return replace(p, opath, "");
  29.     }
  30.    
  31.     auto text = readText(args[1]);
  32.     text = replace(text, "\r", "");
  33.     foreach (line; split(text, "\n")) {
  34.         if (canFind(line, "=") && !startsWith(line, "//")) {
  35.             auto data = split(line, "=");
  36.             switch (data[0]) {
  37.                 case "cmd": {
  38.                     cmd ~= split(data[1], " ");
  39.                     break;
  40.                 }
  41.                
  42.                 case "exclude": {
  43.                     excludes = split(data[1], ",");
  44.                     break;
  45.                 }
  46.                
  47.                 case "build": {
  48.                     buildPath = data[1];
  49.                     break;
  50.                 }
  51.                
  52.                 case "out": {
  53.                     buildPath = "-of" ~ buildPath ~ data[1];
  54.                     break;
  55.                 }
  56.                
  57.                 case "extensions": {
  58.                     extensions ~= split(data[1], ",");
  59.                     break;
  60.                 }
  61.                
  62.                 case "report": {
  63.                     if (data[1] == "true")
  64.                         useReports = true;
  65.                     break;
  66.                 }
  67.                
  68.                 case "dsource": {
  69.                     if(data[1] == "true")
  70.                         makeDSource = true;
  71.                     break;
  72.                 }
  73.                
  74.                 default: {
  75.                     writefln("Invalid setting. '%s' is not a valid setting.", data[0]);
  76.                     readln();
  77.                     return;
  78.                 }
  79.             }
  80.         }
  81.     }
  82.    
  83.     string[] dmd_cmd = cmd[1 .. $];
  84.    
  85.     foreach (string f; dirEntries("src", SpanMode.depth)) {
  86.         if (!canFind(f, "."))
  87.             continue;
  88.            
  89.         auto extension = split(f, ".")[1];
  90.         if (canFind(extensions, extension)) {
  91.             bool canAdd = true;
  92.             foreach (exclude; excludes) {
  93.                 bool splitCanFind(string s1, string s2) {
  94.                     scope auto sf = split(s2, "\\");
  95.                     foreach (rf; sf) {
  96.                         scope auto rff = split (rf, ".");
  97.                         foreach (ef; rff) {
  98.                             if (ef == s1) {
  99.                                 return true;
  100.                             }
  101.                         }
  102.                     }
  103.                     return false;
  104.                 }
  105.                 if (splitCanFind(exclude, f)) {
  106.                     canAdd = false;
  107.                     break;
  108.                 }
  109.             }
  110.             if (canAdd) {
  111.                 import std.path : baseName;
  112.                
  113.                 if(extension == "d") {
  114.                     int c = 0;
  115.                     import std.algorithm : count;
  116.                     import std.conv : to;
  117.                     c = count(dirEntries("cmpl", SpanMode.shallow));
  118.                    
  119.                     if (baseName(f) != "package.d") {
  120.                         fwrite("cmpl\\" ~ to!string(c) ~ "_" ~ baseName(f) ~ ".d", compile(f, useReports));
  121.                     }
  122.                     else {
  123.                         fwrite("cmpl\\package.d", compile(f, useReports));
  124.                     }
  125.                    
  126.                     if (makeDSource) {
  127.                         string ff = makeFixedPath(f);
  128.                         dmd_cmd ~= "dsrc\\" ~ ff;
  129.                         auto fsp = split(ff, "\\");
  130.                         fsp = fsp[0 .. $-1];
  131.                         string fd = "dsrc\\" ~ join(fsp, "\\");
  132.                         if (!exists(fd)) {
  133.                             mkdirRecurse(fd);
  134.                         }
  135.                        
  136.                         fwrite("dsrc\\" ~ ff, compile(f, false));
  137.                     }  
  138.                 }
  139.                 else
  140.                     copy(f, "cmpl\\" ~ baseName(f));
  141.             }
  142.         }
  143.     }
  144.    
  145.     foreach (string f; dirEntries("cmpl", SpanMode.depth)) {
  146.         cmd ~= f;
  147.     }
  148.    
  149.     if (exists(buildPath))
  150.         remove(buildPath);
  151.     cmd ~= buildPath;
  152.     dmd_cmd ~= buildPath;
  153.    
  154.     import std.process;
  155.     scope auto logFile = File("errors.log", "w");
  156.     auto dmdPid = spawnProcess(cmd, stdin, stdout, logFile);
  157.     if (wait(dmdPid) != 0) {
  158.         writeln("Failed to compile! View errors.log for more information.");
  159.         import core.thread;
  160.         Thread.sleep(dur!("msecs")(2000));
  161.     }
  162.     fwrite("cmd.txt", join(dmd_cmd, " "));
  163. }
  164.  
  165. string compile(string dfile, bool useReports) {
  166.     string[] src;
  167.     auto text = readText(dfile);
  168.     text = replace(text, "\r", "");
  169.     int reportCount = 0;
  170.     bool reportMode = false;
  171.     foreach (sline; split(text, "\n")) {
  172.         string line = stripLeft(sline, ' ');
  173.         line = stripLeft(line, '\t');
  174.        
  175.         if (line == "report<") {
  176.             if (!useReports)
  177.                 continue;
  178.             reportCount = 0;
  179.             reportMode = true;
  180.             src ~= "import std.stdio;";
  181.         }
  182.         else if (line.length > 3 && (line[0 .. 3] == "__r") || line == "__r") {
  183.             if (!useReports)
  184.                 continue;
  185.             if (!reportMode) {
  186.                 src ~= line;
  187.                 continue;
  188.             }
  189.             import std.conv : to;
  190.             string nick = "#" ~ to!string(reportCount);
  191.             if (line != "__r")
  192.                 nick = split(line, "__r")[1];
  193.             reportCount++;
  194.             src ~= "writefln(\"%s report executed!\", \"" ~ nick ~ "\");";
  195.         }
  196.         else if (line.length > 3 && (line[0 .. 3] == "__v")) {
  197.             if (!useReports)
  198.                 continue;
  199.             if (!reportMode) {
  200.                 src ~= line;
  201.                 continue;
  202.             }
  203.             auto vars = split(line, "__v")[1];
  204.             string varOut = "writefln(\"";
  205.             foreach (var; split(vars, ","))
  206.                 varOut ~= var ~ " is '%s' ";
  207.             varOut.length -= 1;
  208.             varOut ~= "\", " ~ vars ~ ");";
  209.             src ~= varOut;
  210.         }
  211.         else if (line == ">;") {
  212.             if (!useReports)
  213.                 continue;
  214.             if (!reportMode) {
  215.                 src ~= line;
  216.                 continue;
  217.             }
  218.             reportMode = false;
  219.         }
  220.         else if (line.length > 6 && (line[0 .. 7] == "aswitch")) {
  221.             auto spl = split(line, " ");
  222.             string swArg = spl[1];
  223.             string basedir = spl[2];
  224.             string cl = spl[3];
  225.             string params = spl[4];
  226.            
  227.             auto calls = findMatchingCalls("src\\" ~ basedir, cl, params);
  228.             foreach (imp; calls[0]) {
  229.                 src ~= imp;
  230.             }
  231.             foreach (call; calls[1]) {
  232.                 src ~= call;
  233.             }
  234.         }
  235.         else {
  236.             src ~= sline;
  237.         }
  238.     }
  239.     return join(src, "\r\n");
  240. }
  241.  
  242. auto findMatchingCalls(string basedir, string call, string params) {
  243.     string[][] results;
  244.    
  245.     string[] _imports;
  246.     string[] _cases;
  247.    
  248.     foreach (string name; dirEntries(basedir, SpanMode.depth)) {
  249.         if (endsWith(name, ".d")) {
  250.             auto text = readText(name);
  251.             text = replace(text, "\r", "");
  252.             string[] res;
  253.             string nextImport;
  254.             foreach (line; split(text, "\n")) {
  255.                 if (startsWith(line, "module")) {
  256.                     nextImport = replace(line, "module", "import");
  257.                 }
  258.                 else if (canFind(line, call ~ "(")) {
  259.                     //writefln("'%s' '%s' %s", call, canFind(line, call ~ "("), line);
  260.                     //readln();
  261.                     auto spl = split(line, call ~ "(");
  262.                     auto packetId = split(spl[1], ")")[0];
  263.                    
  264.                     auto packetCall = split(line, "(");
  265.                     string pcall = split(packetCall[$-2], " ")[$-1];
  266.                     import std.string : format;
  267.                     _cases ~= format("case %s: %s(%s); break;", packetId, pcall, params);
  268.                     _imports ~= nextImport;
  269.                     break;
  270.                 }
  271.             }
  272.         }
  273.     }
  274.     results = [_imports, _cases];
  275.     return results;
  276. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement