├── .gitattributes ├── Examples ├── BigMenu │ ├── All.cpy │ └── template.cpy ├── Class │ ├── main.cpy │ └── rectangle.cpy ├── Contest problems │ ├── 897A. Scarborough Fair │ │ ├── a.cpy │ │ └── template.cpy │ ├── 897B. Chtholly's request │ │ ├── b.cpy │ │ └── template.cpy │ ├── 897C. Nephren gives a riddle │ │ ├── c.cpy │ │ └── template.cpy │ ├── 900A. Find Extra One │ │ ├── a.cpy │ │ └── template.cpy │ ├── 900B. Position in Fraction │ │ ├── b.cpy │ │ └── template.cpy │ └── 900C. Remove Extra One │ │ ├── c.cpy │ │ └── template.cpy ├── Hybrid project │ ├── cppFunction.cpp │ ├── cppFunction.h │ ├── cpyFunction.cpy │ └── main.cpp ├── Quick loop │ └── main.cpy ├── Quick print │ └── main.cpy ├── Red black tree │ ├── 1.in │ ├── 1.out │ ├── 2.in │ ├── 2.out │ ├── 3.in │ ├── 3.out │ ├── 4.in │ ├── 4.out │ ├── 5.in │ ├── 5.out │ ├── ReadMe.txt │ ├── main.cpy │ └── rntree.cpy ├── Selection Sort │ ├── main.cpy │ └── sort.cpy ├── Simple array max min │ └── main.cpy └── Simple sum │ ├── main.cpy │ └── template.cpy ├── LICENSE ├── README.md └── Source ├── Makefile ├── defines.h ├── dependenciesMapper.cpp ├── dependenciesMapper.h ├── directoryHandler.cpp ├── directoryHandler.h ├── extensionHandler.cpp ├── extensionHandler.h ├── file.cpp ├── file.h ├── firstReplaces.cpp ├── firstReplaces.h ├── headerGen.cpp ├── headerGen.h ├── line.cpp ├── line.h ├── main.cpp ├── sourceGen.cpp ├── sourceGen.h ├── string.cpp └── string.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto -------------------------------------------------------------------------------- /Examples/BigMenu/All.cpy: -------------------------------------------------------------------------------- 1 | #raw "template.cpy" 2 | 3 | genArray(int size, maxVal) 4 | arr = (int*) malloc(size * sizeof(int)); 5 | for(i = 0; i < size; i++); 6 | arr[i] = rand() % maxVal 7 | return arr 8 | 9 | findBiggestSmallest(int * arr, int size) 10 | max = arr[0] 11 | min = arr[0]; 12 | 13 | for i = 0; i < size; i++ 14 | if arr[i] > max 15 | max = arr[i] 16 | 17 | if arr[i] < min 18 | min = arr[i] 19 | 20 | return max, min 21 | 22 | operations(int a, b) 23 | sum = a + b 24 | subtract = a - b 25 | multiply = a * b 26 | divide = a / b 27 | return sum, subtract, multiply, divide 28 | 29 | main() 30 | srand(time(NULL)) 31 | 32 | int * arr = (int*)malloc(5 * sizeof(int)); 33 | 34 | size = 0 35 | maxVal = 0 36 | option = 0 37 | 38 | do 39 | ! 40 | ! "Test All" 41 | ! 42 | ! "Options" 43 | ! "0 - Stop" 44 | ! "1 - Test input/output (please, do it first)" 45 | ! "2 - Test if-else" 46 | ! "3 - Test for/rof" 47 | ! "4 - Test while" 48 | ! "5 - Function multiple return's" 49 | ! "6 - Print generated array" 50 | ! 51 | ? "Choose option? " option 52 | switch option 53 | case 0: break 54 | case 1: 55 | ! "Test" 56 | ? "Input size and max value: " size maxVal 57 | 58 | !! "size=" size "maxVal=" maxVal 59 | ! 60 | ! endl 61 | break 62 | case 2: 63 | if size < 0 64 | ! "ERROR: Negative value" 65 | else if size == 0 66 | ! "ERROR: Zero value" 67 | else 68 | ! "size=" size " passed test" 69 | ! 70 | break 71 | case 3: 72 | !! "for up:" 73 | for x size 74 | !! x 75 | ! 76 | !! "for down:" 77 | rof x size 78 | !! x 79 | ! 80 | !! "for up:" 81 | for x 2 size 82 | !! x 83 | ! 84 | !! "for down:" 85 | rof x size 2 86 | !! x 87 | ! 88 | ! 89 | break 90 | case 4: 91 | ! "while up:" 92 | x = 0 93 | while x++ < size 94 | !! x 95 | ! 96 | ! "while down:" 97 | x = size 98 | while x-- > 0 99 | !! x 100 | ! 101 | ! 102 | break 103 | case 5: 104 | sum, _, mult = operations(20, 10) 105 | ! "sum=" sum 106 | ! "mult=" mult 107 | ! 108 | break 109 | case 6: 110 | arr = genArray(size, maxVal) 111 | 112 | max, min = findBiggestSmallest(arr, size) 113 | 114 | !! "Array:" 115 | for i = 0; i < size; i++ 116 | !! arr[i] 117 | ! 118 | ! "Biggest number:" max 119 | ! "Smallest number:" min 120 | ! 121 | break 122 | default: 123 | ! "\nERROR: Invalid option.\n" 124 | while ( option != 0 ); 125 | ! 126 | -------------------------------------------------------------------------------- /Examples/BigMenu/template.cpy: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace std 17 | -------------------------------------------------------------------------------- /Examples/Class/main.cpy: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #include "rectangle.h" 4 | 5 | main() 6 | Rectangle rect 7 | 8 | int w, h 9 | 10 | ? "Input rectangle width: " w 11 | ? "Input rectangle height: " h 12 | rect.set_values(w, h) 13 | ! "Rectangle area =" rect.area() 14 | return 0 -------------------------------------------------------------------------------- /Examples/Class/rectangle.cpy: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Rectangle 5 | int width, height; 6 | public: 7 | 8 | known Rectangle() 9 | width = 20 10 | height = 10 11 | 12 | set_values(int x, y) 13 | width = x 14 | height = y 15 | 16 | area () 17 | return width * height 18 | -------------------------------------------------------------------------------- /Examples/Contest problems/897A. Scarborough Fair/a.cpy: -------------------------------------------------------------------------------- 1 | //This is the solution to http://codeforces.com/contest/897/problem/A 2 | //A. Scarborough Fair 3 | #raw "template.cpy" 4 | 5 | int main() 6 | int n, m 7 | string s 8 | cin >> n >> m >> s 9 | while m-- 10 | int l, r 11 | char c, cn 12 | cin >> l >> r >> c >> cn 13 | l--; r--; 14 | for i = l; i <= r; i++ 15 | if s[i] == c 16 | s[i] = cn 17 | cout << s -------------------------------------------------------------------------------- /Examples/Contest problems/897A. Scarborough Fair/template.cpy: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std 3 | #define fastcin ios_base::sync_with_stdio(false) 4 | #define precisecout cout << setprecision(999) 5 | #define pb push_back 6 | #define inf 0x3f3f3f3f 7 | #define mod109 1000000007 8 | #define ll long long 9 | #define binary(x) bitset<8*sizeof(x)>(x) -------------------------------------------------------------------------------- /Examples/Contest problems/897B. Chtholly's request/b.cpy: -------------------------------------------------------------------------------- 1 | //This is the solution to http://codeforces.com/contest/897/problem/B 2 | //B. Chtholly's request 3 | #raw "template.cpy" 4 | 5 | ll compose(ll half) 6 | sz = 0; 7 | aux = half 8 | res = half 9 | while aux 10 | sz++; 11 | res *= 10 12 | res += aux%10 13 | aux /= 10 14 | return res 15 | 16 | int main() 17 | int k, p 18 | cin >> k >> p 19 | ll sum = 0 20 | ll half = 1 21 | while k-- 22 | sum += compose(half) 23 | sum %= p 24 | half++ 25 | cout << sum -------------------------------------------------------------------------------- /Examples/Contest problems/897B. Chtholly's request/template.cpy: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std 3 | #define fastcin ios_base::sync_with_stdio(false) 4 | #define precisecout cout << setprecision(999) 5 | #define pb push_back 6 | #define inf 0x3f3f3f3f 7 | #define mod109 1000000007 8 | #define ll long long 9 | #define binary(x) bitset<8*sizeof(x)>(x) -------------------------------------------------------------------------------- /Examples/Contest problems/897C. Nephren gives a riddle/c.cpy: -------------------------------------------------------------------------------- 1 | //This is the solution to http://codeforces.com/contest/897/problem/C 2 | //C. Nephren gives a riddle 3 | #raw "template.cpy" 4 | 5 | #define N 100007 6 | 7 | ll size[N]; 8 | 9 | string f0 = "What are you doing at the end of the world? Are you busy? Will you save us?"; 10 | string f1 = "What are you doing while sending \"" 11 | string f2 = "\"? Are you busy? Will you send \"" 12 | string f3 = "\"?" 13 | 14 | void setSize() 15 | size[0] = f0.size(); 16 | for i = 1; i < 56; i++ 17 | size[i] = f1.size() + f2.size() + f3.size() + 2*size[i-1]; 18 | for i = 56; i < N; i++ 19 | size[i] = size[i-1] 20 | 21 | void query(ll n, k) 22 | if n == 0 23 | if k < f0.size() 24 | cout << f0[k] 25 | else 26 | cout << '.' 27 | return 28 | 29 | if k < f1.size() 30 | cout << f1[k] 31 | return 32 | 33 | k -= f1.size() 34 | 35 | if k < size[n-1] 36 | query(n-1, k) 37 | return 38 | 39 | k -= size[n-1] 40 | if k < f2.size() 41 | cout << f2[k] 42 | return 43 | 44 | k -= f2.size() 45 | 46 | if k < size[n-1] 47 | query(n-1, k) 48 | return 49 | 50 | k -= size[n-1] 51 | 52 | if k < f3.size() 53 | cout << f3[k] 54 | return 55 | 56 | cout << '.' 57 | return 58 | 59 | 60 | int main() 61 | setSize() 62 | int q 63 | cin >> q 64 | while q-- 65 | ll n, k 66 | cin >> n >> k 67 | k-- 68 | query(n, k) -------------------------------------------------------------------------------- /Examples/Contest problems/897C. Nephren gives a riddle/template.cpy: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std 3 | #define fastcin ios_base::sync_with_stdio(false) 4 | #define precisecout cout << setprecision(999) 5 | #define pb push_back 6 | #define inf 0x3f3f3f3f 7 | #define mod109 1000000007 8 | #define ll long long 9 | #define binary(x) bitset<8*sizeof(x)>(x) -------------------------------------------------------------------------------- /Examples/Contest problems/900A. Find Extra One/a.cpy: -------------------------------------------------------------------------------- 1 | //This is the solution to http://codeforces.com/contest/900/problem/A 2 | //A. Find Extra One 3 | #raw "template.cpy" 4 | 5 | int main() 6 | int n, x, y 7 | cin n 8 | s1 = 0 9 | s2 = 0 10 | while n-- 11 | cin x y 12 | if x > 0 13 | s1++ 14 | else 15 | s2++ 16 | 17 | if(s1 > 1 && s2 > 1) 18 | ! "No" 19 | else 20 | ! "Yes" -------------------------------------------------------------------------------- /Examples/Contest problems/900A. Find Extra One/template.cpy: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std 3 | #define fastcin ios_base::sync_with_stdio(false) 4 | #define precisecout cout << setprecision(999) 5 | #define pb push_back 6 | #define inf 0x3f3f3f3f 7 | #define mod109 1000000007 8 | #define ll long long 9 | #define binary(x) bitset<8*sizeof(x)>(x) -------------------------------------------------------------------------------- /Examples/Contest problems/900B. Position in Fraction/b.cpy: -------------------------------------------------------------------------------- 1 | //This is the solution to http://codeforces.com/contest/900/problem/B 2 | //B. Position in Fraction 3 | #raw "template.cpy" 4 | 5 | int main() 6 | int a, b, c 7 | cin a b c 8 | dec = 0 9 | while dec++ <= b 10 | div = 0 11 | res = 0 12 | 13 | a *= 10 14 | 15 | while a > res 16 | res += b 17 | div++ 18 | if a < res 19 | res -= b 20 | div-- 21 | 22 | pa = a 23 | a -= res 24 | //? pa a div dec 25 | 26 | if div%10 == c 27 | ! dec 28 | return 0 29 | 30 | 31 | ! -1 -------------------------------------------------------------------------------- /Examples/Contest problems/900B. Position in Fraction/template.cpy: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std 3 | #define fastcin ios_base::sync_with_stdio(false) 4 | #define precisecout cout << setprecision(999) 5 | #define pb push_back 6 | #define inf 0x3f3f3f3f 7 | #define mod109 1000000007 8 | #define ll long long 9 | #define binary(x) bitset<8*sizeof(x)>(x) -------------------------------------------------------------------------------- /Examples/Contest problems/900C. Remove Extra One/c.cpy: -------------------------------------------------------------------------------- 1 | //This is the solution to http://codeforces.com/contest/900/problem/C 2 | //C. Remove Extra One 3 | #raw "template.cpy" 4 | 5 | #define N 100007 6 | 7 | int main() 8 | int n 9 | cin n 10 | a = 0 11 | b = 0 12 | int x 13 | 14 | int blk[N] 15 | memset(blk, 0, sizeof(blk)) 16 | 17 | t = n 18 | while t-- 19 | cin x 20 | if x > a 21 | b = a 22 | a = x 23 | blk[a]-- 24 | else if x > b 25 | b = x 26 | blk[a]++ 27 | 28 | int mb = -1000 29 | int mval = -1000 30 | //? n 31 | for int i = 1; i <= n; i++ 32 | //? i blk[i] 33 | if blk[i] > mb 34 | mb = blk[i] 35 | mval = i 36 | 37 | ! mval -------------------------------------------------------------------------------- /Examples/Contest problems/900C. Remove Extra One/template.cpy: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std 3 | #define fastcin ios_base::sync_with_stdio(false) 4 | #define precisecout cout << setprecision(999) 5 | #define pb push_back 6 | #define inf 0x3f3f3f3f 7 | #define mod109 1000000007 8 | #define ll long long 9 | #define binary(x) bitset<8*sizeof(x)>(x) -------------------------------------------------------------------------------- /Examples/Hybrid project/cppFunction.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | vector createVector(int maxValue, int elementAmount){ 6 | vector v; 7 | for(int i = 0; i < elementAmount; i++) 8 | v.push_back(rand()%maxValue); 9 | return v; 10 | } -------------------------------------------------------------------------------- /Examples/Hybrid project/cppFunction.h: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | vector createVector(int maxValue, int elementAmount); 5 | -------------------------------------------------------------------------------- /Examples/Hybrid project/cpyFunction.cpy: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | tuple readTwoIntegers() 7 | int a, b 8 | ? a b 9 | return a, b 10 | 11 | int vectorSum(vector v) 12 | sum = 0 13 | for int i : v 14 | sum += i 15 | return sum 16 | -------------------------------------------------------------------------------- /Examples/Hybrid project/main.cpp: -------------------------------------------------------------------------------- 1 | #include "cppFunction.h" 2 | #include "cpyFunction.h" 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | void printVector(vector v){ 8 | for(int i : v) 9 | cout << i << " "; 10 | cout << endl; 11 | } 12 | 13 | int main(){ 14 | cout << "Input vector size and max value: "; 15 | tuple input = readTwoIntegers(); 16 | 17 | int size = get<0>(input); 18 | int maxVal = get<1>(input); 19 | 20 | vector v = createVector(maxVal, size); 21 | cout << "Vector: "; 22 | printVector(v); 23 | cout << "Sum: "<< vectorSum(v) << endl; 24 | } -------------------------------------------------------------------------------- /Examples/Quick loop/main.cpy: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | main() 4 | ! "for i 10" 5 | for i 10 6 | !! i 7 | ! 8 | ! 9 | 10 | ! "for i 5 10" 11 | for i 5 10 12 | !! i 13 | ! 14 | ! 15 | 16 | ! "for i 4 10 2" 17 | for i 4 10 2 18 | !! i 19 | ! 20 | ! 21 | 22 | ! "for i 10 4 -2" 23 | for i 10 4 -2 24 | !! i 25 | ! 26 | ! 27 | 28 | ! "for i = (float)0; i < 10; i += 0.5" 29 | for i = (float)0; i < 10; i += 0.5 30 | !! i 31 | ! 32 | ! 33 | 34 | ! "Note that:" 35 | ! "for i = 0; i < 10; i += 0.5" 36 | ! "will not work in this case because i is initialized as a integer" 37 | 38 | ! 39 | ! "rof is a shorthand for reversed direction for loops, when step is not specified, it will assume step is -1" 40 | ! "otherwise it will use the given step with given direction, becoming equivalent a for loop" 41 | ! 42 | ! "rof i 10" 43 | rof i 10 44 | !! i 45 | ! 46 | ! 47 | 48 | ! "rof i 10 5" 49 | rof i 10 5 50 | !! i 51 | ! 52 | ! 53 | 54 | ! "rof i 4 10 2" 55 | rof i 4 10 2 56 | !! i 57 | ! 58 | ! 59 | 60 | ! "rof i 10 4 -2" 61 | rof i 10 4 -2 62 | !! i 63 | ! 64 | ! 65 | 66 | ! "rof i = (float)0; i < 10; i += 0.5" 67 | rof i = (float)0; i < 10; i += 0.5 68 | !! i 69 | ! 70 | ! -------------------------------------------------------------------------------- /Examples/Quick print/main.cpy: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main() 4 | int a, b; 5 | std::string str; 6 | ? "Type two integers: " a b "Well done! Now type a string: " str "Congratulations!\n" 7 | 8 | ! 9 | ! "Following line is produced by command: ! a b str \"Second string\"" 10 | ! a b str "Second string" 11 | ! 12 | 13 | !! "!! is a quick print without ending the line..." 14 | ! " Ending the line in the following command exemplified!" 15 | 16 | ! "Following line is produced by command: ?? a b str" 17 | ?? a b str 18 | 19 | //Cout still works, and can optionally imply "<<" 20 | std::cout "A is valued " a std::endl 21 | std::cout << "B is valued " << b << std::endl -------------------------------------------------------------------------------- /Examples/Red black tree/1.in: -------------------------------------------------------------------------------- 1 | 12 2 | 1 5 3 | 1 4 4 | 1 3 5 | 1 2 6 | 1 1 7 | 2 1 8 | 3 1 9 | 4 10 | 5 11 | 6 12 | 7 13 | 8 -------------------------------------------------------------------------------- /Examples/Red black tree/1.out: -------------------------------------------------------------------------------- 1 | 2 2 | erro 3 | 5 4 | 1 5 | 4 2 1 3 5 6 | 1 2 3 4 5 7 | 1 3 2 5 4 8 | -------------------------------------------------------------------------------- /Examples/Red black tree/2.in: -------------------------------------------------------------------------------- 1 | 16 2 | 1 6 3 | 1 3 4 | 1 12 5 | 1 1 6 | 1 2 7 | 1 4 8 | 1 15 9 | 2 15 10 | 3 1 11 | 2 6 12 | 3 6 13 | 4 14 | 5 15 | 8 16 | 7 17 | 6 -------------------------------------------------------------------------------- /Examples/Red black tree/2.out: -------------------------------------------------------------------------------- 1 | erro 2 | erro 3 | 12 4 | 4 5 | 15 6 | 1 7 | 1 4 3 2 15 12 6 8 | 1 2 3 4 6 12 15 9 | 6 2 1 3 4 12 15 10 | -------------------------------------------------------------------------------- /Examples/Red black tree/3.in: -------------------------------------------------------------------------------- 1 | 21 2 | 1 10 3 | 1 5 4 | 1 3 5 | 1 15 6 | 1 20 7 | 1 7 8 | 1 6 9 | 1 12 10 | 1 22 11 | 1 8 12 | 2 3 13 | 2 7 14 | 2 10 15 | 3 5 16 | 3 22 17 | 3 20 18 | 5 19 | 4 20 | 7 21 | 6 22 | 8 -------------------------------------------------------------------------------- /Examples/Red black tree/3.out: -------------------------------------------------------------------------------- 1 | 5 2 | 8 3 | 12 4 | 3 5 | 20 6 | 15 7 | 3 8 | 22 9 | 3 5 6 7 8 10 12 15 20 22 10 | 7 5 3 6 15 10 8 12 20 22 11 | 3 6 5 8 12 10 22 20 15 7 -------------------------------------------------------------------------------- /Examples/Red black tree/4.in: -------------------------------------------------------------------------------- 1 | 20 2 | 1 25 3 | 1 10 4 | 1 15 5 | 1 7 6 | 1 5 7 | 1 3 8 | 1 50 9 | 1 55 10 | 1 20 11 | 1 18 12 | 1 2 13 | 2 15 14 | 3 15 15 | 2 55 16 | 3 2 17 | 4 18 | 5 19 | 6 20 | 7 21 | 8 -------------------------------------------------------------------------------- /Examples/Red black tree/4.out: -------------------------------------------------------------------------------- 1 | 18 2 | 10 3 | erro 4 | erro 5 | 55 6 | 2 7 | 15 7 3 2 5 10 50 20 18 25 55 8 | 2 3 5 7 10 15 18 20 25 50 55 9 | 2 5 3 10 7 18 25 20 55 50 15 -------------------------------------------------------------------------------- /Examples/Red black tree/5.in: -------------------------------------------------------------------------------- 1 | 26 2 | 1 25 3 | 1 23 4 | 1 27 5 | 1 21 6 | 1 19 7 | 1 29 8 | 1 31 9 | 1 20 10 | 1 22 11 | 1 28 12 | 1 30 13 | 1 15 14 | 1 12 15 | 1 10 16 | 1 8 17 | 1 26 18 | 1 35 19 | 2 25 20 | 3 25 21 | 2 12 22 | 3 12 23 | 4 24 | 5 25 | 6 26 | 7 27 | 8 -------------------------------------------------------------------------------- /Examples/Red black tree/5.out: -------------------------------------------------------------------------------- 1 | 26 2 | 23 3 | 15 4 | 10 5 | 35 6 | 8 7 | 25 19 12 10 8 15 21 20 23 22 29 27 26 28 31 30 35 8 | 8 10 12 15 19 20 21 22 23 25 26 27 28 29 30 31 35 -------------------------------------------------------------------------------- /Examples/Red black tree/ReadMe.txt: -------------------------------------------------------------------------------- 1 | This is a simple red-black tree implementation with no remotion, to compile run cpy on main.cpy 2 | .in files are input files and .out are the respective outputs 3 | The input is formated as: 4 | O X 5 | O being: 6 | 1 = insertion of X 7 | 2 = sucessor of X 8 | 3 = predecessor of X 9 | 4 = Query for tree's maximum value 10 | 5 = Query for tree's minimum value 11 | 6 = Pre order impression of all nodes 12 | 7 = In order impression of all nodes 13 | 8 = Post order impression of all nodes 14 | 15 | This code was made as a concept test, compiled to C++, converted to C and used for other purpose than explaining, yet, you may get some usefull information from it. -------------------------------------------------------------------------------- /Examples/Red black tree/main.cpy: -------------------------------------------------------------------------------- 1 | #include "rntree.h" 2 | 3 | int main() 4 | //scanf("%*[^\n]") 5 | 6 | int o, x; 7 | node ** root = tree_init() 8 | while scanf("%d", &o) != EOF 9 | if o == 1 10 | scanf("%d", &x) 11 | //printf("INSERT %d\n", x) 12 | tree_insert(root, x) 13 | (*root)->red = 0 14 | else if (o == 2) 15 | scanf("%d", &x) 16 | //printf("tree_sucessor %d\n", x) 17 | int sucessor = tree_sucessor(root, *root, x); 18 | if sucessor != -1 19 | printf("%d\n", sucessor) 20 | else 21 | printf("erro\n") 22 | else if o == 3 23 | scanf("%d", &x) 24 | //printf("tree_predecessor %d\n", x) 25 | int predecessor = tree_predecessor(root, *root, x); 26 | if predecessor != -1 27 | printf("%d\n", predecessor) 28 | else 29 | printf("erro\n") 30 | else if o == 4 31 | //printf("tree_max %d\n", x) 32 | printf("%d\n", tree_max(*root)) 33 | else if o == 5 34 | //printf("tree_min %d\n", x) 35 | printf("%d\n", tree_min(*root)) 36 | else if o == 6 37 | //printf("tree_preOrder %d\n", x) 38 | tree_preOrder(*root) 39 | printf("\n") 40 | else if o == 7 41 | //printf("tree_inOrder %d\n", x) 42 | tree_inOrder(*root) 43 | printf("\n") 44 | else if o == 8 45 | //printf("tree_postOrder %d\n", x) 46 | tree_postOrder(*root) 47 | printf("\n") 48 | else if o == 9 49 | //printf("treeCostlyPrint %d\n", x) 50 | treeCostlyPrint(*root) 51 | printf("\n") 52 | tree_free(root) -------------------------------------------------------------------------------- /Examples/Red black tree/rntree.cpy: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef struct node 5 | int data 6 | char red 7 | struct node *left, *right 8 | 9 | node* node_init (int data) 10 | node * n = (node *)malloc(sizeof(node)) 11 | n->red = 1 12 | n->left = NULL 13 | n->right = NULL 14 | n->data = data 15 | return n 16 | 17 | node** tree_init() 18 | node ** tree = (node **)malloc(sizeof(node*)) 19 | (*tree) = NULL 20 | return tree 21 | 22 | char isRed(node * n) 23 | return n != NULL && n->red 24 | 25 | void costlyPrint (node * n, int depth, ideal) 26 | if n == NULL 27 | return 28 | if depth < ideal 29 | costlyPrint(n->left, depth+1, ideal) 30 | costlyPrint(n->right, depth+1, ideal) 31 | else if depth == ideal 32 | char c = n->red == 1 ? 'r' : 'b' 33 | printf("%d%c ", n->data, c) 34 | 35 | void treeCostlyPrint (node * n) 36 | for int i = 0; i < 15; i++ 37 | printf("%d - ", i) 38 | costlyPrint(n, 0, i) 39 | printf("\n") 40 | 41 | void rotateRight (node ** r) 42 | node * n = *r 43 | node * l = n->left 44 | n->left = l->right 45 | l->right = n 46 | *r = l 47 | //printf("rotateRight %d %d\n", n->data, l->data) 48 | 49 | void rotateLeft (node ** r) 50 | node * n = *r 51 | node * l = n->right 52 | n->right = l->left 53 | l->left = n 54 | *r = l 55 | //printf("rotateLeft %d %d\n", n->data, l->data) 56 | 57 | void colorSwap (node ** n) 58 | if (*n)->left != NULL 59 | (*n)->left->red = 0 60 | if (*n)->right != NULL 61 | (*n)->right->red = 0 62 | (*n)->red = 1 63 | //printf("colorSwap %d %d %d\n", (*n)->data, (*n)->left->data, (*n)->right->data) 64 | 65 | void tree_balance (node** n) 66 | if isRed((*n)->left) && isRed((*n)->right) && (isRed((*n)->right->right) || isRed((*n)->right->left) || isRed((*n)->left->right) || isRed((*n)->left->left)) 67 | colorSwap(n) 68 | else if isRed((*n)->left) 69 | if (isRed((*n)->left->right)) 70 | rotateLeft(&(*n)->left) 71 | rotateRight(n) 72 | (*n)->red = 0 73 | (*n)->right->red = 1 74 | else if isRed((*n)->left->left) 75 | rotateRight(n) 76 | (*n)->red = 0 77 | (*n)->right->red = 1 78 | else if isRed((*n)->right) 79 | if isRed((*n)->right->left) 80 | rotateRight(&(*n)->right) 81 | rotateLeft(n) 82 | (*n)->red = 0 83 | (*n)->left->red = 1 84 | else if isRed((*n)->right->right) 85 | rotateLeft(n) 86 | (*n)->red = 0 87 | (*n)->left->red = 1 88 | //printf("bal %d\n", (*n)->data) 89 | 90 | void tree_insert (node** n, int data) 91 | if *n == NULL 92 | *n = node_init(data) 93 | return; 94 | 95 | if data < (*n)->data 96 | tree_insert(&(*n)->left, data) 97 | else 98 | tree_insert(&(*n)->right, data) 99 | 100 | tree_balance(n) 101 | return; 102 | 103 | void tree_preOrder (node* n) 104 | if n == NULL 105 | return 106 | printf("%d ", n->data) 107 | tree_preOrder(n->left) 108 | tree_preOrder(n->right) 109 | 110 | void tree_inOrder (node* n) 111 | if n == NULL 112 | return 113 | tree_inOrder(n->left) 114 | printf("%d ", n->data) 115 | tree_inOrder(n->right) 116 | 117 | void tree_postOrder (node* n) 118 | if n == NULL 119 | return 120 | tree_postOrder(n->left) 121 | tree_postOrder(n->right) 122 | printf("%d ", n->data) 123 | 124 | 125 | node* tree_find (node * n, int key) 126 | if n == NULL 127 | return NULL 128 | 129 | if key == n->data 130 | return n 131 | else if key < n->data 132 | return tree_find(n->left, key) 133 | else if key > n->data 134 | return tree_find(n->right, key) 135 | 136 | int tree_sucessor (node** root, node* n, int key) 137 | n = tree_find(n, key) 138 | if n != NULL && n->right != NULL 139 | return tree_min(n->right); 140 | 141 | struct node* successor = NULL; 142 | n = *root; 143 | while root != NULL 144 | if key < n->data 145 | successor = n 146 | n = n->left 147 | else if key > n->data 148 | n = n->right 149 | else 150 | break 151 | 152 | if successor == NULL 153 | return -1 154 | return successor->data 155 | 156 | int tree_predecessor (node** root, node* n, int key) 157 | n = tree_find(n, key) 158 | if n != NULL && n->left != NULL 159 | return tree_max(n->left); 160 | 161 | struct node* predecessor = NULL; 162 | n = *root; 163 | while root != NULL 164 | if key > n->data 165 | predecessor = n 166 | n = n->right 167 | else if key < n->data 168 | n = n->left 169 | else 170 | break 171 | 172 | if predecessor == NULL 173 | return -1 174 | return predecessor->data 175 | 176 | int tree_max (node* n) 177 | if n->right != NULL 178 | return tree_max(n->right) 179 | else 180 | return n->data 181 | 182 | int tree_min (node* n) 183 | if n->left != NULL 184 | return tree_min(n->left) 185 | else 186 | return n->data 187 | 188 | void tree_free2 (node* n) 189 | if n == NULL 190 | return 191 | tree_free2(n->left) 192 | tree_free2(n->right) 193 | free(n) 194 | 195 | void tree_free (node** t) 196 | tree_free2(*t) 197 | free(t) -------------------------------------------------------------------------------- /Examples/Selection Sort/main.cpy: -------------------------------------------------------------------------------- 1 | /* 2 | This is a simple, working, selection sort example 3 | Here you can see how to work with multiple files and 4 | imply variables's types, curly brackets, parenthesis and semicolons 5 | 6 | To compile this code simply run cpy example.cpy 7 | 8 | OBS: 9 | The -k flag keeps the generated source files after compilation, 10 | this way you can see how your code looks in c++ (and share your code in c++)! 11 | The -b flag makes your c++ source code more readable by adding some linebreaks 12 | */ 13 | #include "sort.h" 14 | #include 15 | #include 16 | #include 17 | using namespace std 18 | int * genArray(int size) 19 | //arr implies it's tipe from atribution, thus becoming int * 20 | arr = (int*)malloc(sizeof(int) * size) 21 | 22 | //i does the same, becoming an integer 23 | for i size 24 | arr[i] = rand()%size 25 | return arr 26 | 27 | void printArray(int * arr, int size) 28 | for i size 29 | cout << arr[i] << " " 30 | cout << endl 31 | 32 | int main(int argc, char ** argv) 33 | n = 10 34 | if argc == 2 35 | n = atoi(argv[1]) 36 | 37 | srand(time(NULL)) 38 | arr = genArray(n) 39 | printArray(arr, n) 40 | selectionSort(arr, n) 41 | printArray(arr, n) 42 | 43 | -------------------------------------------------------------------------------- /Examples/Selection Sort/sort.cpy: -------------------------------------------------------------------------------- 1 | void selectionSort(int * arr, int n) 2 | for i = 0; i < n; i++ 3 | for j = i+1; j < n; j++ 4 | if arr[i] > arr[j] 5 | aux = arr[i] 6 | arr[i] = arr[j] 7 | arr[j] = aux -------------------------------------------------------------------------------- /Examples/Simple array max min/main.cpy: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std 5 | 6 | genArray(int size, maxVal) 7 | arr = (int*)malloc(size * sizeof(int)); 8 | for i size 9 | arr[i] = rand()%maxVal 10 | return arr 11 | 12 | findBiggestSmallest(int * arr, int size) 13 | max = arr[0] 14 | min = arr[0]; 15 | 16 | for i size 17 | if arr[i] > max 18 | max = arr[i] 19 | 20 | if arr[i] < min 21 | min = arr[i] 22 | 23 | return max, min 24 | 25 | main() 26 | srand(time(NULL)) 27 | int size, maxVal 28 | ? "Input array size and max value: " size maxVal 29 | 30 | arr = genArray(size, maxVal) 31 | 32 | max, min = findBiggestSmallest(arr, size) 33 | 34 | !! "Array:" 35 | for i = 0; i < size; i++ 36 | !! arr[i] 37 | ! 38 | 39 | ! "Biggest number:" max 40 | ! "Smallest number:" min -------------------------------------------------------------------------------- /Examples/Simple sum/main.cpy: -------------------------------------------------------------------------------- 1 | #raw "template.cpy" 2 | int main() 3 | int a, b; 4 | 5 | ? a b 6 | ! (a + b) -------------------------------------------------------------------------------- /Examples/Simple sum/template.cpy: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std 3 | #define fastcin ios_base::sync_with_stdio(false) 4 | #define precisecout cout << setprecision(999) 5 | #define pb push_back 6 | #define inf 0x3f3f3f3f 7 | #define mod109 1000000007 8 | #define ll long long 9 | #define binary(x) bitset<8*sizeof(x)>(x) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 vrsperanza 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CPY 2 | To create the executable simply execute make on the source folder 3 | To compile cpy files use the created executable targeting the main file of the required project: 4 | cpy main.cpy -flags 5 | 6 | ``` 7 | CPY is a (Pre)Compiler of .cpy files, those are basically C++ without redundancy. 8 | Curly brackets are implied from indentation 9 | Semicolons are implied from line breaks (lines must be marked to continue, not to break) 10 | Headers are interpreted from the sources and includes 11 | Can return multiple values from functions 12 | While still being statically typed (and just as fast as C++, for it is just a pre-compiler) 13 | variable types can be implied from equity or manually specified. 14 | Sequenced style declarations have also been generalised to functions: 15 | "int a, b" works inside function declarations 16 | Simply execute the compiler followed by your source folder and it will create the executable 17 | ``` 18 | In any of the given examples, "cpy mainFile.cpy" will create a working executable 19 | 20 | Features: 21 | 22 | Generates all the necessary headers and compiles resulting project. If you include a header "#include "somecode.h"" of a "somecode.cpy", the header will be generated (as well as the cpp file) 23 | 24 | Default compilation is optimized in makefile style, only recompiling modified files, increasing overall compilation speed 25 | With the use of a flag (-ex) generates a c++ project folder, makefile included, ready for sharing 26 | 27 | Implies semicolons from endlines, 28 | Implies {} using identation, 29 | 30 | Can return multiple values from functions: 31 | ``` 32 | operations(int a, b) 33 | sum = a + b 34 | subtract = a - b 35 | multiply = a * b 36 | divide = a / b 37 | return sum, subtract, multiply, divide 38 | 39 | main() 40 | sum, _, mult = operations(20, 10) 41 | ! sum mult 42 | 43 | //Produces the output: 44 | 30 10 45 | 46 | //_ variables mean ignore this return value 47 | //The last variables can be omitted if not necessary 48 | ``` 49 | 50 | Can optionally imply variable types from assignment: 51 | ``` 52 | a = 10 53 | b = a 54 | //Declares a and b as integers 55 | ``` 56 | 57 | In order not to deduce the type of a directly visible variable or of a class constructor, the known tag was created 58 | ``` 59 | class Rectangle 60 | int width, height; 61 | public: 62 | 63 | known Rectangle() 64 | width = 20 65 | height = 10 66 | //This will declare a Rectangle constructor 67 | 68 | void Rectangle::set_values(int w, h) 69 | known width = w 70 | known height = h 71 | //This will tell the compiler width and height are inside the Rectangle namespace, thus not implying variable declaration 72 | ``` 73 | 74 | In case the known tag is a problem, or variable implication is simply not to your liking, it can be completely disabled by using the -ni flag 75 | 76 | Can deduce function type from return value: 77 | ``` 78 | sum(int a, b) 79 | return a + b 80 | //Is equivalent to: 81 | int sum(int a, b) 82 | return a + b 83 | ``` 84 | 85 | Implies function argument types based on previous: 86 | ``` 87 | somefunction(string a, b) 88 | code... 89 | //Declares a and b as strings 90 | ``` 91 | 92 | Optionally implies parenthesis on if, switch, for and while: 93 | ``` 94 | if x > 0 95 | ... 96 | else if x < 0 97 | ... 98 | for int i = 0; i < 100; i++ 99 | ... 100 | while x-- 101 | ... 102 | switch x 103 | case 1: 104 | ... 105 | break 106 | ... 107 | ``` 108 | 109 | Four new print functions: 110 | ``` 111 | ! arg1 arg2 arg3 112 | //! prints a new line, with each argument separated by spaces 113 | 114 | !! arg1 arg2 arg3 115 | //!! prints each argument separated by spaces 116 | 117 | ? "prompt" variable variable "prompt" variable 118 | //? Reads input given inside variables using cin and prints given strings using cout 119 | 120 | ?? arg1 arg2 arg3 121 | //?? is meant for debugging, prints a new debug line in the format: 122 | //arg1 = ContentOfArg1 | arg2 = ContentOfArg2 | arg3 = ContentOfArg3 123 | ``` 124 | 125 | Simplified for sintax: 126 | ``` 127 | for i a 128 | ... 129 | //Iterates i from 0 up to a, 1 at a time 130 | 131 | for i a b 132 | ... 133 | //Iterates i from a up to b-1, 1 at a time 134 | 135 | rof i a 136 | ... 137 | //Iterates i from a down to b, 1 at a time 138 | 139 | rof i a b 140 | ... 141 | //Iterates i from a down to b, c at a time 142 | 143 | for i a b c 144 | ... 145 | //Iterates i from a up to b-1, c at a time 146 | 147 | for i a b -c 148 | ... 149 | //Iterates i from a down to b, c at a time 150 | 151 | //The standard sintax still works normally 152 | for i = (float)a; i <= b; i += 0.5 153 | ... 154 | //Iterates i from a up to b 0.5 at a time 155 | ``` 156 | 157 | New precompilation tag: #raw "file" 158 | Includes file's content directly in code before exporting, usefull if you can only send one file instead of a project - intended for templates at competitive coding. 159 | 160 | Can be compiled alongside normal cpp files, so hybrid projects are possible
161 | CPY can also compile pure cpp projects, it will automatically link files and compile them intelligently 162 | 163 | Only edits clones of the source files in a separate folder 164 | 165 | ``` 166 | USAGE: cpy SourceCode Flags 167 | Flags: 168 | -h: Shows this help page 169 | -b: Use line breaks on itermediate code 170 | -s: Silent compilation, only prints errors 171 | -ex: Exports project to a directory containing only c++ source and a Makefile 172 | -r: Automatically runs compiled code 173 | -ni: Disables variable implication 174 | -nc: Doesn't compile resulting code 175 | -o target: Specifies target executable name, when not specified target = a 176 | -OtherFlags: Redirects flag to underlying compiler (g++) 177 | ``` 178 | -------------------------------------------------------------------------------- /Source/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | g++ -std=c++11 -o cpy main.cpp dependenciesMapper.cpp extensionHandler.cpp file.cpp directoryHandler.cpp headerGen.cpp line.cpp firstReplaces.cpp sourceGen.cpp string.cpp 3 | 4 | cpy: main.o dependenciesMapper.o extensionHandler.o file.o directoryHandler.o headerGen.o line.o firstReplaces.o sourceGen.o string.o 5 | g++ -std=c++11 -o cpy main.o dependenciesMapper.o extensionHandler.o file.o directoryHandler.o headerGen.o line.o firstReplaces.o sourceGen.o string.o 6 | main.o: main.cpp 7 | dependenciesMapper.o: dependenciesMapper.cpp 8 | extensionHandler.o: extensionHandler.cpp 9 | file.o: file.cpp 10 | directoryHandler.o: directoryHandler.cpp 11 | headerGen.o: headerGen.cpp 12 | line.o: line.cpp 13 | firstReplaces.o: firstReplaces.cpp 14 | sourceGen.o: sourceGen.cpp 15 | string.o: string.cpp -------------------------------------------------------------------------------- /Source/defines.h: -------------------------------------------------------------------------------- 1 | #ifndef _GLOBALHEADER_H_43674_ 2 | #define _GLOBALHEADER_H_43674_ 3 | 4 | #define LINESZ 2048 5 | #define tabSpaces 4 6 | 7 | #define compilationDirectory "CompilationSource" 8 | #define resultProjectDirectory "ExportedProject" 9 | 10 | #define tempFile "autofile.temp" 11 | 12 | #define wordSeparators " \t\r\n()[]{},.;!@#%^&*-=+/:\"\'\\" 13 | #define whiteSpace " \t\n" 14 | 15 | extern bool beauty; 16 | extern bool run; 17 | extern bool compile; 18 | extern bool silent; 19 | extern bool exportProject; 20 | extern bool cleanCompilation; 21 | 22 | #ifdef _WIN32 23 | #define slash "\\" 24 | #else 25 | #define slash "/" 26 | #endif 27 | 28 | #endif -------------------------------------------------------------------------------- /Source/dependenciesMapper.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | #include "extensionHandler.h" 6 | #include "defines.h" 7 | #include "line.h" 8 | 9 | vector getDependencies(char * inputFile){ 10 | vector dependencies; 11 | 12 | FILE * input = fopen(inputFile, "r"); 13 | 14 | char inputFileName[100]; 15 | strcpy(inputFileName, inputFile); 16 | removeExtension(inputFileName); 17 | 18 | int aux, i; 19 | 20 | int bracketsCount = 0; 21 | char buff[LINESZ]; 22 | int buffLen; 23 | 24 | bool multiLineComment = false; 25 | 26 | while (fgets (buff, LINESZ, input)) { 27 | for(i = 0; buff[i] != '\0'; i++){ 28 | if(buff[i] == '/' && buff[i+1] == '*') multiLineComment = true; 29 | else if(buff[i] == '*' && buff[i+1] == '/') multiLineComment = false; 30 | } 31 | 32 | if(!multiLineComment){ 33 | int includePos = internalInclude(buff); 34 | if(includePos != -1){ 35 | string depName = ""; 36 | int j = 0; 37 | for(int i = includePos + 1; buff[i] != '.' && buff[i] != '\"' && buff[i] != '\0'; i++) 38 | depName += buff[i]; 39 | dependencies.push_back(depName); 40 | } 41 | } 42 | } 43 | fclose(input); 44 | 45 | return dependencies; 46 | } -------------------------------------------------------------------------------- /Source/dependenciesMapper.h: -------------------------------------------------------------------------------- 1 | #ifndef _DEPENDENCIESMAPPER_H_43674_ 2 | #define _DEPENDENCIESMAPPER_H_43674_ 3 | 4 | vector getDependencies(char * inputFile); 5 | 6 | #endif -------------------------------------------------------------------------------- /Source/directoryHandler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "file.h" 3 | #include "defines.h" 4 | #include "extensionHandler.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | void makeDirectory(const char * path){ 14 | if(!directoryExists(path)){ 15 | string sysCall = "mkdir "; 16 | sysCall += path; 17 | system(sysCall.c_str()); 18 | } 19 | } 20 | 21 | void clearDirectory(const char * path){ 22 | DIR *dpdf = opendir(path); 23 | struct dirent *epdf; 24 | while ((epdf = readdir(dpdf)) != NULL) 25 | remove(((string) path + (string)slash + (string)epdf->d_name).c_str()); 26 | closedir(dpdf); 27 | } 28 | 29 | void CloneFilesToCompilationDirectory(const std::string& path){ 30 | string compDir = "./"; 31 | compDir += compilationDirectory; 32 | compDir += "/"; 33 | 34 | if(path == compDir) 35 | return; 36 | 37 | DIR *dpdf; 38 | struct dirent *epdf; 39 | dpdf = opendir(path.c_str()); 40 | if (dpdf != NULL){ 41 | while ((epdf = readdir(dpdf)) != NULL){ 42 | if(epdf->d_type==DT_DIR && string(epdf->d_name) != ".." && string(epdf->d_name) != "."){ 43 | CloneFilesToCompilationDirectory(path+epdf->d_name+"/"); 44 | } 45 | if(epdf->d_type==DT_REG && isCodeFile(epdf->d_name)){ 46 | string src = path+epdf->d_name; 47 | string temp = compilationDirectory; 48 | string dest = temp+"//"+epdf->d_name; 49 | if(fileExist(dest.c_str())){ 50 | if(fileModifiedTime(dest.c_str()) < fileModifiedTime(src.c_str())){ 51 | remove(dest.c_str()); 52 | copyFile(src.c_str(), dest.c_str()); 53 | } 54 | } 55 | else 56 | copyFile(src.c_str(), dest.c_str()); 57 | } 58 | } 59 | } 60 | closedir(dpdf); 61 | } 62 | 63 | void prepareDirectory(bool cleanCompilation){ 64 | makeDirectory(compilationDirectory); 65 | if(cleanCompilation) 66 | clearDirectory(compilationDirectory); 67 | CloneFilesToCompilationDirectory("./"); 68 | } 69 | 70 | void buildMakefile(string dirPath, set filesDone, string target){ 71 | FILE * makefile = fopen((dirPath + (string)slash + (string)"Makefile").c_str(), "w+"); 72 | fprintf(makefile, "all:\n"); 73 | fprintf(makefile, "\tg++ -o %s ", target.c_str()); 74 | for(string file : filesDone) 75 | fprintf(makefile, "%s.cpp ", file.c_str()); 76 | 77 | fprintf(makefile, "\n\n%s: ", target.c_str()); 78 | for(string file : filesDone) 79 | fprintf(makefile, "%s.o ", file.c_str()); 80 | fprintf(makefile, "\n\tg++ -o %s ", target.c_str()); 81 | for(string file : filesDone) 82 | fprintf(makefile, "%s.o ", file.c_str()); 83 | 84 | for(string file : filesDone) 85 | fprintf(makefile, "\n%s.o: %s.cpp ", file.c_str(), file.c_str()); 86 | 87 | fclose(makefile); 88 | } 89 | 90 | void createExportDirectory(set filesDone, string target){ 91 | DIR *dpdf = opendir("./"); 92 | struct dirent *epdf; 93 | 94 | string dirPath = ".."; 95 | dirPath += slash; 96 | dirPath += resultProjectDirectory; 97 | 98 | makeDirectory(dirPath.c_str()); 99 | 100 | while ((epdf = readdir(dpdf)) != NULL){ 101 | if(epdf->d_type==DT_REG && isCppFile(epdf->d_name)){ 102 | string fileName = removeExtension((string)epdf->d_name); 103 | if(filesDone.count(fileName)){ 104 | copyFile(epdf->d_name, ((string)dirPath + (string)slash + (string)epdf->d_name).c_str()); 105 | } 106 | } 107 | } 108 | 109 | buildMakefile(dirPath, filesDone, target); 110 | closedir(dpdf); 111 | } -------------------------------------------------------------------------------- /Source/directoryHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef _FOLDERHANDLER_H_ 2 | #define _FOLDERHANDLER_H_ 3 | 4 | void prepareDirectory(bool cleanCompilation); 5 | void createExportDirectory(set filesDone, string target); 6 | 7 | #endif -------------------------------------------------------------------------------- /Source/extensionHandler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | #include "defines.h" 6 | 7 | void removeExtension(char * s){ 8 | int i; 9 | for(i = strlen(s); i >= 0 && s[i] != '.'; i--) s[i] = '\0'; 10 | if(i != -1) s[i] = '\0'; 11 | } 12 | 13 | void replaceHeaderExtension(char * s){ 14 | int i; 15 | for(i = strlen(s); i >= 0 && s[i] != '.'; i--) s[i] = '\0'; 16 | s[++i] = 'h'; 17 | s[++i] = '\0'; 18 | } 19 | 20 | string removeCharExt(char * fileName){ 21 | string s = ""; 22 | for(int i = 0; fileName[i] != '.' && fileName[i] != '\0'; i++){ 23 | s += fileName[i]; 24 | } 25 | return s; 26 | } 27 | 28 | string removeExtension(string fileName){ 29 | string s = ""; 30 | for(int i = 0; fileName[i] != '.' && fileName[i] != '\0'; i++){ 31 | s += fileName[i]; 32 | } 33 | return s; 34 | } 35 | 36 | 37 | void stringToCPY(string input, char * fileName){ 38 | int i; 39 | int j = 0; 40 | for(i = 0; i < input.size(); i++) 41 | fileName[j++] = input[i]; 42 | fileName[j++] = '.'; 43 | fileName[j++] = 'c'; 44 | fileName[j++] = 'p'; 45 | fileName[j++] = 'y'; 46 | fileName[j++] = '\0'; 47 | } 48 | 49 | void stringToCPP(string input, char * fileName){ 50 | int i; 51 | int j = 0; 52 | for(i = 0; i < input.size(); i++) 53 | fileName[j++] = input[i]; 54 | fileName[j++] = '.'; 55 | fileName[j++] = 'c'; 56 | fileName[j++] = 'p'; 57 | fileName[j++] = 'p'; 58 | fileName[j++] = '\0'; 59 | } 60 | 61 | void stringToH(string input, char * fileName){ 62 | int i; 63 | int j = 0; 64 | for(i = 0; i < input.size(); i++) 65 | fileName[j++] = input[i]; 66 | fileName[j++] = '.'; 67 | fileName[j++] = 'h'; 68 | fileName[j++] = '\0'; 69 | } 70 | 71 | 72 | string getExtension(string input){ 73 | int i; 74 | for(i = input.size()-1; i >= 0 && input[i] != '.'; i--); 75 | if(i == -1) 76 | return ""; 77 | 78 | return input.substr(i, input.size()-i); 79 | } 80 | 81 | string cropPath(string input){ 82 | int i; 83 | for(i = input.size()-1; i >= 0 && input[i] != '\\' && input[i] != '/'; i--); 84 | if(i == -1) 85 | return input; 86 | i++; 87 | return input.substr(i, input.size()-i); 88 | } 89 | 90 | bool isCodeFile(string input){ 91 | string ext = getExtension(input); 92 | return (ext == ".cpy" || ext == ".cpp" || ext == ".h"); 93 | } 94 | 95 | bool isCppFile(string input){ 96 | string ext = getExtension(input); 97 | return (ext == ".cpp" || ext == ".h"); 98 | } -------------------------------------------------------------------------------- /Source/extensionHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef _ENTENSIONHANDLER_H_43674_ 2 | #define _ENTENSIONHANDLER_H_43674_ 3 | 4 | #include 5 | 6 | void removeExtension(char * s); 7 | void replaceHeaderExtension(char * s); 8 | std::string removeExtension(std::string fileName); 9 | std::string removeCharExt(char * fileName); 10 | void stringToCPY(std::string input, char * fileName); 11 | void stringToCPP(std::string input, char * fileName); 12 | void stringToH(std::string input, char * fileName); 13 | std::string getExtension(std::string input); 14 | std::string cropPath(std::string input); 15 | bool isCodeFile(std::string input); 16 | bool isCppFile(std::string input); 17 | 18 | #endif -------------------------------------------------------------------------------- /Source/file.cpp: -------------------------------------------------------------------------------- 1 | #include "defines.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | time_t fileModifiedTime(const char *path){ 14 | struct stat attr; 15 | if (stat(path, &attr) == 0) 16 | return attr.st_mtime; 17 | return 0; 18 | } 19 | 20 | bool fileExist (const char * fileName){ 21 | if(access( fileName, F_OK ) != -1) 22 | return true; 23 | return false; 24 | } 25 | 26 | void copyFile(const char * source, const char * dest){ 27 | char buf[BUFSIZ]; 28 | size_t size; 29 | 30 | int src = open(source, O_RDONLY, 0); 31 | int dst = open(dest, O_WRONLY | O_CREAT /*| O_TRUNC/**/, 0644); 32 | 33 | while ((size = read(src, buf, BUFSIZ)) > 0) 34 | write(dst, buf, size); 35 | 36 | close(src); 37 | close(dst); 38 | } 39 | 40 | bool directoryExists(const char *path){ 41 | struct stat info; 42 | 43 | if(stat( path, &info ) != 0) 44 | return false; 45 | else if(info.st_mode & S_IFDIR) 46 | return true; 47 | else 48 | return false; 49 | } -------------------------------------------------------------------------------- /Source/file.h: -------------------------------------------------------------------------------- 1 | #ifndef _FILE_H_43674_ 2 | #define _FILE_H_43674_ 3 | 4 | #include 5 | bool fileExist (const char * fileName); 6 | bool isOverwritable(const char * fileName); 7 | void copyFile(const char * source, const char * dest); 8 | bool directoryExists(const char *path); 9 | time_t fileModifiedTime(const char *path); 10 | 11 | #endif -------------------------------------------------------------------------------- /Source/firstReplaces.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "defines.h" 9 | #include "extensionHandler.h" 10 | #include "file.h" 11 | #include "line.h" 12 | #include "string.h" 13 | #include "sourceGen.h" 14 | using namespace std; 15 | 16 | #include 17 | 18 | void treatLineEndings(const char * filename){ 19 | FILE * input = fopen(filename, "r"); 20 | if(input == NULL) 21 | return; 22 | 23 | FILE * output = fopen(tempFile, "w+"); 24 | char line[LINESZ]; 25 | while (fgets (line, LINESZ, input)) { 26 | int resultPos = 0; 27 | int pos = 0; 28 | while(line[pos] != '\0'){ 29 | if(line[pos] == '\r'){ 30 | line[resultPos++] = '\n'; 31 | pos += 1 + (line[pos+1] == '\n'); 32 | } 33 | else 34 | line[resultPos++] = line[pos++]; 35 | } 36 | 37 | fprintf(output, "%s", line); 38 | } 39 | fclose(input); 40 | fclose(output); 41 | remove(filename); 42 | rename(tempFile, filename); 43 | return; 44 | } 45 | 46 | void forLoopParse(char * line){ 47 | bool rof = false; 48 | vector words = smartSplitWords(line, "for", " \t\n,;()=", true); 49 | if(words.size() == 0){ 50 | words = smartSplitWords(line, "rof", " \t\n,;()=", true); 51 | rof = true; 52 | } 53 | 54 | if(words.size() == 0) 55 | return; 56 | 57 | 58 | if(stringContainsChars(line, ";:,><")){ 59 | if(rof){ 60 | words[1] = "for"; 61 | string result = ""; 62 | for(string s : words) 63 | result += s; 64 | strcpy(line, result.c_str()); 65 | } 66 | 67 | return; 68 | } 69 | 70 | if(isWhitespace(words[words.size()-1], " \t\n,;()")) words.pop_back(); 71 | 72 | 73 | string offSet = words[0]; 74 | string i; 75 | string n; 76 | string step; 77 | string start; 78 | string comparison; 79 | 80 | i = words[3]; 81 | if(words.size() < 7){ 82 | if(rof){ 83 | start = words[5]; 84 | n = "0"; 85 | } 86 | else { 87 | start = "0"; 88 | n = words[5]; 89 | } 90 | 91 | if(rof) 92 | comparison = " >= "; 93 | else 94 | comparison = " < "; 95 | } 96 | else{ 97 | start = words[5]; 98 | n = words[7]; 99 | } 100 | 101 | if(words.size() > 11){ 102 | step = " " + words[9] + "= " + words[11]; 103 | if(words[9] == "-") 104 | comparison = " >= "; 105 | else 106 | comparison = " < "; 107 | } 108 | else if(words.size() > 9){ 109 | step = " += " + words[9]; 110 | comparison = " < "; 111 | } 112 | else{ 113 | if(rof){ 114 | step = "--"; 115 | comparison = " >= "; 116 | } 117 | else { 118 | step = "++"; 119 | comparison = " < "; 120 | } 121 | } 122 | 123 | string result = words[0] + "for(" + i + " = " + start + "; " + i + comparison + n + "; " + i + step + ")\n"; 124 | 125 | strcpy(line, result.c_str()); 126 | return; 127 | } 128 | 129 | void exclamationPrintParse(char * line){ 130 | vector words = smartSplitWords(line, "!", " \t\n,;", true); 131 | if(words.size() > 0){ 132 | string s = words[0] + "std::cout"; 133 | bool first = true; 134 | for(int i = 3; i < words.size(); i += 2){ 135 | if(!first) 136 | s += " << \" \""; 137 | first = false; 138 | s += " << " + words[i]; 139 | } 140 | s += " << std::endl\n"; 141 | strcpy(line, s.c_str()); 142 | return; 143 | } 144 | 145 | words = smartSplitWords(line, "!!", " \t\n,;", true); 146 | if(words.size() > 0){ 147 | string s = words[0] + "std::cout"; 148 | for(int i = 3; i < words.size(); i += 2){ 149 | s += " << " + words[i] + " << \" \""; 150 | } 151 | s += '\n'; 152 | strcpy(line, s.c_str()); 153 | return; 154 | } 155 | } 156 | 157 | void interrogationPrintParse(char * line){ 158 | vector words = smartSplitWords(line, "?", " \t\n,;", true); 159 | if(words.size() > 0){ 160 | string s = words[0]; 161 | char last = 'x'; 162 | for(int i = 3; i < words.size(); i += 2){ 163 | if(words[i][0] == '\"'){ 164 | if(last == 'o') 165 | s += " << " + words[i]; 166 | else if(last == 'x') 167 | s += "std::cout << " + words[i]; 168 | else 169 | if(beauty) 170 | s += "\n" + words[0] + "std::cout << " + words[i]; 171 | else 172 | s += "; std::cout << " + words[i]; 173 | last = 'o'; 174 | } 175 | else{ 176 | if(last == 'i') 177 | s += " >> " + words[i]; 178 | else if(last == 'x') 179 | s += "std::cin >> " + words[i]; 180 | else 181 | if(beauty) 182 | s += "\n" + words[0] + "std::cin >> " + words[i]; 183 | else 184 | s += "; std::cin >> " + words[i]; 185 | last = 'i'; 186 | } 187 | } 188 | s += '\n'; 189 | strcpy(line, s.c_str()); 190 | return; 191 | } 192 | 193 | words = smartSplitWords(line, "??", " \t\n,;", true); 194 | if(words.size() > 0){ 195 | string s = words[0] + "std::cout"; 196 | bool first = true; 197 | for(int i = 3; i < words.size(); i += 2){ 198 | if(first){ 199 | s += " << \"" + words[i] + " = \" << " + words[i]; 200 | first = false; 201 | } else 202 | s += " << \" | " + words[i] + " = \" << " + words[i]; 203 | } 204 | s += " << std::endl\n"; 205 | strcpy(line, s.c_str()); 206 | return; 207 | } 208 | } 209 | 210 | bool coutPrintParse(char * line){ 211 | int pos = max( string_isSubstring(line, "cout"), 212 | string_isSubstring(line, "cerr")); 213 | if(line[pos+4] != ' ' && line[pos+4] != '\t') 214 | return false; 215 | if(pos > 0 && line[pos-1] != ' ' && line[pos-1] != '\t' && line[pos-1] != ':') 216 | return false; 217 | if(pos == -1) 218 | return false; 219 | 220 | for(int i = 0; line[i] != '\0'; i++){ 221 | if(line[i] == '\"'){ 222 | i++; 223 | while(line[i] != '\"' && line[i] != '\0') i++; 224 | } 225 | 226 | if(line[i] == '<' && line[i+1] == '<') 227 | return false; 228 | } 229 | 230 | int i = pos; 231 | 232 | while(line[i] != '\n' && line[i] != '\0'){ 233 | 234 | if(line[i] == '\"' && line[i-1] != '\\'){ 235 | i++; 236 | while(!(line[i] == '\"' && line[i-1] != '\\') && line[i] != '\0') i++; 237 | } 238 | 239 | while(!stringContainsChar(" \t\n", line[i]) && line[i] != '\0') i++; 240 | 241 | int insertPos = i; 242 | 243 | while(stringContainsChar(" \t\n", line[i]) && line[i] != '\0') i++; 244 | 245 | 246 | if(line[i] != '\n' && line[i] != '\0'){ 247 | stringInsert(line, " <<", insertPos); 248 | i += 3; 249 | } 250 | } 251 | return true; 252 | } 253 | 254 | bool cinPrintParse(char * line){ 255 | int pos = string_isSubstring(line, "cin"); 256 | 257 | if(line[pos+3] != ' ' && line[pos+3] != '\t') 258 | return false; 259 | if(pos > 0 && line[pos-1] != ' ' && line[pos-1] != '\t' && line[pos-1] != ':') 260 | return false; 261 | if(pos == -1) 262 | return false; 263 | 264 | for(int i = 0; line[i] != '\0'; i++){ 265 | if(line[i] == '\"' && line[i-1] != '\\'){ 266 | i++; 267 | while(!(line[i] == '\"' && line[i-1] != '\\') && line[i] != '\0') i++; 268 | } 269 | 270 | if(line[i] == '>' && line[i+1] == '>') 271 | return false; 272 | } 273 | 274 | int i = pos; 275 | 276 | while(line[i] != '\n' && line[i] != '\0'){ 277 | 278 | if(line[i] == '\"'){ 279 | i++; 280 | while(line[i] != '\"' && line[i] != '\0') i++; 281 | } 282 | 283 | while(!stringContainsChar(" \t\n", line[i]) && line[i] != '\0') i++; 284 | 285 | int insertPos = i; 286 | 287 | while(stringContainsChar(" \t\n", line[i]) && line[i] != '\0') i++; 288 | 289 | 290 | if(line[i] != '\n' && line[i] != '\0'){ 291 | stringInsert(line, " >>", insertPos); 292 | i += 3; 293 | } 294 | } 295 | return true; 296 | } 297 | 298 | void replaceQuickPrints(const char * filename){ 299 | FILE * input = fopen(filename, "r"); 300 | if(input == NULL) 301 | return; 302 | 303 | FILE * output = fopen(tempFile, "w+"); 304 | char line[LINESZ]; 305 | while (fgets (line, LINESZ, input)) { 306 | 307 | int pos = strlen(line)-1; 308 | while(pos >= 0 && stringContainsChar(" \t\n", line[pos])) pos--; 309 | if(pos != -1 && line[pos] == ';'){ 310 | line[pos] = '\n'; 311 | line[pos+1] = '\0'; 312 | } 313 | 314 | exclamationPrintParse(line); 315 | interrogationPrintParse(line); 316 | coutPrintParse(line); 317 | cinPrintParse(line); 318 | 319 | fprintf(output, "%s", line); 320 | } 321 | fclose(input); 322 | fclose(output); 323 | remove(filename); 324 | rename(tempFile, filename); 325 | } 326 | 327 | bool replaceRawIncludesInner(const char * filename){ 328 | bool replacedSomething = false; 329 | FILE * input = fopen(filename, "r"); 330 | if(input == NULL) 331 | return replacedSomething; 332 | 333 | FILE * output = fopen(tempFile, "w+"); 334 | char line[LINESZ]; 335 | char line2[LINESZ]; 336 | while (fgets (line, LINESZ, input)) { 337 | string includeName = rawInclude(line); 338 | if(includeName != ""){ 339 | replacedSomething = true; 340 | 341 | //Keep whatever is after #raw "file.ext" 342 | //Eg: 343 | //#raw "template.cpy" //Some comment 344 | int aspCnt = 0; 345 | int i = 0; 346 | while(aspCnt < 2 && line[i] != '\0') 347 | if(line[i++] == '\"') 348 | aspCnt++; 349 | 350 | if(line[i] != '\n') 351 | while(line[i] != '\0') 352 | fprintf(output, "%c", line[i++]); 353 | 354 | //Copies include content to current file 355 | if(fileExist(includeName.c_str())){ 356 | //treatLineEndings(includeName.c_str()); 357 | FILE * copy = fopen(includeName.c_str(), "r"); 358 | if(copy != NULL){ 359 | while (fgets (line2, LINESZ, copy)){ 360 | fprintf(output, "%s", line2); 361 | } 362 | fprintf(output, "\n"); 363 | fclose(copy); 364 | } 365 | } 366 | else { 367 | printf("Raw include file not found: %s", includeName.c_str()); 368 | } 369 | } 370 | else 371 | fprintf(output, "%s", line); 372 | } 373 | fclose(input); 374 | fclose(output); 375 | remove(filename); 376 | rename(tempFile, filename); 377 | return replacedSomething; 378 | } 379 | 380 | void replaceRawIncludes(const char * filename){ 381 | int timeout = 1000; 382 | while(replaceRawIncludesInner(filename) && timeout--); 383 | if(timeout <= 0) 384 | printf("Too many iterations on raw replacement | File: %s\n", filename); 385 | } 386 | 387 | void joinContinuedLines(const char * filename){ 388 | FILE * input = fopen(filename, "r"); 389 | if(input == NULL) 390 | return; 391 | 392 | FILE * output = fopen(tempFile, "w+"); 393 | char line[LINESZ]; 394 | while (fgets (line, LINESZ, input)) { 395 | for(int i = 0; line[i] != '\0';){ 396 | int j = i+1; 397 | while(stringContainsChar(" \t", line[j])) j++; 398 | if(line[i] == '\\' && line[j] == '\n'){ 399 | line[i] = ' '; 400 | line[j] = ' '; 401 | } 402 | i = j; 403 | } 404 | fprintf(output, "%s", line); 405 | } 406 | fclose(input); 407 | fclose(output); 408 | remove(filename); 409 | rename(tempFile, filename); 410 | return; 411 | 412 | } 413 | 414 | int getLineNumber(const char * ptr, const char * str){ 415 | const char * p = str; 416 | int line = 1; 417 | while(p != ptr){ 418 | if(*p == '\n') line++; 419 | p++; 420 | } 421 | return line; 422 | } 423 | 424 | // see http://en.cppreference.com/w/cpp/language/string_literal 425 | // input: ptr points to opening '"' 426 | // prefixR"delimiter(raw_characters)delimiter" 427 | // ^ptr 428 | bool isRawStringLiteral(const char * ptr, const char * str){ 429 | const char * p = ptr; 430 | if(*p != '"' || p == str || p[-1] != 'R') return false; 431 | 432 | // figure out if we have valid prefix (L,u,U,u8) 433 | p--; // p now points to 'R' 434 | while(p >= str && (isalnum(*p) || *p=='_')) p--; 435 | p++; 436 | // now p points to start of prefix: 437 | // u8R"... 438 | // ^p^ptr-1 (ptr-1-p) is length of prefix 439 | if(ptr-1-p > 2) return false; // invalid prefix - too long 440 | if(ptr-1-p == 2) return *p=='u' && p[1]=='8'; 441 | if(ptr-1-p == 1) return *p=='u' || *p=='U' || *p=='L'; 442 | return true; // ptr-1-p == 0, no prefix 443 | } 444 | 445 | // endSeq = )delimiter" 446 | // max length of endSeq is 16+2=18 chars (not counting terminating null) 447 | // input: ptr points to opening '"' 448 | bool getRawStringEndSequence(const char * ptr, char endSeq[20]){ 449 | const char * p = ptr; 450 | if(*p != '"') return false; 451 | p++; 452 | ptr++; 453 | // now p and ptr point to start of delimiter or '(' if there is no delimiter 454 | while(*p && !(*p=='('||*p==')'||*p=='\\'||isspace(*p))) p++; 455 | // now p points to '(' 456 | if(p-ptr > 16) return false; // delimiter too long 457 | if(*p != '(') return false; 458 | 459 | endSeq[0] = ')'; 460 | memcpy(endSeq+1, ptr, p-ptr); // copy delimiter to endSeq 461 | endSeq[p-ptr+1] = '"'; 462 | endSeq[p-ptr+2] = 0; 463 | return true; 464 | } 465 | 466 | /* 467 | removeComments() does not handle line continuations, so it should be called after joinContinuedLines() 468 | 469 | removeComments() correctly handles /* and // inside char/string literals except these cases: 470 | 471 | - #include"..." is treated as normal string with escapes, which is not standard-compliant (see q-char-sequence in the C11 standard http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf); 472 | #include<...> is not treated as string, so // and /* inside <...> will start a comment 473 | 474 | - unclosed char/string literals in inactive preprocessor blocks (warning in g++, error in cpy): 475 | #if 0 476 | "/* 477 | #endif 478 | 479 | - probably in some other nontrivial interactions of strings and comments with preprocessor 480 | 481 | */ 482 | void removeComments(const char * filename){ 483 | FILE * input = fopen(filename, "rb"); 484 | if(input == NULL) 485 | return; 486 | 487 | // read entire input file into src 488 | fseek(input, 0, SEEK_END); 489 | int size = ftell(input); // input file size 490 | fseek(input, 0, SEEK_SET); 491 | char* src = (char*)malloc(size+1); 492 | fread(src, 1, size, input); 493 | src[size] = 0; // null-terminate src 494 | fclose(input); 495 | 496 | char* dst = (char*)calloc(size+1,1); // cannot be larger than src 497 | char* p = src; 498 | char* q = dst; 499 | 500 | while(*p){ 501 | if(*p == '/'){ 502 | p++; // skip '/' 503 | if(*p == '/'){ // line comment 504 | p++; // skip '/' 505 | while(*p && *p != '\n') p++; // skip everything until eof or eol, don't skip eol 506 | } 507 | else if(*p == '*'){ // block comment 508 | p++; // skip '*' 509 | char* end = strstr(p, "*/"); 510 | if(end){ 511 | *q++ = ' '; // block comment is replaced with a single space char: "int/**/a" -> "int a", not "inta" 512 | p = end + 2; 513 | } 514 | else{ // unclosed block comment 515 | printf("%s:%d: error: unclosed block comment\n", filename, getLineNumber(p,src)); 516 | exit(1); 517 | } 518 | } 519 | else 520 | *q++ = '/'; // not a comment - just copy '/' to dst 521 | } 522 | else if(*p == '"' || *p == '\''){ // string or char literal 523 | if(isRawStringLiteral(p,src)){ 524 | char endSeq[20] = {0}; 525 | if(!getRawStringEndSequence(p,endSeq)){ 526 | printf("%s:%d: error: invalid raw string literal\n", filename, getLineNumber(p,src)); 527 | exit(1); 528 | } 529 | char* end = strstr(p, endSeq); 530 | if(!end){ 531 | printf("%s:%d: error: unclosed raw string literal\n", filename, getLineNumber(p,src)); 532 | exit(1); 533 | } 534 | end += strlen(endSeq); 535 | // copy entire contents of raw string to dst 536 | memcpy(q, p, end-p); 537 | q += end-p; 538 | p = end; 539 | } 540 | else{ 541 | char c = *p; 542 | char* start = p; 543 | *q++ = *p++; // copy opening quote 544 | while(*p){ 545 | if(*p == '\\'){ // copy \ and char that follows it 546 | *q++ = *p++; 547 | if(!*p) break; 548 | *q++ = *p++; 549 | continue; 550 | } 551 | else if(*p == c || *p == '\n') break; 552 | *q++ = *p++; 553 | } 554 | if(*p == c) 555 | *q++ = *p++; // copy closing quote 556 | else{ // *p == 0 (eof) or *p == '\n' (eol) 557 | printf("%s:%d: error: unclosed character or string literal\n", filename, getLineNumber(start,src)); 558 | exit(1); 559 | } 560 | } 561 | } 562 | else 563 | *q++ = *p++; // copy char to dst and increment src and dst pointers 564 | } 565 | 566 | FILE * output = fopen(tempFile, "wb"); 567 | fwrite(dst, 1, strlen(dst), output); 568 | fclose(output); 569 | remove(filename); 570 | rename(tempFile, filename); 571 | free(src); 572 | free(dst); 573 | } 574 | 575 | void formatLineSpacing(char * line){ 576 | int resultPos = 0; 577 | int i = 0; 578 | while(line[i] == ' ' || line[i] == '\t') 579 | line[resultPos++] = line[i++]; 580 | 581 | while(line[i] != '\0'){ 582 | line[resultPos++] = line[i++]; 583 | if(line[i] == ' ' || line[i] == '\t'){ 584 | line[resultPos++] = ' '; 585 | while(line[i] == ' ' || line[i] == '\t') 586 | i++; 587 | } 588 | } 589 | if(line[i-1] == ' ') 590 | line[resultPos-1] = '\0'; 591 | else 592 | line[resultPos] = '\0'; 593 | } 594 | 595 | void implyWordSeparationSpaces(char * line){ 596 | if(line[0] == '#') 597 | return; 598 | 599 | string resultString = ""; 600 | for(int i = 0; line[i] != '\0'; i++){ 601 | 602 | if(line[i] == '\"' && line[i-1] != '\\'){ 603 | resultString += line[i++]; 604 | while(!(line[i] == '\"' && line[i-1] != '\\') && line[i] != '\0') 605 | resultString += line[i++]; 606 | } 607 | 608 | int j = i; 609 | while(stringContainsChar("+-*/%=<>&^|!?,", line[j])) 610 | j++; 611 | 612 | if(i != j){ 613 | char last; 614 | char next; 615 | int k = i-1; 616 | while((line[k] == ' ' || line[k] == '\t') && k >= 0) 617 | k--; 618 | if(k != -1) 619 | last = line[k]; 620 | else 621 | last = '\0'; 622 | 623 | k = j; 624 | while((line[k] == ' ' || line[k] == '\t' || line[k] == '\n') && line[k] != '\0') 625 | k++; 626 | next = line[k]; 627 | 628 | bool isOperator = !stringContainsChar("+-*/%=<>&^|!?,;.([{", last) && last != '\0' && 629 | !stringContainsChar(")]};,.", next) && next != '\0'; 630 | 631 | if( isOperator && 632 | (line[i] != '/' || line[i+1] != '/') && 633 | (line[i] != '/' || line[i+1] != '*') && 634 | (line[i] != '*' || line[i+1] != '/') && 635 | (line[i] != '-' || line[i+1] != '>') && 636 | line[i] != ',') 637 | resultString += ' '; 638 | 639 | 640 | k = i; 641 | while(k < j) 642 | resultString += line[k++]; 643 | 644 | if( isOperator && 645 | (line[i] != '/' || line[i+1] != '/') && 646 | (line[i] != '/' || line[i+1] != '*') && 647 | (line[i] != '*' || line[i+1] != '/') && 648 | (line[i] != '-' || line[i+1] != '>')) 649 | resultString += ' '; 650 | 651 | i = k-1; 652 | } 653 | else{ 654 | resultString += line[i]; 655 | } 656 | } 657 | 658 | strcpy(line, resultString.c_str()); 659 | } 660 | 661 | void formatSpacing(const char * filename){ 662 | FILE * input = fopen(filename, "r"); 663 | if(input == NULL) 664 | return; 665 | 666 | FILE * output = fopen(tempFile, "w+"); 667 | char line[LINESZ]; 668 | while (fgets (line, LINESZ, input)) { 669 | implyWordSeparationSpaces(line); 670 | formatLineSpacing(line); 671 | fprintf(output, "%s", line); 672 | } 673 | fclose(input); 674 | fclose(output); 675 | remove(filename); 676 | rename(tempFile, filename); 677 | return; 678 | } 679 | 680 | void treatCurlyBrackets(const char * filename){ 681 | FILE * input = fopen(filename, "r"); 682 | if(input == NULL) 683 | return; 684 | 685 | FILE * output = fopen(tempFile, "w+"); 686 | char line[LINESZ]; 687 | while (fgets (line, LINESZ, input)) { 688 | stack open; 689 | for(int i = 0; line[i] != '\0'; i++){ 690 | if(line[i] == '{') 691 | open.push(i); 692 | else if(line[i] == '}') 693 | if(open.empty()) 694 | line[i] = ' '; 695 | else 696 | open.pop(); 697 | } 698 | 699 | while(!open.empty()){ 700 | line[open.top()] = ' '; 701 | open.pop(); 702 | } 703 | 704 | fprintf(output, "%s", line); 705 | } 706 | fclose(input); 707 | fclose(output); 708 | remove(filename); 709 | rename(tempFile, filename); 710 | return; 711 | } 712 | 713 | void makeMultipleReturnAssignments(char * input){ 714 | char line[LINESZ]; 715 | strcpy(line, input); 716 | 717 | int i = 0; 718 | while(line[i] != '\0' && line[i] != '=') i++; 719 | if(line[i] == '\0') return; 720 | 721 | //Equity found 722 | 723 | int equityPosition = i; 724 | i++; 725 | 726 | while(line[i] == ' ' || line[i] == '\t') i++; 727 | while(line[i] != '\0' && !stringContainsChar(wordSeparators, line[i])) i++; 728 | while(line[i] == ' ' || line[i] == '\t') i++; 729 | 730 | if(line[i] != '(') return; 731 | 732 | //Only one name after assignment assured 733 | //( found 734 | 735 | while(line[i] != '\0' && line[i] != ')') i++; 736 | if(line[i] == '\0') return; 737 | i++; 738 | 739 | //) found 740 | 741 | while(line[i] != '\0'){ 742 | if(stringContainsChar(wordSeparators, line[i])) i++; 743 | else if(line[i] != '\0') return; 744 | } 745 | 746 | //Nothing after ) assured 747 | 748 | string functionCall = string(line + equityPosition); 749 | line[equityPosition] = '\0'; 750 | 751 | i = 0; 752 | string offSet = ""; 753 | while(stringContainsChar(wordSeparators, line[i])) offSet += line[i++]; 754 | 755 | int j = 0; 756 | while(line[i] != '\0') line[j++] = line[i++]; 757 | line[j] = '\0'; 758 | 759 | string result = offSet + "unpackingFunctionArguments " + functionCall; 760 | 761 | vector words = smartSplitWords(line, "", ","); 762 | 763 | if(words.size() <= 1){ 764 | return; 765 | } 766 | 767 | for(int i = 0; i < words.size(); i++){ 768 | words[i] = removeStartEndWhitespace(words[i]); 769 | if(words[i] == "_") 770 | continue; 771 | result += offSet + words[i] + " = get<" + to_string(i) + ">(unpackingFunctionArguments)\n"; 772 | } 773 | 774 | strcpy(input, result.c_str()); 775 | } 776 | 777 | void implyMultipleReturnValues(char * line){ 778 | if(getFirstWord(line) != "return") 779 | return; 780 | 781 | int i = 0; 782 | while(line[i] == ' ' || line[i] == '\t') i++; 783 | i += 7; 784 | 785 | vector words = smartSplitWords(line + i, "", ","); 786 | 787 | if(words.size() <= 1) 788 | return; 789 | 790 | string result = ""; 791 | for(int j = 0; j < i; j++) 792 | result += line[j]; 793 | result += "make_tuple("; 794 | for(string word : words) 795 | result += removeStartEndWhitespace(word) + ", "; 796 | result[result.size()-2] = ')'; 797 | result[result.size()-1] = '\n'; 798 | strcpy(line, result.c_str()); 799 | } 800 | 801 | void finalLineReplaces(const char * filename){ 802 | FILE * input = fopen(filename, "r"); 803 | if(input == NULL) 804 | return; 805 | 806 | FILE * output = fopen(tempFile, "w+"); 807 | char line[LINESZ]; 808 | while (fgets (line, LINESZ, input)) { 809 | implyMultipleReturnValues(line); 810 | makeMultipleReturnAssignments(line); 811 | forLoopParse(line); 812 | fprintf(output, "%s", line); 813 | } 814 | fclose(input); 815 | fclose(output); 816 | remove(filename); 817 | rename(tempFile, filename); 818 | return; 819 | } 820 | 821 | void firstReplaces(const char * filename){ 822 | treatLineEndings(filename); 823 | replaceRawIncludes(filename); 824 | joinContinuedLines(filename); 825 | removeComments(filename); 826 | treatCurlyBrackets(filename); 827 | replaceQuickPrints(filename); 828 | formatSpacing(filename); 829 | finalLineReplaces(filename); 830 | } 831 | -------------------------------------------------------------------------------- /Source/firstReplaces.h: -------------------------------------------------------------------------------- 1 | #ifndef _RAWINCLUDES_H_43674_ 2 | #define _RAWINCLUDES_H_43674_ 3 | 4 | void firstReplaces(const char * filename); 5 | 6 | #endif -------------------------------------------------------------------------------- /Source/headerGen.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | #include 6 | #include 7 | 8 | #include "defines.h" 9 | #include "sourceGen.h" 10 | #include "headerGen.h" 11 | #include "string.h" 12 | #include "file.h" 13 | #include "line.h" 14 | #include "extensionHandler.h" 15 | #include "dependenciesMapper.h" 16 | 17 | int headersMade = 0; 18 | 19 | void exportUntilKeyClose(FILE * input, FILE * output, FILE * lineBreakCompensation){ 20 | int keyAmt = 1; 21 | char line[LINESZ]; 22 | while (keyAmt && fgets (line, LINESZ, input)) { 23 | for(int i = 0; line[i] != '\0'; i++){ 24 | if(line[i] == '{') 25 | keyAmt++; 26 | else if(line[i] == '}') 27 | keyAmt--; 28 | } 29 | fprintf(output, "%s", line); 30 | fprintf(lineBreakCompensation, "\n"); 31 | } 32 | } 33 | 34 | void generateHeader(const char * inputFile, const char * outputFile){ 35 | FILE * input = fopen(inputFile, "r"); 36 | FILE * header = fopen(outputFile, "w+"); 37 | FILE * source = fopen(tempFile, "w+"); 38 | 39 | char inputFileHeader[100]; 40 | strcpy(inputFileHeader, inputFile); 41 | replaceHeaderExtension(inputFileHeader); 42 | 43 | char inputFileName[100]; 44 | strcpy(inputFileName, inputFile); 45 | removeExtension(inputFileName); 46 | 47 | headersMade++; 48 | fprintf(header, "#ifndef _PROCEDURALHEADER%d_%s_H_\n", headersMade, inputFileName); 49 | fprintf(header, "#define _PROCEDURALHEADER%d_%s_H_\n", headersMade, inputFileName); 50 | 51 | char line[LINESZ]; 52 | bool headerIncluded = false; 53 | while (fgets (line, LINESZ, input)) { 54 | bool toHeader = false; 55 | bool toSource = true; 56 | bool functionDeclaration = false; 57 | if(line[0] == '#' || string_isSubstring(line, "using namespace") != -1){ 58 | toHeader = true; 59 | toSource = false; 60 | } 61 | else if(isFunctionDeclaration(line)){ 62 | toHeader = true; 63 | toSource = true; 64 | functionDeclaration = true; 65 | } 66 | else if(string_isWord(line, "struct") != -1 || string_isWord(line, "class") != -1){ 67 | int len = strlen(line); 68 | for(len = len-1; stringContainsChar(" \t\n", line[len]); len--); 69 | if(len != -1 && line[len] == '{'){ 70 | fprintf(header, "%s", line); 71 | exportUntilKeyClose(input, header, source); 72 | continue; 73 | } 74 | } 75 | 76 | if(toSource) 77 | fprintf(source, "%s", line); 78 | else if(!headerIncluded){ 79 | headerIncluded = true; 80 | fprintf(source, "#include \"%s\"\n", inputFileHeader); 81 | } else 82 | fprintf(source, "\n"); 83 | 84 | if(toHeader){ 85 | if(functionDeclaration){ 86 | int l = strlen(line); 87 | for(l = l-1; l != -1 && line[l] != '{'; l--); 88 | if(l != -1) 89 | line[l] = ';'; 90 | } 91 | 92 | fprintf(header, "%s", line); 93 | } 94 | } 95 | fprintf(header, "#endif"); 96 | 97 | fclose(header); 98 | fclose(source); 99 | fclose(input); 100 | 101 | remove(inputFile); 102 | rename(tempFile, inputFile); 103 | } -------------------------------------------------------------------------------- /Source/headerGen.h: -------------------------------------------------------------------------------- 1 | #ifndef _HEADER_H_ 2 | #define _HEADER_H_ 3 | 4 | void generateHeader(const char * inputFile, const char * outputFile); 5 | 6 | #endif -------------------------------------------------------------------------------- /Source/line.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "string.h" 7 | #include "defines.h" 8 | using namespace std; 9 | 10 | vector splitWords(char * line, string firstWordRequired="", string separators=wordSeparators){ 11 | vector words; 12 | int pos = 0; 13 | if(line[pos] != '\0'){ 14 | string word; 15 | while(stringContainsChar(separators, line[pos])) pos++; 16 | while(line[pos] != '\0' && !stringContainsChar(separators, line[pos])) word += line[pos++]; 17 | 18 | if(firstWordRequired != "" && word != firstWordRequired) 19 | return words; 20 | 21 | words.push_back(word); 22 | } 23 | 24 | while(line[pos] != '\0'){ 25 | string word; 26 | while(stringContainsChar(separators, line[pos])) pos++; 27 | while(line[pos] != '\0' && !stringContainsChar(separators, line[pos])) word += line[pos++]; 28 | words.push_back(word); 29 | } 30 | return words; 31 | } 32 | 33 | int stringClosePosition(char * line, int startPos){ 34 | for(int i = startPos+1; line[i] != '\0'; i++) 35 | if(line[i] == '\"' && line[i-1] != '\\') 36 | return i; 37 | return -1; 38 | } 39 | 40 | int closePosition(char * line, int startPos, char open, char close){ 41 | int count = 0; 42 | for(int i = startPos; line[i] != '\0'; i++){ 43 | if(line[i] == open) 44 | count++; 45 | else if(line[i] == close) 46 | count--; 47 | if(count == 0) 48 | return i; 49 | } 50 | return -1; 51 | } 52 | 53 | vector smartSplitWords(char * line, string firstWordRequired="", string separators=wordSeparators, bool keepSplits=false){ 54 | vector words; 55 | int pos = 0; 56 | string word; 57 | 58 | bool firstWordRequiredDone = (firstWordRequired == ""); 59 | 60 | while(line[pos] != '\0'){ 61 | word = ""; 62 | if(keepSplits){ 63 | while(stringContainsChar(separators, line[pos])) 64 | word += line[pos++]; 65 | words.push_back(word); 66 | } else { 67 | while(stringContainsChar(separators, line[pos])) pos++; 68 | } 69 | 70 | word = ""; 71 | while(line[pos] != '\0' && !stringContainsChar(separators, line[pos])){ 72 | int pos2 = pos; 73 | 74 | if(line[pos] == '(') 75 | pos2 = closePosition(line, pos, '(', ')'); 76 | else if(line[pos] == '[') 77 | pos2 = closePosition(line, pos, '[', ']'); 78 | else if(line[pos] == '{') 79 | pos2 = closePosition(line, pos, '{', '}'); 80 | else if(line[pos] == '\"') 81 | pos2 = stringClosePosition(line, pos); 82 | 83 | while(pos <= pos2) 84 | word += line[pos++]; 85 | } 86 | 87 | if(!firstWordRequiredDone && firstWordRequired != word) 88 | return vector(); 89 | else 90 | firstWordRequiredDone = true; 91 | 92 | if(word != "") 93 | words.push_back(word); 94 | else 95 | break; 96 | } 97 | return words; 98 | } 99 | 100 | string getFirstWord(char * line, string separators=wordSeparators){ 101 | string word = ""; 102 | int i = 0; 103 | while(line[i] == ' ' || line[i] == '\t') i++; 104 | while(line[i] != '\0' && !stringContainsChar(separators, line[i])) word += line[i++]; 105 | return word; 106 | } 107 | 108 | bool isExternalInclude(char * line){ 109 | char stringInclude[] = "#include"; 110 | int i; 111 | for(i = 0; stringInclude[i] == line[i] && stringInclude[i] != '\0' && line[i] != '\0'; i++); 112 | 113 | if(i != 8) 114 | return false; 115 | while(line[i] == ' ' || line[i] == '\t') i++; 116 | if(line[i] == '<') 117 | return true; 118 | return false; 119 | } 120 | 121 | bool isNamespaceDeclaration(char * line){ 122 | return smartSplitWords(line, "using").size() > 0; 123 | } 124 | 125 | bool isFunctionDeclaration(char * line){ 126 | int whitespaceCount = 0; 127 | int openDec = 0; 128 | 129 | 130 | 131 | while(1){ 132 | while(stringContainsChar(" \t\r\n)[]{},.;!@#%^&*-=+/:\"\'\\", line[openDec])) openDec++; 133 | if(line[openDec] == '(') 134 | break; 135 | 136 | whitespaceCount++; 137 | 138 | while(!stringContainsChar(wordSeparators, line[openDec]) && line[openDec] != '\0') openDec++; 139 | if(line[openDec] == '(') 140 | break; 141 | 142 | if(line[openDec] == '\0') 143 | return false; 144 | } 145 | 146 | int len = strlen(line); 147 | len--; 148 | while(len >= 0 && line[len] != '{') len--; 149 | if(len >= 0 && line[len] == '{'){ 150 | if( string_isWord(line, "do") != -1 || 151 | string_isWord(line, "else") != -1 || 152 | string_isWord(line, "if") != -1 || 153 | string_isWord(line, "class") != -1 || 154 | string_isWord(line, "struct") != -1 || 155 | string_isWord(line, "typedef") != -1 || 156 | string_isWord(line, "for") != -1 || 157 | string_isWord(line, "while") != -1) 158 | return false; 159 | return true; 160 | } 161 | else return false; 162 | } 163 | 164 | int internalInclude(char * line){ 165 | char stringInclude[] = "#include"; 166 | int i; 167 | for(i = 0; stringInclude[i] == line[i] && stringInclude[i] != '\0' && line[i] != '\0'; i++); 168 | 169 | if(i != 8) 170 | return -1; 171 | while(line[i] == ' ' || line[i] == '\t') i++; 172 | 173 | if(line[i] == '\"') 174 | return i; 175 | return -1; 176 | } 177 | 178 | string rawInclude(char * line){ 179 | char compString[] = "#raw"; 180 | int i; 181 | for(i = 0; compString[i] == line[i] && compString[i] != '\0' && line[i] != '\0'; i++); 182 | 183 | string includeName = ""; 184 | if(i != 4) 185 | return includeName; 186 | while(line[i] == ' ' || line[i] == '\t') i++; 187 | if(line[i] == '\"'){ 188 | i++; 189 | while(line[i] != '\"' && line[i] != '\0') includeName += line[i++]; 190 | return includeName; 191 | } 192 | return includeName; 193 | } -------------------------------------------------------------------------------- /Source/line.h: -------------------------------------------------------------------------------- 1 | #ifndef _LINE_H_43674_ 2 | #define _LINE_H_43674_ 3 | 4 | #include 5 | #include 6 | #include "defines.h" 7 | 8 | using namespace std; 9 | 10 | 11 | int stringClosePosition(char * line, int startPos); 12 | int closePosition(char * line, int startPos, char open, char close); 13 | void addPahrenthesis(char * s); 14 | bool isExternalInclude(char * line); 15 | bool isNamespaceDeclaration(char * line); 16 | int internalInclude(char * line); 17 | string rawInclude(char * line); 18 | vector splitWords(char * line, string firstWordRequired="", string separators=wordSeparators); 19 | string getFirstWord(char * line, string separators=wordSeparators); 20 | vector smartSplitWords(char * line, string firstWordRequired="", string separators=wordSeparators, bool keepSplits=false); 21 | bool isFunctionDeclaration(char * line); 22 | #endif -------------------------------------------------------------------------------- /Source/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "defines.h" 13 | #include "sourceGen.h" 14 | #include "headerGen.h" 15 | #include "string.h" 16 | #include "file.h" 17 | #include "line.h" 18 | #include "extensionHandler.h" 19 | #include "dependenciesMapper.h" 20 | #include "firstReplaces.h" 21 | #include "directoryHandler.h" 22 | 23 | using namespace std; 24 | 25 | bool beauty = false; 26 | bool run = false; 27 | bool compile = true; 28 | bool silent = false; 29 | bool exportProject = false; 30 | bool cleanCompilation = false; 31 | bool implyVariables = true; 32 | 33 | void printHelp(){ 34 | printf("USAGE: cpy SourceCode Flags\n"); 35 | printf("Flags:\n"); 36 | printf("\t-h: Shows this help page\n"); 37 | printf("\t-b: Use line breaks on itermediate code\n"); 38 | printf("\t-s: Silent compilation, only prints errors\n"); 39 | printf("\t-cl: Clean compilation, deletes CompilationSource before compiling\n"); 40 | printf("\t-ex: Exports project to a directory containing only c++ source and a Makefile\n"); 41 | printf("\t-r: Automatically runs compiled code\n"); 42 | printf("\t-ni: Disables variable implication\n"); 43 | printf("\t-nc: Doesn't compile resulting code\n"); 44 | printf("\t-o target: Specifies target executable name, when not specified target = a\n"); 45 | printf("\t-OtherFlags: Redirects flag to underlying compiler\n"); 46 | exit(0); 47 | } 48 | 49 | void smartCompilation(map > dependenceMap, string mainFile, string target, string compilation, bool silent){ 50 | set generatedObjects; 51 | stack toProcess; 52 | generatedObjects.insert(mainFile); 53 | toProcess.push(mainFile); 54 | string systemCall; 55 | 56 | bool someObjectUpdated = false; 57 | 58 | //Create / Update / Check Object files 59 | while(!toProcess.empty()){ 60 | string fileName = toProcess.top(); 61 | toProcess.pop(); 62 | 63 | 64 | string cppSource = fileName + ".cpp"; 65 | 66 | if(!fileExist(cppSource.c_str())) 67 | continue; 68 | 69 | generatedObjects.insert(fileName); 70 | 71 | string targetObject = fileName + ".o"; 72 | 73 | if(fileModifiedTime(targetObject.c_str()) < fileModifiedTime(cppSource.c_str())){ 74 | systemCall = "g++ -c " + cppSource + " -o " + targetObject; 75 | 76 | if(!silent) 77 | cout << systemCall << endl; 78 | int returnValue = system(systemCall.c_str()); 79 | if(returnValue != 0) 80 | return; 81 | 82 | 83 | //One object file was updated, linking has to happen again 84 | someObjectUpdated = true; 85 | } 86 | 87 | if(dependenceMap.count(fileName)){ 88 | for(string dependence : dependenceMap[fileName]){ 89 | if(!generatedObjects.count(dependence)){ 90 | toProcess.push(dependence); 91 | } 92 | } 93 | } 94 | else 95 | printf("File not found: %s\n", fileName.c_str()); 96 | } 97 | 98 | //Link all objects into the desired executable 99 | string trueTarget = "../" + target; 100 | if(someObjectUpdated || !fileExist((trueTarget + ".exe").c_str())){ 101 | 102 | #ifdef _WIN32 103 | compilation += "-o " + trueTarget + " "; 104 | #else 105 | compilation += "-o " + target + " "; 106 | #endif 107 | 108 | for(string object : generatedObjects){ 109 | compilation += object + ".o "; 110 | } 111 | if(!silent) 112 | cout << compilation << endl; 113 | system(compilation.c_str()); 114 | remove(trueTarget.c_str()); 115 | rename(target.c_str(), trueTarget.c_str()); 116 | } else { 117 | if(!silent) 118 | cout << target << " is up to date\n"; 119 | } 120 | } 121 | 122 | int main(int argc, char ** argv){ 123 | int i, j; 124 | 125 | char target[LINESZ] = "a"; 126 | 127 | char compilation[LINESZ] = "g++ "; 128 | 129 | //Process Arguments 130 | if(argc < 2){ 131 | printHelp(); 132 | exit(0); 133 | } 134 | 135 | char argument[LINESZ]; 136 | string stringSource = ""; 137 | for(i = 1; i < argc; i++){ 138 | strcpy(argument, argv[i]); 139 | stringToLower(argument); 140 | 141 | if(strcmp("-o", argument) == 0){ 142 | if(i + 1 >= argc){ 143 | printf("ERROR: Output flag requires filename\nEg: %s main.c -o execName\n", argv[0]); 144 | exit(0); 145 | } 146 | strcpy(target, argv[i + 1]); 147 | i++; 148 | } else if(strcmp("-b", argument) == 0 || strcmp("-beauty", argument) == 0 || strcmp("-toruncodes", argument) == 0){ 149 | beauty = true; 150 | } else if(strcmp("-r", argument) == 0 || strcmp("-run", argument) == 0){ 151 | run = true; 152 | compile = true; 153 | } else if(strcmp("-ni", argument) == 0|| strcmp("-noimplication", argument) == 0){ 154 | implyVariables = false; 155 | } else if(strcmp("-nc", argument) == 0|| strcmp("-nocompile", argument) == 0){ 156 | compile = false; 157 | run = false; 158 | } else if(strcmp("-s", argument) == 0|| strcmp("-silent", argument) == 0){ 159 | silent = true; 160 | } else if(strcmp("-cl", argument) == 0 || strcmp("-clear", argument) == 0 || strcmp("-clean", argument) == 0){ 161 | cleanCompilation = true; 162 | } else if(strcmp("-ex", argument) == 0|| strcmp("-export", argument) == 0){ 163 | exportProject = true; 164 | beauty = true; 165 | } else if(strcmp("-h", argument) == 0 || strcmp("-help", argument) == 0 || strcmp("-?", argument) == 0 || strcmp("?", argument) == 0 || strcmp("help", argument) == 0 || strcmp("--help", argument) == 0){ 166 | printHelp(); 167 | } else { 168 | if(argv[i][0] != '-'){ 169 | if(stringSource == "") 170 | stringSource = removeCharExt(argv[i]); 171 | else 172 | printf("ERROR: Only one source file must be specified, ignoring %s\n", argv[i]); 173 | } else { 174 | strcat(compilation, argv[i]); 175 | strcat(compilation, " "); 176 | } 177 | } 178 | } 179 | 180 | //Prepare compilation folder and move to it 181 | prepareDirectory(cleanCompilation); 182 | chdir(compilationDirectory); 183 | stringSource = cropPath(stringSource); 184 | 185 | //Generate complete c++ source 186 | stack dependenciesToProcess; 187 | set filesDone; 188 | set requiredHeaders; 189 | set allowedHeaders; 190 | map > dependenceMap; 191 | 192 | dependenciesToProcess.push(stringSource); 193 | 194 | char cpyFile[100]; 195 | char cppFile[100]; 196 | char headerFile[100]; 197 | 198 | //Generate complete c++ source 199 | while(!dependenciesToProcess.empty()){ 200 | string fileName = dependenciesToProcess.top(); 201 | dependenciesToProcess.pop(); 202 | 203 | filesDone.insert(fileName); 204 | 205 | stringToCPY(fileName, cpyFile); 206 | stringToCPP(fileName, cppFile); 207 | 208 | vector dependencies; 209 | 210 | bool wroteCppFile = false; 211 | if(!fileExist(cppFile)){ 212 | if(fileExist(cpyFile)){ 213 | firstReplaces(cpyFile); 214 | generateSource(cpyFile, cppFile, beauty, implyVariables); 215 | allowedHeaders.insert(fileName); 216 | } 217 | } else { 218 | if(fileExist(cpyFile)){ 219 | if(fileModifiedTime(cppFile) < fileModifiedTime(cpyFile)){ 220 | remove(cppFile); 221 | firstReplaces(cpyFile); 222 | generateSource(cpyFile, cppFile, beauty, implyVariables); 223 | allowedHeaders.insert(fileName); 224 | } 225 | } 226 | } 227 | 228 | dependencies = getDependencies(cppFile); 229 | 230 | pair > dep; 231 | dep.first = fileName; 232 | dep.second = dependencies; 233 | 234 | dependenceMap.insert(dep); 235 | 236 | for(string fileName : dependencies){ 237 | requiredHeaders.insert(fileName); 238 | 239 | if(!filesDone.count(fileName)){ 240 | filesDone.insert(fileName); 241 | dependenciesToProcess.push(fileName); 242 | } 243 | } 244 | } 245 | 246 | //Generate necessary headers 247 | for(string fileName : requiredHeaders){ 248 | if(allowedHeaders.count(fileName)){ 249 | stringToCPP(fileName, cppFile); 250 | stringToH(fileName, headerFile); 251 | if(fileExist(headerFile)) 252 | remove(headerFile); 253 | generateHeader(cppFile, headerFile); 254 | } 255 | } 256 | 257 | if(exportProject){ 258 | createExportDirectory(filesDone, target); 259 | } 260 | 261 | //Compile files 262 | if(compile){ 263 | //Generate necessary object files and link 264 | smartCompilation(dependenceMap, stringSource, (string)target, (string)compilation, silent); 265 | 266 | if(run){ 267 | if(!silent) 268 | printf("Running code:\n"); 269 | system(((string)".." + (string)slash + (string)target).c_str()); 270 | } 271 | } 272 | } 273 | -------------------------------------------------------------------------------- /Source/sourceGen.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | #include "defines.h" 12 | #include "sourceGen.h" 13 | #include "headerGen.h" 14 | #include "string.h" 15 | #include "file.h" 16 | #include "line.h" 17 | #include "extensionHandler.h" 18 | #include "dependenciesMapper.h" 19 | #include "firstReplaces.h" 20 | 21 | FILE * input; 22 | FILE * output; 23 | 24 | int i, j; 25 | 26 | stack offSets; 27 | stack closeWithLineEnding; 28 | bool multiLineComment; 29 | char buff[LINESZ]; 30 | char buff2[LINESZ]; 31 | int buffLen; 32 | 33 | char buffPrevious[LINESZ]; 34 | int buffPreviousLen; 35 | 36 | bool canDeclareFunction; 37 | 38 | bool structTypedef; 39 | char structName[LINESZ]; 40 | vector > seenWords; 41 | 42 | void addPahrenthesis(char * s){ 43 | int offset = 0; 44 | for(offset = 0; stringContainsChar(" \n\t", s[offset]); offset++) 45 | if(s[offset+1] == '/' && s[offset+2] == '/') 46 | while(s[offset] != '\n') 47 | offset++; 48 | 49 | if( string_isWord(s, "class") >= 0 || 50 | string_isWord(s, "struct") >= 0) 51 | return; 52 | 53 | int len = strlen(s); 54 | 55 | if(s[len-2] == '{'){ 56 | int lookStart = max(max(max( 57 | string_isWord(s, "if"), 58 | string_isWord(s, "for")), 59 | string_isWord(s, "while")), 60 | string_isWord(s, "switch")); 61 | 62 | if(lookStart != -1){ 63 | int i = lookStart; 64 | while(stringContainsChar(" \t\n", s[i])) 65 | i++; 66 | 67 | bool imply = true; 68 | 69 | while(!stringContainsChar(" \t\n(", s[i]) && s[i] != '\0') i++; 70 | while(stringContainsChar(" \t\n", s[i])) i++; 71 | 72 | int parenthesisCount = 0; 73 | for(; s[i] != '\0'; i++){ 74 | if(s[i] == '(') 75 | parenthesisCount++; 76 | else if(s[i] == ')') 77 | parenthesisCount--; 78 | 79 | if(parenthesisCount == 0){ 80 | if(s[i] == ')') 81 | i++; 82 | while(stringContainsChar(" \t\n{;", s[i])) 83 | i++; 84 | imply = !(s[i] == '\0'); 85 | break; 86 | } 87 | } 88 | 89 | if(imply){ 90 | for(i = lookStart; s[i] != '\0'; i++){ 91 | if(s[i] == ' ' || s[i] == '\t'){ 92 | s[i] = '('; 93 | break; 94 | } 95 | } 96 | 97 | s[len-2] = ')'; 98 | s[len-1] = '{'; 99 | s[len] = '\n'; 100 | s[len+1] = '\0'; 101 | } 102 | } 103 | } 104 | } 105 | 106 | void implyFunction(char * s){ 107 | if( !canDeclareFunction || 108 | string_isWord(s, "do") != -1 || 109 | string_isWord(s, "else") != -1 || 110 | string_isWord(s, "if") != -1 || 111 | string_isWord(s, "class") != -1 || 112 | string_isWord(s, "struct") != -1 || 113 | string_isWord(s, "typedef") != -1) 114 | return; 115 | 116 | 117 | bool cancel = false; 118 | bool skipSplit = false; 119 | vector split = smartSplitWords(s, "", wordSeparators, true); 120 | string result = ""; 121 | for(string word : split){ 122 | if(word == "known"){ 123 | cancel = true; 124 | skipSplit = true; 125 | } 126 | else{ 127 | if(!skipSplit) 128 | result += word; 129 | skipSplit = false; 130 | } 131 | } 132 | 133 | if(cancel){ 134 | strcpy(s, result.c_str()); 135 | return; 136 | } 137 | 138 | char lastType[LINESZ]; 139 | lastType[0] = '\0'; 140 | int typeStartIndex = 0; 141 | 142 | int i = 0; 143 | while(s[i] == ' ' || s[i] == '\t') i++; 144 | 145 | int wordCount = 0; 146 | while(s[i] != '(' && s[i] != '\0'){ 147 | if(s[i] == ' ' || s[i] == '\t'){ 148 | while(s[i] == ' ' || s[i] == '\t') i++; 149 | if(s[i] != '(' && s[i] != '\0') 150 | wordCount++; 151 | i--; 152 | } 153 | i++; 154 | } 155 | 156 | if(wordCount == 0){ 157 | int pos = 0; 158 | while(s[pos] == ' ' || s[pos] == '\t') pos++; 159 | 160 | if(string_isWord(s, "main") != -1) 161 | stringInsert(s, "int ", pos); 162 | else 163 | stringInsert(s, "auto ", pos); 164 | } 165 | 166 | if(s[i] == '(') i++; 167 | 168 | while(s[i] == ' ' || s[i] == '\t') i++; 169 | 170 | int wordStartIndex = i; 171 | int wordEndIndex = i; 172 | int lastWordEndIndex = i; 173 | 174 | wordCount = 0; 175 | while(s[i] != '\0' && s[i] != '\n'){ 176 | wordCount++; 177 | while(s[i] != ' ' && s[i] != '\t' && s[i] != '\0' && s[i] != '\n' && s[i] != ',' && s[i] != '(' && s[i] != '=') i++; 178 | 179 | lastWordEndIndex = wordEndIndex; 180 | wordEndIndex = i; 181 | 182 | while(s[i] == ' ' || s[i] == '\t') i++; 183 | 184 | if(s[i] == '=') while(!(s[i] == ',' || s[i] == '\n' || s[i] == '\0')) i++; 185 | 186 | 187 | if(s[i] == '(' || s[i] == ',' || s[i] == '\n' || s[i] == '\0'){ 188 | if(wordCount == 1){ 189 | strInsert(s, lastType, wordStartIndex); 190 | while(!(s[i] == '(' || s[i] == ',' || s[i] == '\n' || s[i] == '\0')) i++; 191 | } else if (wordCount > 1) { 192 | int j; 193 | for(j = wordStartIndex; j < lastWordEndIndex; j++){ 194 | lastType[j-wordStartIndex] = s[j]; 195 | } 196 | lastType[j-wordStartIndex] = ' '; 197 | lastType[j-wordStartIndex+1] = '\0'; 198 | } 199 | wordCount = 0; 200 | i++; 201 | while(s[i] == ' ' || s[i] == '\t') i++; 202 | wordStartIndex = i; 203 | } 204 | } 205 | } 206 | 207 | bool wordSeen(string word){ 208 | for(unordered_set set : seenWords) 209 | if(set.count(word)) 210 | return true; 211 | return false; 212 | } 213 | 214 | void implyVariablesType(char * line){ 215 | if(line[0] == '#') return; 216 | 217 | vector firstSplit = smartSplitWords(line, "", " \t\n()[]{},.;!@#%^&*-+/:\'\\", true); 218 | vector > wordGroups; 219 | wordGroups.push_back(vector()); 220 | for(int i = 1; i < firstSplit.size(); i += 2){ 221 | if(!isWhitespace(firstSplit[i-1], " \t\n<>)[]-!@#%^&*-+/:\'\"\\")) 222 | wordGroups.push_back(vector()); 223 | wordGroups.back().push_back(firstSplit[i]); 224 | } 225 | 226 | line[0] = '\0'; 227 | 228 | int whiteSpaceID = 0; 229 | string type = ""; 230 | for(int id = 0; id < wordGroups.size(); id++){ 231 | if(wordGroups[id].size() == 1 && (removeStartEndWhitespace(firstSplit[whiteSpaceID]) == "," || removeStartEndWhitespace(firstSplit[whiteSpaceID]) == ";" || removeStartEndWhitespace(firstSplit[whiteSpaceID]) == "") && type == "known"){ 232 | seenWords.back().insert(wordGroups[id][0]); 233 | wordGroups[id][0] = ""; 234 | if(whiteSpaceID+2 < firstSplit.size()) 235 | firstSplit[whiteSpaceID+2] = ""; 236 | } 237 | else if(wordGroups[id].size() > 2 && wordGroups[id][1] == "="){ 238 | if(type == "known"){ 239 | seenWords.back().insert(wordGroups[id][0]); 240 | if(whiteSpaceID + 2 * wordGroups[id].size() < firstSplit.size()) 241 | firstSplit[whiteSpaceID + 2 * wordGroups[id].size()] = "; "; 242 | } 243 | } 244 | else if(wordGroups[id].size() > 2){ 245 | type = wordGroups[id][0]; 246 | } 247 | else if(wordGroups[id].size() == 2){ 248 | type = wordGroups[id][0]; 249 | 250 | if(type == "known"){ 251 | seenWords.back().insert(wordGroups[id][1]); 252 | wordGroups[id][0] = ""; 253 | wordGroups[id][1] = ""; 254 | if(whiteSpaceID+2 < firstSplit.size()){ 255 | firstSplit[whiteSpaceID+1] = ""; 256 | firstSplit[whiteSpaceID+2] = ""; 257 | } 258 | if(whiteSpaceID+4 < firstSplit.size()){ 259 | firstSplit[whiteSpaceID+3] = ""; 260 | firstSplit[whiteSpaceID+4] = ""; 261 | } 262 | } 263 | } 264 | 265 | if(wordGroups[id].size() > 2 && wordGroups[id][2] == "="){ 266 | type = wordGroups[id][0]; 267 | 268 | if(type == "known") 269 | seenWords.back().insert(wordGroups[id][1]); 270 | } 271 | 272 | 273 | whiteSpaceID += 2 * wordGroups[id].size(); 274 | } 275 | 276 | whiteSpaceID = 0; 277 | for(vector words : wordGroups){ 278 | 279 | if(words.size() >= 2 && words[1] == "=" && !wordSeen(words[0])){ 280 | words.insert (words.begin(), 1, "auto"); 281 | firstSplit.insert (firstSplit.begin() + whiteSpaceID + 1, 2, " "); 282 | firstSplit[whiteSpaceID + 1] = "auto"; 283 | } 284 | 285 | if(words.size() > 0 && words[0] == "known"){ 286 | if(words.size() == 2){ 287 | seenWords.back().insert(words[1]); 288 | words[1] = ""; 289 | if(whiteSpaceID+4 < firstSplit.size()) 290 | firstSplit[whiteSpaceID+4] = ""; 291 | } 292 | 293 | words[0] = ""; 294 | if(whiteSpaceID+2 < firstSplit.size()) 295 | firstSplit[whiteSpaceID+2] = ""; 296 | } 297 | 298 | for(string word : words){ 299 | strcat(line, firstSplit[whiteSpaceID].c_str()); 300 | strcat(line, word.c_str()); 301 | seenWords.back().insert(word); 302 | whiteSpaceID += 2; 303 | } 304 | } 305 | if(whiteSpaceID < firstSplit.size()) 306 | strcat(line, firstSplit[whiteSpaceID].c_str()); 307 | 308 | if(isWhitespace(string(line), " \t,;\n")){ 309 | line[0] = '\n'; 310 | line[1] = '\0'; 311 | } 312 | } 313 | 314 | int closeKeys(int offset, bool beauty){ 315 | int closeAmount = 0; 316 | while(offset < offSets.top()){ 317 | closeAmount++; 318 | bool closeLineEnding = closeWithLineEnding.top(); 319 | closeWithLineEnding.pop(); 320 | offSets.pop(); 321 | int retOffset = offSets.top(); 322 | 323 | buffPreviousLen = strlen(buffPrevious); 324 | if(buffPrevious[buffPreviousLen-1] == '\n'){ 325 | if(beauty){ 326 | for(i = 0; i < retOffset/tabSpaces; i++) 327 | buffPrevious[buffPreviousLen++] = '\t'; 328 | for(j = 0; j < retOffset%tabSpaces; j++) 329 | buffPrevious[buffPreviousLen++] = ' '; 330 | buffPrevious[buffPreviousLen++] = '}'; 331 | buffPrevious[buffPreviousLen++] = '\n'; 332 | buffPrevious[buffPreviousLen] = '\0'; 333 | } 334 | else { 335 | buffPrevious[buffPreviousLen-1] = '}'; 336 | buffPrevious[buffPreviousLen++] = '\n'; 337 | buffPrevious[buffPreviousLen] = '\0'; 338 | } 339 | } 340 | else { 341 | if(beauty){ 342 | buffPrevious[buffPreviousLen++] = '\n'; 343 | for(i = 0; i < retOffset/tabSpaces; i++) 344 | buffPrevious[buffPreviousLen++] = '\t'; 345 | for(j = 0; j < retOffset%tabSpaces; j++) 346 | buffPrevious[buffPreviousLen++] = ' '; 347 | buffPrevious[buffPreviousLen++] = '}'; 348 | buffPrevious[buffPreviousLen++] = '\n'; 349 | buffPrevious[buffPreviousLen] = '\0'; 350 | } else { 351 | buffPrevious[buffPreviousLen++] = '}'; 352 | buffPrevious[buffPreviousLen] = '\0'; 353 | } 354 | } 355 | 356 | if(closeLineEnding){ 357 | if(structTypedef){ 358 | structTypedef = false; 359 | i = 0; 360 | buffPrevious[buffPreviousLen-1] = ' '; 361 | while(structName[i] != '\0') 362 | buffPrevious[buffPreviousLen++] = structName[i++]; 363 | buffPreviousLen++; 364 | } 365 | buffPrevious[buffPreviousLen-1] = ';'; 366 | buffPrevious[buffPreviousLen++] = '\n'; 367 | buffPrevious[buffPreviousLen] = '\0'; 368 | } 369 | } 370 | if(offSets.top() == 0) 371 | canDeclareFunction = true; 372 | else 373 | canDeclareFunction = closeWithLineEnding.top(); 374 | return closeAmount; 375 | } 376 | 377 | int placeLineEnding(char * line){ 378 | int len = strlen(line); 379 | 380 | int last = len-1; 381 | while(last >= 0 && stringContainsChar(" \t\n", line[last])) last--; 382 | 383 | if(last != -1 && line[last] != ';'){ 384 | line[++last] = ';'; 385 | line[++last] = '\n'; 386 | line[++last] = '\0'; 387 | } 388 | return last; 389 | } 390 | 391 | void generateSource(char * inputFile, char * outputFile, bool beauty, bool implyVariables){ 392 | input = fopen(inputFile, "r"); 393 | output = fopen(outputFile, "w+"); 394 | 395 | if(input == NULL){ 396 | printf("File not found\n"); 397 | printf("USAGE: cmp SourceCode Flags"); 398 | exit(0); 399 | } 400 | offSets.push(0); 401 | closeWithLineEnding.push(false); 402 | 403 | seenWords.clear(); 404 | seenWords.push_back(unordered_set()); 405 | 406 | multiLineComment = false; 407 | canDeclareFunction = true; 408 | structTypedef = false; 409 | 410 | buffPrevious[0] = '\0'; 411 | 412 | char emptyLinesBuffPrevious[LINESZ]; 413 | emptyLinesBuffPrevious[0] = '\0'; 414 | char emptyLinesBuff[LINESZ]; 415 | emptyLinesBuff[0] = '\0'; 416 | 417 | bool firstPrevious = true; 418 | 419 | while (fgets (buff, LINESZ, input)) { 420 | //Skip empty lines 421 | emptyLinesBuff[0] = '\0'; 422 | bool empty = isEmptyLine(buff); 423 | if(empty) 424 | strcpy(emptyLinesBuff, buff); 425 | 426 | while(empty){ 427 | if(!fgets (buff2, LINESZ, input)) 428 | break; 429 | 430 | empty = isEmptyLine(buff2); 431 | if(empty) 432 | strcat(emptyLinesBuff, buff2); 433 | else 434 | strcpy(buff, buff2); 435 | } 436 | 437 | //Read tab spaces 438 | int buffLen = strlen(buff); 439 | int offset = 0; 440 | for(i = 0; i < buffLen; i++){ 441 | if(buff[i] == '\t') 442 | offset += tabSpaces; 443 | else if(buff[i] == ' ') 444 | offset++; 445 | else if(buff[i] == '\n') 446 | offset = 0; 447 | else if(buff[i] == '/' && buff[i+1] == '/'){ 448 | while(buff[i] != '\n' && buff[i] != '\0') 449 | i++; 450 | offset = 0; 451 | } 452 | else 453 | break; 454 | } 455 | bool oneLineComment = false; 456 | bool cPreCompilerTag = false; 457 | bool multiLineCommentEnd = false; 458 | 459 | //Interpret comments & precompiler flags 460 | if(buff[i] == '#') 461 | cPreCompilerTag = true; 462 | else{ 463 | buffLen = strlen(buff); 464 | for(; i < buffLen-1; i++){ 465 | if(buff[i] == '/'){ 466 | if(buff[i+1] == '/') 467 | oneLineComment = true; 468 | if(buff[i+1] == '*'){ 469 | multiLineComment = true; 470 | } 471 | } 472 | 473 | if(buff[i] == '*' && buff[i+1] == '/'){ 474 | multiLineComment = false; 475 | multiLineCommentEnd = true; 476 | } 477 | } 478 | } 479 | 480 | int outScopeAmount = 0; 481 | if(!multiLineComment && !multiLineCommentEnd && !cPreCompilerTag && !oneLineComment){ 482 | buffLen = placeLineEnding(buff); 483 | 484 | if(offset > offSets.top()){ 485 | implyFunction(buffPrevious); 486 | buffPreviousLen = strlen(buffPrevious); 487 | 488 | seenWords.push_back(unordered_set()); 489 | 490 | offSets.push(offset); 491 | closeWithLineEnding.push(false); 492 | canDeclareFunction = false; 493 | 494 | if(string_isWord(buffPrevious, "struct") >= 0){ 495 | closeWithLineEnding.top() = true; 496 | if(string_isWord(buffPrevious, "typedef") >= 0){ 497 | structTypedef = true; 498 | getStructName(buffPrevious, structName); 499 | } 500 | else structTypedef = false; 501 | } 502 | 503 | if(string_isWord(buffPrevious, "class") >= 0){ 504 | closeWithLineEnding.top() = true; 505 | canDeclareFunction = true; 506 | } 507 | 508 | if(buffPrevious[buffPreviousLen-1] == '\n') 509 | buffPrevious[buffPreviousLen-2] = '{'; 510 | else 511 | buffPrevious[buffPreviousLen-1] = '{'; 512 | 513 | 514 | addPahrenthesis(buffPrevious); 515 | } 516 | 517 | outScopeAmount = closeKeys(offset, beauty); 518 | } 519 | 520 | if(implyVariables) 521 | implyVariablesType(buffPrevious); 522 | while(outScopeAmount--) 523 | seenWords.pop_back(); 524 | 525 | if(!firstPrevious){ 526 | fputs(emptyLinesBuffPrevious, output); 527 | fputs(buffPrevious, output); 528 | } 529 | else 530 | firstPrevious = false; 531 | 532 | strcpy(buffPrevious, buff); 533 | strcpy(emptyLinesBuffPrevious, emptyLinesBuff); 534 | 535 | buffPreviousLen = buffLen; 536 | } 537 | 538 | int outScopeAmount = closeKeys(0, beauty); 539 | if(implyVariables) 540 | implyVariablesType(buffPrevious); 541 | while(outScopeAmount--) 542 | seenWords.pop_back(); 543 | fputs(emptyLinesBuffPrevious, output); 544 | fputs(buffPrevious, output); 545 | fclose(input); 546 | fclose(output); 547 | } -------------------------------------------------------------------------------- /Source/sourceGen.h: -------------------------------------------------------------------------------- 1 | #ifndef _SOURCEGEN_H_ 2 | #define _SOURCEGEN_H_ 3 | 4 | void generateSource(char * inputFile, char * outputFile, bool beauty = false, bool implyVariables = true); 5 | 6 | #endif -------------------------------------------------------------------------------- /Source/string.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #include "defines.h" 5 | #include "string.h" 6 | 7 | 8 | 9 | bool stringContainsChar(const string& s, const char& check){ 10 | return s.find_first_of(check) != std::string::npos; 11 | } 12 | 13 | bool stringContainsChars(const string& s1, const string& s2){ 14 | for(char c : s1) 15 | if(s2.find_first_of(c) != string::npos) 16 | return true; 17 | return false; 18 | } 19 | 20 | bool isWhitespace(const string& s, const string& ignore){ 21 | for(char c : s) 22 | if(ignore.find(c) == string::npos) 23 | return false; 24 | return true; 25 | } 26 | 27 | string removeStartEndWhitespace(const string& s, const string& whitespace){ 28 | int i = 0; 29 | while(stringContainsChar(whitespace, s[i])) i++; 30 | 31 | int j = s.size()-1; 32 | while(stringContainsChar(whitespace, s[j])) j--; 33 | return s.substr(i, j-i+1); 34 | } 35 | 36 | char strsub(const char* a, const char* b, int as){ 37 | int bs = 0; 38 | while(a[as] != '\0' && b[bs] != '\0'){ 39 | if(a[as++] != b[bs++]) 40 | return 0; 41 | } 42 | return 1; 43 | } 44 | 45 | int string_isSubstring(const char* mainStr, const string& subStr){ 46 | int aux; 47 | for(aux = 0; mainStr[aux] != '\0'; aux++){ 48 | int aux1; 49 | for(aux1 = 0; subStr[aux1] == mainStr[aux+aux1]; aux1++){ 50 | if(subStr[aux1+1] == '\0') return aux; 51 | if(mainStr[aux+aux1+1] == '\0') return -1; 52 | } 53 | } 54 | return -1; 55 | } 56 | 57 | int string_isWord(const char* mainStr, const string& subStr, const string& separators){ 58 | int aux; 59 | for(aux = 0; mainStr[aux] != '\0'; aux++){ 60 | if(aux-1 == -1 || stringContainsChar(separators, mainStr[aux-1])){ 61 | int aux1; 62 | for(aux1 = 0; subStr[aux1] == mainStr[aux+aux1]; aux1++){ 63 | if(subStr[aux1+1] == '\0') 64 | if(mainStr[aux+aux1+1] == '\0' || stringContainsChar(separators, mainStr[aux+aux1+1])) 65 | return aux; 66 | if(mainStr[aux+aux1+1] == '\0') return -1; 67 | } 68 | } 69 | } 70 | return -1; 71 | } 72 | 73 | void strInsert(char* dest, const char* insert, int index){ 74 | std::string strInsert(insert); 75 | stringInsert(dest, strInsert, index); 76 | } 77 | 78 | void stringInsert(char* dest, const string& insert, int index){ 79 | std::string strDest(dest); 80 | strDest.insert(index, insert); 81 | strcpy(dest,strDest.c_str()); 82 | } 83 | 84 | void getStructName(const char* line, char* buffer){ 85 | int spc = 0; 86 | int i, j; 87 | for(i = 0; line[i] != '\0' && spc < 2; i++){ 88 | if(line[i] == ' ' || line[i] == '\t') 89 | spc++; 90 | while(line[i] == ' ' || line[i] == '\t') i++; 91 | } 92 | i--; 93 | 94 | if(spc != 2){ 95 | printf("typedef struct name not properly specified\n%d\n", line); 96 | exit(0); 97 | } 98 | 99 | j = 0; 100 | while(line[i] != '\0' && line[i] != ' ' && line[i] != '\t' && line[i] != ';' && line[i] != '{'){ 101 | buffer[j++] = line[i++]; 102 | } 103 | buffer[j] = '\0'; 104 | } 105 | 106 | bool isEmptyLine(const char* line){ 107 | for(int i = 0; line[i] != '\0' && !(line[i] == '/' && line[i+1] == '/'); i++){ 108 | if(line[i] != ' ' && line[i] != '\t' && line[i] != '\n') 109 | return false; 110 | } 111 | return true; 112 | } 113 | 114 | bool structHasTypedef(const char* line){ 115 | return string_isSubstring(line, "typedef") >= 0; 116 | } 117 | 118 | void stringToLower(char * s){ 119 | for(int i = 0; s[i]; i++) 120 | s[i] = tolower(s[i]); 121 | } 122 | -------------------------------------------------------------------------------- /Source/string.h: -------------------------------------------------------------------------------- 1 | #ifndef _STRING_H_43674_ 2 | #define _STRING_H_43674_ 3 | 4 | #include 5 | #include 6 | #include "defines.h" 7 | using namespace std; 8 | 9 | bool isWhitespace(const string& s, const string& ignore=whiteSpace); 10 | string removeStartEndWhitespace(const string& s, const string& whitespace=" \t\n"); 11 | char strsub(const char* a, const char* b, int as); 12 | int string_isSubstring(const char* mainStr, const string& subStr); 13 | void strInsert(char* dest, const char* insert, int index); 14 | void stringInsert(char* dest, const string& insert, int index); 15 | void getStructName(const char* line, char* buffer); 16 | bool isEmptyLine(const char* line); 17 | bool structHasTypedef(const char* line); 18 | bool stringContainsChar(const string& s, const char& check); 19 | bool stringContainsChars(const string& s1, const string& s2); 20 | void stringToLower(char * s); 21 | int string_isWord(const char* mainStr, const string& subStr, const string& separators=wordSeparators); 22 | 23 | #endif --------------------------------------------------------------------------------