release 0.1.15
[liba.git] / script / godbolt.py
blob999d716286fc9c00c1e155efbd751e1488fb7473
1 #!/usr/bin/env python
2 from subprocess import Popen
3 import urllib.request
4 import urllib.parse
5 import urllib.error
6 import sys, os, re
7 import ssl, json
10 class godbolt(object):
11 ssl._create_default_https_context = ssl._create_unverified_context
12 compiler = {"CC": "", "CXX": "", "CFLAGS": "", "CXXFLAGS": ""}
13 home_url = "https://godbolt.org"
14 headers = {
15 "Content-Type": "application/json;charset=utf-8",
16 "Accept": "application/json;charset=utf-8",
17 "User-Agent": "godbolt",
20 def languages(self):
21 url = self.home_url + "/api/languages"
22 request = urllib.request.Request(url, headers=self.headers)
23 reponse = urllib.request.urlopen(request)
24 text = reponse.read().decode("UTF-8")
25 sys.stdout.write(text)
26 return 0
28 def compilers(self, lang):
29 url = self.home_url + "/api/compilers/" + lang
30 request = urllib.request.Request(url, headers=self.headers)
31 reponse = urllib.request.urlopen(request)
32 text = reponse.read().decode("UTF-8")
33 sys.stdout.write(text)
34 return 0
36 def compile(self, source, output=""):
37 if os.path.splitext(source)[-1] != ".c":
38 option = self.compiler["CXXFLAGS"]
39 compiler = self.compiler["CXX"]
40 else:
41 option = self.compiler["CFLAGS"]
42 compiler = self.compiler["CC"]
43 if not compiler:
44 return False
45 if not output:
46 output = source + ".s"
47 with open(source, "r") as f:
48 source = f.read()
49 data = json.dumps(
51 "source": source,
52 "options": {
53 "userArguments": option,
56 ).encode("UTF-8")
57 url = self.home_url + "/api/compiler/" + compiler + "/compile"
58 request = urllib.request.Request(url, data=data, headers=self.headers)
59 reponse = urllib.request.urlopen(request)
60 text = reponse.read()
61 with open(output, "wb") as f:
62 f.write(text)
63 text = text.decode("UTF-8")
64 if "<Compilation failed>" not in text:
65 return True
66 return text.split("Standard error:")[-1]
69 if __name__ == "__main__":
70 import argparse
72 parser = argparse.ArgumentParser()
73 parser.add_argument("-S")
74 parser.add_argument("-O")
75 parser.add_argument("--cc", default="")
76 parser.add_argument("--cxx", default="")
77 parser.add_argument("--cflags", default="")
78 parser.add_argument("--cxxflags", default="")
79 parser.add_argument("-l", "--lang", default="")
80 args = parser.parse_known_args()
81 if not args[0].O:
82 args[0].O = "build"
83 if not args[0].S:
84 args[0].S = "src"
85 o = godbolt()
86 if args[0].lang:
87 exit(o.compilers(args[0].lang))
88 args[0].S = os.path.relpath(args[0].S)
89 args[0].O = os.path.relpath(args[0].O)
90 single = os.path.join(os.path.dirname(__file__), "single.py")
91 single = [sys.executable, single, "-Iinclude", "-C", args[0].S]
92 single += ["-O", os.path.join(args[0].O, args[0].S)]
93 Popen(single).wait()
94 os.chdir(args[0].O)
95 o.compiler["CC"] = args[0].cc
96 o.compiler["CFLAGS"] = args[0].cflags
97 o.compiler["CXX"] = args[0].cxx
98 o.compiler["CXXFLAGS"] = args[0].cxxflags
99 for dirpath, dirnames, filenames in os.walk(args[0].S):
100 for filename in filenames:
101 source = os.path.join(dirpath, filename)
102 prefix, suffix = os.path.splitext(source)
103 if suffix in (".c", ".cc", ".cpp", ".cxx"):
104 err = o.compile(source)
105 if err != False:
106 sys.stdout.write(source)
107 if type(err) == type(""):
108 sys.stdout.write(err) # type: ignore
109 if err != False:
110 sys.stdout.write("\n")