Compare commits
859 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a07539fb88 | ||
|
|
6988e5f074 | ||
|
|
aba016da72 | ||
|
|
09aef5c0ae | ||
|
|
9b161187ec | ||
|
|
8883f36fe3 | ||
|
|
0850f68fd1 | ||
|
|
57f4e90257 | ||
|
|
f8f428cc18 | ||
|
|
e23e86921b | ||
|
|
65ed6a9def | ||
|
|
e99c788155 | ||
|
|
c7022c1a0c | ||
|
|
26cd41f0c7 | ||
|
|
fb19846855 | ||
|
|
205ea95802 | ||
|
|
c5215fdd48 | ||
|
|
fad5eb0a87 | ||
|
|
b3c0e9d3cc | ||
|
|
470b79385b | ||
|
|
1ecf99bd0f | ||
|
|
e0fb4d1da9 | ||
|
|
ac2a0e615b | ||
|
|
52bd4e29ff | ||
|
|
833e4d1319 | ||
|
|
564b60520c | ||
|
|
085987ff2c | ||
|
|
aaf9cfd18c | ||
|
|
7ff686d6ec | ||
|
|
0cc9409fda | ||
|
|
6dd27e7cff | ||
|
|
d0eeb3ebdc | ||
|
|
fa99986143 | ||
|
|
6ea8eba8ce | ||
|
|
9b5c7153c9 | ||
|
|
d52b0c32a0 | ||
|
|
7734ead520 | ||
|
|
1bed9b3fea | ||
|
|
8b57c49490 | ||
|
|
296450451b | ||
|
|
4f5f90222f | ||
|
|
f58fb32283 | ||
|
|
9c45b4462c | ||
|
|
690f6ea1d7 | ||
|
|
1c140f7382 | ||
|
|
e5a93bf99a | ||
|
|
f3c368ca73 | ||
|
|
b8823a8b34 | ||
|
|
355a42f36d | ||
|
|
658bcbcbdc | ||
|
|
7669c5b5ec | ||
|
|
a390ca5f30 | ||
|
|
c46c41eae3 | ||
|
|
82aa5b1de6 | ||
|
|
12379c697a | ||
|
|
f5348e17f8 | ||
|
|
a2b4abd89a | ||
|
|
6d5e100d0d | ||
|
|
1886d03faa | ||
|
|
9b62facdd4 | ||
|
|
da92f5b2d6 | ||
|
|
f1069a30b9 | ||
|
|
2718b42828 | ||
|
|
fc52f2c007 | ||
|
|
0b9070fe01 | ||
|
|
c04598f2b0 | ||
|
|
96778a1c21 | ||
|
|
935d891e9d | ||
|
|
682875adff | ||
|
|
0126d01435 | ||
|
|
946db8ba65 | ||
|
|
7814a8e131 | ||
|
|
ebc3d232f4 | ||
|
|
f087c66f95 | ||
|
|
508fdc3496 | ||
|
|
d63752ef4d | ||
|
|
6fb76443b3 | ||
|
|
2eefed84c9 | ||
|
|
230530f5ea | ||
|
|
17d92233d9 | ||
|
|
54a65e6d87 | ||
|
|
26d385c18b | ||
|
|
da2a22c384 | ||
|
|
0fa9a8929c | ||
|
|
2a1a531ba3 | ||
|
|
51f6b6d33f | ||
|
|
b5a100b859 | ||
|
|
54fcab20e3 | ||
|
|
a2bc90d1d7 | ||
|
|
c01f8c3d3c | ||
|
|
e4181a7f1b | ||
|
|
01f6f2d741 | ||
|
|
c5df37c111 | ||
|
|
e0ceeab0d1 | ||
|
|
93077c98e4 | ||
|
|
3dab303826 | ||
|
|
3160fd24ba | ||
|
|
ce7822c130 | ||
|
|
745a3adebd | ||
|
|
218ec6c085 | ||
|
|
d30d7800e0 | ||
|
|
8820d97039 | ||
|
|
b52fde7cf7 | ||
|
|
2b4d0b6ff9 | ||
|
|
21f1370d2a | ||
|
|
d78f9b834a | ||
|
|
445deb7470 | ||
|
|
02b67558e8 | ||
|
|
91c8f87fb1 | ||
|
|
d056b7fa52 | ||
|
|
2a609af518 | ||
|
|
1d5d6616ae | ||
|
|
b9b3efb09f | ||
|
|
0f34d506b5 | ||
|
|
5eccc122e8 | ||
|
|
681b51aac4 | ||
|
|
4268cb8efe | ||
|
|
3f1a72908c | ||
|
|
2fed476ce1 | ||
|
|
6cb39dd3da | ||
|
|
88cc1ca55a | ||
|
|
1bd9769111 | ||
|
|
47372813ef | ||
|
|
fc213c873d | ||
|
|
972f0bd3db | ||
|
|
808310a569 | ||
|
|
0a5450fe04 | ||
|
|
9bab0b8a24 | ||
|
|
17182732f5 | ||
|
|
18c77744ff | ||
|
|
ac93a6ff6c | ||
|
|
13e3b2f433 | ||
|
|
f2da6581ba | ||
|
|
444fc892b0 | ||
|
|
b56aee3697 | ||
|
|
35a7dcb162 | ||
|
|
e0fde02290 | ||
|
|
59b8245bbc | ||
|
|
8f9daaa3ba | ||
|
|
d3b751e4d9 | ||
|
|
7731061903 | ||
|
|
b9683d3748 | ||
|
|
66979aa468 | ||
|
|
93f9c023cc | ||
|
|
e0ee0cc66a | ||
|
|
9b135a9c20 | ||
|
|
e171bf74f8 | ||
|
|
bb2e99dfc2 | ||
|
|
b37d175e59 | ||
|
|
f087633efd | ||
|
|
bbce726c8a | ||
|
|
bbc4ea4ae8 | ||
|
|
2126d81488 | ||
|
|
06b381d1c9 | ||
|
|
08eea0f0e4 | ||
|
|
a1798a8188 | ||
|
|
0fac8cba47 | ||
|
|
1ca74aba6f | ||
|
|
2ce30382d9 | ||
|
|
8bc545be2a | ||
|
|
891fcd8ce1 | ||
|
|
bd06091874 | ||
|
|
3e3edcc465 | ||
|
|
89a32267f7 | ||
|
|
021177ca9b | ||
|
|
115364b0a9 | ||
|
|
6d15d00ac4 | ||
|
|
bdaa43510b | ||
|
|
9a51f5c350 | ||
|
|
301c0a6303 | ||
|
|
65f486ff02 | ||
|
|
df096a7771 | ||
|
|
0e9a9f243f | ||
|
|
12c964b2b7 | ||
|
|
cf71f5cd60 | ||
|
|
adab2e16bd | ||
|
|
a3e3235d97 | ||
|
|
2be3c4b0e3 | ||
|
|
0ee796632a | ||
|
|
1fe67c125d | ||
|
|
ba996f5e27 | ||
|
|
64bf5bafe9 | ||
|
|
4d05bbf2a4 | ||
|
|
471990f771 | ||
|
|
7b623aab9d | ||
|
|
e871ae1270 | ||
|
|
c44830ebf3 | ||
|
|
3e4a04f34d | ||
|
|
38827dd9ca | ||
|
|
21fd9f037e | ||
|
|
033763eaf7 | ||
|
|
2573094df2 | ||
|
|
745026b7b4 | ||
|
|
a07d955eaa | ||
|
|
9d6f4e2e7f | ||
|
|
ff07d54843 | ||
|
|
e53879328c | ||
|
|
b792412d31 | ||
|
|
49c6f1053c | ||
|
|
4d960f6dc6 | ||
|
|
8941665896 | ||
|
|
9cc0f60666 | ||
|
|
fdb8edf5ea | ||
|
|
9ba9fe818d | ||
|
|
92224d27b1 | ||
|
|
157a4bd926 | ||
|
|
29d6881112 | ||
|
|
e2692921e1 | ||
|
|
b63138c3ec | ||
|
|
a59fcc33e6 | ||
|
|
07311f3157 | ||
|
|
17637ed1bb | ||
|
|
f15828e901 | ||
|
|
dadd689359 | ||
|
|
b750cab56a | ||
|
|
485748c416 | ||
|
|
080699f7df | ||
|
|
8e35f54931 | ||
|
|
d44f1a77ee | ||
|
|
4181046488 | ||
|
|
d7c398b638 | ||
|
|
5f5d0aa4ff | ||
|
|
9f1520b4c0 | ||
|
|
a98e8c0889 | ||
|
|
ee445a2ba4 | ||
|
|
b2c226cb7d | ||
|
|
13614f4e1c | ||
|
|
4f9ccdd70f | ||
|
|
4e36b1e3da | ||
|
|
f12f8a6c14 | ||
|
|
c57c54ce96 | ||
|
|
c8130df1d9 | ||
|
|
af8a742d00 | ||
|
|
e67500aa15 | ||
|
|
a6d3bf6fc3 | ||
|
|
3e617f3cd6 | ||
|
|
0fe35b907a | ||
|
|
3fc7c97827 | ||
|
|
7f79d249a6 | ||
|
|
f138374027 | ||
|
|
f52a1ae849 | ||
|
|
3bc0fe1ee3 | ||
|
|
fa0cc27400 | ||
|
|
4cb29bde2e | ||
|
|
2dcf75a722 | ||
|
|
671fd94e25 | ||
|
|
717d2f6f9e | ||
|
|
8cb95cb916 | ||
|
|
56b446190a | ||
|
|
86f9e836be | ||
|
|
a90a170361 | ||
|
|
889a5e0cf1 | ||
|
|
9f8bc00cf5 | ||
|
|
3363a1c227 | ||
|
|
fc9939c4e1 | ||
|
|
7267f796e6 | ||
|
|
7dfeceb8cc | ||
|
|
3807e520ec | ||
|
|
7625b1a4f4 | ||
|
|
1fc5cc1b59 | ||
|
|
61ccb43487 | ||
|
|
bf24b120d7 | ||
|
|
b70acf3c5b | ||
|
|
b5be6b72cb | ||
|
|
318ad3c1e4 | ||
|
|
e949a2ed2f | ||
|
|
8d0108fc5d | ||
|
|
ba41efa8a0 | ||
|
|
f81660b6db | ||
|
|
91bceb4ace | ||
|
|
be746628c7 | ||
|
|
ec5f531f4b | ||
|
|
37e5816bcd | ||
|
|
665bb43a4c | ||
|
|
e4bf004560 | ||
|
|
1609df3275 | ||
|
|
24f288770e | ||
|
|
65e6319b12 | ||
|
|
ec75953f50 | ||
|
|
801a13f791 | ||
|
|
eea8d6aa96 | ||
|
|
2b9cd71d67 | ||
|
|
5df83e3bd9 | ||
|
|
6061707371 | ||
|
|
20899c05a4 | ||
|
|
4c8c5e2f74 | ||
|
|
d1a95c643e | ||
|
|
9c3ea0d32d | ||
|
|
67e0894d9e | ||
|
|
6cc87a31c6 | ||
|
|
b8c766a9c5 | ||
|
|
66441c9b4b | ||
|
|
18d51d1de8 | ||
|
|
01d5fc670b | ||
|
|
0f1cbfd3da | ||
|
|
586f10ecb1 | ||
|
|
978737f5d5 | ||
|
|
fa0e057f8a | ||
|
|
bca7bfa927 | ||
|
|
12d654a6fc | ||
|
|
8e64e4383c | ||
|
|
f59d8cde26 | ||
|
|
94c0519be2 | ||
|
|
529c502876 | ||
|
|
c04c8f10f0 | ||
|
|
e05d35e6e0 | ||
|
|
e1e2df656a | ||
|
|
f7da5b29f0 | ||
|
|
2b4c236773 | ||
|
|
a8ca75738a | ||
|
|
aad4890082 | ||
|
|
e5edd3b983 | ||
|
|
a47341cf96 | ||
|
|
e46bda5093 | ||
|
|
a98d1d67d6 | ||
|
|
ba2884f343 | ||
|
|
1d80155d5e | ||
|
|
a0e42aa4e2 | ||
|
|
92959cd4ef | ||
|
|
2c802399c3 | ||
|
|
8ed72a8470 | ||
|
|
0d9a8207d6 | ||
|
|
04edbb0703 | ||
|
|
e1c1fce92c | ||
|
|
c8695209f6 | ||
|
|
9b95112a2d | ||
|
|
a602c57c8d | ||
|
|
f3228592f5 | ||
|
|
87b8254da1 | ||
|
|
20eab80189 | ||
|
|
810389c07a | ||
|
|
3badd3782b | ||
|
|
be2a264915 | ||
|
|
b81baf5423 | ||
|
|
64359c9417 | ||
|
|
5a3853f83f | ||
|
|
532d746036 | ||
|
|
c66e18b175 | ||
|
|
2d4bd3b3ad | ||
|
|
a96d6c68e2 | ||
|
|
504815091f | ||
|
|
4dd3e7fe35 | ||
|
|
4c614909ff | ||
|
|
b0a23c73cf | ||
|
|
922c1f8f9f | ||
|
|
c3c58eb601 | ||
|
|
ce3c52d17d | ||
|
|
6663d0264e | ||
|
|
6e4d623dc8 | ||
|
|
8e704d9718 | ||
|
|
5bd32bd90d | ||
|
|
b9f417e2e6 | ||
|
|
9f7b087235 | ||
|
|
2cb9738649 | ||
|
|
0dc590a9f8 | ||
|
|
dfd2c60509 | ||
|
|
fd27393df3 | ||
|
|
233950da40 | ||
|
|
bd0aafb4fd | ||
|
|
a672eae3d1 | ||
|
|
99d0d771a7 | ||
|
|
8dcea0ac07 | ||
|
|
7a6c6ec946 | ||
|
|
dfe79cc784 | ||
|
|
4a439c2359 | ||
|
|
4c16c82500 | ||
|
|
5513c49c54 | ||
|
|
b61f48e5aa | ||
|
|
de4b39a1a3 | ||
|
|
322502b441 | ||
|
|
b7dfd333c5 | ||
|
|
178da7c6a9 | ||
|
|
d89ea3e6f9 | ||
|
|
6c9c1e6712 | ||
|
|
b10bcd924b | ||
|
|
d8e2e9a41f | ||
|
|
1f70b279ba | ||
|
|
e33e57684f | ||
|
|
a0c6649960 | ||
|
|
ca73dea3b9 | ||
|
|
648bd22427 | ||
|
|
0231d8f86d | ||
|
|
a91908e567 | ||
|
|
ae33883c2f | ||
|
|
4dca5d4db7 | ||
|
|
21701190ac | ||
|
|
5cd86443ee | ||
|
|
779ddb1832 | ||
|
|
445feaeef5 | ||
|
|
932d973e36 | ||
|
|
9eb6f627fa | ||
|
|
323c2d6775 | ||
|
|
09baeec0da | ||
|
|
8247bccf71 | ||
|
|
bbf37c0404 | ||
|
|
e336b0d60e | ||
|
|
5cd4430a8d | ||
|
|
23420ff67a | ||
|
|
ef50e01c5e | ||
|
|
cc0064b267 | ||
|
|
1aaa599147 | ||
|
|
d27472cc74 | ||
|
|
80ea44c485 | ||
|
|
dba29970d7 | ||
|
|
4cd2617848 | ||
|
|
5b31794dfe | ||
|
|
355f4b0c15 | ||
|
|
bbb5e5d56a | ||
|
|
b8bd9a71c8 | ||
|
|
be3865211c | ||
|
|
0f19cbc6e5 | ||
|
|
49da42983a | ||
|
|
7db7109a5b | ||
|
|
9f8d192991 | ||
|
|
760fd65487 | ||
|
|
8b1df1a259 | ||
|
|
9bc97a5785 | ||
|
|
6707f70b4a | ||
|
|
df30ef5177 | ||
|
|
7e8ad6cad3 | ||
|
|
e0e18f3841 | ||
|
|
328f0dd631 | ||
|
|
15c8d46b04 | ||
|
|
052918a6d9 | ||
|
|
afe41de6b3 | ||
|
|
2ad5dba50a | ||
|
|
0b8a14fed7 | ||
|
|
ac9013162e | ||
|
|
ed2bc7fbe9 | ||
|
|
d0c820acd6 | ||
|
|
2f9f2cbb19 | ||
|
|
bad0de0dcb | ||
|
|
3b62c145f8 | ||
|
|
3914e82f17 | ||
|
|
b522b788b6 | ||
|
|
1b73c79234 | ||
|
|
36956da4d2 | ||
|
|
f4d878f3d8 | ||
|
|
61acd18e79 | ||
|
|
e1b4acfb6e | ||
|
|
d85d3c74db | ||
|
|
8ecee175f2 | ||
|
|
8b10617bba | ||
|
|
90b16a3e85 | ||
|
|
4dc1fb923a | ||
|
|
b8dec948d4 | ||
|
|
87670a7ac1 | ||
|
|
63d293cdbe | ||
|
|
f0dbec0c93 | ||
|
|
79789af2e7 | ||
|
|
8639b0fae9 | ||
|
|
00665a0b72 | ||
|
|
b59c8399fb | ||
|
|
289b30715d | ||
|
|
7770304576 | ||
|
|
890ffa05f8 | ||
|
|
89014b4524 | ||
|
|
f8608a5228 | ||
|
|
437c1e40b2 | ||
|
|
53db80da89 | ||
|
|
28cc3cc960 | ||
|
|
1291778032 | ||
|
|
b930baa580 | ||
|
|
66ee2dec53 | ||
|
|
f2ae2f7eef | ||
|
|
88a593d559 | ||
|
|
5d9bb0a050 | ||
|
|
8048f4d4f6 | ||
|
|
d48e6ae66f | ||
|
|
4f46bd19d0 | ||
|
|
ca49510e6d | ||
|
|
25ac04a444 | ||
|
|
8e52c2e754 | ||
|
|
2bb5ec1e41 | ||
|
|
55522373fd | ||
|
|
c9471e7782 | ||
|
|
5b262ff5ab | ||
|
|
e8d0538a00 | ||
|
|
a1c63e8be6 | ||
|
|
a64b1b4375 | ||
|
|
64500ab0fa | ||
|
|
00b853418e | ||
|
|
8d56bf5ceb | ||
|
|
44f419ec0f | ||
|
|
177cab5fe7 | ||
|
|
187d6a66a5 | ||
|
|
6952fe3a5c | ||
|
|
b19b7c39ac | ||
|
|
9276c4e163 | ||
|
|
2cd7a0395d | ||
|
|
f2be249385 | ||
|
|
81b01f1c2b | ||
|
|
a4d9e63d12 | ||
|
|
64af2aafda | ||
|
|
40cdcf1183 | ||
|
|
182d9cb752 | ||
|
|
c2ddfb343a | ||
|
|
9e9bfc4e26 | ||
|
|
f63c6c008f | ||
|
|
eb2f01aee8 | ||
|
|
30fb5c3e81 | ||
|
|
c780901cd5 | ||
|
|
ca419f3cd8 | ||
|
|
a45421baaf | ||
|
|
be6a3696a9 | ||
|
|
7943ecb812 | ||
|
|
16d8397e30 | ||
|
|
1a6682c21d | ||
|
|
82b14a05f2 | ||
|
|
e66b158f0b | ||
|
|
c88e435724 | ||
|
|
eeb2a1a6e3 | ||
|
|
7335a70a02 | ||
|
|
1b7b2ba216 | ||
|
|
3c836dd71b | ||
|
|
90fce8bfa6 | ||
|
|
1f1ea18b54 | ||
|
|
07caa3fccd | ||
|
|
83fc6fdb34 | ||
|
|
2acb9a6ea7 | ||
|
|
e482b5694f | ||
|
|
6c959207db | ||
|
|
71e8ae01b8 | ||
|
|
a7cc3248fe | ||
|
|
82e09c17a9 | ||
|
|
ae341b31c8 | ||
|
|
ab7adb0027 | ||
|
|
b4b5921dd0 | ||
|
|
c683e4aaa2 | ||
|
|
b7159818f9 | ||
|
|
d4b55fc5b2 | ||
|
|
4f7627972e | ||
|
|
920e1ccfe0 | ||
|
|
54ea317375 | ||
|
|
0731b44809 | ||
|
|
cb84e3f029 | ||
|
|
bb6115b737 | ||
|
|
d8715fba1a | ||
|
|
b4cc8cbac4 | ||
|
|
c3a77d6268 | ||
|
|
ba8c4c6b1a | ||
|
|
44bc2e80dd | ||
|
|
4e8cec05ab | ||
|
|
afecb93e2e | ||
|
|
437c3863f1 | ||
|
|
710435b51b | ||
|
|
cd791bd855 | ||
|
|
7cc6b801e0 | ||
|
|
5a3844981b | ||
|
|
863d166c7b | ||
|
|
b04219fdbb | ||
|
|
61734cc7ae | ||
|
|
0951524ca2 | ||
|
|
b0a6b979a3 | ||
|
|
7f2b077da4 | ||
|
|
06ac31cf1a | ||
|
|
2e14aff80f | ||
|
|
a59a93f476 | ||
|
|
e859f36967 | ||
|
|
25ed5fedda | ||
|
|
3778f1bf77 | ||
|
|
f85f46461f | ||
|
|
5bb517355e | ||
|
|
22eea17b06 | ||
|
|
c8d6efd602 | ||
|
|
b6b17e5648 | ||
|
|
88b012ad3b | ||
|
|
581b320b9d | ||
|
|
b42a5b118f | ||
|
|
eeb322ae64 | ||
|
|
52ede09b17 | ||
|
|
f5c432bcab | ||
|
|
7c12e8ea44 | ||
|
|
30860491ba | ||
|
|
0f6f83a709 | ||
|
|
e3fe634f99 | ||
|
|
dc3e969e14 | ||
|
|
b7f6404168 | ||
|
|
b6b5ec8f75 | ||
|
|
ca37730c9d | ||
|
|
6fb8ae2bd6 | ||
|
|
2924fdfcf7 | ||
|
|
eac390f289 | ||
|
|
de54273f51 | ||
|
|
6b727c0440 | ||
|
|
2c6be49d20 | ||
|
|
a42b7355f4 | ||
|
|
b4a5251391 | ||
|
|
a183ea29f9 | ||
|
|
affffb39b3 | ||
|
|
0ef327bbee | ||
|
|
795b70423e | ||
|
|
49227f65ff | ||
|
|
a386b4c983 | ||
|
|
5cb3fa2f89 | ||
|
|
43d716280e | ||
|
|
cc6170d7fc | ||
|
|
4d300e4dec | ||
|
|
1f58b2d084 | ||
|
|
6903fa2d47 | ||
|
|
319ae90184 | ||
|
|
7b884e0075 | ||
|
|
3e7b4ae0c3 | ||
|
|
3b75d0ce23 | ||
|
|
48807de305 | ||
|
|
1d7d1a3499 | ||
|
|
969008dbb0 | ||
|
|
6976e602f6 | ||
|
|
3b087e03ea | ||
|
|
6c8b023298 | ||
|
|
8dbf59fec5 | ||
|
|
ac0f8b81ae | ||
|
|
5fc032a9d1 | ||
|
|
806e3cd075 | ||
|
|
8923325d5c | ||
|
|
a2b2c8adc9 | ||
|
|
d20238c2a7 | ||
|
|
4ce83bf57b | ||
|
|
b500953425 | ||
|
|
2f99720901 | ||
|
|
6bd9008025 | ||
|
|
c97df052a9 | ||
|
|
7d9c5e0f7d | ||
|
|
d62d5fe59a | ||
|
|
d8cec35b10 | ||
|
|
f81cff539a | ||
|
|
5fff491bbd | ||
|
|
781915f183 | ||
|
|
5b44a819d3 | ||
|
|
056f15aa53 | ||
|
|
37bda7e029 | ||
|
|
454dc9b7c2 | ||
|
|
b3d7a5c5d0 | ||
|
|
475521dd74 | ||
|
|
3c09c5f12d | ||
|
|
1a9e66915b | ||
|
|
84d11c19fd | ||
|
|
312263c7d9 | ||
|
|
3369783e0a | ||
|
|
47ff813012 | ||
|
|
3b39d4d1c1 | ||
|
|
2fab2b310b | ||
|
|
c2ac4465cd | ||
|
|
bb8059f6aa | ||
|
|
4c2cc32f2e | ||
|
|
89a3fbc0fb | ||
|
|
077353b47e | ||
|
|
46621fd2c3 | ||
|
|
d6625ac34d | ||
|
|
b46b36729f | ||
|
|
893fabd336 | ||
|
|
44ea0da2b0 | ||
|
|
4f4e1026f5 | ||
|
|
8c23f20c68 | ||
|
|
4f65227971 | ||
|
|
e4736fe469 | ||
|
|
e32925397b | ||
|
|
f5f042ffdc | ||
|
|
d445a9aafb | ||
|
|
464660651d | ||
|
|
8d9141ed9a | ||
|
|
4be37222ef | ||
|
|
b0d9f7372a | ||
|
|
704fde01e8 | ||
|
|
0c9a858f2d | ||
|
|
b8ba80bff7 | ||
|
|
8ec6ccc54d | ||
|
|
1ca9e552d9 | ||
|
|
8f0a4a25f8 | ||
|
|
071af57bcf | ||
|
|
d68865f3b1 | ||
|
|
a724952f75 | ||
|
|
a4215f469c | ||
|
|
4c1abcb0ce | ||
|
|
1dd272080d | ||
|
|
3e3a79ea13 | ||
|
|
771655e3fe | ||
|
|
60cd5bf939 | ||
|
|
91b7690428 | ||
|
|
bb01bea4e2 | ||
|
|
c145589f25 | ||
|
|
c7c82f1b44 | ||
|
|
f58ac2b46b | ||
|
|
016007bd25 | ||
|
|
4ee00b2309 | ||
|
|
fb81bc3291 | ||
|
|
c646d287f8 | ||
|
|
51d4539a79 | ||
|
|
f273c64a94 | ||
|
|
74ec95e7f6 | ||
|
|
65f340bb95 | ||
|
|
4d014d6d7e | ||
|
|
fe56461387 | ||
|
|
56efed71b5 | ||
|
|
91f18ffd47 | ||
|
|
a4c4125b11 | ||
|
|
993b412160 | ||
|
|
2c2e389b77 | ||
|
|
3291235711 | ||
|
|
461cdb593b | ||
|
|
7f00e8c033 | ||
|
|
a87089fd2d | ||
|
|
1e24c2e4f4 | ||
|
|
9e56811a37 | ||
|
|
6060e098c9 | ||
|
|
aa1e052cb4 | ||
|
|
1a652afe16 | ||
|
|
6f1e45d5ba | ||
|
|
91130ea3fc | ||
|
|
b7caa1751c | ||
|
|
4c3da0f2e1 | ||
|
|
39b4ef4b02 | ||
|
|
74be4a62c5 | ||
|
|
e11489eb5f | ||
|
|
f970610c04 | ||
|
|
68b48cc045 | ||
|
|
7596b33506 | ||
|
|
2b7aff202a | ||
|
|
e76c55a9b8 | ||
|
|
ca211065b6 | ||
|
|
c7442ef0d2 | ||
|
|
a691aa2a13 | ||
|
|
00787fe781 | ||
|
|
f5a29eab5c | ||
|
|
2b94d7fc7f | ||
|
|
51f8ce26cf | ||
|
|
092fcaffe4 | ||
|
|
7e6ede1051 | ||
|
|
ddfef21125 | ||
|
|
3af101ccc1 | ||
|
|
4f088b6f1c | ||
|
|
da9aad8876 | ||
|
|
96dc42d99c | ||
|
|
1e50f5dd28 | ||
|
|
f127799d79 | ||
|
|
6b1d73446d | ||
|
|
fd4e161497 | ||
|
|
6362a9d610 | ||
|
|
d55fc35df1 | ||
|
|
67e9d33486 | ||
|
|
219859f8bb | ||
|
|
e0493457d5 | ||
|
|
1e3a7d4fab | ||
|
|
848dec3da2 | ||
|
|
ae0880997b | ||
|
|
9eb50a9624 | ||
|
|
acecefee88 | ||
|
|
ba784bdf36 | ||
|
|
c4de28938f | ||
|
|
6c33ba14a4 | ||
|
|
7a5b571c67 | ||
|
|
599e3c7b3f | ||
|
|
86bc7795a3 | ||
|
|
a3efdb13f2 | ||
|
|
3a97280ae8 | ||
|
|
4f3f6e28d5 | ||
|
|
79ada05756 | ||
|
|
c48271958f | ||
|
|
ac66d96c5a | ||
|
|
e5165aeb27 | ||
|
|
970f4c06e1 | ||
|
|
22ef7370e7 | ||
|
|
a38be3eb48 | ||
|
|
73c028c40a | ||
|
|
783289068a | ||
|
|
bb3651abc8 | ||
|
|
f0134f363b | ||
|
|
ce88d41907 | ||
|
|
0f9539e1e3 | ||
|
|
90e07b19ab | ||
|
|
63d1d145e2 | ||
|
|
c039bb38d4 | ||
|
|
861add3d72 | ||
|
|
6886913fdf | ||
|
|
c75d3b0ede | ||
|
|
7c0eb47dfb | ||
|
|
dbcdf83ed8 | ||
|
|
d31eab94fd | ||
|
|
553f08b819 | ||
|
|
32258af87b | ||
|
|
d251d48439 | ||
|
|
f9917c8c7b | ||
|
|
5a458da42a | ||
|
|
89c6c5bb85 | ||
|
|
fdd61b83ff | ||
|
|
32559ccad1 | ||
|
|
826efc2295 | ||
|
|
88f174a014 | ||
|
|
780bdb3e80 | ||
|
|
828e1e35fd | ||
|
|
fc85dd175e | ||
|
|
89ba380b3c | ||
|
|
b57b6e341e | ||
|
|
ad0e6e971e | ||
|
|
fdba0cb03c | ||
|
|
61ee9f299d | ||
|
|
16a23ff740 | ||
|
|
1d5d21726a | ||
|
|
7b662103a0 | ||
|
|
da729e5b38 | ||
|
|
5c39a1bb26 | ||
|
|
14ae5708d6 | ||
|
|
ffaf58f0a9 | ||
|
|
4496a44f68 | ||
|
|
4f1d92b332 | ||
|
|
ab664c7e17 | ||
|
|
8ee84584a4 | ||
|
|
748d1c171d | ||
|
|
a7434fd008 | ||
|
|
d9bb8179d3 | ||
|
|
ee36057dd5 | ||
|
|
a476aabf1a | ||
|
|
f3769a97d5 | ||
|
|
ca18202eb9 | ||
|
|
5eb60a6da2 | ||
|
|
f86ea9aad5 | ||
|
|
5bcdbb1ce4 | ||
|
|
2e530f4889 | ||
|
|
7f515b0e88 | ||
|
|
b4dd3209b2 | ||
|
|
262d92834a | ||
|
|
faf663133b | ||
|
|
64a6c2c1b6 | ||
|
|
847aaffbb8 | ||
|
|
a8472e0fdb | ||
|
|
1580ec1804 | ||
|
|
8906b2fe09 | ||
|
|
e798e4fd75 | ||
|
|
4b1a7d3868 | ||
|
|
e27af97a3c | ||
|
|
542b839ec7 | ||
|
|
67cd4ee8d2 | ||
|
|
c8a8ad97f7 | ||
|
|
d87f7a1e81 | ||
|
|
adc1b50395 | ||
|
|
e86619e75d | ||
|
|
b40dc8a1da | ||
|
|
86da6feb40 | ||
|
|
fe532a98f9 | ||
|
|
39ce85cf5d | ||
|
|
72e60dea36 | ||
|
|
7c1f74713e | ||
|
|
a5ff487889 | ||
|
|
331b815300 | ||
|
|
2348f8e2a8 | ||
|
|
251b3c6406 | ||
|
|
cc21706c50 | ||
|
|
25931f12c1 | ||
|
|
91a7a4a786 | ||
|
|
d89e57ea8d | ||
|
|
5a901bb555 | ||
|
|
284f1d6beb | ||
|
|
bc6fdad786 | ||
|
|
c05db38a5e | ||
|
|
34c56766b7 | ||
|
|
5479097790 | ||
|
|
20d4e527bd | ||
|
|
a824c3f02f | ||
|
|
bc3b406bff |
3
.dockerignore
Normal file
3
.dockerignore
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.git
|
||||||
|
build/_workspace
|
||||||
|
build/_bin
|
||||||
4
.github/CONTRIBUTING.md
vendored
4
.github/CONTRIBUTING.md
vendored
@@ -9,9 +9,7 @@ and help.
|
|||||||
|
|
||||||
If you'd like to contribute to go-ethereum please fork, fix, commit and
|
If you'd like to contribute to go-ethereum please fork, fix, commit and
|
||||||
send a pull request. Commits which do not comply with the coding standards
|
send a pull request. Commits which do not comply with the coding standards
|
||||||
are ignored (use gofmt!). If you send pull requests make absolute sure that you
|
are ignored (use gofmt!).
|
||||||
commit on the `develop` branch and that you do not merge to master.
|
|
||||||
Commits that are directly based on master are simply ignored.
|
|
||||||
|
|
||||||
See [Developers' Guide](https://github.com/ethereum/go-ethereum/wiki/Developers'-Guide)
|
See [Developers' Guide](https://github.com/ethereum/go-ethereum/wiki/Developers'-Guide)
|
||||||
for more details on configuring your environment, testing, and
|
for more details on configuring your environment, testing, and
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -13,8 +13,7 @@
|
|||||||
.ethtest
|
.ethtest
|
||||||
*/**/*tx_database*
|
*/**/*tx_database*
|
||||||
*/**/*dapps*
|
*/**/*dapps*
|
||||||
Godeps/_workspace/pkg
|
build/_vendor/pkg
|
||||||
Godeps/_workspace/bin
|
|
||||||
|
|
||||||
#*
|
#*
|
||||||
.#*
|
.#*
|
||||||
|
|||||||
27
.mailmap
27
.mailmap
@@ -17,6 +17,7 @@ Taylor Gerring <taylor.gerring@gmail.com> <taylor.gerring@ethereum.org>
|
|||||||
Bas van Kervel <bas@ethdev.com>
|
Bas van Kervel <bas@ethdev.com>
|
||||||
Bas van Kervel <bas@ethdev.com> <basvankervel@ziggo.nl>
|
Bas van Kervel <bas@ethdev.com> <basvankervel@ziggo.nl>
|
||||||
Bas van Kervel <bas@ethdev.com> <basvankervel@gmail.com>
|
Bas van Kervel <bas@ethdev.com> <basvankervel@gmail.com>
|
||||||
|
Bas van Kervel <bas@ethdev.com> <bas-vk@users.noreply.github.com>
|
||||||
|
|
||||||
Sven Ehlert <sven@ethdev.com>
|
Sven Ehlert <sven@ethdev.com>
|
||||||
|
|
||||||
@@ -63,3 +64,29 @@ Joseph Chow <ethereum@outlook.com> ethers <TODO>
|
|||||||
Enrique Fynn <enriquefynn@gmail.com>
|
Enrique Fynn <enriquefynn@gmail.com>
|
||||||
|
|
||||||
Vincent G <caktux@gmail.com>
|
Vincent G <caktux@gmail.com>
|
||||||
|
|
||||||
|
RJ Catalano <rj@erisindustries.com>
|
||||||
|
|
||||||
|
Nchinda Nchinda <nchinda2@gmail.com>
|
||||||
|
|
||||||
|
Aron Fischer <homotopycolimit@users.noreply.github.com>
|
||||||
|
|
||||||
|
Vlad Gluhovsky <gluk256@users.noreply.github.com>
|
||||||
|
|
||||||
|
Ville Sundell <github@solarius.fi>
|
||||||
|
|
||||||
|
Elliot Shepherd <elliot@identitii.com>
|
||||||
|
|
||||||
|
Yohann Léon <sybiload@gmail.com>
|
||||||
|
|
||||||
|
Gregg Dourgarian <greggd@tempworks.com>
|
||||||
|
|
||||||
|
Casey Detrio <cdetrio@gmail.com>
|
||||||
|
|
||||||
|
Jens Agerberg <github@agerberg.me>
|
||||||
|
|
||||||
|
Nick Johnson <arachnid@notdot.net>
|
||||||
|
|
||||||
|
Henning Diedrich <hd@eonblast.com>
|
||||||
|
Henning Diedrich <hd@eonblast.com> Drake Burroughs <wildfyre@hotmail.com>
|
||||||
|
|
||||||
|
|||||||
103
.travis.yml
103
.travis.yml
@@ -3,39 +3,120 @@ go_import_path: github.com/ethereum/go-ethereum
|
|||||||
sudo: false
|
sudo: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- os: linux
|
|
||||||
dist: trusty
|
|
||||||
go: 1.4.2
|
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: trusty
|
dist: trusty
|
||||||
go: 1.5.4
|
go: 1.5.4
|
||||||
|
env:
|
||||||
|
- GO15VENDOREXPERIMENT=1
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: trusty
|
dist: trusty
|
||||||
go: 1.6.2
|
go: 1.6.2
|
||||||
|
- os: linux
|
||||||
|
dist: trusty
|
||||||
|
go: 1.7.4
|
||||||
- os: osx
|
- os: osx
|
||||||
go: 1.6.2
|
go: 1.7.4
|
||||||
|
|
||||||
# This builder does the PPA upload (and nothing else).
|
# This builder does the Ubuntu PPA and Linux Azure uploads
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: trusty
|
dist: trusty
|
||||||
go: 1.6.2
|
sudo: required
|
||||||
env: PPA
|
go: 1.7.4
|
||||||
|
env:
|
||||||
|
- ubuntu-ppa
|
||||||
|
- azure-linux
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
- devscripts
|
- devscripts
|
||||||
- debhelper
|
- debhelper
|
||||||
- dput
|
- dput
|
||||||
|
- gcc-multilib
|
||||||
script:
|
script:
|
||||||
- go run build/ci.go debsrc -signer "Felix Lange (Geth CI Testing Key) <fjl@twurst.com>" -upload ppa:lp-fjl/geth-ci-testing
|
# Build for the primary platforms that Trusty can manage
|
||||||
|
- go run build/ci.go debsrc -signer "Go Ethereum Linux Builder <geth-ci@ethereum.org>" -upload ppa:ethereum/ethereum
|
||||||
|
- go run build/ci.go install
|
||||||
|
- go run build/ci.go archive -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
||||||
|
- go run build/ci.go install -arch 386
|
||||||
|
- go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
||||||
|
|
||||||
|
# Switch over GCC to cross compilation (breaks 386, hence why do it here only)
|
||||||
|
- sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-arm-linux-gnueabihf libc6-dev-armhf-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross
|
||||||
|
- sudo ln -s /usr/include/asm-generic /usr/include/asm
|
||||||
|
|
||||||
|
- GOARM=5 CC=arm-linux-gnueabi-gcc go run build/ci.go install -arch arm
|
||||||
|
- GOARM=5 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
||||||
|
- GOARM=6 CC=arm-linux-gnueabi-gcc go run build/ci.go install -arch arm
|
||||||
|
- GOARM=6 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
||||||
|
- GOARM=7 CC=arm-linux-gnueabihf-gcc go run build/ci.go install -arch arm
|
||||||
|
- GOARM=7 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
||||||
|
- CC=aarch64-linux-gnu-gcc go run build/ci.go install -arch arm64
|
||||||
|
- go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
||||||
|
|
||||||
|
# This builder does the Android Maven and Azure uploads
|
||||||
|
- os: linux
|
||||||
|
dist: precise # Needed for the android tools
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- oracle-java8-installer
|
||||||
|
- oracle-java8-set-default
|
||||||
|
language: android
|
||||||
|
android:
|
||||||
|
components:
|
||||||
|
- platform-tools
|
||||||
|
- tools
|
||||||
|
- android-15
|
||||||
|
- android-19
|
||||||
|
- android-24
|
||||||
|
env:
|
||||||
|
- azure-android
|
||||||
|
- maven-android
|
||||||
|
before_install:
|
||||||
|
- curl https://storage.googleapis.com/golang/go1.8rc3.linux-amd64.tar.gz | tar -xz
|
||||||
|
- export PATH=`pwd`/go/bin:$PATH
|
||||||
|
- export GOROOT=`pwd`/go
|
||||||
|
- export GOPATH=$HOME/go # Drop post Go 1.8
|
||||||
|
script:
|
||||||
|
# Build the Android archive and upload it to Maven Central and Azure
|
||||||
|
- curl https://dl.google.com/android/repository/android-ndk-r13b-linux-x86_64.zip -o android-ndk-r13b.zip
|
||||||
|
- unzip -q android-ndk-r13b.zip && rm android-ndk-r13b.zip
|
||||||
|
- mv android-ndk-r13b $HOME
|
||||||
|
- export ANDROID_NDK=$HOME/android-ndk-r13b
|
||||||
|
|
||||||
|
- mkdir -p $GOPATH/src/github.com/ethereum
|
||||||
|
- ln -s `pwd` $GOPATH/src/github.com/ethereum
|
||||||
|
- go run build/ci.go aar -signer ANDROID_SIGNING_KEY -deploy https://oss.sonatype.org -upload gethstore/builds
|
||||||
|
|
||||||
|
# This builder does the OSX Azure, iOS CocoaPods and iOS Azure uploads
|
||||||
|
- os: osx
|
||||||
|
go: 1.7.4
|
||||||
|
env:
|
||||||
|
- azure-osx
|
||||||
|
- azure-ios
|
||||||
|
- cocoapods-ios
|
||||||
|
script:
|
||||||
|
- go run build/ci.go install
|
||||||
|
- go run build/ci.go archive -type tar -signer OSX_SIGNING_KEY -upload gethstore/builds
|
||||||
|
|
||||||
|
# Build the iOS framework and upload it to CocoaPods and Azure
|
||||||
|
- gem uninstall cocoapods -a
|
||||||
|
- gem install cocoapods --pre
|
||||||
|
|
||||||
|
- mv ~/.cocoapods/repos/master ~/.cocoapods/repos/master.bak
|
||||||
|
- sed -i '.bak' 's/repo.join/!repo.join/g' $(dirname `gem which cocoapods`)/cocoapods/sources_manager.rb
|
||||||
|
- if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then git clone --depth=1 https://github.com/CocoaPods/Specs.git ~/.cocoapods/repos/master && pod setup --verbose; fi
|
||||||
|
|
||||||
|
- xctool -version
|
||||||
|
- xcrun simctl list
|
||||||
|
|
||||||
|
- go run build/ci.go xcode -signer IOS_SIGNING_KEY -deploy trunk -upload gethstore/builds
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- go get golang.org/x/tools/cmd/cover
|
- go get golang.org/x/tools/cmd/cover
|
||||||
script:
|
script:
|
||||||
- go run build/ci.go install
|
- go run build/ci.go install
|
||||||
- go run build/ci.go test -coverage -vet
|
- go run build/ci.go test -coverage -vet -misspell
|
||||||
after_success:
|
|
||||||
# - go run build/ci.go archive -type tar
|
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
webhooks:
|
webhooks:
|
||||||
|
|||||||
29
AUTHORS
29
AUTHORS
@@ -1,36 +1,63 @@
|
|||||||
# This is the official list of go-ethereum authors for copyright purposes.
|
# This is the official list of go-ethereum authors for copyright purposes.
|
||||||
|
|
||||||
|
Ales Katona <ales@coinbase.com>
|
||||||
Alex Leverington <alex@ethdev.com>
|
Alex Leverington <alex@ethdev.com>
|
||||||
Alexandre Van de Sande <alex.vandesande@ethdev.com>
|
Alexandre Van de Sande <alex.vandesande@ethdev.com>
|
||||||
|
Aron Fischer <homotopycolimit@users.noreply.github.com>
|
||||||
Bas van Kervel <bas@ethdev.com>
|
Bas van Kervel <bas@ethdev.com>
|
||||||
|
Benjamin Brent <benjamin@benjaminbrent.com>
|
||||||
|
Casey Detrio <cdetrio@gmail.com>
|
||||||
Christoph Jentzsch <jentzsch.software@gmail.com>
|
Christoph Jentzsch <jentzsch.software@gmail.com>
|
||||||
Daniel A. Nagy <nagy.da@gmail.com>
|
Daniel A. Nagy <nagy.da@gmail.com>
|
||||||
Drake Burroughs <wildfyre@hotmail.com>
|
Elliot Shepherd <elliot@identitii.com>
|
||||||
Enrique Fynn <enriquefynn@gmail.com>
|
Enrique Fynn <enriquefynn@gmail.com>
|
||||||
Ethan Buchman <ethan@coinculture.info>
|
Ethan Buchman <ethan@coinculture.info>
|
||||||
Fabian Vogelsteller <fabian@frozeman.de>
|
Fabian Vogelsteller <fabian@frozeman.de>
|
||||||
|
Fabio Berger <fabioberger1991@gmail.com>
|
||||||
Felix Lange <fjl@twurst.com>
|
Felix Lange <fjl@twurst.com>
|
||||||
|
Gregg Dourgarian <greggd@tempworks.com>
|
||||||
Gustav Simonsson <gustav.simonsson@gmail.com>
|
Gustav Simonsson <gustav.simonsson@gmail.com>
|
||||||
|
Hao Bryan Cheng <haobcheng@gmail.com>
|
||||||
|
Henning Diedrich <hd@eonblast.com>
|
||||||
Isidoro Ghezzi <isidoro.ghezzi@icloud.com>
|
Isidoro Ghezzi <isidoro.ghezzi@icloud.com>
|
||||||
Jae Kwon <jkwon.work@gmail.com>
|
Jae Kwon <jkwon.work@gmail.com>
|
||||||
Jason Carver <jacarver@linkedin.com>
|
Jason Carver <jacarver@linkedin.com>
|
||||||
Jeff R. Allen <jra@nella.org>
|
Jeff R. Allen <jra@nella.org>
|
||||||
Jeffrey Wilcke <jeffrey@ethereum.org>
|
Jeffrey Wilcke <jeffrey@ethereum.org>
|
||||||
|
Jens Agerberg <github@agerberg.me>
|
||||||
|
Jonathan Brown <jbrown@bluedroplet.com>
|
||||||
Joseph Chow <ethereum@outlook.com>
|
Joseph Chow <ethereum@outlook.com>
|
||||||
|
Justin Clark-Casey <justincc@justincc.org>
|
||||||
|
Kenji Siu <kenji@isuntv.com>
|
||||||
Kobi Gurkan <kobigurk@gmail.com>
|
Kobi Gurkan <kobigurk@gmail.com>
|
||||||
Lefteris Karapetsas <lefteris@refu.co>
|
Lefteris Karapetsas <lefteris@refu.co>
|
||||||
Leif Jurvetson <leijurv@gmail.com>
|
Leif Jurvetson <leijurv@gmail.com>
|
||||||
Maran Hidskes <maran.hidskes@gmail.com>
|
Maran Hidskes <maran.hidskes@gmail.com>
|
||||||
Marek Kotewicz <marek.kotewicz@gmail.com>
|
Marek Kotewicz <marek.kotewicz@gmail.com>
|
||||||
|
Martin Holst Swende <martin@swende.se>
|
||||||
|
Matthew Di Ferrante <mattdf@users.noreply.github.com>
|
||||||
Matthew Wampler-Doty <matthew.wampler.doty@gmail.com>
|
Matthew Wampler-Doty <matthew.wampler.doty@gmail.com>
|
||||||
|
Nchinda Nchinda <nchinda2@gmail.com>
|
||||||
Nick Dodson <silentcicero@outlook.com>
|
Nick Dodson <silentcicero@outlook.com>
|
||||||
|
Nick Johnson <arachnid@notdot.net>
|
||||||
|
Paulo L F Casaretto <pcasaretto@gmail.com>
|
||||||
Peter Pratscher <pratscher@gmail.com>
|
Peter Pratscher <pratscher@gmail.com>
|
||||||
Péter Szilágyi <peterke@gmail.com>
|
Péter Szilágyi <peterke@gmail.com>
|
||||||
|
RJ Catalano <rj@erisindustries.com>
|
||||||
Ramesh Nair <ram@hiddentao.com>
|
Ramesh Nair <ram@hiddentao.com>
|
||||||
Ricardo Catalinas Jiménez <r@untroubled.be>
|
Ricardo Catalinas Jiménez <r@untroubled.be>
|
||||||
Rémy Roy <remyroy@remyroy.com>
|
Rémy Roy <remyroy@remyroy.com>
|
||||||
|
Stein Dekker <dekker.stein@gmail.com>
|
||||||
|
Steven Roose <stevenroose@gmail.com>
|
||||||
Taylor Gerring <taylor.gerring@gmail.com>
|
Taylor Gerring <taylor.gerring@gmail.com>
|
||||||
|
Thomas Bocek <tom@tomp2p.net>
|
||||||
|
Tosh Camille <tochecamille@gmail.com>
|
||||||
Viktor Trón <viktor.tron@gmail.com>
|
Viktor Trón <viktor.tron@gmail.com>
|
||||||
|
Ville Sundell <github@solarius.fi>
|
||||||
Vincent G <caktux@gmail.com>
|
Vincent G <caktux@gmail.com>
|
||||||
Vitalik Buterin <v@buterin.com>
|
Vitalik Buterin <v@buterin.com>
|
||||||
|
Vlad Gluhovsky <gluk256@users.noreply.github.com>
|
||||||
|
Yohann Léon <sybiload@gmail.com>
|
||||||
|
Yoichi Hirai <i@yoichihirai.com>
|
||||||
Zsolt Felföldi <zsfelfoldi@gmail.com>
|
Zsolt Felföldi <zsfelfoldi@gmail.com>
|
||||||
|
ΞTHΞЯSPHΞЯΞ <{viktor.tron,nagydani,zsfelfoldi}@gmail.com>
|
||||||
|
|||||||
14
Dockerfile
Normal file
14
Dockerfile
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
FROM alpine:3.5
|
||||||
|
|
||||||
|
ADD . /go-ethereum
|
||||||
|
RUN \
|
||||||
|
apk add --update git go make gcc musl-dev linux-headers && \
|
||||||
|
(cd go-ethereum && make geth) && \
|
||||||
|
cp go-ethereum/build/bin/geth /geth && \
|
||||||
|
apk del git go make gcc musl-dev linux-headers && \
|
||||||
|
rm -rf /go-ethereum && rm -rf /var/cache/apk/*
|
||||||
|
|
||||||
|
EXPOSE 8545
|
||||||
|
EXPOSE 30303
|
||||||
|
|
||||||
|
ENTRYPOINT ["/geth"]
|
||||||
329
Godeps/Godeps.json
generated
329
Godeps/Godeps.json
generated
@@ -1,329 +0,0 @@
|
|||||||
{
|
|
||||||
"ImportPath": "github.com/ethereum/go-ethereum",
|
|
||||||
"GoVersion": "go1.5.2",
|
|
||||||
"GodepVersion": "v74",
|
|
||||||
"Packages": [
|
|
||||||
"./..."
|
|
||||||
],
|
|
||||||
"Deps": [
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/Gustav-Simonsson/go-opencl/cl",
|
|
||||||
"Rev": "593e01cfc4f3353585015321e01951d4a907d3ef"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/cespare/cp",
|
|
||||||
"Rev": "165db2f241fd235aec29ba6d9b1ccd5f1c14637c"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/davecgh/go-spew/spew",
|
|
||||||
"Rev": "5215b55f46b2b919f50a1df0eaa5886afe4e3b3d"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/ethereum/ethash",
|
|
||||||
"Comment": "v23.1-247-g2e80de5",
|
|
||||||
"Rev": "2e80de5022370cfe632195b1720db52d07ff8a77"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/fatih/color",
|
|
||||||
"Comment": "v0.1-12-g9aae6aa",
|
|
||||||
"Rev": "9aae6aaa22315390f03959adca2c4d395b02fcef"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/gizak/termui",
|
|
||||||
"Rev": "08a5d3f67b7d9ec87830ea39c48e570a1f18531f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/golang/snappy",
|
|
||||||
"Rev": "799c780093d646c1b79d30894e22512c319fa137"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/golang-lru",
|
|
||||||
"Rev": "a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/golang-lru/simplelru",
|
|
||||||
"Rev": "a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/huin/goupnp",
|
|
||||||
"Rev": "46bde78b11f3f021f2a511df138be9e2fc7506e8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/huin/goupnp/dcps/internetgateway1",
|
|
||||||
"Rev": "46bde78b11f3f021f2a511df138be9e2fc7506e8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/huin/goupnp/dcps/internetgateway2",
|
|
||||||
"Rev": "46bde78b11f3f021f2a511df138be9e2fc7506e8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/huin/goupnp/httpu",
|
|
||||||
"Rev": "46bde78b11f3f021f2a511df138be9e2fc7506e8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/huin/goupnp/scpd",
|
|
||||||
"Rev": "46bde78b11f3f021f2a511df138be9e2fc7506e8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/huin/goupnp/soap",
|
|
||||||
"Rev": "46bde78b11f3f021f2a511df138be9e2fc7506e8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/huin/goupnp/ssdp",
|
|
||||||
"Rev": "46bde78b11f3f021f2a511df138be9e2fc7506e8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/jackpal/gateway",
|
|
||||||
"Rev": "192609c58b8985e645cbe82ddcb28a4362ca0fdc"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/jackpal/go-nat-pmp",
|
|
||||||
"Rev": "46523a463303c6ede3ddfe45bde1c7ed52ebaacd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/mattn/go-colorable",
|
|
||||||
"Rev": "9fdad7c47650b7d2e1da50644c1f4ba7f172f252"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/mattn/go-isatty",
|
|
||||||
"Rev": "56b76bdf51f7708750eac80fa38b952bb9f32639"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/mattn/go-runewidth",
|
|
||||||
"Comment": "travisish-44-ge882a96",
|
|
||||||
"Rev": "e882a96ec18dd43fa283187b66af74497c9101c0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/microsoft/go-winio",
|
|
||||||
"Comment": "v0.2.0",
|
|
||||||
"Rev": "9e2895e5f6c3f16473b91d37fae6e89990a4520c"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/nsf/termbox-go",
|
|
||||||
"Rev": "362329b0aa6447eadd52edd8d660ec1dff470295"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/pborman/uuid",
|
|
||||||
"Comment": "v1.0-6-g0f1a469",
|
|
||||||
"Rev": "0f1a46960a86dcdf5dd30d3e6568a497a997909f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/peterh/liner",
|
|
||||||
"Rev": "ad1edfd30321d8f006ccf05f1e0524adeb943060"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/rcrowley/go-metrics",
|
|
||||||
"Rev": "51425a2415d21afadfd55cd93432c0bc69e9598d"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/rjeczalik/notify",
|
|
||||||
"Rev": "f627deca7a510d96f0ef9388f2d0e8b16d21f87f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/robertkrimen/otto",
|
|
||||||
"Rev": "53221230c215611a90762720c9042ac782ef74ee"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/robertkrimen/otto/ast",
|
|
||||||
"Rev": "53221230c215611a90762720c9042ac782ef74ee"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/robertkrimen/otto/dbg",
|
|
||||||
"Rev": "53221230c215611a90762720c9042ac782ef74ee"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/robertkrimen/otto/file",
|
|
||||||
"Rev": "53221230c215611a90762720c9042ac782ef74ee"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/robertkrimen/otto/parser",
|
|
||||||
"Rev": "53221230c215611a90762720c9042ac782ef74ee"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/robertkrimen/otto/registry",
|
|
||||||
"Rev": "53221230c215611a90762720c9042ac782ef74ee"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/robertkrimen/otto/token",
|
|
||||||
"Rev": "53221230c215611a90762720c9042ac782ef74ee"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/rs/cors",
|
|
||||||
"Rev": "5950cf11d77f8a61b432a25dd4d444b4ced01379"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/rs/xhandler",
|
|
||||||
"Rev": "d9d9599b6aaf6a058cb7b1f48291ded2cbd13390"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/cache",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/comparer",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/errors",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/filter",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/iterator",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/journal",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/memdb",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/opt",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/storage",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/table",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/util",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/crypto/pbkdf2",
|
|
||||||
"Rev": "1f22c0103821b9390939b6776727195525381532"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/crypto/ripemd160",
|
|
||||||
"Rev": "1f22c0103821b9390939b6776727195525381532"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/crypto/scrypt",
|
|
||||||
"Rev": "1f22c0103821b9390939b6776727195525381532"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/net/context",
|
|
||||||
"Rev": "8968c61983e8f51a91b8c0ef25bf739278c89634"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/net/html",
|
|
||||||
"Rev": "8968c61983e8f51a91b8c0ef25bf739278c89634"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/net/html/atom",
|
|
||||||
"Rev": "8968c61983e8f51a91b8c0ef25bf739278c89634"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/net/html/charset",
|
|
||||||
"Rev": "8968c61983e8f51a91b8c0ef25bf739278c89634"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/net/websocket",
|
|
||||||
"Rev": "8968c61983e8f51a91b8c0ef25bf739278c89634"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/sys/unix",
|
|
||||||
"Rev": "50c6bc5e4292a1d4e65c6e9be5f53be28bcbe28e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/encoding",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/encoding/charmap",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/encoding/htmlindex",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/encoding/internal",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/encoding/internal/identifier",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/encoding/japanese",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/encoding/korean",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/encoding/simplifiedchinese",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/encoding/traditionalchinese",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/encoding/unicode",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/internal/tag",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/internal/utf8internal",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/language",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/runes",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/transform",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/tools/go/ast/astutil",
|
|
||||||
"Rev": "758728c4b28cfbac299730969ef8f655c4761283"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/tools/imports",
|
|
||||||
"Rev": "758728c4b28cfbac299730969ef8f655c4761283"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "gopkg.in/check.v1",
|
|
||||||
"Rev": "4f90aeace3a26ad7021961c297b22c42160c7b25"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "gopkg.in/fatih/set.v0",
|
|
||||||
"Comment": "v0.1.0-3-g27c4092",
|
|
||||||
"Rev": "27c40922c40b43fe04554d8223a402af3ea333f3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "gopkg.in/karalabe/cookiejar.v2/collections/prque",
|
|
||||||
"Rev": "8dcd6a7f4951f6ff3ee9cbb919a06d8925822e57"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "gopkg.in/urfave/cli.v1",
|
|
||||||
"Comment": "v1.17.0",
|
|
||||||
"Rev": "01857ac33766ce0c93856370626f9799281c14f4"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
5
Godeps/Readme
generated
5
Godeps/Readme
generated
@@ -1,5 +0,0 @@
|
|||||||
This directory tree is generated automatically by godep.
|
|
||||||
|
|
||||||
Please do not edit.
|
|
||||||
|
|
||||||
See https://github.com/tools/godep for more information.
|
|
||||||
2
Godeps/_workspace/.gitignore
generated
vendored
2
Godeps/_workspace/.gitignore
generated
vendored
@@ -1,2 +0,0 @@
|
|||||||
/pkg
|
|
||||||
/bin
|
|
||||||
26
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/cl.go
generated
vendored
26
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/cl.go
generated
vendored
@@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
Package cl provides a binding to the OpenCL api. It's mostly a low-level
|
|
||||||
wrapper that avoids adding functionality while still making the interface
|
|
||||||
a little more friendly and easy to use.
|
|
||||||
|
|
||||||
Resource life-cycle management:
|
|
||||||
|
|
||||||
For any CL object that gets created (buffer, queue, kernel, etc..) you should
|
|
||||||
call object.Release() when finished with it to free the CL resources. This
|
|
||||||
explicitely calls the related clXXXRelease method for the type. However,
|
|
||||||
as a fallback there is a finalizer set for every resource item that takes
|
|
||||||
care of it (eventually) if Release isn't called. In this way you can have
|
|
||||||
better control over the life cycle of resources while having a fall back
|
|
||||||
to avoid leaks. This is similar to how file handles and such are handled
|
|
||||||
in the Go standard packages.
|
|
||||||
*/
|
|
||||||
package cl
|
|
||||||
|
|
||||||
// #include "headers/1.2/opencl.h"
|
|
||||||
// #cgo CFLAGS: -Iheaders/1.2
|
|
||||||
// #cgo darwin LDFLAGS: -framework OpenCL
|
|
||||||
// #cgo linux LDFLAGS: -lOpenCL
|
|
||||||
import "C"
|
|
||||||
import "errors"
|
|
||||||
|
|
||||||
var ErrUnsupported = errors.New("cl: unsupported")
|
|
||||||
161
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/context.go
generated
vendored
161
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/context.go
generated
vendored
@@ -1,161 +0,0 @@
|
|||||||
package cl
|
|
||||||
|
|
||||||
// #include <stdlib.h>
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"runtime"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const maxImageFormats = 256
|
|
||||||
|
|
||||||
type Context struct {
|
|
||||||
clContext C.cl_context
|
|
||||||
devices []*Device
|
|
||||||
}
|
|
||||||
|
|
||||||
type MemObject struct {
|
|
||||||
clMem C.cl_mem
|
|
||||||
size int
|
|
||||||
}
|
|
||||||
|
|
||||||
func releaseContext(c *Context) {
|
|
||||||
if c.clContext != nil {
|
|
||||||
C.clReleaseContext(c.clContext)
|
|
||||||
c.clContext = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func releaseMemObject(b *MemObject) {
|
|
||||||
if b.clMem != nil {
|
|
||||||
C.clReleaseMemObject(b.clMem)
|
|
||||||
b.clMem = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newMemObject(mo C.cl_mem, size int) *MemObject {
|
|
||||||
memObject := &MemObject{clMem: mo, size: size}
|
|
||||||
runtime.SetFinalizer(memObject, releaseMemObject)
|
|
||||||
return memObject
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *MemObject) Release() {
|
|
||||||
releaseMemObject(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: properties
|
|
||||||
func CreateContext(devices []*Device) (*Context, error) {
|
|
||||||
deviceIds := buildDeviceIdList(devices)
|
|
||||||
var err C.cl_int
|
|
||||||
clContext := C.clCreateContext(nil, C.cl_uint(len(devices)), &deviceIds[0], nil, nil, &err)
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
if clContext == nil {
|
|
||||||
return nil, ErrUnknown
|
|
||||||
}
|
|
||||||
context := &Context{clContext: clContext, devices: devices}
|
|
||||||
runtime.SetFinalizer(context, releaseContext)
|
|
||||||
return context, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) GetSupportedImageFormats(flags MemFlag, imageType MemObjectType) ([]ImageFormat, error) {
|
|
||||||
var formats [maxImageFormats]C.cl_image_format
|
|
||||||
var nFormats C.cl_uint
|
|
||||||
if err := C.clGetSupportedImageFormats(ctx.clContext, C.cl_mem_flags(flags), C.cl_mem_object_type(imageType), maxImageFormats, &formats[0], &nFormats); err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
fmts := make([]ImageFormat, nFormats)
|
|
||||||
for i, f := range formats[:nFormats] {
|
|
||||||
fmts[i] = ImageFormat{
|
|
||||||
ChannelOrder: ChannelOrder(f.image_channel_order),
|
|
||||||
ChannelDataType: ChannelDataType(f.image_channel_data_type),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fmts, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) CreateCommandQueue(device *Device, properties CommandQueueProperty) (*CommandQueue, error) {
|
|
||||||
var err C.cl_int
|
|
||||||
clQueue := C.clCreateCommandQueue(ctx.clContext, device.id, C.cl_command_queue_properties(properties), &err)
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
if clQueue == nil {
|
|
||||||
return nil, ErrUnknown
|
|
||||||
}
|
|
||||||
commandQueue := &CommandQueue{clQueue: clQueue, device: device}
|
|
||||||
runtime.SetFinalizer(commandQueue, releaseCommandQueue)
|
|
||||||
return commandQueue, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) CreateProgramWithSource(sources []string) (*Program, error) {
|
|
||||||
cSources := make([]*C.char, len(sources))
|
|
||||||
for i, s := range sources {
|
|
||||||
cs := C.CString(s)
|
|
||||||
cSources[i] = cs
|
|
||||||
defer C.free(unsafe.Pointer(cs))
|
|
||||||
}
|
|
||||||
var err C.cl_int
|
|
||||||
clProgram := C.clCreateProgramWithSource(ctx.clContext, C.cl_uint(len(sources)), &cSources[0], nil, &err)
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
if clProgram == nil {
|
|
||||||
return nil, ErrUnknown
|
|
||||||
}
|
|
||||||
program := &Program{clProgram: clProgram, devices: ctx.devices}
|
|
||||||
runtime.SetFinalizer(program, releaseProgram)
|
|
||||||
return program, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) CreateBufferUnsafe(flags MemFlag, size int, dataPtr unsafe.Pointer) (*MemObject, error) {
|
|
||||||
var err C.cl_int
|
|
||||||
clBuffer := C.clCreateBuffer(ctx.clContext, C.cl_mem_flags(flags), C.size_t(size), dataPtr, &err)
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
if clBuffer == nil {
|
|
||||||
return nil, ErrUnknown
|
|
||||||
}
|
|
||||||
return newMemObject(clBuffer, size), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) CreateEmptyBuffer(flags MemFlag, size int) (*MemObject, error) {
|
|
||||||
return ctx.CreateBufferUnsafe(flags, size, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) CreateEmptyBufferFloat32(flags MemFlag, size int) (*MemObject, error) {
|
|
||||||
return ctx.CreateBufferUnsafe(flags, 4*size, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) CreateBuffer(flags MemFlag, data []byte) (*MemObject, error) {
|
|
||||||
return ctx.CreateBufferUnsafe(flags, len(data), unsafe.Pointer(&data[0]))
|
|
||||||
}
|
|
||||||
|
|
||||||
//float64
|
|
||||||
func (ctx *Context) CreateBufferFloat32(flags MemFlag, data []float32) (*MemObject, error) {
|
|
||||||
return ctx.CreateBufferUnsafe(flags, 4*len(data), unsafe.Pointer(&data[0]))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) CreateUserEvent() (*Event, error) {
|
|
||||||
var err C.cl_int
|
|
||||||
clEvent := C.clCreateUserEvent(ctx.clContext, &err)
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
return newEvent(clEvent), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) Release() {
|
|
||||||
releaseContext(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
// http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateSubBuffer.html
|
|
||||||
// func (memObject *MemObject) CreateSubBuffer(flags MemFlag, bufferCreateType BufferCreateType, )
|
|
||||||
510
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/device.go
generated
vendored
510
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/device.go
generated
vendored
@@ -1,510 +0,0 @@
|
|||||||
package cl
|
|
||||||
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #include "cl_ext.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const maxDeviceCount = 64
|
|
||||||
|
|
||||||
type DeviceType uint
|
|
||||||
|
|
||||||
const (
|
|
||||||
DeviceTypeCPU DeviceType = C.CL_DEVICE_TYPE_CPU
|
|
||||||
DeviceTypeGPU DeviceType = C.CL_DEVICE_TYPE_GPU
|
|
||||||
DeviceTypeAccelerator DeviceType = C.CL_DEVICE_TYPE_ACCELERATOR
|
|
||||||
DeviceTypeDefault DeviceType = C.CL_DEVICE_TYPE_DEFAULT
|
|
||||||
DeviceTypeAll DeviceType = C.CL_DEVICE_TYPE_ALL
|
|
||||||
)
|
|
||||||
|
|
||||||
type FPConfig int
|
|
||||||
|
|
||||||
const (
|
|
||||||
FPConfigDenorm FPConfig = C.CL_FP_DENORM // denorms are supported
|
|
||||||
FPConfigInfNaN FPConfig = C.CL_FP_INF_NAN // INF and NaNs are supported
|
|
||||||
FPConfigRoundToNearest FPConfig = C.CL_FP_ROUND_TO_NEAREST // round to nearest even rounding mode supported
|
|
||||||
FPConfigRoundToZero FPConfig = C.CL_FP_ROUND_TO_ZERO // round to zero rounding mode supported
|
|
||||||
FPConfigRoundToInf FPConfig = C.CL_FP_ROUND_TO_INF // round to positive and negative infinity rounding modes supported
|
|
||||||
FPConfigFMA FPConfig = C.CL_FP_FMA // IEEE754-2008 fused multiply-add is supported
|
|
||||||
FPConfigSoftFloat FPConfig = C.CL_FP_SOFT_FLOAT // Basic floating-point operations (such as addition, subtraction, multiplication) are implemented in software
|
|
||||||
)
|
|
||||||
|
|
||||||
var fpConfigNameMap = map[FPConfig]string{
|
|
||||||
FPConfigDenorm: "Denorm",
|
|
||||||
FPConfigInfNaN: "InfNaN",
|
|
||||||
FPConfigRoundToNearest: "RoundToNearest",
|
|
||||||
FPConfigRoundToZero: "RoundToZero",
|
|
||||||
FPConfigRoundToInf: "RoundToInf",
|
|
||||||
FPConfigFMA: "FMA",
|
|
||||||
FPConfigSoftFloat: "SoftFloat",
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c FPConfig) String() string {
|
|
||||||
var parts []string
|
|
||||||
for bit, name := range fpConfigNameMap {
|
|
||||||
if c&bit != 0 {
|
|
||||||
parts = append(parts, name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if parts == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return strings.Join(parts, "|")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dt DeviceType) String() string {
|
|
||||||
var parts []string
|
|
||||||
if dt&DeviceTypeCPU != 0 {
|
|
||||||
parts = append(parts, "CPU")
|
|
||||||
}
|
|
||||||
if dt&DeviceTypeGPU != 0 {
|
|
||||||
parts = append(parts, "GPU")
|
|
||||||
}
|
|
||||||
if dt&DeviceTypeAccelerator != 0 {
|
|
||||||
parts = append(parts, "Accelerator")
|
|
||||||
}
|
|
||||||
if dt&DeviceTypeDefault != 0 {
|
|
||||||
parts = append(parts, "Default")
|
|
||||||
}
|
|
||||||
if parts == nil {
|
|
||||||
parts = append(parts, "None")
|
|
||||||
}
|
|
||||||
return strings.Join(parts, "|")
|
|
||||||
}
|
|
||||||
|
|
||||||
type Device struct {
|
|
||||||
id C.cl_device_id
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildDeviceIdList(devices []*Device) []C.cl_device_id {
|
|
||||||
deviceIds := make([]C.cl_device_id, len(devices))
|
|
||||||
for i, d := range devices {
|
|
||||||
deviceIds[i] = d.id
|
|
||||||
}
|
|
||||||
return deviceIds
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtain the list of devices available on a platform. 'platform' refers
|
|
||||||
// to the platform returned by GetPlatforms or can be nil. If platform
|
|
||||||
// is nil, the behavior is implementation-defined.
|
|
||||||
func GetDevices(platform *Platform, deviceType DeviceType) ([]*Device, error) {
|
|
||||||
var deviceIds [maxDeviceCount]C.cl_device_id
|
|
||||||
var numDevices C.cl_uint
|
|
||||||
var platformId C.cl_platform_id
|
|
||||||
if platform != nil {
|
|
||||||
platformId = platform.id
|
|
||||||
}
|
|
||||||
if err := C.clGetDeviceIDs(platformId, C.cl_device_type(deviceType), C.cl_uint(maxDeviceCount), &deviceIds[0], &numDevices); err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
if numDevices > maxDeviceCount {
|
|
||||||
numDevices = maxDeviceCount
|
|
||||||
}
|
|
||||||
devices := make([]*Device, numDevices)
|
|
||||||
for i := 0; i < int(numDevices); i++ {
|
|
||||||
devices[i] = &Device{id: deviceIds[i]}
|
|
||||||
}
|
|
||||||
return devices, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) nullableId() C.cl_device_id {
|
|
||||||
if d == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return d.id
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) GetInfoString(param C.cl_device_info, panicOnError bool) (string, error) {
|
|
||||||
var strC [1024]C.char
|
|
||||||
var strN C.size_t
|
|
||||||
if err := C.clGetDeviceInfo(d.id, param, 1024, unsafe.Pointer(&strC), &strN); err != C.CL_SUCCESS {
|
|
||||||
if panicOnError {
|
|
||||||
panic("Should never fail")
|
|
||||||
}
|
|
||||||
return "", toError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenCL strings are NUL-terminated, and the terminator is included in strN
|
|
||||||
// Go strings aren't NUL-terminated, so subtract 1 from the length
|
|
||||||
return C.GoStringN((*C.char)(unsafe.Pointer(&strC)), C.int(strN-1)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) getInfoUint(param C.cl_device_info, panicOnError bool) (uint, error) {
|
|
||||||
var val C.cl_uint
|
|
||||||
if err := C.clGetDeviceInfo(d.id, param, C.size_t(unsafe.Sizeof(val)), unsafe.Pointer(&val), nil); err != C.CL_SUCCESS {
|
|
||||||
if panicOnError {
|
|
||||||
panic("Should never fail")
|
|
||||||
}
|
|
||||||
return 0, toError(err)
|
|
||||||
}
|
|
||||||
return uint(val), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) getInfoSize(param C.cl_device_info, panicOnError bool) (int, error) {
|
|
||||||
var val C.size_t
|
|
||||||
if err := C.clGetDeviceInfo(d.id, param, C.size_t(unsafe.Sizeof(val)), unsafe.Pointer(&val), nil); err != C.CL_SUCCESS {
|
|
||||||
if panicOnError {
|
|
||||||
panic("Should never fail")
|
|
||||||
}
|
|
||||||
return 0, toError(err)
|
|
||||||
}
|
|
||||||
return int(val), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) getInfoUlong(param C.cl_device_info, panicOnError bool) (int64, error) {
|
|
||||||
var val C.cl_ulong
|
|
||||||
if err := C.clGetDeviceInfo(d.id, param, C.size_t(unsafe.Sizeof(val)), unsafe.Pointer(&val), nil); err != C.CL_SUCCESS {
|
|
||||||
if panicOnError {
|
|
||||||
panic("Should never fail")
|
|
||||||
}
|
|
||||||
return 0, toError(err)
|
|
||||||
}
|
|
||||||
return int64(val), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) getInfoBool(param C.cl_device_info, panicOnError bool) (bool, error) {
|
|
||||||
var val C.cl_bool
|
|
||||||
if err := C.clGetDeviceInfo(d.id, param, C.size_t(unsafe.Sizeof(val)), unsafe.Pointer(&val), nil); err != C.CL_SUCCESS {
|
|
||||||
if panicOnError {
|
|
||||||
panic("Should never fail")
|
|
||||||
}
|
|
||||||
return false, toError(err)
|
|
||||||
}
|
|
||||||
return val == C.CL_TRUE, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) Name() string {
|
|
||||||
str, _ := d.GetInfoString(C.CL_DEVICE_NAME, true)
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) Vendor() string {
|
|
||||||
str, _ := d.GetInfoString(C.CL_DEVICE_VENDOR, true)
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) Extensions() string {
|
|
||||||
str, _ := d.GetInfoString(C.CL_DEVICE_EXTENSIONS, true)
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) OpenCLCVersion() string {
|
|
||||||
str, _ := d.GetInfoString(C.CL_DEVICE_OPENCL_C_VERSION, true)
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) Profile() string {
|
|
||||||
str, _ := d.GetInfoString(C.CL_DEVICE_PROFILE, true)
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) Version() string {
|
|
||||||
str, _ := d.GetInfoString(C.CL_DEVICE_VERSION, true)
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) DriverVersion() string {
|
|
||||||
str, _ := d.GetInfoString(C.CL_DRIVER_VERSION, true)
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
// The default compute device address space size specified as an
|
|
||||||
// unsigned integer value in bits. Currently supported values are 32 or 64 bits.
|
|
||||||
func (d *Device) AddressBits() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_ADDRESS_BITS, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Size of global memory cache line in bytes.
|
|
||||||
func (d *Device) GlobalMemCachelineSize() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maximum configured clock frequency of the device in MHz.
|
|
||||||
func (d *Device) MaxClockFrequency() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_MAX_CLOCK_FREQUENCY, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The number of parallel compute units on the OpenCL device.
|
|
||||||
// A work-group executes on a single compute unit. The minimum value is 1.
|
|
||||||
func (d *Device) MaxComputeUnits() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_MAX_COMPUTE_UNITS, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max number of arguments declared with the __constant qualifier in a kernel.
|
|
||||||
// The minimum value is 8 for devices that are not of type CL_DEVICE_TYPE_CUSTOM.
|
|
||||||
func (d *Device) MaxConstantArgs() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_MAX_CONSTANT_ARGS, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max number of simultaneous image objects that can be read by a kernel.
|
|
||||||
// The minimum value is 128 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE.
|
|
||||||
func (d *Device) MaxReadImageArgs() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_MAX_READ_IMAGE_ARGS, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maximum number of samplers that can be used in a kernel. The minimum
|
|
||||||
// value is 16 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE. (Also see sampler_t.)
|
|
||||||
func (d *Device) MaxSamplers() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_MAX_SAMPLERS, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maximum dimensions that specify the global and local work-item IDs used
|
|
||||||
// by the data parallel execution model. (Refer to clEnqueueNDRangeKernel).
|
|
||||||
// The minimum value is 3 for devices that are not of type CL_DEVICE_TYPE_CUSTOM.
|
|
||||||
func (d *Device) MaxWorkItemDimensions() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max number of simultaneous image objects that can be written to by a
|
|
||||||
// kernel. The minimum value is 8 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE.
|
|
||||||
func (d *Device) MaxWriteImageArgs() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_MAX_WRITE_IMAGE_ARGS, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The minimum value is the size (in bits) of the largest OpenCL built-in
|
|
||||||
// data type supported by the device (long16 in FULL profile, long16 or
|
|
||||||
// int16 in EMBEDDED profile) for devices that are not of type CL_DEVICE_TYPE_CUSTOM.
|
|
||||||
func (d *Device) MemBaseAddrAlign() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_MEM_BASE_ADDR_ALIGN, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) NativeVectorWidthChar() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) NativeVectorWidthShort() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) NativeVectorWidthInt() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_NATIVE_VECTOR_WIDTH_INT, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) NativeVectorWidthLong() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) NativeVectorWidthFloat() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) NativeVectorWidthDouble() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) NativeVectorWidthHalf() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max height of 2D image in pixels. The minimum value is 8192
|
|
||||||
// if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE.
|
|
||||||
func (d *Device) Image2DMaxHeight() int {
|
|
||||||
val, _ := d.getInfoSize(C.CL_DEVICE_IMAGE2D_MAX_HEIGHT, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max width of 2D image or 1D image not created from a buffer object in
|
|
||||||
// pixels. The minimum value is 8192 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE.
|
|
||||||
func (d *Device) Image2DMaxWidth() int {
|
|
||||||
val, _ := d.getInfoSize(C.CL_DEVICE_IMAGE2D_MAX_WIDTH, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max depth of 3D image in pixels. The minimum value is 2048 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE.
|
|
||||||
func (d *Device) Image3DMaxDepth() int {
|
|
||||||
val, _ := d.getInfoSize(C.CL_DEVICE_IMAGE3D_MAX_DEPTH, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max height of 3D image in pixels. The minimum value is 2048 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE.
|
|
||||||
func (d *Device) Image3DMaxHeight() int {
|
|
||||||
val, _ := d.getInfoSize(C.CL_DEVICE_IMAGE3D_MAX_HEIGHT, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max width of 3D image in pixels. The minimum value is 2048 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE.
|
|
||||||
func (d *Device) Image3DMaxWidth() int {
|
|
||||||
val, _ := d.getInfoSize(C.CL_DEVICE_IMAGE3D_MAX_WIDTH, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max size in bytes of the arguments that can be passed to a kernel. The
|
|
||||||
// minimum value is 1024 for devices that are not of type CL_DEVICE_TYPE_CUSTOM.
|
|
||||||
// For this minimum value, only a maximum of 128 arguments can be passed to a kernel.
|
|
||||||
func (d *Device) MaxParameterSize() int {
|
|
||||||
val, _ := d.getInfoSize(C.CL_DEVICE_MAX_PARAMETER_SIZE, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maximum number of work-items in a work-group executing a kernel on a
|
|
||||||
// single compute unit, using the data parallel execution model. (Refer
|
|
||||||
// to clEnqueueNDRangeKernel). The minimum value is 1.
|
|
||||||
func (d *Device) MaxWorkGroupSize() int {
|
|
||||||
val, _ := d.getInfoSize(C.CL_DEVICE_MAX_WORK_GROUP_SIZE, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Describes the resolution of device timer. This is measured in nanoseconds.
|
|
||||||
func (d *Device) ProfilingTimerResolution() int {
|
|
||||||
val, _ := d.getInfoSize(C.CL_DEVICE_PROFILING_TIMER_RESOLUTION, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Size of local memory arena in bytes. The minimum value is 32 KB for
|
|
||||||
// devices that are not of type CL_DEVICE_TYPE_CUSTOM.
|
|
||||||
func (d *Device) LocalMemSize() int64 {
|
|
||||||
val, _ := d.getInfoUlong(C.CL_DEVICE_LOCAL_MEM_SIZE, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max size in bytes of a constant buffer allocation. The minimum value is
|
|
||||||
// 64 KB for devices that are not of type CL_DEVICE_TYPE_CUSTOM.
|
|
||||||
func (d *Device) MaxConstantBufferSize() int64 {
|
|
||||||
val, _ := d.getInfoUlong(C.CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max size of memory object allocation in bytes. The minimum value is max
|
|
||||||
// (1/4th of CL_DEVICE_GLOBAL_MEM_SIZE, 128*1024*1024) for devices that are
|
|
||||||
// not of type CL_DEVICE_TYPE_CUSTOM.
|
|
||||||
func (d *Device) MaxMemAllocSize() int64 {
|
|
||||||
val, _ := d.getInfoUlong(C.CL_DEVICE_MAX_MEM_ALLOC_SIZE, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
// Size of global device memory in bytes.
|
|
||||||
func (d *Device) GlobalMemSize() int64 {
|
|
||||||
val, _ := d.getInfoUlong(C.CL_DEVICE_GLOBAL_MEM_SIZE, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) Available() bool {
|
|
||||||
val, _ := d.getInfoBool(C.CL_DEVICE_AVAILABLE, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) CompilerAvailable() bool {
|
|
||||||
val, _ := d.getInfoBool(C.CL_DEVICE_COMPILER_AVAILABLE, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) EndianLittle() bool {
|
|
||||||
val, _ := d.getInfoBool(C.CL_DEVICE_ENDIAN_LITTLE, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is CL_TRUE if the device implements error correction for all
|
|
||||||
// accesses to compute device memory (global and constant). Is
|
|
||||||
// CL_FALSE if the device does not implement such error correction.
|
|
||||||
func (d *Device) ErrorCorrectionSupport() bool {
|
|
||||||
val, _ := d.getInfoBool(C.CL_DEVICE_ERROR_CORRECTION_SUPPORT, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) HostUnifiedMemory() bool {
|
|
||||||
val, _ := d.getInfoBool(C.CL_DEVICE_HOST_UNIFIED_MEMORY, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) ImageSupport() bool {
|
|
||||||
val, _ := d.getInfoBool(C.CL_DEVICE_IMAGE_SUPPORT, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) Type() DeviceType {
|
|
||||||
var deviceType C.cl_device_type
|
|
||||||
if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_TYPE, C.size_t(unsafe.Sizeof(deviceType)), unsafe.Pointer(&deviceType), nil); err != C.CL_SUCCESS {
|
|
||||||
panic("Failed to get device type")
|
|
||||||
}
|
|
||||||
return DeviceType(deviceType)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Describes double precision floating-point capability of the OpenCL device
|
|
||||||
func (d *Device) DoubleFPConfig() FPConfig {
|
|
||||||
var fpConfig C.cl_device_fp_config
|
|
||||||
if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_DOUBLE_FP_CONFIG, C.size_t(unsafe.Sizeof(fpConfig)), unsafe.Pointer(&fpConfig), nil); err != C.CL_SUCCESS {
|
|
||||||
panic("Failed to get double FP config")
|
|
||||||
}
|
|
||||||
return FPConfig(fpConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Describes the OPTIONAL half precision floating-point capability of the OpenCL device
|
|
||||||
func (d *Device) HalfFPConfig() FPConfig {
|
|
||||||
var fpConfig C.cl_device_fp_config
|
|
||||||
err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_HALF_FP_CONFIG, C.size_t(unsafe.Sizeof(fpConfig)), unsafe.Pointer(&fpConfig), nil)
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return FPConfig(0)
|
|
||||||
}
|
|
||||||
return FPConfig(fpConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type of local memory supported. This can be set to CL_LOCAL implying dedicated
|
|
||||||
// local memory storage such as SRAM, or CL_GLOBAL. For custom devices, CL_NONE
|
|
||||||
// can also be returned indicating no local memory support.
|
|
||||||
func (d *Device) LocalMemType() LocalMemType {
|
|
||||||
var memType C.cl_device_local_mem_type
|
|
||||||
if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_LOCAL_MEM_TYPE, C.size_t(unsafe.Sizeof(memType)), unsafe.Pointer(&memType), nil); err != C.CL_SUCCESS {
|
|
||||||
return LocalMemType(C.CL_NONE)
|
|
||||||
}
|
|
||||||
return LocalMemType(memType)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Describes the execution capabilities of the device. The mandated minimum capability is CL_EXEC_KERNEL.
|
|
||||||
func (d *Device) ExecutionCapabilities() ExecCapability {
|
|
||||||
var execCap C.cl_device_exec_capabilities
|
|
||||||
if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_EXECUTION_CAPABILITIES, C.size_t(unsafe.Sizeof(execCap)), unsafe.Pointer(&execCap), nil); err != C.CL_SUCCESS {
|
|
||||||
panic("Failed to get execution capabilities")
|
|
||||||
}
|
|
||||||
return ExecCapability(execCap)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) GlobalMemCacheType() MemCacheType {
|
|
||||||
var memType C.cl_device_mem_cache_type
|
|
||||||
if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, C.size_t(unsafe.Sizeof(memType)), unsafe.Pointer(&memType), nil); err != C.CL_SUCCESS {
|
|
||||||
return MemCacheType(C.CL_NONE)
|
|
||||||
}
|
|
||||||
return MemCacheType(memType)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maximum number of work-items that can be specified in each dimension of the work-group to clEnqueueNDRangeKernel.
|
|
||||||
//
|
|
||||||
// Returns n size_t entries, where n is the value returned by the query for CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS.
|
|
||||||
//
|
|
||||||
// The minimum value is (1, 1, 1) for devices that are not of type CL_DEVICE_TYPE_CUSTOM.
|
|
||||||
func (d *Device) MaxWorkItemSizes() []int {
|
|
||||||
dims := d.MaxWorkItemDimensions()
|
|
||||||
sizes := make([]C.size_t, dims)
|
|
||||||
if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_MAX_WORK_ITEM_SIZES, C.size_t(int(unsafe.Sizeof(sizes[0]))*dims), unsafe.Pointer(&sizes[0]), nil); err != C.CL_SUCCESS {
|
|
||||||
panic("Failed to get max work item sizes")
|
|
||||||
}
|
|
||||||
intSizes := make([]int, dims)
|
|
||||||
for i, s := range sizes {
|
|
||||||
intSizes[i] = int(s)
|
|
||||||
}
|
|
||||||
return intSizes
|
|
||||||
}
|
|
||||||
51
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/device12.go
generated
vendored
51
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/device12.go
generated
vendored
@@ -1,51 +0,0 @@
|
|||||||
// +build cl12
|
|
||||||
|
|
||||||
package cl
|
|
||||||
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
const FPConfigCorrectlyRoundedDivideSqrt FPConfig = C.CL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
fpConfigNameMap[FPConfigCorrectlyRoundedDivideSqrt] = "CorrectlyRoundedDivideSqrt"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) BuiltInKernels() string {
|
|
||||||
str, _ := d.getInfoString(C.CL_DEVICE_BUILT_IN_KERNELS, true)
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is CL_FALSE if the implementation does not have a linker available. Is CL_TRUE if the linker is available. This can be CL_FALSE for the embedded platform profile only. This must be CL_TRUE if CL_DEVICE_COMPILER_AVAILABLE is CL_TRUE
|
|
||||||
func (d *Device) LinkerAvailable() bool {
|
|
||||||
val, _ := d.getInfoBool(C.CL_DEVICE_LINKER_AVAILABLE, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) ParentDevice() *Device {
|
|
||||||
var deviceId C.cl_device_id
|
|
||||||
if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_PARENT_DEVICE, C.size_t(unsafe.Sizeof(deviceId)), unsafe.Pointer(&deviceId), nil); err != C.CL_SUCCESS {
|
|
||||||
panic("ParentDevice failed")
|
|
||||||
}
|
|
||||||
if deviceId == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &Device{id: deviceId}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max number of pixels for a 1D image created from a buffer object. The minimum value is 65536 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE.
|
|
||||||
func (d *Device) ImageMaxBufferSize() int {
|
|
||||||
val, _ := d.getInfoSize(C.CL_DEVICE_IMAGE_MAX_BUFFER_SIZE, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max number of images in a 1D or 2D image array. The minimum value is 2048 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE
|
|
||||||
func (d *Device) ImageMaxArraySize() int {
|
|
||||||
val, _ := d.getInfoSize(C.CL_DEVICE_IMAGE_MAX_ARRAY_SIZE, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
1210
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/cl.h
generated
vendored
1210
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/cl.h
generated
vendored
File diff suppressed because it is too large
Load Diff
315
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/cl_ext.h
generated
vendored
315
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/cl_ext.h
generated
vendored
@@ -1,315 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2008-2013 The Khronos Group Inc.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and/or associated documentation files (the
|
|
||||||
* "Materials"), to deal in the Materials without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Materials, and to
|
|
||||||
* permit persons to whom the Materials are furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Materials.
|
|
||||||
*
|
|
||||||
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* $Revision: 11928 $ on $Date: 2010-07-13 09:04:56 -0700 (Tue, 13 Jul 2010) $ */
|
|
||||||
|
|
||||||
/* cl_ext.h contains OpenCL extensions which don't have external */
|
|
||||||
/* (OpenGL, D3D) dependencies. */
|
|
||||||
|
|
||||||
#ifndef __CL_EXT_H
|
|
||||||
#define __CL_EXT_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#include <AvailabilityMacros.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cl.h>
|
|
||||||
|
|
||||||
/* cl_khr_fp16 extension - no extension #define since it has no functions */
|
|
||||||
#define CL_DEVICE_HALF_FP_CONFIG 0x1033
|
|
||||||
|
|
||||||
/* Memory object destruction
|
|
||||||
*
|
|
||||||
* Apple extension for use to manage externally allocated buffers used with cl_mem objects with CL_MEM_USE_HOST_PTR
|
|
||||||
*
|
|
||||||
* Registers a user callback function that will be called when the memory object is deleted and its resources
|
|
||||||
* freed. Each call to clSetMemObjectCallbackFn registers the specified user callback function on a callback
|
|
||||||
* stack associated with memobj. The registered user callback functions are called in the reverse order in
|
|
||||||
* which they were registered. The user callback functions are called and then the memory object is deleted
|
|
||||||
* and its resources freed. This provides a mechanism for the application (and libraries) using memobj to be
|
|
||||||
* notified when the memory referenced by host_ptr, specified when the memory object is created and used as
|
|
||||||
* the storage bits for the memory object, can be reused or freed.
|
|
||||||
*
|
|
||||||
* The application may not call CL api's with the cl_mem object passed to the pfn_notify.
|
|
||||||
*
|
|
||||||
* Please check for the "cl_APPLE_SetMemObjectDestructor" extension using clGetDeviceInfo(CL_DEVICE_EXTENSIONS)
|
|
||||||
* before using.
|
|
||||||
*/
|
|
||||||
#define cl_APPLE_SetMemObjectDestructor 1
|
|
||||||
cl_int CL_API_ENTRY clSetMemObjectDestructorAPPLE( cl_mem /* memobj */,
|
|
||||||
void (* /*pfn_notify*/)( cl_mem /* memobj */, void* /*user_data*/),
|
|
||||||
void * /*user_data */ ) CL_EXT_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
|
|
||||||
/* Context Logging Functions
|
|
||||||
*
|
|
||||||
* The next three convenience functions are intended to be used as the pfn_notify parameter to clCreateContext().
|
|
||||||
* Please check for the "cl_APPLE_ContextLoggingFunctions" extension using clGetDeviceInfo(CL_DEVICE_EXTENSIONS)
|
|
||||||
* before using.
|
|
||||||
*
|
|
||||||
* clLogMessagesToSystemLog fowards on all log messages to the Apple System Logger
|
|
||||||
*/
|
|
||||||
#define cl_APPLE_ContextLoggingFunctions 1
|
|
||||||
extern void CL_API_ENTRY clLogMessagesToSystemLogAPPLE( const char * /* errstr */,
|
|
||||||
const void * /* private_info */,
|
|
||||||
size_t /* cb */,
|
|
||||||
void * /* user_data */ ) CL_EXT_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
/* clLogMessagesToStdout sends all log messages to the file descriptor stdout */
|
|
||||||
extern void CL_API_ENTRY clLogMessagesToStdoutAPPLE( const char * /* errstr */,
|
|
||||||
const void * /* private_info */,
|
|
||||||
size_t /* cb */,
|
|
||||||
void * /* user_data */ ) CL_EXT_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
/* clLogMessagesToStderr sends all log messages to the file descriptor stderr */
|
|
||||||
extern void CL_API_ENTRY clLogMessagesToStderrAPPLE( const char * /* errstr */,
|
|
||||||
const void * /* private_info */,
|
|
||||||
size_t /* cb */,
|
|
||||||
void * /* user_data */ ) CL_EXT_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* cl_khr_icd extension *
|
|
||||||
************************/
|
|
||||||
#define cl_khr_icd 1
|
|
||||||
|
|
||||||
/* cl_platform_info */
|
|
||||||
#define CL_PLATFORM_ICD_SUFFIX_KHR 0x0920
|
|
||||||
|
|
||||||
/* Additional Error Codes */
|
|
||||||
#define CL_PLATFORM_NOT_FOUND_KHR -1001
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
||||||
clIcdGetPlatformIDsKHR(cl_uint /* num_entries */,
|
|
||||||
cl_platform_id * /* platforms */,
|
|
||||||
cl_uint * /* num_platforms */);
|
|
||||||
|
|
||||||
typedef CL_API_ENTRY cl_int (CL_API_CALL *clIcdGetPlatformIDsKHR_fn)(
|
|
||||||
cl_uint /* num_entries */,
|
|
||||||
cl_platform_id * /* platforms */,
|
|
||||||
cl_uint * /* num_platforms */);
|
|
||||||
|
|
||||||
|
|
||||||
/* Extension: cl_khr_image2D_buffer
|
|
||||||
*
|
|
||||||
* This extension allows a 2D image to be created from a cl_mem buffer without a copy.
|
|
||||||
* The type associated with a 2D image created from a buffer in an OpenCL program is image2d_t.
|
|
||||||
* Both the sampler and sampler-less read_image built-in functions are supported for 2D images
|
|
||||||
* and 2D images created from a buffer. Similarly, the write_image built-ins are also supported
|
|
||||||
* for 2D images created from a buffer.
|
|
||||||
*
|
|
||||||
* When the 2D image from buffer is created, the client must specify the width,
|
|
||||||
* height, image format (i.e. channel order and channel data type) and optionally the row pitch
|
|
||||||
*
|
|
||||||
* The pitch specified must be a multiple of CL_DEVICE_IMAGE_PITCH_ALIGNMENT pixels.
|
|
||||||
* The base address of the buffer must be aligned to CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT pixels.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*************************************
|
|
||||||
* cl_khr_initalize_memory extension *
|
|
||||||
*************************************/
|
|
||||||
|
|
||||||
#define CL_CONTEXT_MEMORY_INITIALIZE_KHR 0x200E
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
* cl_khr_terminate_context extension *
|
|
||||||
**************************************/
|
|
||||||
|
|
||||||
#define CL_DEVICE_TERMINATE_CAPABILITY_KHR 0x200F
|
|
||||||
#define CL_CONTEXT_TERMINATE_KHR 0x2010
|
|
||||||
|
|
||||||
#define cl_khr_terminate_context 1
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL clTerminateContextKHR(cl_context /* context */) CL_EXT_SUFFIX__VERSION_1_2;
|
|
||||||
|
|
||||||
typedef CL_API_ENTRY cl_int (CL_API_CALL *clTerminateContextKHR_fn)(cl_context /* context */) CL_EXT_SUFFIX__VERSION_1_2;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Extension: cl_khr_spir
|
|
||||||
*
|
|
||||||
* This extension adds support to create an OpenCL program object from a
|
|
||||||
* Standard Portable Intermediate Representation (SPIR) instance
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define CL_DEVICE_SPIR_VERSIONS 0x40E0
|
|
||||||
#define CL_PROGRAM_BINARY_TYPE_INTERMEDIATE 0x40E1
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************
|
|
||||||
* cl_nv_device_attribute_query extension *
|
|
||||||
******************************************/
|
|
||||||
/* cl_nv_device_attribute_query extension - no extension #define since it has no functions */
|
|
||||||
#define CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV 0x4000
|
|
||||||
#define CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV 0x4001
|
|
||||||
#define CL_DEVICE_REGISTERS_PER_BLOCK_NV 0x4002
|
|
||||||
#define CL_DEVICE_WARP_SIZE_NV 0x4003
|
|
||||||
#define CL_DEVICE_GPU_OVERLAP_NV 0x4004
|
|
||||||
#define CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV 0x4005
|
|
||||||
#define CL_DEVICE_INTEGRATED_MEMORY_NV 0x4006
|
|
||||||
|
|
||||||
/*********************************
|
|
||||||
* cl_amd_device_attribute_query *
|
|
||||||
*********************************/
|
|
||||||
#define CL_DEVICE_PROFILING_TIMER_OFFSET_AMD 0x4036
|
|
||||||
|
|
||||||
/*********************************
|
|
||||||
* cl_arm_printf extension
|
|
||||||
*********************************/
|
|
||||||
#define CL_PRINTF_CALLBACK_ARM 0x40B0
|
|
||||||
#define CL_PRINTF_BUFFERSIZE_ARM 0x40B1
|
|
||||||
|
|
||||||
#ifdef CL_VERSION_1_1
|
|
||||||
/***********************************
|
|
||||||
* cl_ext_device_fission extension *
|
|
||||||
***********************************/
|
|
||||||
#define cl_ext_device_fission 1
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
||||||
clReleaseDeviceEXT( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1;
|
|
||||||
|
|
||||||
typedef CL_API_ENTRY cl_int
|
|
||||||
(CL_API_CALL *clReleaseDeviceEXT_fn)( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1;
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
||||||
clRetainDeviceEXT( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1;
|
|
||||||
|
|
||||||
typedef CL_API_ENTRY cl_int
|
|
||||||
(CL_API_CALL *clRetainDeviceEXT_fn)( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1;
|
|
||||||
|
|
||||||
typedef cl_ulong cl_device_partition_property_ext;
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
||||||
clCreateSubDevicesEXT( cl_device_id /*in_device*/,
|
|
||||||
const cl_device_partition_property_ext * /* properties */,
|
|
||||||
cl_uint /*num_entries*/,
|
|
||||||
cl_device_id * /*out_devices*/,
|
|
||||||
cl_uint * /*num_devices*/ ) CL_EXT_SUFFIX__VERSION_1_1;
|
|
||||||
|
|
||||||
typedef CL_API_ENTRY cl_int
|
|
||||||
( CL_API_CALL * clCreateSubDevicesEXT_fn)( cl_device_id /*in_device*/,
|
|
||||||
const cl_device_partition_property_ext * /* properties */,
|
|
||||||
cl_uint /*num_entries*/,
|
|
||||||
cl_device_id * /*out_devices*/,
|
|
||||||
cl_uint * /*num_devices*/ ) CL_EXT_SUFFIX__VERSION_1_1;
|
|
||||||
|
|
||||||
/* cl_device_partition_property_ext */
|
|
||||||
#define CL_DEVICE_PARTITION_EQUALLY_EXT 0x4050
|
|
||||||
#define CL_DEVICE_PARTITION_BY_COUNTS_EXT 0x4051
|
|
||||||
#define CL_DEVICE_PARTITION_BY_NAMES_EXT 0x4052
|
|
||||||
#define CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN_EXT 0x4053
|
|
||||||
|
|
||||||
/* clDeviceGetInfo selectors */
|
|
||||||
#define CL_DEVICE_PARENT_DEVICE_EXT 0x4054
|
|
||||||
#define CL_DEVICE_PARTITION_TYPES_EXT 0x4055
|
|
||||||
#define CL_DEVICE_AFFINITY_DOMAINS_EXT 0x4056
|
|
||||||
#define CL_DEVICE_REFERENCE_COUNT_EXT 0x4057
|
|
||||||
#define CL_DEVICE_PARTITION_STYLE_EXT 0x4058
|
|
||||||
|
|
||||||
/* error codes */
|
|
||||||
#define CL_DEVICE_PARTITION_FAILED_EXT -1057
|
|
||||||
#define CL_INVALID_PARTITION_COUNT_EXT -1058
|
|
||||||
#define CL_INVALID_PARTITION_NAME_EXT -1059
|
|
||||||
|
|
||||||
/* CL_AFFINITY_DOMAINs */
|
|
||||||
#define CL_AFFINITY_DOMAIN_L1_CACHE_EXT 0x1
|
|
||||||
#define CL_AFFINITY_DOMAIN_L2_CACHE_EXT 0x2
|
|
||||||
#define CL_AFFINITY_DOMAIN_L3_CACHE_EXT 0x3
|
|
||||||
#define CL_AFFINITY_DOMAIN_L4_CACHE_EXT 0x4
|
|
||||||
#define CL_AFFINITY_DOMAIN_NUMA_EXT 0x10
|
|
||||||
#define CL_AFFINITY_DOMAIN_NEXT_FISSIONABLE_EXT 0x100
|
|
||||||
|
|
||||||
/* cl_device_partition_property_ext list terminators */
|
|
||||||
#define CL_PROPERTIES_LIST_END_EXT ((cl_device_partition_property_ext) 0)
|
|
||||||
#define CL_PARTITION_BY_COUNTS_LIST_END_EXT ((cl_device_partition_property_ext) 0)
|
|
||||||
#define CL_PARTITION_BY_NAMES_LIST_END_EXT ((cl_device_partition_property_ext) 0 - 1)
|
|
||||||
|
|
||||||
/*********************************
|
|
||||||
* cl_qcom_ext_host_ptr extension
|
|
||||||
*********************************/
|
|
||||||
|
|
||||||
#define CL_MEM_EXT_HOST_PTR_QCOM (1 << 29)
|
|
||||||
|
|
||||||
#define CL_DEVICE_EXT_MEM_PADDING_IN_BYTES_QCOM 0x40A0
|
|
||||||
#define CL_DEVICE_PAGE_SIZE_QCOM 0x40A1
|
|
||||||
#define CL_IMAGE_ROW_ALIGNMENT_QCOM 0x40A2
|
|
||||||
#define CL_IMAGE_SLICE_ALIGNMENT_QCOM 0x40A3
|
|
||||||
#define CL_MEM_HOST_UNCACHED_QCOM 0x40A4
|
|
||||||
#define CL_MEM_HOST_WRITEBACK_QCOM 0x40A5
|
|
||||||
#define CL_MEM_HOST_WRITETHROUGH_QCOM 0x40A6
|
|
||||||
#define CL_MEM_HOST_WRITE_COMBINING_QCOM 0x40A7
|
|
||||||
|
|
||||||
typedef cl_uint cl_image_pitch_info_qcom;
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
||||||
clGetDeviceImageInfoQCOM(cl_device_id device,
|
|
||||||
size_t image_width,
|
|
||||||
size_t image_height,
|
|
||||||
const cl_image_format *image_format,
|
|
||||||
cl_image_pitch_info_qcom param_name,
|
|
||||||
size_t param_value_size,
|
|
||||||
void *param_value,
|
|
||||||
size_t *param_value_size_ret);
|
|
||||||
|
|
||||||
typedef struct _cl_mem_ext_host_ptr
|
|
||||||
{
|
|
||||||
/* Type of external memory allocation. */
|
|
||||||
/* Legal values will be defined in layered extensions. */
|
|
||||||
cl_uint allocation_type;
|
|
||||||
|
|
||||||
/* Host cache policy for this external memory allocation. */
|
|
||||||
cl_uint host_cache_policy;
|
|
||||||
|
|
||||||
} cl_mem_ext_host_ptr;
|
|
||||||
|
|
||||||
/*********************************
|
|
||||||
* cl_qcom_ion_host_ptr extension
|
|
||||||
*********************************/
|
|
||||||
|
|
||||||
#define CL_MEM_ION_HOST_PTR_QCOM 0x40A8
|
|
||||||
|
|
||||||
typedef struct _cl_mem_ion_host_ptr
|
|
||||||
{
|
|
||||||
/* Type of external memory allocation. */
|
|
||||||
/* Must be CL_MEM_ION_HOST_PTR_QCOM for ION allocations. */
|
|
||||||
cl_mem_ext_host_ptr ext_host_ptr;
|
|
||||||
|
|
||||||
/* ION file descriptor */
|
|
||||||
int ion_filedesc;
|
|
||||||
|
|
||||||
/* Host pointer to the ION allocated memory */
|
|
||||||
void* ion_hostptr;
|
|
||||||
|
|
||||||
} cl_mem_ion_host_ptr;
|
|
||||||
|
|
||||||
#endif /* CL_VERSION_1_1 */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __CL_EXT_H */
|
|
||||||
158
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/cl_gl.h
generated
vendored
158
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/cl_gl.h
generated
vendored
@@ -1,158 +0,0 @@
|
|||||||
/**********************************************************************************
|
|
||||||
* Copyright (c) 2008 - 2012 The Khronos Group Inc.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and/or associated documentation files (the
|
|
||||||
* "Materials"), to deal in the Materials without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Materials, and to
|
|
||||||
* permit persons to whom the Materials are furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Materials.
|
|
||||||
*
|
|
||||||
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
|
||||||
**********************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __OPENCL_CL_GL_H
|
|
||||||
#define __OPENCL_CL_GL_H
|
|
||||||
|
|
||||||
#include <cl.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef cl_uint cl_gl_object_type;
|
|
||||||
typedef cl_uint cl_gl_texture_info;
|
|
||||||
typedef cl_uint cl_gl_platform_info;
|
|
||||||
typedef struct __GLsync *cl_GLsync;
|
|
||||||
|
|
||||||
/* cl_gl_object_type = 0x2000 - 0x200F enum values are currently taken */
|
|
||||||
#define CL_GL_OBJECT_BUFFER 0x2000
|
|
||||||
#define CL_GL_OBJECT_TEXTURE2D 0x2001
|
|
||||||
#define CL_GL_OBJECT_TEXTURE3D 0x2002
|
|
||||||
#define CL_GL_OBJECT_RENDERBUFFER 0x2003
|
|
||||||
#define CL_GL_OBJECT_TEXTURE2D_ARRAY 0x200E
|
|
||||||
#define CL_GL_OBJECT_TEXTURE1D 0x200F
|
|
||||||
#define CL_GL_OBJECT_TEXTURE1D_ARRAY 0x2010
|
|
||||||
#define CL_GL_OBJECT_TEXTURE_BUFFER 0x2011
|
|
||||||
|
|
||||||
/* cl_gl_texture_info */
|
|
||||||
#define CL_GL_TEXTURE_TARGET 0x2004
|
|
||||||
#define CL_GL_MIPMAP_LEVEL 0x2005
|
|
||||||
#define CL_GL_NUM_SAMPLES 0x2012
|
|
||||||
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_mem CL_API_CALL
|
|
||||||
clCreateFromGLBuffer(cl_context /* context */,
|
|
||||||
cl_mem_flags /* flags */,
|
|
||||||
cl_GLuint /* bufobj */,
|
|
||||||
int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_mem CL_API_CALL
|
|
||||||
clCreateFromGLTexture(cl_context /* context */,
|
|
||||||
cl_mem_flags /* flags */,
|
|
||||||
cl_GLenum /* target */,
|
|
||||||
cl_GLint /* miplevel */,
|
|
||||||
cl_GLuint /* texture */,
|
|
||||||
cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_2;
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_mem CL_API_CALL
|
|
||||||
clCreateFromGLRenderbuffer(cl_context /* context */,
|
|
||||||
cl_mem_flags /* flags */,
|
|
||||||
cl_GLuint /* renderbuffer */,
|
|
||||||
cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
||||||
clGetGLObjectInfo(cl_mem /* memobj */,
|
|
||||||
cl_gl_object_type * /* gl_object_type */,
|
|
||||||
cl_GLuint * /* gl_object_name */) CL_API_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
||||||
clGetGLTextureInfo(cl_mem /* memobj */,
|
|
||||||
cl_gl_texture_info /* param_name */,
|
|
||||||
size_t /* param_value_size */,
|
|
||||||
void * /* param_value */,
|
|
||||||
size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
||||||
clEnqueueAcquireGLObjects(cl_command_queue /* command_queue */,
|
|
||||||
cl_uint /* num_objects */,
|
|
||||||
const cl_mem * /* mem_objects */,
|
|
||||||
cl_uint /* num_events_in_wait_list */,
|
|
||||||
const cl_event * /* event_wait_list */,
|
|
||||||
cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
||||||
clEnqueueReleaseGLObjects(cl_command_queue /* command_queue */,
|
|
||||||
cl_uint /* num_objects */,
|
|
||||||
const cl_mem * /* mem_objects */,
|
|
||||||
cl_uint /* num_events_in_wait_list */,
|
|
||||||
const cl_event * /* event_wait_list */,
|
|
||||||
cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
|
|
||||||
/* Deprecated OpenCL 1.1 APIs */
|
|
||||||
extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_mem CL_API_CALL
|
|
||||||
clCreateFromGLTexture2D(cl_context /* context */,
|
|
||||||
cl_mem_flags /* flags */,
|
|
||||||
cl_GLenum /* target */,
|
|
||||||
cl_GLint /* miplevel */,
|
|
||||||
cl_GLuint /* texture */,
|
|
||||||
cl_int * /* errcode_ret */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED;
|
|
||||||
|
|
||||||
extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_mem CL_API_CALL
|
|
||||||
clCreateFromGLTexture3D(cl_context /* context */,
|
|
||||||
cl_mem_flags /* flags */,
|
|
||||||
cl_GLenum /* target */,
|
|
||||||
cl_GLint /* miplevel */,
|
|
||||||
cl_GLuint /* texture */,
|
|
||||||
cl_int * /* errcode_ret */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED;
|
|
||||||
|
|
||||||
/* cl_khr_gl_sharing extension */
|
|
||||||
|
|
||||||
#define cl_khr_gl_sharing 1
|
|
||||||
|
|
||||||
typedef cl_uint cl_gl_context_info;
|
|
||||||
|
|
||||||
/* Additional Error Codes */
|
|
||||||
#define CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR -1000
|
|
||||||
|
|
||||||
/* cl_gl_context_info */
|
|
||||||
#define CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR 0x2006
|
|
||||||
#define CL_DEVICES_FOR_GL_CONTEXT_KHR 0x2007
|
|
||||||
|
|
||||||
/* Additional cl_context_properties */
|
|
||||||
#define CL_GL_CONTEXT_KHR 0x2008
|
|
||||||
#define CL_EGL_DISPLAY_KHR 0x2009
|
|
||||||
#define CL_GLX_DISPLAY_KHR 0x200A
|
|
||||||
#define CL_WGL_HDC_KHR 0x200B
|
|
||||||
#define CL_CGL_SHAREGROUP_KHR 0x200C
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
||||||
clGetGLContextInfoKHR(const cl_context_properties * /* properties */,
|
|
||||||
cl_gl_context_info /* param_name */,
|
|
||||||
size_t /* param_value_size */,
|
|
||||||
void * /* param_value */,
|
|
||||||
size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetGLContextInfoKHR_fn)(
|
|
||||||
const cl_context_properties * properties,
|
|
||||||
cl_gl_context_info param_name,
|
|
||||||
size_t param_value_size,
|
|
||||||
void * param_value,
|
|
||||||
size_t * param_value_size_ret);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __OPENCL_CL_GL_H */
|
|
||||||
65
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/cl_gl_ext.h
generated
vendored
65
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/cl_gl_ext.h
generated
vendored
@@ -1,65 +0,0 @@
|
|||||||
/**********************************************************************************
|
|
||||||
* Copyright (c) 2008-2012 The Khronos Group Inc.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and/or associated documentation files (the
|
|
||||||
* "Materials"), to deal in the Materials without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Materials, and to
|
|
||||||
* permit persons to whom the Materials are furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Materials.
|
|
||||||
*
|
|
||||||
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
|
||||||
**********************************************************************************/
|
|
||||||
|
|
||||||
/* $Revision: 11708 $ on $Date: 2010-06-13 23:36:24 -0700 (Sun, 13 Jun 2010) $ */
|
|
||||||
|
|
||||||
/* cl_gl_ext.h contains vendor (non-KHR) OpenCL extensions which have */
|
|
||||||
/* OpenGL dependencies. */
|
|
||||||
|
|
||||||
#ifndef __OPENCL_CL_GL_EXT_H
|
|
||||||
#define __OPENCL_CL_GL_EXT_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cl_gl.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For each extension, follow this template
|
|
||||||
* cl_VEN_extname extension */
|
|
||||||
/* #define cl_VEN_extname 1
|
|
||||||
* ... define new types, if any
|
|
||||||
* ... define new tokens, if any
|
|
||||||
* ... define new APIs, if any
|
|
||||||
*
|
|
||||||
* If you need GLtypes here, mirror them with a cl_GLtype, rather than including a GL header
|
|
||||||
* This allows us to avoid having to decide whether to include GL headers or GLES here.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* cl_khr_gl_event extension
|
|
||||||
* See section 9.9 in the OpenCL 1.1 spec for more information
|
|
||||||
*/
|
|
||||||
#define CL_COMMAND_GL_FENCE_SYNC_OBJECT_KHR 0x200D
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_event CL_API_CALL
|
|
||||||
clCreateEventFromGLsyncKHR(cl_context /* context */,
|
|
||||||
cl_GLsync /* cl_GLsync */,
|
|
||||||
cl_int * /* errcode_ret */) CL_EXT_SUFFIX__VERSION_1_1;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __OPENCL_CL_GL_EXT_H */
|
|
||||||
1278
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/cl_platform.h
generated
vendored
1278
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/cl_platform.h
generated
vendored
File diff suppressed because it is too large
Load Diff
43
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/opencl.h
generated
vendored
43
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/opencl.h
generated
vendored
@@ -1,43 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2008-2012 The Khronos Group Inc.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and/or associated documentation files (the
|
|
||||||
* "Materials"), to deal in the Materials without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Materials, and to
|
|
||||||
* permit persons to whom the Materials are furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Materials.
|
|
||||||
*
|
|
||||||
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* $Revision: 11708 $ on $Date: 2010-06-13 23:36:24 -0700 (Sun, 13 Jun 2010) $ */
|
|
||||||
|
|
||||||
#ifndef __OPENCL_H
|
|
||||||
#define __OPENCL_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cl.h>
|
|
||||||
#include <cl_gl.h>
|
|
||||||
#include <cl_gl_ext.h>
|
|
||||||
#include <cl_ext.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __OPENCL_H */
|
|
||||||
|
|
||||||
83
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/image.go
generated
vendored
83
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/image.go
generated
vendored
@@ -1,83 +0,0 @@
|
|||||||
// +build cl12
|
|
||||||
|
|
||||||
package cl
|
|
||||||
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
import (
|
|
||||||
"image"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (ctx *Context) CreateImage(flags MemFlag, imageFormat ImageFormat, imageDesc ImageDescription, data []byte) (*MemObject, error) {
|
|
||||||
format := imageFormat.toCl()
|
|
||||||
desc := imageDesc.toCl()
|
|
||||||
var dataPtr unsafe.Pointer
|
|
||||||
if data != nil {
|
|
||||||
dataPtr = unsafe.Pointer(&data[0])
|
|
||||||
}
|
|
||||||
var err C.cl_int
|
|
||||||
clBuffer := C.clCreateImage(ctx.clContext, C.cl_mem_flags(flags), &format, &desc, dataPtr, &err)
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
if clBuffer == nil {
|
|
||||||
return nil, ErrUnknown
|
|
||||||
}
|
|
||||||
return newMemObject(clBuffer, len(data)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) CreateImageSimple(flags MemFlag, width, height int, channelOrder ChannelOrder, channelDataType ChannelDataType, data []byte) (*MemObject, error) {
|
|
||||||
format := ImageFormat{channelOrder, channelDataType}
|
|
||||||
desc := ImageDescription{
|
|
||||||
Type: MemObjectTypeImage2D,
|
|
||||||
Width: width,
|
|
||||||
Height: height,
|
|
||||||
}
|
|
||||||
return ctx.CreateImage(flags, format, desc, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) CreateImageFromImage(flags MemFlag, img image.Image) (*MemObject, error) {
|
|
||||||
switch m := img.(type) {
|
|
||||||
case *image.Gray:
|
|
||||||
format := ImageFormat{ChannelOrderIntensity, ChannelDataTypeUNormInt8}
|
|
||||||
desc := ImageDescription{
|
|
||||||
Type: MemObjectTypeImage2D,
|
|
||||||
Width: m.Bounds().Dx(),
|
|
||||||
Height: m.Bounds().Dy(),
|
|
||||||
RowPitch: m.Stride,
|
|
||||||
}
|
|
||||||
return ctx.CreateImage(flags, format, desc, m.Pix)
|
|
||||||
case *image.RGBA:
|
|
||||||
format := ImageFormat{ChannelOrderRGBA, ChannelDataTypeUNormInt8}
|
|
||||||
desc := ImageDescription{
|
|
||||||
Type: MemObjectTypeImage2D,
|
|
||||||
Width: m.Bounds().Dx(),
|
|
||||||
Height: m.Bounds().Dy(),
|
|
||||||
RowPitch: m.Stride,
|
|
||||||
}
|
|
||||||
return ctx.CreateImage(flags, format, desc, m.Pix)
|
|
||||||
}
|
|
||||||
|
|
||||||
b := img.Bounds()
|
|
||||||
w := b.Dx()
|
|
||||||
h := b.Dy()
|
|
||||||
data := make([]byte, w*h*4)
|
|
||||||
dataOffset := 0
|
|
||||||
for y := 0; y < h; y++ {
|
|
||||||
for x := 0; x < w; x++ {
|
|
||||||
c := img.At(x+b.Min.X, y+b.Min.Y)
|
|
||||||
r, g, b, a := c.RGBA()
|
|
||||||
data[dataOffset] = uint8(r >> 8)
|
|
||||||
data[dataOffset+1] = uint8(g >> 8)
|
|
||||||
data[dataOffset+2] = uint8(b >> 8)
|
|
||||||
data[dataOffset+3] = uint8(a >> 8)
|
|
||||||
dataOffset += 4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ctx.CreateImageSimple(flags, w, h, ChannelOrderRGBA, ChannelDataTypeUNormInt8, data)
|
|
||||||
}
|
|
||||||
127
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/kernel.go
generated
vendored
127
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/kernel.go
generated
vendored
@@ -1,127 +0,0 @@
|
|||||||
package cl
|
|
||||||
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ErrUnsupportedArgumentType struct {
|
|
||||||
Index int
|
|
||||||
Value interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e ErrUnsupportedArgumentType) Error() string {
|
|
||||||
return fmt.Sprintf("cl: unsupported argument type for index %d: %+v", e.Index, e.Value)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Kernel struct {
|
|
||||||
clKernel C.cl_kernel
|
|
||||||
name string
|
|
||||||
}
|
|
||||||
|
|
||||||
type LocalBuffer int
|
|
||||||
|
|
||||||
func releaseKernel(k *Kernel) {
|
|
||||||
if k.clKernel != nil {
|
|
||||||
C.clReleaseKernel(k.clKernel)
|
|
||||||
k.clKernel = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) Release() {
|
|
||||||
releaseKernel(k)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArgs(args ...interface{}) error {
|
|
||||||
for index, arg := range args {
|
|
||||||
if err := k.SetArg(index, arg); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArg(index int, arg interface{}) error {
|
|
||||||
switch val := arg.(type) {
|
|
||||||
case uint8:
|
|
||||||
return k.SetArgUint8(index, val)
|
|
||||||
case int8:
|
|
||||||
return k.SetArgInt8(index, val)
|
|
||||||
case uint32:
|
|
||||||
return k.SetArgUint32(index, val)
|
|
||||||
case uint64:
|
|
||||||
return k.SetArgUint64(index, val)
|
|
||||||
case int32:
|
|
||||||
return k.SetArgInt32(index, val)
|
|
||||||
case float32:
|
|
||||||
return k.SetArgFloat32(index, val)
|
|
||||||
case *MemObject:
|
|
||||||
return k.SetArgBuffer(index, val)
|
|
||||||
case LocalBuffer:
|
|
||||||
return k.SetArgLocal(index, int(val))
|
|
||||||
default:
|
|
||||||
return ErrUnsupportedArgumentType{Index: index, Value: arg}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArgBuffer(index int, buffer *MemObject) error {
|
|
||||||
return k.SetArgUnsafe(index, int(unsafe.Sizeof(buffer.clMem)), unsafe.Pointer(&buffer.clMem))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArgFloat32(index int, val float32) error {
|
|
||||||
return k.SetArgUnsafe(index, int(unsafe.Sizeof(val)), unsafe.Pointer(&val))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArgInt8(index int, val int8) error {
|
|
||||||
return k.SetArgUnsafe(index, int(unsafe.Sizeof(val)), unsafe.Pointer(&val))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArgUint8(index int, val uint8) error {
|
|
||||||
return k.SetArgUnsafe(index, int(unsafe.Sizeof(val)), unsafe.Pointer(&val))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArgInt32(index int, val int32) error {
|
|
||||||
return k.SetArgUnsafe(index, int(unsafe.Sizeof(val)), unsafe.Pointer(&val))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArgUint32(index int, val uint32) error {
|
|
||||||
return k.SetArgUnsafe(index, int(unsafe.Sizeof(val)), unsafe.Pointer(&val))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArgUint64(index int, val uint64) error {
|
|
||||||
return k.SetArgUnsafe(index, int(unsafe.Sizeof(val)), unsafe.Pointer(&val))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArgLocal(index int, size int) error {
|
|
||||||
return k.SetArgUnsafe(index, size, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArgUnsafe(index, argSize int, arg unsafe.Pointer) error {
|
|
||||||
//fmt.Println("FUNKY: ", index, argSize)
|
|
||||||
return toError(C.clSetKernelArg(k.clKernel, C.cl_uint(index), C.size_t(argSize), arg))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) PreferredWorkGroupSizeMultiple(device *Device) (int, error) {
|
|
||||||
var size C.size_t
|
|
||||||
err := C.clGetKernelWorkGroupInfo(k.clKernel, device.nullableId(), C.CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, C.size_t(unsafe.Sizeof(size)), unsafe.Pointer(&size), nil)
|
|
||||||
return int(size), toError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) WorkGroupSize(device *Device) (int, error) {
|
|
||||||
var size C.size_t
|
|
||||||
err := C.clGetKernelWorkGroupInfo(k.clKernel, device.nullableId(), C.CL_KERNEL_WORK_GROUP_SIZE, C.size_t(unsafe.Sizeof(size)), unsafe.Pointer(&size), nil)
|
|
||||||
return int(size), toError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) NumArgs() (int, error) {
|
|
||||||
var num C.cl_uint
|
|
||||||
err := C.clGetKernelInfo(k.clKernel, C.CL_KERNEL_NUM_ARGS, C.size_t(unsafe.Sizeof(num)), unsafe.Pointer(&num), nil)
|
|
||||||
return int(num), toError(err)
|
|
||||||
}
|
|
||||||
7
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/kernel10.go
generated
vendored
7
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/kernel10.go
generated
vendored
@@ -1,7 +0,0 @@
|
|||||||
// +build !cl12
|
|
||||||
|
|
||||||
package cl
|
|
||||||
|
|
||||||
func (k *Kernel) ArgName(index int) (string, error) {
|
|
||||||
return "", ErrUnsupported
|
|
||||||
}
|
|
||||||
20
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/kernel12.go
generated
vendored
20
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/kernel12.go
generated
vendored
@@ -1,20 +0,0 @@
|
|||||||
// +build cl12
|
|
||||||
|
|
||||||
package cl
|
|
||||||
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
func (k *Kernel) ArgName(index int) (string, error) {
|
|
||||||
var strC [1024]byte
|
|
||||||
var strN C.size_t
|
|
||||||
if err := C.clGetKernelArgInfo(k.clKernel, C.cl_uint(index), C.CL_KERNEL_ARG_NAME, 1024, unsafe.Pointer(&strC[0]), &strN); err != C.CL_SUCCESS {
|
|
||||||
return "", toError(err)
|
|
||||||
}
|
|
||||||
return string(strC[:strN]), nil
|
|
||||||
}
|
|
||||||
83
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/platform.go
generated
vendored
83
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/platform.go
generated
vendored
@@ -1,83 +0,0 @@
|
|||||||
package cl
|
|
||||||
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
const maxPlatforms = 32
|
|
||||||
|
|
||||||
type Platform struct {
|
|
||||||
id C.cl_platform_id
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtain the list of platforms available.
|
|
||||||
func GetPlatforms() ([]*Platform, error) {
|
|
||||||
var platformIds [maxPlatforms]C.cl_platform_id
|
|
||||||
var nPlatforms C.cl_uint
|
|
||||||
if err := C.clGetPlatformIDs(C.cl_uint(maxPlatforms), &platformIds[0], &nPlatforms); err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
platforms := make([]*Platform, nPlatforms)
|
|
||||||
for i := 0; i < int(nPlatforms); i++ {
|
|
||||||
platforms[i] = &Platform{id: platformIds[i]}
|
|
||||||
}
|
|
||||||
return platforms, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Platform) GetDevices(deviceType DeviceType) ([]*Device, error) {
|
|
||||||
return GetDevices(p, deviceType)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Platform) getInfoString(param C.cl_platform_info) (string, error) {
|
|
||||||
var strC [2048]byte
|
|
||||||
var strN C.size_t
|
|
||||||
if err := C.clGetPlatformInfo(p.id, param, 2048, unsafe.Pointer(&strC[0]), &strN); err != C.CL_SUCCESS {
|
|
||||||
return "", toError(err)
|
|
||||||
}
|
|
||||||
return string(strC[:(strN - 1)]), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Platform) Name() string {
|
|
||||||
if str, err := p.getInfoString(C.CL_PLATFORM_NAME); err != nil {
|
|
||||||
panic("Platform.Name() should never fail")
|
|
||||||
} else {
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Platform) Vendor() string {
|
|
||||||
if str, err := p.getInfoString(C.CL_PLATFORM_VENDOR); err != nil {
|
|
||||||
panic("Platform.Vendor() should never fail")
|
|
||||||
} else {
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Platform) Profile() string {
|
|
||||||
if str, err := p.getInfoString(C.CL_PLATFORM_PROFILE); err != nil {
|
|
||||||
panic("Platform.Profile() should never fail")
|
|
||||||
} else {
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Platform) Version() string {
|
|
||||||
if str, err := p.getInfoString(C.CL_PLATFORM_VERSION); err != nil {
|
|
||||||
panic("Platform.Version() should never fail")
|
|
||||||
} else {
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Platform) Extensions() string {
|
|
||||||
if str, err := p.getInfoString(C.CL_PLATFORM_EXTENSIONS); err != nil {
|
|
||||||
panic("Platform.Extensions() should never fail")
|
|
||||||
} else {
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
}
|
|
||||||
105
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/program.go
generated
vendored
105
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/program.go
generated
vendored
@@ -1,105 +0,0 @@
|
|||||||
package cl
|
|
||||||
|
|
||||||
// #include <stdlib.h>
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"runtime"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
type BuildError struct {
|
|
||||||
Message string
|
|
||||||
Device *Device
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e BuildError) Error() string {
|
|
||||||
if e.Device != nil {
|
|
||||||
return fmt.Sprintf("cl: build error on %q: %s", e.Device.Name(), e.Message)
|
|
||||||
} else {
|
|
||||||
return fmt.Sprintf("cl: build error: %s", e.Message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Program struct {
|
|
||||||
clProgram C.cl_program
|
|
||||||
devices []*Device
|
|
||||||
}
|
|
||||||
|
|
||||||
func releaseProgram(p *Program) {
|
|
||||||
if p.clProgram != nil {
|
|
||||||
C.clReleaseProgram(p.clProgram)
|
|
||||||
p.clProgram = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Program) Release() {
|
|
||||||
releaseProgram(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Program) BuildProgram(devices []*Device, options string) error {
|
|
||||||
var cOptions *C.char
|
|
||||||
if options != "" {
|
|
||||||
cOptions = C.CString(options)
|
|
||||||
defer C.free(unsafe.Pointer(cOptions))
|
|
||||||
}
|
|
||||||
var deviceList []C.cl_device_id
|
|
||||||
var deviceListPtr *C.cl_device_id
|
|
||||||
numDevices := C.cl_uint(len(devices))
|
|
||||||
if devices != nil && len(devices) > 0 {
|
|
||||||
deviceList = buildDeviceIdList(devices)
|
|
||||||
deviceListPtr = &deviceList[0]
|
|
||||||
}
|
|
||||||
if err := C.clBuildProgram(p.clProgram, numDevices, deviceListPtr, cOptions, nil, nil); err != C.CL_SUCCESS {
|
|
||||||
buffer := make([]byte, 4096)
|
|
||||||
var bLen C.size_t
|
|
||||||
var err C.cl_int
|
|
||||||
|
|
||||||
for _, dev := range p.devices {
|
|
||||||
for i := 2; i >= 0; i-- {
|
|
||||||
err = C.clGetProgramBuildInfo(p.clProgram, dev.id, C.CL_PROGRAM_BUILD_LOG, C.size_t(len(buffer)), unsafe.Pointer(&buffer[0]), &bLen)
|
|
||||||
if err == C.CL_INVALID_VALUE && i > 0 && bLen < 1024*1024 {
|
|
||||||
// INVALID_VALUE probably means our buffer isn't large enough
|
|
||||||
buffer = make([]byte, bLen)
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return toError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if bLen > 1 {
|
|
||||||
return BuildError{
|
|
||||||
Device: dev,
|
|
||||||
Message: string(buffer[:bLen-1]),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return BuildError{
|
|
||||||
Device: nil,
|
|
||||||
Message: "build failed and produced no log entries",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Program) CreateKernel(name string) (*Kernel, error) {
|
|
||||||
cName := C.CString(name)
|
|
||||||
defer C.free(unsafe.Pointer(cName))
|
|
||||||
var err C.cl_int
|
|
||||||
clKernel := C.clCreateKernel(p.clProgram, cName, &err)
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
kernel := &Kernel{clKernel: clKernel, name: name}
|
|
||||||
runtime.SetFinalizer(kernel, releaseKernel)
|
|
||||||
return kernel, nil
|
|
||||||
}
|
|
||||||
193
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/queue.go
generated
vendored
193
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/queue.go
generated
vendored
@@ -1,193 +0,0 @@
|
|||||||
package cl
|
|
||||||
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
type CommandQueueProperty int
|
|
||||||
|
|
||||||
const (
|
|
||||||
CommandQueueOutOfOrderExecModeEnable CommandQueueProperty = C.CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE
|
|
||||||
CommandQueueProfilingEnable CommandQueueProperty = C.CL_QUEUE_PROFILING_ENABLE
|
|
||||||
)
|
|
||||||
|
|
||||||
type CommandQueue struct {
|
|
||||||
clQueue C.cl_command_queue
|
|
||||||
device *Device
|
|
||||||
}
|
|
||||||
|
|
||||||
func releaseCommandQueue(q *CommandQueue) {
|
|
||||||
if q.clQueue != nil {
|
|
||||||
C.clReleaseCommandQueue(q.clQueue)
|
|
||||||
q.clQueue = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call clReleaseCommandQueue on the CommandQueue. Using the CommandQueue after Release will cause a panick.
|
|
||||||
func (q *CommandQueue) Release() {
|
|
||||||
releaseCommandQueue(q)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Blocks until all previously queued OpenCL commands in a command-queue are issued to the associated device and have completed.
|
|
||||||
func (q *CommandQueue) Finish() error {
|
|
||||||
return toError(C.clFinish(q.clQueue))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Issues all previously queued OpenCL commands in a command-queue to the device associated with the command-queue.
|
|
||||||
func (q *CommandQueue) Flush() error {
|
|
||||||
return toError(C.clFlush(q.clQueue))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enqueues a command to map a region of the buffer object given by buffer into the host address space and returns a pointer to this mapped region.
|
|
||||||
func (q *CommandQueue) EnqueueMapBuffer(buffer *MemObject, blocking bool, flags MapFlag, offset, size int, eventWaitList []*Event) (*MappedMemObject, *Event, error) {
|
|
||||||
var event C.cl_event
|
|
||||||
var err C.cl_int
|
|
||||||
ptr := C.clEnqueueMapBuffer(q.clQueue, buffer.clMem, clBool(blocking), flags.toCl(), C.size_t(offset), C.size_t(size), C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event, &err)
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return nil, nil, toError(err)
|
|
||||||
}
|
|
||||||
ev := newEvent(event)
|
|
||||||
if ptr == nil {
|
|
||||||
return nil, ev, ErrUnknown
|
|
||||||
}
|
|
||||||
return &MappedMemObject{ptr: ptr, size: size}, ev, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enqueues a command to map a region of an image object into the host address space and returns a pointer to this mapped region.
|
|
||||||
func (q *CommandQueue) EnqueueMapImage(buffer *MemObject, blocking bool, flags MapFlag, origin, region [3]int, eventWaitList []*Event) (*MappedMemObject, *Event, error) {
|
|
||||||
cOrigin := sizeT3(origin)
|
|
||||||
cRegion := sizeT3(region)
|
|
||||||
var event C.cl_event
|
|
||||||
var err C.cl_int
|
|
||||||
var rowPitch, slicePitch C.size_t
|
|
||||||
ptr := C.clEnqueueMapImage(q.clQueue, buffer.clMem, clBool(blocking), flags.toCl(), &cOrigin[0], &cRegion[0], &rowPitch, &slicePitch, C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event, &err)
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return nil, nil, toError(err)
|
|
||||||
}
|
|
||||||
ev := newEvent(event)
|
|
||||||
if ptr == nil {
|
|
||||||
return nil, ev, ErrUnknown
|
|
||||||
}
|
|
||||||
size := 0 // TODO: could calculate this
|
|
||||||
return &MappedMemObject{ptr: ptr, size: size, rowPitch: int(rowPitch), slicePitch: int(slicePitch)}, ev, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enqueues a command to unmap a previously mapped region of a memory object.
|
|
||||||
func (q *CommandQueue) EnqueueUnmapMemObject(buffer *MemObject, mappedObj *MappedMemObject, eventWaitList []*Event) (*Event, error) {
|
|
||||||
var event C.cl_event
|
|
||||||
if err := C.clEnqueueUnmapMemObject(q.clQueue, buffer.clMem, mappedObj.ptr, C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event); err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
return newEvent(event), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enqueues a command to copy a buffer object to another buffer object.
|
|
||||||
func (q *CommandQueue) EnqueueCopyBuffer(srcBuffer, dstBuffer *MemObject, srcOffset, dstOffset, byteCount int, eventWaitList []*Event) (*Event, error) {
|
|
||||||
var event C.cl_event
|
|
||||||
err := toError(C.clEnqueueCopyBuffer(q.clQueue, srcBuffer.clMem, dstBuffer.clMem, C.size_t(srcOffset), C.size_t(dstOffset), C.size_t(byteCount), C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event))
|
|
||||||
return newEvent(event), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enqueue commands to write to a buffer object from host memory.
|
|
||||||
func (q *CommandQueue) EnqueueWriteBuffer(buffer *MemObject, blocking bool, offset, dataSize int, dataPtr unsafe.Pointer, eventWaitList []*Event) (*Event, error) {
|
|
||||||
var event C.cl_event
|
|
||||||
err := toError(C.clEnqueueWriteBuffer(q.clQueue, buffer.clMem, clBool(blocking), C.size_t(offset), C.size_t(dataSize), dataPtr, C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event))
|
|
||||||
return newEvent(event), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *CommandQueue) EnqueueWriteBufferFloat32(buffer *MemObject, blocking bool, offset int, data []float32, eventWaitList []*Event) (*Event, error) {
|
|
||||||
dataPtr := unsafe.Pointer(&data[0])
|
|
||||||
dataSize := int(unsafe.Sizeof(data[0])) * len(data)
|
|
||||||
return q.EnqueueWriteBuffer(buffer, blocking, offset, dataSize, dataPtr, eventWaitList)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enqueue commands to read from a buffer object to host memory.
|
|
||||||
func (q *CommandQueue) EnqueueReadBuffer(buffer *MemObject, blocking bool, offset, dataSize int, dataPtr unsafe.Pointer, eventWaitList []*Event) (*Event, error) {
|
|
||||||
var event C.cl_event
|
|
||||||
err := toError(C.clEnqueueReadBuffer(q.clQueue, buffer.clMem, clBool(blocking), C.size_t(offset), C.size_t(dataSize), dataPtr, C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event))
|
|
||||||
return newEvent(event), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *CommandQueue) EnqueueReadBufferFloat32(buffer *MemObject, blocking bool, offset int, data []float32, eventWaitList []*Event) (*Event, error) {
|
|
||||||
dataPtr := unsafe.Pointer(&data[0])
|
|
||||||
dataSize := int(unsafe.Sizeof(data[0])) * len(data)
|
|
||||||
return q.EnqueueReadBuffer(buffer, blocking, offset, dataSize, dataPtr, eventWaitList)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enqueues a command to execute a kernel on a device.
|
|
||||||
func (q *CommandQueue) EnqueueNDRangeKernel(kernel *Kernel, globalWorkOffset, globalWorkSize, localWorkSize []int, eventWaitList []*Event) (*Event, error) {
|
|
||||||
workDim := len(globalWorkSize)
|
|
||||||
var globalWorkOffsetList []C.size_t
|
|
||||||
var globalWorkOffsetPtr *C.size_t
|
|
||||||
if globalWorkOffset != nil {
|
|
||||||
globalWorkOffsetList = make([]C.size_t, len(globalWorkOffset))
|
|
||||||
for i, off := range globalWorkOffset {
|
|
||||||
globalWorkOffsetList[i] = C.size_t(off)
|
|
||||||
}
|
|
||||||
globalWorkOffsetPtr = &globalWorkOffsetList[0]
|
|
||||||
}
|
|
||||||
var globalWorkSizeList []C.size_t
|
|
||||||
var globalWorkSizePtr *C.size_t
|
|
||||||
if globalWorkSize != nil {
|
|
||||||
globalWorkSizeList = make([]C.size_t, len(globalWorkSize))
|
|
||||||
for i, off := range globalWorkSize {
|
|
||||||
globalWorkSizeList[i] = C.size_t(off)
|
|
||||||
}
|
|
||||||
globalWorkSizePtr = &globalWorkSizeList[0]
|
|
||||||
}
|
|
||||||
var localWorkSizeList []C.size_t
|
|
||||||
var localWorkSizePtr *C.size_t
|
|
||||||
if localWorkSize != nil {
|
|
||||||
localWorkSizeList = make([]C.size_t, len(localWorkSize))
|
|
||||||
for i, off := range localWorkSize {
|
|
||||||
localWorkSizeList[i] = C.size_t(off)
|
|
||||||
}
|
|
||||||
localWorkSizePtr = &localWorkSizeList[0]
|
|
||||||
}
|
|
||||||
var event C.cl_event
|
|
||||||
err := toError(C.clEnqueueNDRangeKernel(q.clQueue, kernel.clKernel, C.cl_uint(workDim), globalWorkOffsetPtr, globalWorkSizePtr, localWorkSizePtr, C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event))
|
|
||||||
return newEvent(event), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enqueues a command to read from a 2D or 3D image object to host memory.
|
|
||||||
func (q *CommandQueue) EnqueueReadImage(image *MemObject, blocking bool, origin, region [3]int, rowPitch, slicePitch int, data []byte, eventWaitList []*Event) (*Event, error) {
|
|
||||||
cOrigin := sizeT3(origin)
|
|
||||||
cRegion := sizeT3(region)
|
|
||||||
var event C.cl_event
|
|
||||||
err := toError(C.clEnqueueReadImage(q.clQueue, image.clMem, clBool(blocking), &cOrigin[0], &cRegion[0], C.size_t(rowPitch), C.size_t(slicePitch), unsafe.Pointer(&data[0]), C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event))
|
|
||||||
return newEvent(event), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enqueues a command to write from a 2D or 3D image object to host memory.
|
|
||||||
func (q *CommandQueue) EnqueueWriteImage(image *MemObject, blocking bool, origin, region [3]int, rowPitch, slicePitch int, data []byte, eventWaitList []*Event) (*Event, error) {
|
|
||||||
cOrigin := sizeT3(origin)
|
|
||||||
cRegion := sizeT3(region)
|
|
||||||
var event C.cl_event
|
|
||||||
err := toError(C.clEnqueueWriteImage(q.clQueue, image.clMem, clBool(blocking), &cOrigin[0], &cRegion[0], C.size_t(rowPitch), C.size_t(slicePitch), unsafe.Pointer(&data[0]), C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event))
|
|
||||||
return newEvent(event), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *CommandQueue) EnqueueFillBuffer(buffer *MemObject, pattern unsafe.Pointer, patternSize, offset, size int, eventWaitList []*Event) (*Event, error) {
|
|
||||||
var event C.cl_event
|
|
||||||
err := toError(C.clEnqueueFillBuffer(q.clQueue, buffer.clMem, pattern, C.size_t(patternSize), C.size_t(offset), C.size_t(size), C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event))
|
|
||||||
return newEvent(event), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// A synchronization point that enqueues a barrier operation.
|
|
||||||
func (q *CommandQueue) EnqueueBarrierWithWaitList(eventWaitList []*Event) (*Event, error) {
|
|
||||||
var event C.cl_event
|
|
||||||
err := toError(C.clEnqueueBarrierWithWaitList(q.clQueue, C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event))
|
|
||||||
return newEvent(event), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enqueues a marker command which waits for either a list of events to complete, or all previously enqueued commands to complete.
|
|
||||||
func (q *CommandQueue) EnqueueMarkerWithWaitList(eventWaitList []*Event) (*Event, error) {
|
|
||||||
var event C.cl_event
|
|
||||||
err := toError(C.clEnqueueMarkerWithWaitList(q.clQueue, C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event))
|
|
||||||
return newEvent(event), err
|
|
||||||
}
|
|
||||||
487
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/types.go
generated
vendored
487
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/types.go
generated
vendored
@@ -1,487 +0,0 @@
|
|||||||
package cl
|
|
||||||
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrUnknown = errors.New("cl: unknown error") // Generally an unexpected result from an OpenCL function (e.g. CL_SUCCESS but null pointer)
|
|
||||||
)
|
|
||||||
|
|
||||||
type ErrOther int
|
|
||||||
|
|
||||||
func (e ErrOther) Error() string {
|
|
||||||
return fmt.Sprintf("cl: error %d", int(e))
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrDeviceNotFound = errors.New("cl: Device Not Found")
|
|
||||||
ErrDeviceNotAvailable = errors.New("cl: Device Not Available")
|
|
||||||
ErrCompilerNotAvailable = errors.New("cl: Compiler Not Available")
|
|
||||||
ErrMemObjectAllocationFailure = errors.New("cl: Mem Object Allocation Failure")
|
|
||||||
ErrOutOfResources = errors.New("cl: Out Of Resources")
|
|
||||||
ErrOutOfHostMemory = errors.New("cl: Out Of Host Memory")
|
|
||||||
ErrProfilingInfoNotAvailable = errors.New("cl: Profiling Info Not Available")
|
|
||||||
ErrMemCopyOverlap = errors.New("cl: Mem Copy Overlap")
|
|
||||||
ErrImageFormatMismatch = errors.New("cl: Image Format Mismatch")
|
|
||||||
ErrImageFormatNotSupported = errors.New("cl: Image Format Not Supported")
|
|
||||||
ErrBuildProgramFailure = errors.New("cl: Build Program Failure")
|
|
||||||
ErrMapFailure = errors.New("cl: Map Failure")
|
|
||||||
ErrMisalignedSubBufferOffset = errors.New("cl: Misaligned Sub Buffer Offset")
|
|
||||||
ErrExecStatusErrorForEventsInWaitList = errors.New("cl: Exec Status Error For Events In Wait List")
|
|
||||||
ErrCompileProgramFailure = errors.New("cl: Compile Program Failure")
|
|
||||||
ErrLinkerNotAvailable = errors.New("cl: Linker Not Available")
|
|
||||||
ErrLinkProgramFailure = errors.New("cl: Link Program Failure")
|
|
||||||
ErrDevicePartitionFailed = errors.New("cl: Device Partition Failed")
|
|
||||||
ErrKernelArgInfoNotAvailable = errors.New("cl: Kernel Arg Info Not Available")
|
|
||||||
ErrInvalidValue = errors.New("cl: Invalid Value")
|
|
||||||
ErrInvalidDeviceType = errors.New("cl: Invalid Device Type")
|
|
||||||
ErrInvalidPlatform = errors.New("cl: Invalid Platform")
|
|
||||||
ErrInvalidDevice = errors.New("cl: Invalid Device")
|
|
||||||
ErrInvalidContext = errors.New("cl: Invalid Context")
|
|
||||||
ErrInvalidQueueProperties = errors.New("cl: Invalid Queue Properties")
|
|
||||||
ErrInvalidCommandQueue = errors.New("cl: Invalid Command Queue")
|
|
||||||
ErrInvalidHostPtr = errors.New("cl: Invalid Host Ptr")
|
|
||||||
ErrInvalidMemObject = errors.New("cl: Invalid Mem Object")
|
|
||||||
ErrInvalidImageFormatDescriptor = errors.New("cl: Invalid Image Format Descriptor")
|
|
||||||
ErrInvalidImageSize = errors.New("cl: Invalid Image Size")
|
|
||||||
ErrInvalidSampler = errors.New("cl: Invalid Sampler")
|
|
||||||
ErrInvalidBinary = errors.New("cl: Invalid Binary")
|
|
||||||
ErrInvalidBuildOptions = errors.New("cl: Invalid Build Options")
|
|
||||||
ErrInvalidProgram = errors.New("cl: Invalid Program")
|
|
||||||
ErrInvalidProgramExecutable = errors.New("cl: Invalid Program Executable")
|
|
||||||
ErrInvalidKernelName = errors.New("cl: Invalid Kernel Name")
|
|
||||||
ErrInvalidKernelDefinition = errors.New("cl: Invalid Kernel Definition")
|
|
||||||
ErrInvalidKernel = errors.New("cl: Invalid Kernel")
|
|
||||||
ErrInvalidArgIndex = errors.New("cl: Invalid Arg Index")
|
|
||||||
ErrInvalidArgValue = errors.New("cl: Invalid Arg Value")
|
|
||||||
ErrInvalidArgSize = errors.New("cl: Invalid Arg Size")
|
|
||||||
ErrInvalidKernelArgs = errors.New("cl: Invalid Kernel Args")
|
|
||||||
ErrInvalidWorkDimension = errors.New("cl: Invalid Work Dimension")
|
|
||||||
ErrInvalidWorkGroupSize = errors.New("cl: Invalid Work Group Size")
|
|
||||||
ErrInvalidWorkItemSize = errors.New("cl: Invalid Work Item Size")
|
|
||||||
ErrInvalidGlobalOffset = errors.New("cl: Invalid Global Offset")
|
|
||||||
ErrInvalidEventWaitList = errors.New("cl: Invalid Event Wait List")
|
|
||||||
ErrInvalidEvent = errors.New("cl: Invalid Event")
|
|
||||||
ErrInvalidOperation = errors.New("cl: Invalid Operation")
|
|
||||||
ErrInvalidGlObject = errors.New("cl: Invalid Gl Object")
|
|
||||||
ErrInvalidBufferSize = errors.New("cl: Invalid Buffer Size")
|
|
||||||
ErrInvalidMipLevel = errors.New("cl: Invalid Mip Level")
|
|
||||||
ErrInvalidGlobalWorkSize = errors.New("cl: Invalid Global Work Size")
|
|
||||||
ErrInvalidProperty = errors.New("cl: Invalid Property")
|
|
||||||
ErrInvalidImageDescriptor = errors.New("cl: Invalid Image Descriptor")
|
|
||||||
ErrInvalidCompilerOptions = errors.New("cl: Invalid Compiler Options")
|
|
||||||
ErrInvalidLinkerOptions = errors.New("cl: Invalid Linker Options")
|
|
||||||
ErrInvalidDevicePartitionCount = errors.New("cl: Invalid Device Partition Count")
|
|
||||||
)
|
|
||||||
var errorMap = map[C.cl_int]error{
|
|
||||||
C.CL_SUCCESS: nil,
|
|
||||||
C.CL_DEVICE_NOT_FOUND: ErrDeviceNotFound,
|
|
||||||
C.CL_DEVICE_NOT_AVAILABLE: ErrDeviceNotAvailable,
|
|
||||||
C.CL_COMPILER_NOT_AVAILABLE: ErrCompilerNotAvailable,
|
|
||||||
C.CL_MEM_OBJECT_ALLOCATION_FAILURE: ErrMemObjectAllocationFailure,
|
|
||||||
C.CL_OUT_OF_RESOURCES: ErrOutOfResources,
|
|
||||||
C.CL_OUT_OF_HOST_MEMORY: ErrOutOfHostMemory,
|
|
||||||
C.CL_PROFILING_INFO_NOT_AVAILABLE: ErrProfilingInfoNotAvailable,
|
|
||||||
C.CL_MEM_COPY_OVERLAP: ErrMemCopyOverlap,
|
|
||||||
C.CL_IMAGE_FORMAT_MISMATCH: ErrImageFormatMismatch,
|
|
||||||
C.CL_IMAGE_FORMAT_NOT_SUPPORTED: ErrImageFormatNotSupported,
|
|
||||||
C.CL_BUILD_PROGRAM_FAILURE: ErrBuildProgramFailure,
|
|
||||||
C.CL_MAP_FAILURE: ErrMapFailure,
|
|
||||||
C.CL_MISALIGNED_SUB_BUFFER_OFFSET: ErrMisalignedSubBufferOffset,
|
|
||||||
C.CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST: ErrExecStatusErrorForEventsInWaitList,
|
|
||||||
C.CL_INVALID_VALUE: ErrInvalidValue,
|
|
||||||
C.CL_INVALID_DEVICE_TYPE: ErrInvalidDeviceType,
|
|
||||||
C.CL_INVALID_PLATFORM: ErrInvalidPlatform,
|
|
||||||
C.CL_INVALID_DEVICE: ErrInvalidDevice,
|
|
||||||
C.CL_INVALID_CONTEXT: ErrInvalidContext,
|
|
||||||
C.CL_INVALID_QUEUE_PROPERTIES: ErrInvalidQueueProperties,
|
|
||||||
C.CL_INVALID_COMMAND_QUEUE: ErrInvalidCommandQueue,
|
|
||||||
C.CL_INVALID_HOST_PTR: ErrInvalidHostPtr,
|
|
||||||
C.CL_INVALID_MEM_OBJECT: ErrInvalidMemObject,
|
|
||||||
C.CL_INVALID_IMAGE_FORMAT_DESCRIPTOR: ErrInvalidImageFormatDescriptor,
|
|
||||||
C.CL_INVALID_IMAGE_SIZE: ErrInvalidImageSize,
|
|
||||||
C.CL_INVALID_SAMPLER: ErrInvalidSampler,
|
|
||||||
C.CL_INVALID_BINARY: ErrInvalidBinary,
|
|
||||||
C.CL_INVALID_BUILD_OPTIONS: ErrInvalidBuildOptions,
|
|
||||||
C.CL_INVALID_PROGRAM: ErrInvalidProgram,
|
|
||||||
C.CL_INVALID_PROGRAM_EXECUTABLE: ErrInvalidProgramExecutable,
|
|
||||||
C.CL_INVALID_KERNEL_NAME: ErrInvalidKernelName,
|
|
||||||
C.CL_INVALID_KERNEL_DEFINITION: ErrInvalidKernelDefinition,
|
|
||||||
C.CL_INVALID_KERNEL: ErrInvalidKernel,
|
|
||||||
C.CL_INVALID_ARG_INDEX: ErrInvalidArgIndex,
|
|
||||||
C.CL_INVALID_ARG_VALUE: ErrInvalidArgValue,
|
|
||||||
C.CL_INVALID_ARG_SIZE: ErrInvalidArgSize,
|
|
||||||
C.CL_INVALID_KERNEL_ARGS: ErrInvalidKernelArgs,
|
|
||||||
C.CL_INVALID_WORK_DIMENSION: ErrInvalidWorkDimension,
|
|
||||||
C.CL_INVALID_WORK_GROUP_SIZE: ErrInvalidWorkGroupSize,
|
|
||||||
C.CL_INVALID_WORK_ITEM_SIZE: ErrInvalidWorkItemSize,
|
|
||||||
C.CL_INVALID_GLOBAL_OFFSET: ErrInvalidGlobalOffset,
|
|
||||||
C.CL_INVALID_EVENT_WAIT_LIST: ErrInvalidEventWaitList,
|
|
||||||
C.CL_INVALID_EVENT: ErrInvalidEvent,
|
|
||||||
C.CL_INVALID_OPERATION: ErrInvalidOperation,
|
|
||||||
C.CL_INVALID_GL_OBJECT: ErrInvalidGlObject,
|
|
||||||
C.CL_INVALID_BUFFER_SIZE: ErrInvalidBufferSize,
|
|
||||||
C.CL_INVALID_MIP_LEVEL: ErrInvalidMipLevel,
|
|
||||||
C.CL_INVALID_GLOBAL_WORK_SIZE: ErrInvalidGlobalWorkSize,
|
|
||||||
C.CL_INVALID_PROPERTY: ErrInvalidProperty,
|
|
||||||
}
|
|
||||||
|
|
||||||
func toError(code C.cl_int) error {
|
|
||||||
if err, ok := errorMap[code]; ok {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return ErrOther(code)
|
|
||||||
}
|
|
||||||
|
|
||||||
type LocalMemType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
LocalMemTypeNone LocalMemType = C.CL_NONE
|
|
||||||
LocalMemTypeGlobal LocalMemType = C.CL_GLOBAL
|
|
||||||
LocalMemTypeLocal LocalMemType = C.CL_LOCAL
|
|
||||||
)
|
|
||||||
|
|
||||||
var localMemTypeMap = map[LocalMemType]string{
|
|
||||||
LocalMemTypeNone: "None",
|
|
||||||
LocalMemTypeGlobal: "Global",
|
|
||||||
LocalMemTypeLocal: "Local",
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t LocalMemType) String() string {
|
|
||||||
name := localMemTypeMap[t]
|
|
||||||
if name == "" {
|
|
||||||
name = "Unknown"
|
|
||||||
}
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
type ExecCapability int
|
|
||||||
|
|
||||||
const (
|
|
||||||
ExecCapabilityKernel ExecCapability = C.CL_EXEC_KERNEL // The OpenCL device can execute OpenCL kernels.
|
|
||||||
ExecCapabilityNativeKernel ExecCapability = C.CL_EXEC_NATIVE_KERNEL // The OpenCL device can execute native kernels.
|
|
||||||
)
|
|
||||||
|
|
||||||
func (ec ExecCapability) String() string {
|
|
||||||
var parts []string
|
|
||||||
if ec&ExecCapabilityKernel != 0 {
|
|
||||||
parts = append(parts, "Kernel")
|
|
||||||
}
|
|
||||||
if ec&ExecCapabilityNativeKernel != 0 {
|
|
||||||
parts = append(parts, "NativeKernel")
|
|
||||||
}
|
|
||||||
if parts == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return strings.Join(parts, "|")
|
|
||||||
}
|
|
||||||
|
|
||||||
type MemCacheType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
MemCacheTypeNone MemCacheType = C.CL_NONE
|
|
||||||
MemCacheTypeReadOnlyCache MemCacheType = C.CL_READ_ONLY_CACHE
|
|
||||||
MemCacheTypeReadWriteCache MemCacheType = C.CL_READ_WRITE_CACHE
|
|
||||||
)
|
|
||||||
|
|
||||||
func (ct MemCacheType) String() string {
|
|
||||||
switch ct {
|
|
||||||
case MemCacheTypeNone:
|
|
||||||
return "None"
|
|
||||||
case MemCacheTypeReadOnlyCache:
|
|
||||||
return "ReadOnly"
|
|
||||||
case MemCacheTypeReadWriteCache:
|
|
||||||
return "ReadWrite"
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("Unknown(%x)", int(ct))
|
|
||||||
}
|
|
||||||
|
|
||||||
type MemFlag int
|
|
||||||
|
|
||||||
const (
|
|
||||||
MemReadWrite MemFlag = C.CL_MEM_READ_WRITE
|
|
||||||
MemWriteOnly MemFlag = C.CL_MEM_WRITE_ONLY
|
|
||||||
MemReadOnly MemFlag = C.CL_MEM_READ_ONLY
|
|
||||||
MemUseHostPtr MemFlag = C.CL_MEM_USE_HOST_PTR
|
|
||||||
MemAllocHostPtr MemFlag = C.CL_MEM_ALLOC_HOST_PTR
|
|
||||||
MemCopyHostPtr MemFlag = C.CL_MEM_COPY_HOST_PTR
|
|
||||||
|
|
||||||
MemWriteOnlyHost MemFlag = C.CL_MEM_HOST_WRITE_ONLY
|
|
||||||
MemReadOnlyHost MemFlag = C.CL_MEM_HOST_READ_ONLY
|
|
||||||
MemNoAccessHost MemFlag = C.CL_MEM_HOST_NO_ACCESS
|
|
||||||
)
|
|
||||||
|
|
||||||
type MemObjectType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
MemObjectTypeBuffer MemObjectType = C.CL_MEM_OBJECT_BUFFER
|
|
||||||
MemObjectTypeImage2D MemObjectType = C.CL_MEM_OBJECT_IMAGE2D
|
|
||||||
MemObjectTypeImage3D MemObjectType = C.CL_MEM_OBJECT_IMAGE3D
|
|
||||||
)
|
|
||||||
|
|
||||||
type MapFlag int
|
|
||||||
|
|
||||||
const (
|
|
||||||
// This flag specifies that the region being mapped in the memory object is being mapped for reading.
|
|
||||||
MapFlagRead MapFlag = C.CL_MAP_READ
|
|
||||||
MapFlagWrite MapFlag = C.CL_MAP_WRITE
|
|
||||||
MapFlagWriteInvalidateRegion MapFlag = C.CL_MAP_WRITE_INVALIDATE_REGION
|
|
||||||
)
|
|
||||||
|
|
||||||
func (mf MapFlag) toCl() C.cl_map_flags {
|
|
||||||
return C.cl_map_flags(mf)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ChannelOrder int
|
|
||||||
|
|
||||||
const (
|
|
||||||
ChannelOrderR ChannelOrder = C.CL_R
|
|
||||||
ChannelOrderA ChannelOrder = C.CL_A
|
|
||||||
ChannelOrderRG ChannelOrder = C.CL_RG
|
|
||||||
ChannelOrderRA ChannelOrder = C.CL_RA
|
|
||||||
ChannelOrderRGB ChannelOrder = C.CL_RGB
|
|
||||||
ChannelOrderRGBA ChannelOrder = C.CL_RGBA
|
|
||||||
ChannelOrderBGRA ChannelOrder = C.CL_BGRA
|
|
||||||
ChannelOrderARGB ChannelOrder = C.CL_ARGB
|
|
||||||
ChannelOrderIntensity ChannelOrder = C.CL_INTENSITY
|
|
||||||
ChannelOrderLuminance ChannelOrder = C.CL_LUMINANCE
|
|
||||||
ChannelOrderRx ChannelOrder = C.CL_Rx
|
|
||||||
ChannelOrderRGx ChannelOrder = C.CL_RGx
|
|
||||||
ChannelOrderRGBx ChannelOrder = C.CL_RGBx
|
|
||||||
)
|
|
||||||
|
|
||||||
var channelOrderNameMap = map[ChannelOrder]string{
|
|
||||||
ChannelOrderR: "R",
|
|
||||||
ChannelOrderA: "A",
|
|
||||||
ChannelOrderRG: "RG",
|
|
||||||
ChannelOrderRA: "RA",
|
|
||||||
ChannelOrderRGB: "RGB",
|
|
||||||
ChannelOrderRGBA: "RGBA",
|
|
||||||
ChannelOrderBGRA: "BGRA",
|
|
||||||
ChannelOrderARGB: "ARGB",
|
|
||||||
ChannelOrderIntensity: "Intensity",
|
|
||||||
ChannelOrderLuminance: "Luminance",
|
|
||||||
ChannelOrderRx: "Rx",
|
|
||||||
ChannelOrderRGx: "RGx",
|
|
||||||
ChannelOrderRGBx: "RGBx",
|
|
||||||
}
|
|
||||||
|
|
||||||
func (co ChannelOrder) String() string {
|
|
||||||
name := channelOrderNameMap[co]
|
|
||||||
if name == "" {
|
|
||||||
name = fmt.Sprintf("Unknown(%x)", int(co))
|
|
||||||
}
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
type ChannelDataType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
ChannelDataTypeSNormInt8 ChannelDataType = C.CL_SNORM_INT8
|
|
||||||
ChannelDataTypeSNormInt16 ChannelDataType = C.CL_SNORM_INT16
|
|
||||||
ChannelDataTypeUNormInt8 ChannelDataType = C.CL_UNORM_INT8
|
|
||||||
ChannelDataTypeUNormInt16 ChannelDataType = C.CL_UNORM_INT16
|
|
||||||
ChannelDataTypeUNormShort565 ChannelDataType = C.CL_UNORM_SHORT_565
|
|
||||||
ChannelDataTypeUNormShort555 ChannelDataType = C.CL_UNORM_SHORT_555
|
|
||||||
ChannelDataTypeUNormInt101010 ChannelDataType = C.CL_UNORM_INT_101010
|
|
||||||
ChannelDataTypeSignedInt8 ChannelDataType = C.CL_SIGNED_INT8
|
|
||||||
ChannelDataTypeSignedInt16 ChannelDataType = C.CL_SIGNED_INT16
|
|
||||||
ChannelDataTypeSignedInt32 ChannelDataType = C.CL_SIGNED_INT32
|
|
||||||
ChannelDataTypeUnsignedInt8 ChannelDataType = C.CL_UNSIGNED_INT8
|
|
||||||
ChannelDataTypeUnsignedInt16 ChannelDataType = C.CL_UNSIGNED_INT16
|
|
||||||
ChannelDataTypeUnsignedInt32 ChannelDataType = C.CL_UNSIGNED_INT32
|
|
||||||
ChannelDataTypeHalfFloat ChannelDataType = C.CL_HALF_FLOAT
|
|
||||||
ChannelDataTypeFloat ChannelDataType = C.CL_FLOAT
|
|
||||||
)
|
|
||||||
|
|
||||||
var channelDataTypeNameMap = map[ChannelDataType]string{
|
|
||||||
ChannelDataTypeSNormInt8: "SNormInt8",
|
|
||||||
ChannelDataTypeSNormInt16: "SNormInt16",
|
|
||||||
ChannelDataTypeUNormInt8: "UNormInt8",
|
|
||||||
ChannelDataTypeUNormInt16: "UNormInt16",
|
|
||||||
ChannelDataTypeUNormShort565: "UNormShort565",
|
|
||||||
ChannelDataTypeUNormShort555: "UNormShort555",
|
|
||||||
ChannelDataTypeUNormInt101010: "UNormInt101010",
|
|
||||||
ChannelDataTypeSignedInt8: "SignedInt8",
|
|
||||||
ChannelDataTypeSignedInt16: "SignedInt16",
|
|
||||||
ChannelDataTypeSignedInt32: "SignedInt32",
|
|
||||||
ChannelDataTypeUnsignedInt8: "UnsignedInt8",
|
|
||||||
ChannelDataTypeUnsignedInt16: "UnsignedInt16",
|
|
||||||
ChannelDataTypeUnsignedInt32: "UnsignedInt32",
|
|
||||||
ChannelDataTypeHalfFloat: "HalfFloat",
|
|
||||||
ChannelDataTypeFloat: "Float",
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ct ChannelDataType) String() string {
|
|
||||||
name := channelDataTypeNameMap[ct]
|
|
||||||
if name == "" {
|
|
||||||
name = fmt.Sprintf("Unknown(%x)", int(ct))
|
|
||||||
}
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
type ImageFormat struct {
|
|
||||||
ChannelOrder ChannelOrder
|
|
||||||
ChannelDataType ChannelDataType
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f ImageFormat) toCl() C.cl_image_format {
|
|
||||||
var format C.cl_image_format
|
|
||||||
format.image_channel_order = C.cl_channel_order(f.ChannelOrder)
|
|
||||||
format.image_channel_data_type = C.cl_channel_type(f.ChannelDataType)
|
|
||||||
return format
|
|
||||||
}
|
|
||||||
|
|
||||||
type ProfilingInfo int
|
|
||||||
|
|
||||||
const (
|
|
||||||
// A 64-bit value that describes the current device time counter in
|
|
||||||
// nanoseconds when the command identified by event is enqueued in
|
|
||||||
// a command-queue by the host.
|
|
||||||
ProfilingInfoCommandQueued ProfilingInfo = C.CL_PROFILING_COMMAND_QUEUED
|
|
||||||
// A 64-bit value that describes the current device time counter in
|
|
||||||
// nanoseconds when the command identified by event that has been
|
|
||||||
// enqueued is submitted by the host to the device associated with the command-queue.
|
|
||||||
ProfilingInfoCommandSubmit ProfilingInfo = C.CL_PROFILING_COMMAND_SUBMIT
|
|
||||||
// A 64-bit value that describes the current device time counter in
|
|
||||||
// nanoseconds when the command identified by event starts execution on the device.
|
|
||||||
ProfilingInfoCommandStart ProfilingInfo = C.CL_PROFILING_COMMAND_START
|
|
||||||
// A 64-bit value that describes the current device time counter in
|
|
||||||
// nanoseconds when the command identified by event has finished
|
|
||||||
// execution on the device.
|
|
||||||
ProfilingInfoCommandEnd ProfilingInfo = C.CL_PROFILING_COMMAND_END
|
|
||||||
)
|
|
||||||
|
|
||||||
type CommmandExecStatus int
|
|
||||||
|
|
||||||
const (
|
|
||||||
CommmandExecStatusComplete CommmandExecStatus = C.CL_COMPLETE
|
|
||||||
CommmandExecStatusRunning CommmandExecStatus = C.CL_RUNNING
|
|
||||||
CommmandExecStatusSubmitted CommmandExecStatus = C.CL_SUBMITTED
|
|
||||||
CommmandExecStatusQueued CommmandExecStatus = C.CL_QUEUED
|
|
||||||
)
|
|
||||||
|
|
||||||
type Event struct {
|
|
||||||
clEvent C.cl_event
|
|
||||||
}
|
|
||||||
|
|
||||||
func releaseEvent(ev *Event) {
|
|
||||||
if ev.clEvent != nil {
|
|
||||||
C.clReleaseEvent(ev.clEvent)
|
|
||||||
ev.clEvent = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Event) Release() {
|
|
||||||
releaseEvent(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Event) GetEventProfilingInfo(paramName ProfilingInfo) (int64, error) {
|
|
||||||
var paramValue C.cl_ulong
|
|
||||||
if err := C.clGetEventProfilingInfo(e.clEvent, C.cl_profiling_info(paramName), C.size_t(unsafe.Sizeof(paramValue)), unsafe.Pointer(¶mValue), nil); err != C.CL_SUCCESS {
|
|
||||||
return 0, toError(err)
|
|
||||||
}
|
|
||||||
return int64(paramValue), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets the execution status of a user event object.
|
|
||||||
//
|
|
||||||
// `status` specifies the new execution status to be set and
|
|
||||||
// can be CL_COMPLETE or a negative integer value to indicate
|
|
||||||
// an error. A negative integer value causes all enqueued commands
|
|
||||||
// that wait on this user event to be terminated. clSetUserEventStatus
|
|
||||||
// can only be called once to change the execution status of event.
|
|
||||||
func (e *Event) SetUserEventStatus(status int) error {
|
|
||||||
return toError(C.clSetUserEventStatus(e.clEvent, C.cl_int(status)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Waits on the host thread for commands identified by event objects in
|
|
||||||
// events to complete. A command is considered complete if its execution
|
|
||||||
// status is CL_COMPLETE or a negative value. The events specified in
|
|
||||||
// event_list act as synchronization points.
|
|
||||||
//
|
|
||||||
// If the cl_khr_gl_event extension is enabled, event objects can also be
|
|
||||||
// used to reflect the status of an OpenGL sync object. The sync object
|
|
||||||
// in turn refers to a fence command executing in an OpenGL command
|
|
||||||
// stream. This provides another method of coordinating sharing of buffers
|
|
||||||
// and images between OpenGL and OpenCL.
|
|
||||||
func WaitForEvents(events []*Event) error {
|
|
||||||
return toError(C.clWaitForEvents(C.cl_uint(len(events)), eventListPtr(events)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func newEvent(clEvent C.cl_event) *Event {
|
|
||||||
ev := &Event{clEvent: clEvent}
|
|
||||||
runtime.SetFinalizer(ev, releaseEvent)
|
|
||||||
return ev
|
|
||||||
}
|
|
||||||
|
|
||||||
func eventListPtr(el []*Event) *C.cl_event {
|
|
||||||
if el == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
elist := make([]C.cl_event, len(el))
|
|
||||||
for i, e := range el {
|
|
||||||
elist[i] = e.clEvent
|
|
||||||
}
|
|
||||||
return (*C.cl_event)(&elist[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
func clBool(b bool) C.cl_bool {
|
|
||||||
if b {
|
|
||||||
return C.CL_TRUE
|
|
||||||
}
|
|
||||||
return C.CL_FALSE
|
|
||||||
}
|
|
||||||
|
|
||||||
func sizeT3(i3 [3]int) [3]C.size_t {
|
|
||||||
var val [3]C.size_t
|
|
||||||
val[0] = C.size_t(i3[0])
|
|
||||||
val[1] = C.size_t(i3[1])
|
|
||||||
val[2] = C.size_t(i3[2])
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
type MappedMemObject struct {
|
|
||||||
ptr unsafe.Pointer
|
|
||||||
size int
|
|
||||||
rowPitch int
|
|
||||||
slicePitch int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mb *MappedMemObject) ByteSlice() []byte {
|
|
||||||
var byteSlice []byte
|
|
||||||
sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&byteSlice))
|
|
||||||
sliceHeader.Cap = mb.size
|
|
||||||
sliceHeader.Len = mb.size
|
|
||||||
sliceHeader.Data = uintptr(mb.ptr)
|
|
||||||
return byteSlice
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mb *MappedMemObject) Ptr() unsafe.Pointer {
|
|
||||||
return mb.ptr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mb *MappedMemObject) Size() int {
|
|
||||||
return mb.size
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mb *MappedMemObject) RowPitch() int {
|
|
||||||
return mb.rowPitch
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mb *MappedMemObject) SlicePitch() int {
|
|
||||||
return mb.slicePitch
|
|
||||||
}
|
|
||||||
71
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/types12.go
generated
vendored
71
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/types12.go
generated
vendored
@@ -1,71 +0,0 @@
|
|||||||
// +build cl12
|
|
||||||
|
|
||||||
package cl
|
|
||||||
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
const (
|
|
||||||
ChannelDataTypeUNormInt24 ChannelDataType = C.CL_UNORM_INT24
|
|
||||||
ChannelOrderDepth ChannelOrder = C.CL_DEPTH
|
|
||||||
ChannelOrderDepthStencil ChannelOrder = C.CL_DEPTH_STENCIL
|
|
||||||
MemHostNoAccess MemFlag = C.CL_MEM_HOST_NO_ACCESS // OpenCL 1.2
|
|
||||||
MemHostReadOnly MemFlag = C.CL_MEM_HOST_READ_ONLY // OpenCL 1.2
|
|
||||||
MemHostWriteOnly MemFlag = C.CL_MEM_HOST_WRITE_ONLY // OpenCL 1.2
|
|
||||||
MemObjectTypeImage1D MemObjectType = C.CL_MEM_OBJECT_IMAGE1D
|
|
||||||
MemObjectTypeImage1DArray MemObjectType = C.CL_MEM_OBJECT_IMAGE1D_ARRAY
|
|
||||||
MemObjectTypeImage1DBuffer MemObjectType = C.CL_MEM_OBJECT_IMAGE1D_BUFFER
|
|
||||||
MemObjectTypeImage2DArray MemObjectType = C.CL_MEM_OBJECT_IMAGE2D_ARRAY
|
|
||||||
// This flag specifies that the region being mapped in the memory object is being mapped for writing.
|
|
||||||
//
|
|
||||||
// The contents of the region being mapped are to be discarded. This is typically the case when the
|
|
||||||
// region being mapped is overwritten by the host. This flag allows the implementation to no longer
|
|
||||||
// guarantee that the pointer returned by clEnqueueMapBuffer or clEnqueueMapImage contains the
|
|
||||||
// latest bits in the region being mapped which can be a significant performance enhancement.
|
|
||||||
MapFlagWriteInvalidateRegion MapFlag = C.CL_MAP_WRITE_INVALIDATE_REGION
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
errorMap[C.CL_COMPILE_PROGRAM_FAILURE] = ErrCompileProgramFailure
|
|
||||||
errorMap[C.CL_DEVICE_PARTITION_FAILED] = ErrDevicePartitionFailed
|
|
||||||
errorMap[C.CL_INVALID_COMPILER_OPTIONS] = ErrInvalidCompilerOptions
|
|
||||||
errorMap[C.CL_INVALID_DEVICE_PARTITION_COUNT] = ErrInvalidDevicePartitionCount
|
|
||||||
errorMap[C.CL_INVALID_IMAGE_DESCRIPTOR] = ErrInvalidImageDescriptor
|
|
||||||
errorMap[C.CL_INVALID_LINKER_OPTIONS] = ErrInvalidLinkerOptions
|
|
||||||
errorMap[C.CL_KERNEL_ARG_INFO_NOT_AVAILABLE] = ErrKernelArgInfoNotAvailable
|
|
||||||
errorMap[C.CL_LINK_PROGRAM_FAILURE] = ErrLinkProgramFailure
|
|
||||||
errorMap[C.CL_LINKER_NOT_AVAILABLE] = ErrLinkerNotAvailable
|
|
||||||
channelOrderNameMap[ChannelOrderDepth] = "Depth"
|
|
||||||
channelOrderNameMap[ChannelOrderDepthStencil] = "DepthStencil"
|
|
||||||
channelDataTypeNameMap[ChannelDataTypeUNormInt24] = "UNormInt24"
|
|
||||||
}
|
|
||||||
|
|
||||||
type ImageDescription struct {
|
|
||||||
Type MemObjectType
|
|
||||||
Width, Height, Depth int
|
|
||||||
ArraySize, RowPitch, SlicePitch int
|
|
||||||
NumMipLevels, NumSamples int
|
|
||||||
Buffer *MemObject
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d ImageDescription) toCl() C.cl_image_desc {
|
|
||||||
var desc C.cl_image_desc
|
|
||||||
desc.image_type = C.cl_mem_object_type(d.Type)
|
|
||||||
desc.image_width = C.size_t(d.Width)
|
|
||||||
desc.image_height = C.size_t(d.Height)
|
|
||||||
desc.image_depth = C.size_t(d.Depth)
|
|
||||||
desc.image_array_size = C.size_t(d.ArraySize)
|
|
||||||
desc.image_row_pitch = C.size_t(d.RowPitch)
|
|
||||||
desc.image_slice_pitch = C.size_t(d.SlicePitch)
|
|
||||||
desc.num_mip_levels = C.cl_uint(d.NumMipLevels)
|
|
||||||
desc.num_samples = C.cl_uint(d.NumSamples)
|
|
||||||
desc.buffer = nil
|
|
||||||
if d.Buffer != nil {
|
|
||||||
desc.buffer = d.Buffer.clMem
|
|
||||||
}
|
|
||||||
return desc
|
|
||||||
}
|
|
||||||
45
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/types_darwin.go
generated
vendored
45
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/types_darwin.go
generated
vendored
@@ -1,45 +0,0 @@
|
|||||||
package cl
|
|
||||||
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
// Extension: cl_APPLE_fixed_alpha_channel_orders
|
|
||||||
//
|
|
||||||
// These selectors may be passed to clCreateImage2D() in the cl_image_format.image_channel_order field.
|
|
||||||
// They are like CL_BGRA and CL_ARGB except that the alpha channel to be ignored. On calls to read_imagef,
|
|
||||||
// the alpha will be 0xff (1.0f) if the sample falls in the image and 0 if it does not fall in the image.
|
|
||||||
// On calls to write_imagef, the alpha value is ignored and 0xff (1.0f) is written. These formats are
|
|
||||||
// currently only available for the CL_UNORM_INT8 cl_channel_type. They are intended to support legacy
|
|
||||||
// image formats.
|
|
||||||
const (
|
|
||||||
ChannelOrder1RGBApple ChannelOrder = C.CL_1RGB_APPLE // Introduced in MacOS X.7.
|
|
||||||
ChannelOrderBGR1Apple ChannelOrder = C.CL_BGR1_APPLE // Introduced in MacOS X.7.
|
|
||||||
)
|
|
||||||
|
|
||||||
// Extension: cl_APPLE_biased_fixed_point_image_formats
|
|
||||||
//
|
|
||||||
// This selector may be passed to clCreateImage2D() in the cl_image_format.image_channel_data_type field.
|
|
||||||
// It defines a biased signed 1.14 fixed point storage format, with range [-1, 3). The conversion from
|
|
||||||
// float to this fixed point format is defined as follows:
|
|
||||||
//
|
|
||||||
// ushort float_to_sfixed14( float x ){
|
|
||||||
// int i = convert_int_sat_rte( x * 0x1.0p14f ); // scale [-1, 3.0) to [-16384, 3*16384), round to nearest integer
|
|
||||||
// i = add_sat( i, 0x4000 ); // apply bias, to convert to [0, 65535) range
|
|
||||||
// return convert_ushort_sat(i); // clamp to destination size
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// The inverse conversion is the reverse process. The formats are currently only available on the CPU with
|
|
||||||
// the CL_RGBA channel layout.
|
|
||||||
const (
|
|
||||||
ChannelDataTypeSFixed14Apple ChannelDataType = C.CL_SFIXED14_APPLE // Introduced in MacOS X.7.
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
channelOrderNameMap[ChannelOrder1RGBApple] = "1RGBApple"
|
|
||||||
channelOrderNameMap[ChannelOrderBGR1Apple] = "RGB1Apple"
|
|
||||||
channelDataTypeNameMap[ChannelDataTypeSFixed14Apple] = "SFixed14Apple"
|
|
||||||
}
|
|
||||||
628
Godeps/_workspace/src/github.com/ethereum/ethash/ethash_opencl.go
generated
vendored
628
Godeps/_workspace/src/github.com/ethereum/ethash/ethash_opencl.go
generated
vendored
@@ -1,628 +0,0 @@
|
|||||||
// Copyright 2014 The go-ethereum Authors
|
|
||||||
// This file is part of the go-ethereum library.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
// +build opencl
|
|
||||||
|
|
||||||
package ethash
|
|
||||||
|
|
||||||
//#cgo LDFLAGS: -w
|
|
||||||
//#include <stdint.h>
|
|
||||||
//#include <string.h>
|
|
||||||
//#include "src/libethash/internal.h"
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import (
|
|
||||||
crand "crypto/rand"
|
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
|
||||||
"math"
|
|
||||||
"math/big"
|
|
||||||
mrand "math/rand"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/Gustav-Simonsson/go-opencl/cl"
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/pow"
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This code have two main entry points:
|
|
||||||
|
|
||||||
1. The initCL(...) function configures one or more OpenCL device
|
|
||||||
(for now only GPU) and loads the Ethash DAG onto device memory
|
|
||||||
|
|
||||||
2. The Search(...) function loads a Ethash nonce into device(s) memory and
|
|
||||||
executes the Ethash OpenCL kernel.
|
|
||||||
|
|
||||||
Throughout the code, we refer to "host memory" and "device memory".
|
|
||||||
For most systems (e.g. regular PC GPU miner) the host memory is RAM and
|
|
||||||
device memory is the GPU global memory (e.g. GDDR5).
|
|
||||||
|
|
||||||
References mentioned in code comments:
|
|
||||||
|
|
||||||
1. https://github.com/ethereum/wiki/wiki/Ethash
|
|
||||||
2. https://github.com/ethereum/cpp-ethereum/blob/develop/libethash-cl/ethash_cl_miner.cpp
|
|
||||||
3. https://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/
|
|
||||||
4. http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/12/AMD_OpenCL_Programming_User_Guide.pdf
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
type OpenCLDevice struct {
|
|
||||||
deviceId int
|
|
||||||
device *cl.Device
|
|
||||||
openCL11 bool // OpenCL version 1.1 and 1.2 are handled a bit different
|
|
||||||
openCL12 bool
|
|
||||||
|
|
||||||
dagBuf *cl.MemObject // Ethash full DAG in device mem
|
|
||||||
headerBuf *cl.MemObject // Hash of block-to-mine in device mem
|
|
||||||
searchBuffers []*cl.MemObject
|
|
||||||
|
|
||||||
searchKernel *cl.Kernel
|
|
||||||
hashKernel *cl.Kernel
|
|
||||||
|
|
||||||
queue *cl.CommandQueue
|
|
||||||
ctx *cl.Context
|
|
||||||
workGroupSize int
|
|
||||||
|
|
||||||
nonceRand *mrand.Rand // seeded by crypto/rand, see comments where it's initialised
|
|
||||||
result common.Hash
|
|
||||||
}
|
|
||||||
|
|
||||||
type OpenCLMiner struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
|
|
||||||
ethash *Ethash // Ethash full DAG & cache in host mem
|
|
||||||
|
|
||||||
deviceIds []int
|
|
||||||
devices []*OpenCLDevice
|
|
||||||
|
|
||||||
dagSize uint64
|
|
||||||
|
|
||||||
hashRate int32 // Go atomics & uint64 have some issues; int32 is supported on all platforms
|
|
||||||
}
|
|
||||||
|
|
||||||
type pendingSearch struct {
|
|
||||||
bufIndex uint32
|
|
||||||
startNonce uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
SIZEOF_UINT32 = 4
|
|
||||||
|
|
||||||
// See [1]
|
|
||||||
ethashMixBytesLen = 128
|
|
||||||
ethashAccesses = 64
|
|
||||||
|
|
||||||
// See [4]
|
|
||||||
workGroupSize = 32 // must be multiple of 8
|
|
||||||
maxSearchResults = 63
|
|
||||||
searchBufSize = 2
|
|
||||||
globalWorkSize = 1024 * 256
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewCL(deviceIds []int) *OpenCLMiner {
|
|
||||||
ids := make([]int, len(deviceIds))
|
|
||||||
copy(ids, deviceIds)
|
|
||||||
return &OpenCLMiner{
|
|
||||||
ethash: New(),
|
|
||||||
dagSize: 0, // to see if we need to update DAG.
|
|
||||||
deviceIds: ids,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PrintDevices() {
|
|
||||||
fmt.Println("=============================================")
|
|
||||||
fmt.Println("============ OpenCL Device Info =============")
|
|
||||||
fmt.Println("=============================================")
|
|
||||||
|
|
||||||
var found []*cl.Device
|
|
||||||
|
|
||||||
platforms, err := cl.GetPlatforms()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Plaform error (check your OpenCL installation):", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, p := range platforms {
|
|
||||||
fmt.Println("Platform id ", i)
|
|
||||||
fmt.Println("Platform Name ", p.Name())
|
|
||||||
fmt.Println("Platform Vendor ", p.Vendor())
|
|
||||||
fmt.Println("Platform Version ", p.Version())
|
|
||||||
fmt.Println("Platform Extensions ", p.Extensions())
|
|
||||||
fmt.Println("Platform Profile ", p.Profile())
|
|
||||||
fmt.Println("")
|
|
||||||
|
|
||||||
devices, err := cl.GetDevices(p, cl.DeviceTypeGPU)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Device error (check your GPU drivers) :", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, d := range devices {
|
|
||||||
fmt.Println("Device OpenCL id ", i)
|
|
||||||
fmt.Println("Device id for mining ", len(found))
|
|
||||||
fmt.Println("Device Name ", d.Name())
|
|
||||||
fmt.Println("Vendor ", d.Vendor())
|
|
||||||
fmt.Println("Version ", d.Version())
|
|
||||||
fmt.Println("Driver version ", d.DriverVersion())
|
|
||||||
fmt.Println("Address bits ", d.AddressBits())
|
|
||||||
fmt.Println("Max clock freq ", d.MaxClockFrequency())
|
|
||||||
fmt.Println("Global mem size ", d.GlobalMemSize())
|
|
||||||
fmt.Println("Max constant buffer size", d.MaxConstantBufferSize())
|
|
||||||
fmt.Println("Max mem alloc size ", d.MaxMemAllocSize())
|
|
||||||
fmt.Println("Max compute units ", d.MaxComputeUnits())
|
|
||||||
fmt.Println("Max work group size ", d.MaxWorkGroupSize())
|
|
||||||
fmt.Println("Max work item sizes ", d.MaxWorkItemSizes())
|
|
||||||
fmt.Println("=============================================")
|
|
||||||
|
|
||||||
found = append(found, d)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(found) == 0 {
|
|
||||||
fmt.Println("Found no GPU(s). Check that your OS can see the GPU(s)")
|
|
||||||
} else {
|
|
||||||
var idsFormat string
|
|
||||||
for i := 0; i < len(found); i++ {
|
|
||||||
idsFormat += strconv.Itoa(i)
|
|
||||||
if i != len(found)-1 {
|
|
||||||
idsFormat += ","
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fmt.Printf("Found %v devices. Benchmark first GPU: geth gpubench 0\n", len(found))
|
|
||||||
fmt.Printf("Mine using all GPUs: geth --minegpu %v\n", idsFormat)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// See [2]. We basically do the same here, but the Go OpenCL bindings
|
|
||||||
// are at a slightly higher abtraction level.
|
|
||||||
func InitCL(blockNum uint64, c *OpenCLMiner) error {
|
|
||||||
platforms, err := cl.GetPlatforms()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Plaform error: %v\nCheck your OpenCL installation and then run geth gpuinfo", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var devices []*cl.Device
|
|
||||||
for _, p := range platforms {
|
|
||||||
ds, err := cl.GetDevices(p, cl.DeviceTypeGPU)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Devices error: %v\nCheck your GPU drivers and then run geth gpuinfo", err)
|
|
||||||
}
|
|
||||||
for _, d := range ds {
|
|
||||||
devices = append(devices, d)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pow := New()
|
|
||||||
_ = pow.getDAG(blockNum) // generates DAG if we don't have it
|
|
||||||
pow.Light.getCache(blockNum) // and cache
|
|
||||||
|
|
||||||
c.ethash = pow
|
|
||||||
dagSize := uint64(C.ethash_get_datasize(C.uint64_t(blockNum)))
|
|
||||||
c.dagSize = dagSize
|
|
||||||
|
|
||||||
for _, id := range c.deviceIds {
|
|
||||||
if id > len(devices)-1 {
|
|
||||||
return fmt.Errorf("Device id not found. See available device ids with: geth gpuinfo")
|
|
||||||
} else {
|
|
||||||
err := initCLDevice(id, devices[id], c)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(c.devices) == 0 {
|
|
||||||
return fmt.Errorf("No GPU devices found")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func initCLDevice(deviceId int, device *cl.Device, c *OpenCLMiner) error {
|
|
||||||
devMaxAlloc := uint64(device.MaxMemAllocSize())
|
|
||||||
devGlobalMem := uint64(device.GlobalMemSize())
|
|
||||||
|
|
||||||
// TODO: more fine grained version logic
|
|
||||||
if device.Version() == "OpenCL 1.0" {
|
|
||||||
fmt.Println("Device OpenCL version not supported: ", device.Version())
|
|
||||||
return fmt.Errorf("opencl version not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
var cl11, cl12 bool
|
|
||||||
if device.Version() == "OpenCL 1.1" {
|
|
||||||
cl11 = true
|
|
||||||
}
|
|
||||||
if device.Version() == "OpenCL 1.2" {
|
|
||||||
cl12 = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// log warnings but carry on; some device drivers report inaccurate values
|
|
||||||
if c.dagSize > devGlobalMem {
|
|
||||||
fmt.Printf("WARNING: device memory may be insufficient: %v. DAG size: %v.\n", devGlobalMem, c.dagSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.dagSize > devMaxAlloc {
|
|
||||||
fmt.Printf("WARNING: DAG size (%v) larger than device max memory allocation size (%v).\n", c.dagSize, devMaxAlloc)
|
|
||||||
fmt.Printf("You probably have to export GPU_MAX_ALLOC_PERCENT=95\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Initialising device %v: %v\n", deviceId, device.Name())
|
|
||||||
|
|
||||||
context, err := cl.CreateContext([]*cl.Device{device})
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed creating context: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: test running with CL_QUEUE_PROFILING_ENABLE for profiling?
|
|
||||||
queue, err := context.CreateCommandQueue(device, 0)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("command queue err: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// See [4] section 3.2 and [3] "clBuildProgram".
|
|
||||||
// The OpenCL kernel code is compiled at run-time.
|
|
||||||
kvs := make(map[string]string, 4)
|
|
||||||
kvs["GROUP_SIZE"] = strconv.FormatUint(workGroupSize, 10)
|
|
||||||
kvs["DAG_SIZE"] = strconv.FormatUint(c.dagSize/ethashMixBytesLen, 10)
|
|
||||||
kvs["ACCESSES"] = strconv.FormatUint(ethashAccesses, 10)
|
|
||||||
kvs["MAX_OUTPUTS"] = strconv.FormatUint(maxSearchResults, 10)
|
|
||||||
kernelCode := replaceWords(kernel, kvs)
|
|
||||||
|
|
||||||
program, err := context.CreateProgramWithSource([]string{kernelCode})
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("program err: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if using AMD OpenCL impl, you can set this to debug on x86 CPU device.
|
|
||||||
see AMD OpenCL programming guide section 4.2
|
|
||||||
|
|
||||||
export in shell before running:
|
|
||||||
export AMD_OCL_BUILD_OPTIONS_APPEND="-g -O0"
|
|
||||||
export CPU_MAX_COMPUTE_UNITS=1
|
|
||||||
|
|
||||||
buildOpts := "-g -cl-opt-disable"
|
|
||||||
|
|
||||||
*/
|
|
||||||
buildOpts := ""
|
|
||||||
err = program.BuildProgram([]*cl.Device{device}, buildOpts)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("program build err: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var searchKernelName, hashKernelName string
|
|
||||||
searchKernelName = "ethash_search"
|
|
||||||
hashKernelName = "ethash_hash"
|
|
||||||
|
|
||||||
searchKernel, err := program.CreateKernel(searchKernelName)
|
|
||||||
hashKernel, err := program.CreateKernel(hashKernelName)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("kernel err: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: when this DAG size appears, patch the Go bindings
|
|
||||||
// (context.go) to work with uint64 as size_t
|
|
||||||
if c.dagSize > math.MaxInt32 {
|
|
||||||
fmt.Println("DAG too large for allocation.")
|
|
||||||
return fmt.Errorf("DAG too large for alloc")
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: patch up Go bindings to work with size_t, will overflow if > maxint32
|
|
||||||
// TODO: fuck. shit's gonna overflow around 2017-06-09 12:17:02
|
|
||||||
dagBuf := *(new(*cl.MemObject))
|
|
||||||
dagBuf, err = context.CreateEmptyBuffer(cl.MemReadOnly, int(c.dagSize))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("allocating dag buf failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// write DAG to device mem
|
|
||||||
dagPtr := unsafe.Pointer(c.ethash.Full.current.ptr.data)
|
|
||||||
_, err = queue.EnqueueWriteBuffer(dagBuf, true, 0, int(c.dagSize), dagPtr, nil)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("writing to dag buf failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
searchBuffers := make([]*cl.MemObject, searchBufSize)
|
|
||||||
for i := 0; i < searchBufSize; i++ {
|
|
||||||
searchBuff, err := context.CreateEmptyBuffer(cl.MemWriteOnly, (1+maxSearchResults)*SIZEOF_UINT32)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("search buffer err: %v", err)
|
|
||||||
}
|
|
||||||
searchBuffers[i] = searchBuff
|
|
||||||
}
|
|
||||||
|
|
||||||
headerBuf, err := context.CreateEmptyBuffer(cl.MemReadOnly, 32)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("header buffer err: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unique, random nonces are crucial for mining efficieny.
|
|
||||||
// While we do not need cryptographically secure PRNG for nonces,
|
|
||||||
// we want to have uniform distribution and minimal repetition of nonces.
|
|
||||||
// We could guarantee strict uniqueness of nonces by generating unique ranges,
|
|
||||||
// but a int64 seed from crypto/rand should be good enough.
|
|
||||||
// we then use math/rand for speed and to avoid draining OS entropy pool
|
|
||||||
seed, err := crand.Int(crand.Reader, big.NewInt(math.MaxInt64))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
nonceRand := mrand.New(mrand.NewSource(seed.Int64()))
|
|
||||||
|
|
||||||
deviceStruct := &OpenCLDevice{
|
|
||||||
deviceId: deviceId,
|
|
||||||
device: device,
|
|
||||||
openCL11: cl11,
|
|
||||||
openCL12: cl12,
|
|
||||||
|
|
||||||
dagBuf: dagBuf,
|
|
||||||
headerBuf: headerBuf,
|
|
||||||
searchBuffers: searchBuffers,
|
|
||||||
|
|
||||||
searchKernel: searchKernel,
|
|
||||||
hashKernel: hashKernel,
|
|
||||||
|
|
||||||
queue: queue,
|
|
||||||
ctx: context,
|
|
||||||
|
|
||||||
workGroupSize: workGroupSize,
|
|
||||||
|
|
||||||
nonceRand: nonceRand,
|
|
||||||
}
|
|
||||||
c.devices = append(c.devices, deviceStruct)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OpenCLMiner) Search(block pow.Block, stop <-chan struct{}, index int) (uint64, []byte) {
|
|
||||||
c.mu.Lock()
|
|
||||||
newDagSize := uint64(C.ethash_get_datasize(C.uint64_t(block.NumberU64())))
|
|
||||||
if newDagSize > c.dagSize {
|
|
||||||
// TODO: clean up buffers from previous DAG?
|
|
||||||
err := InitCL(block.NumberU64(), c)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("OpenCL init error: ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
defer c.mu.Unlock()
|
|
||||||
|
|
||||||
// Avoid unneeded OpenCL initialisation if we received stop while running InitCL
|
|
||||||
select {
|
|
||||||
case <-stop:
|
|
||||||
return 0, []byte{0}
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
headerHash := block.HashNoNonce()
|
|
||||||
diff := block.Difficulty()
|
|
||||||
target256 := new(big.Int).Div(maxUint256, diff)
|
|
||||||
target64 := new(big.Int).Rsh(target256, 192).Uint64()
|
|
||||||
var zero uint32 = 0
|
|
||||||
|
|
||||||
d := c.devices[index]
|
|
||||||
|
|
||||||
_, err := d.queue.EnqueueWriteBuffer(d.headerBuf, false, 0, 32, unsafe.Pointer(&headerHash[0]), nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clEnqueueWriterBuffer : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < searchBufSize; i++ {
|
|
||||||
_, err := d.queue.EnqueueWriteBuffer(d.searchBuffers[i], false, 0, 4, unsafe.Pointer(&zero), nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clEnqueueWriterBuffer : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait for all search buffers to complete
|
|
||||||
err = d.queue.Finish()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clFinish : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = d.searchKernel.SetArg(1, d.headerBuf)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clSetKernelArg : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = d.searchKernel.SetArg(2, d.dagBuf)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clSetKernelArg : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = d.searchKernel.SetArg(4, target64)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clSetKernelArg : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
err = d.searchKernel.SetArg(5, uint32(math.MaxUint32))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clSetKernelArg : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait on this before returning
|
|
||||||
var preReturnEvent *cl.Event
|
|
||||||
if d.openCL12 {
|
|
||||||
preReturnEvent, err = d.ctx.CreateUserEvent()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search create CL user event : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pending := make([]pendingSearch, 0, searchBufSize)
|
|
||||||
var p *pendingSearch
|
|
||||||
searchBufIndex := uint32(0)
|
|
||||||
var checkNonce uint64
|
|
||||||
loops := int64(0)
|
|
||||||
prevHashRate := int32(0)
|
|
||||||
start := time.Now().UnixNano()
|
|
||||||
// we grab a single random nonce and sets this as argument to the kernel search function
|
|
||||||
// the device will then add each local threads gid to the nonce, creating a unique nonce
|
|
||||||
// for each device computing unit executing in parallel
|
|
||||||
initNonce := uint64(d.nonceRand.Int63())
|
|
||||||
for nonce := initNonce; ; nonce += uint64(globalWorkSize) {
|
|
||||||
select {
|
|
||||||
case <-stop:
|
|
||||||
|
|
||||||
/*
|
|
||||||
if d.openCL12 {
|
|
||||||
err = cl.WaitForEvents([]*cl.Event{preReturnEvent})
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search WaitForEvents: ", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
atomic.AddInt32(&c.hashRate, -prevHashRate)
|
|
||||||
return 0, []byte{0}
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loops % (1 << 7)) == 0 {
|
|
||||||
elapsed := time.Now().UnixNano() - start
|
|
||||||
// TODO: verify if this is correct hash rate calculation
|
|
||||||
hashes := (float64(1e9) / float64(elapsed)) * float64(loops*1024*256)
|
|
||||||
hashrateDiff := int32(hashes) - prevHashRate
|
|
||||||
prevHashRate = int32(hashes)
|
|
||||||
atomic.AddInt32(&c.hashRate, hashrateDiff)
|
|
||||||
}
|
|
||||||
loops++
|
|
||||||
|
|
||||||
err = d.searchKernel.SetArg(0, d.searchBuffers[searchBufIndex])
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clSetKernelArg : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
err = d.searchKernel.SetArg(3, nonce)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clSetKernelArg : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
// execute kernel
|
|
||||||
_, err := d.queue.EnqueueNDRangeKernel(
|
|
||||||
d.searchKernel,
|
|
||||||
[]int{0},
|
|
||||||
[]int{globalWorkSize},
|
|
||||||
[]int{d.workGroupSize},
|
|
||||||
nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clEnqueueNDRangeKernel : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
pending = append(pending, pendingSearch{bufIndex: searchBufIndex, startNonce: nonce})
|
|
||||||
searchBufIndex = (searchBufIndex + 1) % searchBufSize
|
|
||||||
|
|
||||||
if len(pending) == searchBufSize {
|
|
||||||
p = &(pending[searchBufIndex])
|
|
||||||
cres, _, err := d.queue.EnqueueMapBuffer(d.searchBuffers[p.bufIndex], true,
|
|
||||||
cl.MapFlagRead, 0, (1+maxSearchResults)*SIZEOF_UINT32,
|
|
||||||
nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clEnqueueMapBuffer: ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
results := cres.ByteSlice()
|
|
||||||
nfound := binary.LittleEndian.Uint32(results)
|
|
||||||
nfound = uint32(math.Min(float64(nfound), float64(maxSearchResults)))
|
|
||||||
// OpenCL returns the offsets from the start nonce
|
|
||||||
for i := uint32(0); i < nfound; i++ {
|
|
||||||
lo := (i + 1) * SIZEOF_UINT32
|
|
||||||
hi := (i + 2) * SIZEOF_UINT32
|
|
||||||
upperNonce := uint64(binary.LittleEndian.Uint32(results[lo:hi]))
|
|
||||||
checkNonce = p.startNonce + upperNonce
|
|
||||||
if checkNonce != 0 {
|
|
||||||
// We verify that the nonce is indeed a solution by
|
|
||||||
// executing the Ethash verification function (on the CPU).
|
|
||||||
cache := c.ethash.Light.getCache(block.NumberU64())
|
|
||||||
ok, mixDigest, result := cache.compute(c.dagSize, headerHash, checkNonce)
|
|
||||||
|
|
||||||
// TODO: return result first
|
|
||||||
if ok && result.Big().Cmp(target256) <= 0 {
|
|
||||||
_, err = d.queue.EnqueueUnmapMemObject(d.searchBuffers[p.bufIndex], cres, nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clEnqueueUnmapMemObject: ", err)
|
|
||||||
}
|
|
||||||
if d.openCL12 {
|
|
||||||
err = cl.WaitForEvents([]*cl.Event{preReturnEvent})
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search WaitForEvents: ", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return checkNonce, mixDigest.Bytes()
|
|
||||||
}
|
|
||||||
_, err := d.queue.EnqueueWriteBuffer(d.searchBuffers[p.bufIndex], false, 0, 4, unsafe.Pointer(&zero), nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search cl: EnqueueWriteBuffer", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_, err = d.queue.EnqueueUnmapMemObject(d.searchBuffers[p.bufIndex], cres, nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clEnqueueUnMapMemObject: ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
pending = append(pending[:searchBufIndex], pending[searchBufIndex+1:]...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if d.openCL12 {
|
|
||||||
err := cl.WaitForEvents([]*cl.Event{preReturnEvent})
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clWaitForEvents: ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OpenCLMiner) Verify(block pow.Block) bool {
|
|
||||||
return c.ethash.Light.Verify(block)
|
|
||||||
}
|
|
||||||
func (c *OpenCLMiner) GetHashrate() int64 {
|
|
||||||
return int64(atomic.LoadInt32(&c.hashRate))
|
|
||||||
}
|
|
||||||
func (c *OpenCLMiner) Turbo(on bool) {
|
|
||||||
// This is GPU mining. Always be turbo.
|
|
||||||
}
|
|
||||||
|
|
||||||
func replaceWords(text string, kvs map[string]string) string {
|
|
||||||
for k, v := range kvs {
|
|
||||||
text = strings.Replace(text, k, v, -1)
|
|
||||||
}
|
|
||||||
return text
|
|
||||||
}
|
|
||||||
|
|
||||||
func logErr(err error) {
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in OpenCL call:", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func argErr(err error) error {
|
|
||||||
return fmt.Errorf("arg err: %v", err)
|
|
||||||
}
|
|
||||||
600
Godeps/_workspace/src/github.com/ethereum/ethash/ethash_opencl_kernel_go_str.go
generated
vendored
600
Godeps/_workspace/src/github.com/ethereum/ethash/ethash_opencl_kernel_go_str.go
generated
vendored
@@ -1,600 +0,0 @@
|
|||||||
package ethash
|
|
||||||
|
|
||||||
/* DO NOT EDIT!!!
|
|
||||||
|
|
||||||
This code is version controlled at
|
|
||||||
https://github.com/ethereum/cpp-ethereum/blob/develop/libethash-cl/ethash_cl_miner_kernel.cl
|
|
||||||
|
|
||||||
If needed change it there first, then copy over here.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const kernel = `
|
|
||||||
// author Tim Hughes <tim@twistedfury.com>
|
|
||||||
// Tested on Radeon HD 7850
|
|
||||||
// Hashrate: 15940347 hashes/s
|
|
||||||
// Bandwidth: 124533 MB/s
|
|
||||||
// search kernel should fit in <= 84 VGPRS (3 wavefronts)
|
|
||||||
|
|
||||||
#define THREADS_PER_HASH (128 / 16)
|
|
||||||
#define HASHES_PER_LOOP (GROUP_SIZE / THREADS_PER_HASH)
|
|
||||||
|
|
||||||
#define FNV_PRIME 0x01000193
|
|
||||||
|
|
||||||
__constant uint2 const Keccak_f1600_RC[24] = {
|
|
||||||
(uint2)(0x00000001, 0x00000000),
|
|
||||||
(uint2)(0x00008082, 0x00000000),
|
|
||||||
(uint2)(0x0000808a, 0x80000000),
|
|
||||||
(uint2)(0x80008000, 0x80000000),
|
|
||||||
(uint2)(0x0000808b, 0x00000000),
|
|
||||||
(uint2)(0x80000001, 0x00000000),
|
|
||||||
(uint2)(0x80008081, 0x80000000),
|
|
||||||
(uint2)(0x00008009, 0x80000000),
|
|
||||||
(uint2)(0x0000008a, 0x00000000),
|
|
||||||
(uint2)(0x00000088, 0x00000000),
|
|
||||||
(uint2)(0x80008009, 0x00000000),
|
|
||||||
(uint2)(0x8000000a, 0x00000000),
|
|
||||||
(uint2)(0x8000808b, 0x00000000),
|
|
||||||
(uint2)(0x0000008b, 0x80000000),
|
|
||||||
(uint2)(0x00008089, 0x80000000),
|
|
||||||
(uint2)(0x00008003, 0x80000000),
|
|
||||||
(uint2)(0x00008002, 0x80000000),
|
|
||||||
(uint2)(0x00000080, 0x80000000),
|
|
||||||
(uint2)(0x0000800a, 0x00000000),
|
|
||||||
(uint2)(0x8000000a, 0x80000000),
|
|
||||||
(uint2)(0x80008081, 0x80000000),
|
|
||||||
(uint2)(0x00008080, 0x80000000),
|
|
||||||
(uint2)(0x80000001, 0x00000000),
|
|
||||||
(uint2)(0x80008008, 0x80000000),
|
|
||||||
};
|
|
||||||
|
|
||||||
void keccak_f1600_round(uint2* a, uint r, uint out_size)
|
|
||||||
{
|
|
||||||
#if !__ENDIAN_LITTLE__
|
|
||||||
for (uint i = 0; i != 25; ++i)
|
|
||||||
a[i] = a[i].yx;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint2 b[25];
|
|
||||||
uint2 t;
|
|
||||||
|
|
||||||
// Theta
|
|
||||||
b[0] = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20];
|
|
||||||
b[1] = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21];
|
|
||||||
b[2] = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22];
|
|
||||||
b[3] = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23];
|
|
||||||
b[4] = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24];
|
|
||||||
t = b[4] ^ (uint2)(b[1].x << 1 | b[1].y >> 31, b[1].y << 1 | b[1].x >> 31);
|
|
||||||
a[0] ^= t;
|
|
||||||
a[5] ^= t;
|
|
||||||
a[10] ^= t;
|
|
||||||
a[15] ^= t;
|
|
||||||
a[20] ^= t;
|
|
||||||
t = b[0] ^ (uint2)(b[2].x << 1 | b[2].y >> 31, b[2].y << 1 | b[2].x >> 31);
|
|
||||||
a[1] ^= t;
|
|
||||||
a[6] ^= t;
|
|
||||||
a[11] ^= t;
|
|
||||||
a[16] ^= t;
|
|
||||||
a[21] ^= t;
|
|
||||||
t = b[1] ^ (uint2)(b[3].x << 1 | b[3].y >> 31, b[3].y << 1 | b[3].x >> 31);
|
|
||||||
a[2] ^= t;
|
|
||||||
a[7] ^= t;
|
|
||||||
a[12] ^= t;
|
|
||||||
a[17] ^= t;
|
|
||||||
a[22] ^= t;
|
|
||||||
t = b[2] ^ (uint2)(b[4].x << 1 | b[4].y >> 31, b[4].y << 1 | b[4].x >> 31);
|
|
||||||
a[3] ^= t;
|
|
||||||
a[8] ^= t;
|
|
||||||
a[13] ^= t;
|
|
||||||
a[18] ^= t;
|
|
||||||
a[23] ^= t;
|
|
||||||
t = b[3] ^ (uint2)(b[0].x << 1 | b[0].y >> 31, b[0].y << 1 | b[0].x >> 31);
|
|
||||||
a[4] ^= t;
|
|
||||||
a[9] ^= t;
|
|
||||||
a[14] ^= t;
|
|
||||||
a[19] ^= t;
|
|
||||||
a[24] ^= t;
|
|
||||||
|
|
||||||
// Rho Pi
|
|
||||||
b[0] = a[0];
|
|
||||||
b[10] = (uint2)(a[1].x << 1 | a[1].y >> 31, a[1].y << 1 | a[1].x >> 31);
|
|
||||||
b[7] = (uint2)(a[10].x << 3 | a[10].y >> 29, a[10].y << 3 | a[10].x >> 29);
|
|
||||||
b[11] = (uint2)(a[7].x << 6 | a[7].y >> 26, a[7].y << 6 | a[7].x >> 26);
|
|
||||||
b[17] = (uint2)(a[11].x << 10 | a[11].y >> 22, a[11].y << 10 | a[11].x >> 22);
|
|
||||||
b[18] = (uint2)(a[17].x << 15 | a[17].y >> 17, a[17].y << 15 | a[17].x >> 17);
|
|
||||||
b[3] = (uint2)(a[18].x << 21 | a[18].y >> 11, a[18].y << 21 | a[18].x >> 11);
|
|
||||||
b[5] = (uint2)(a[3].x << 28 | a[3].y >> 4, a[3].y << 28 | a[3].x >> 4);
|
|
||||||
b[16] = (uint2)(a[5].y << 4 | a[5].x >> 28, a[5].x << 4 | a[5].y >> 28);
|
|
||||||
b[8] = (uint2)(a[16].y << 13 | a[16].x >> 19, a[16].x << 13 | a[16].y >> 19);
|
|
||||||
b[21] = (uint2)(a[8].y << 23 | a[8].x >> 9, a[8].x << 23 | a[8].y >> 9);
|
|
||||||
b[24] = (uint2)(a[21].x << 2 | a[21].y >> 30, a[21].y << 2 | a[21].x >> 30);
|
|
||||||
b[4] = (uint2)(a[24].x << 14 | a[24].y >> 18, a[24].y << 14 | a[24].x >> 18);
|
|
||||||
b[15] = (uint2)(a[4].x << 27 | a[4].y >> 5, a[4].y << 27 | a[4].x >> 5);
|
|
||||||
b[23] = (uint2)(a[15].y << 9 | a[15].x >> 23, a[15].x << 9 | a[15].y >> 23);
|
|
||||||
b[19] = (uint2)(a[23].y << 24 | a[23].x >> 8, a[23].x << 24 | a[23].y >> 8);
|
|
||||||
b[13] = (uint2)(a[19].x << 8 | a[19].y >> 24, a[19].y << 8 | a[19].x >> 24);
|
|
||||||
b[12] = (uint2)(a[13].x << 25 | a[13].y >> 7, a[13].y << 25 | a[13].x >> 7);
|
|
||||||
b[2] = (uint2)(a[12].y << 11 | a[12].x >> 21, a[12].x << 11 | a[12].y >> 21);
|
|
||||||
b[20] = (uint2)(a[2].y << 30 | a[2].x >> 2, a[2].x << 30 | a[2].y >> 2);
|
|
||||||
b[14] = (uint2)(a[20].x << 18 | a[20].y >> 14, a[20].y << 18 | a[20].x >> 14);
|
|
||||||
b[22] = (uint2)(a[14].y << 7 | a[14].x >> 25, a[14].x << 7 | a[14].y >> 25);
|
|
||||||
b[9] = (uint2)(a[22].y << 29 | a[22].x >> 3, a[22].x << 29 | a[22].y >> 3);
|
|
||||||
b[6] = (uint2)(a[9].x << 20 | a[9].y >> 12, a[9].y << 20 | a[9].x >> 12);
|
|
||||||
b[1] = (uint2)(a[6].y << 12 | a[6].x >> 20, a[6].x << 12 | a[6].y >> 20);
|
|
||||||
|
|
||||||
// Chi
|
|
||||||
a[0] = bitselect(b[0] ^ b[2], b[0], b[1]);
|
|
||||||
a[1] = bitselect(b[1] ^ b[3], b[1], b[2]);
|
|
||||||
a[2] = bitselect(b[2] ^ b[4], b[2], b[3]);
|
|
||||||
a[3] = bitselect(b[3] ^ b[0], b[3], b[4]);
|
|
||||||
if (out_size >= 4)
|
|
||||||
{
|
|
||||||
a[4] = bitselect(b[4] ^ b[1], b[4], b[0]);
|
|
||||||
a[5] = bitselect(b[5] ^ b[7], b[5], b[6]);
|
|
||||||
a[6] = bitselect(b[6] ^ b[8], b[6], b[7]);
|
|
||||||
a[7] = bitselect(b[7] ^ b[9], b[7], b[8]);
|
|
||||||
a[8] = bitselect(b[8] ^ b[5], b[8], b[9]);
|
|
||||||
if (out_size >= 8)
|
|
||||||
{
|
|
||||||
a[9] = bitselect(b[9] ^ b[6], b[9], b[5]);
|
|
||||||
a[10] = bitselect(b[10] ^ b[12], b[10], b[11]);
|
|
||||||
a[11] = bitselect(b[11] ^ b[13], b[11], b[12]);
|
|
||||||
a[12] = bitselect(b[12] ^ b[14], b[12], b[13]);
|
|
||||||
a[13] = bitselect(b[13] ^ b[10], b[13], b[14]);
|
|
||||||
a[14] = bitselect(b[14] ^ b[11], b[14], b[10]);
|
|
||||||
a[15] = bitselect(b[15] ^ b[17], b[15], b[16]);
|
|
||||||
a[16] = bitselect(b[16] ^ b[18], b[16], b[17]);
|
|
||||||
a[17] = bitselect(b[17] ^ b[19], b[17], b[18]);
|
|
||||||
a[18] = bitselect(b[18] ^ b[15], b[18], b[19]);
|
|
||||||
a[19] = bitselect(b[19] ^ b[16], b[19], b[15]);
|
|
||||||
a[20] = bitselect(b[20] ^ b[22], b[20], b[21]);
|
|
||||||
a[21] = bitselect(b[21] ^ b[23], b[21], b[22]);
|
|
||||||
a[22] = bitselect(b[22] ^ b[24], b[22], b[23]);
|
|
||||||
a[23] = bitselect(b[23] ^ b[20], b[23], b[24]);
|
|
||||||
a[24] = bitselect(b[24] ^ b[21], b[24], b[20]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iota
|
|
||||||
a[0] ^= Keccak_f1600_RC[r];
|
|
||||||
|
|
||||||
#if !__ENDIAN_LITTLE__
|
|
||||||
for (uint i = 0; i != 25; ++i)
|
|
||||||
a[i] = a[i].yx;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void keccak_f1600_no_absorb(ulong* a, uint in_size, uint out_size, uint isolate)
|
|
||||||
{
|
|
||||||
for (uint i = in_size; i != 25; ++i)
|
|
||||||
{
|
|
||||||
a[i] = 0;
|
|
||||||
}
|
|
||||||
#if __ENDIAN_LITTLE__
|
|
||||||
a[in_size] ^= 0x0000000000000001;
|
|
||||||
a[24-out_size*2] ^= 0x8000000000000000;
|
|
||||||
#else
|
|
||||||
a[in_size] ^= 0x0100000000000000;
|
|
||||||
a[24-out_size*2] ^= 0x0000000000000080;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Originally I unrolled the first and last rounds to interface
|
|
||||||
// better with surrounding code, however I haven't done this
|
|
||||||
// without causing the AMD compiler to blow up the VGPR usage.
|
|
||||||
uint r = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// This dynamic branch stops the AMD compiler unrolling the loop
|
|
||||||
// and additionally saves about 33% of the VGPRs, enough to gain another
|
|
||||||
// wavefront. Ideally we'd get 4 in flight, but 3 is the best I can
|
|
||||||
// massage out of the compiler. It doesn't really seem to matter how
|
|
||||||
// much we try and help the compiler save VGPRs because it seems to throw
|
|
||||||
// that information away, hence the implementation of keccak here
|
|
||||||
// doesn't bother.
|
|
||||||
if (isolate)
|
|
||||||
{
|
|
||||||
keccak_f1600_round((uint2*)a, r++, 25);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (r < 23);
|
|
||||||
|
|
||||||
// final round optimised for digest size
|
|
||||||
keccak_f1600_round((uint2*)a, r++, out_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define copy(dst, src, count) for (uint i = 0; i != count; ++i) { (dst)[i] = (src)[i]; }
|
|
||||||
|
|
||||||
#define countof(x) (sizeof(x) / sizeof(x[0]))
|
|
||||||
|
|
||||||
uint fnv(uint x, uint y)
|
|
||||||
{
|
|
||||||
return x * FNV_PRIME ^ y;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint4 fnv4(uint4 x, uint4 y)
|
|
||||||
{
|
|
||||||
return x * FNV_PRIME ^ y;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint fnv_reduce(uint4 v)
|
|
||||||
{
|
|
||||||
return fnv(fnv(fnv(v.x, v.y), v.z), v.w);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef union
|
|
||||||
{
|
|
||||||
ulong ulongs[32 / sizeof(ulong)];
|
|
||||||
uint uints[32 / sizeof(uint)];
|
|
||||||
} hash32_t;
|
|
||||||
|
|
||||||
typedef union
|
|
||||||
{
|
|
||||||
ulong ulongs[64 / sizeof(ulong)];
|
|
||||||
uint4 uint4s[64 / sizeof(uint4)];
|
|
||||||
} hash64_t;
|
|
||||||
|
|
||||||
typedef union
|
|
||||||
{
|
|
||||||
uint uints[128 / sizeof(uint)];
|
|
||||||
uint4 uint4s[128 / sizeof(uint4)];
|
|
||||||
} hash128_t;
|
|
||||||
|
|
||||||
hash64_t init_hash(__constant hash32_t const* header, ulong nonce, uint isolate)
|
|
||||||
{
|
|
||||||
hash64_t init;
|
|
||||||
uint const init_size = countof(init.ulongs);
|
|
||||||
uint const hash_size = countof(header->ulongs);
|
|
||||||
|
|
||||||
// sha3_512(header .. nonce)
|
|
||||||
ulong state[25];
|
|
||||||
copy(state, header->ulongs, hash_size);
|
|
||||||
state[hash_size] = nonce;
|
|
||||||
keccak_f1600_no_absorb(state, hash_size + 1, init_size, isolate);
|
|
||||||
|
|
||||||
copy(init.ulongs, state, init_size);
|
|
||||||
return init;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint inner_loop_chunks(uint4 init, uint thread_id, __local uint* share, __global hash128_t const* g_dag, __global hash128_t const* g_dag1, __global hash128_t const* g_dag2, __global hash128_t const* g_dag3, uint isolate)
|
|
||||||
{
|
|
||||||
uint4 mix = init;
|
|
||||||
|
|
||||||
// share init0
|
|
||||||
if (thread_id == 0)
|
|
||||||
*share = mix.x;
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
uint init0 = *share;
|
|
||||||
|
|
||||||
uint a = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
bool update_share = thread_id == (a/4) % THREADS_PER_HASH;
|
|
||||||
|
|
||||||
#pragma unroll
|
|
||||||
for (uint i = 0; i != 4; ++i)
|
|
||||||
{
|
|
||||||
if (update_share)
|
|
||||||
{
|
|
||||||
uint m[4] = { mix.x, mix.y, mix.z, mix.w };
|
|
||||||
*share = fnv(init0 ^ (a+i), m[i]) % DAG_SIZE;
|
|
||||||
}
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
|
|
||||||
mix = fnv4(mix, *share>=3 * DAG_SIZE / 4 ? g_dag3[*share - 3 * DAG_SIZE / 4].uint4s[thread_id] : *share>=DAG_SIZE / 2 ? g_dag2[*share - DAG_SIZE / 2].uint4s[thread_id] : *share>=DAG_SIZE / 4 ? g_dag1[*share - DAG_SIZE / 4].uint4s[thread_id]:g_dag[*share].uint4s[thread_id]);
|
|
||||||
}
|
|
||||||
} while ((a += 4) != (ACCESSES & isolate));
|
|
||||||
|
|
||||||
return fnv_reduce(mix);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint inner_loop(uint4 init, uint thread_id, __local uint* share, __global hash128_t const* g_dag, uint isolate)
|
|
||||||
{
|
|
||||||
uint4 mix = init;
|
|
||||||
|
|
||||||
// share init0
|
|
||||||
if (thread_id == 0)
|
|
||||||
*share = mix.x;
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
uint init0 = *share;
|
|
||||||
|
|
||||||
uint a = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
bool update_share = thread_id == (a/4) % THREADS_PER_HASH;
|
|
||||||
|
|
||||||
#pragma unroll
|
|
||||||
for (uint i = 0; i != 4; ++i)
|
|
||||||
{
|
|
||||||
if (update_share)
|
|
||||||
{
|
|
||||||
uint m[4] = { mix.x, mix.y, mix.z, mix.w };
|
|
||||||
*share = fnv(init0 ^ (a+i), m[i]) % DAG_SIZE;
|
|
||||||
}
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
|
|
||||||
mix = fnv4(mix, g_dag[*share].uint4s[thread_id]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while ((a += 4) != (ACCESSES & isolate));
|
|
||||||
|
|
||||||
return fnv_reduce(mix);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
hash32_t final_hash(hash64_t const* init, hash32_t const* mix, uint isolate)
|
|
||||||
{
|
|
||||||
ulong state[25];
|
|
||||||
|
|
||||||
hash32_t hash;
|
|
||||||
uint const hash_size = countof(hash.ulongs);
|
|
||||||
uint const init_size = countof(init->ulongs);
|
|
||||||
uint const mix_size = countof(mix->ulongs);
|
|
||||||
|
|
||||||
// keccak_256(keccak_512(header..nonce) .. mix);
|
|
||||||
copy(state, init->ulongs, init_size);
|
|
||||||
copy(state + init_size, mix->ulongs, mix_size);
|
|
||||||
keccak_f1600_no_absorb(state, init_size+mix_size, hash_size, isolate);
|
|
||||||
|
|
||||||
// copy out
|
|
||||||
copy(hash.ulongs, state, hash_size);
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
hash32_t compute_hash_simple(
|
|
||||||
__constant hash32_t const* g_header,
|
|
||||||
__global hash128_t const* g_dag,
|
|
||||||
ulong nonce,
|
|
||||||
uint isolate
|
|
||||||
)
|
|
||||||
{
|
|
||||||
hash64_t init = init_hash(g_header, nonce, isolate);
|
|
||||||
|
|
||||||
hash128_t mix;
|
|
||||||
for (uint i = 0; i != countof(mix.uint4s); ++i)
|
|
||||||
{
|
|
||||||
mix.uint4s[i] = init.uint4s[i % countof(init.uint4s)];
|
|
||||||
}
|
|
||||||
|
|
||||||
uint mix_val = mix.uints[0];
|
|
||||||
uint init0 = mix.uints[0];
|
|
||||||
uint a = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
uint pi = fnv(init0 ^ a, mix_val) % DAG_SIZE;
|
|
||||||
uint n = (a+1) % countof(mix.uints);
|
|
||||||
|
|
||||||
#pragma unroll
|
|
||||||
for (uint i = 0; i != countof(mix.uints); ++i)
|
|
||||||
{
|
|
||||||
mix.uints[i] = fnv(mix.uints[i], g_dag[pi].uints[i]);
|
|
||||||
mix_val = i == n ? mix.uints[i] : mix_val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (++a != (ACCESSES & isolate));
|
|
||||||
|
|
||||||
// reduce to output
|
|
||||||
hash32_t fnv_mix;
|
|
||||||
for (uint i = 0; i != countof(fnv_mix.uints); ++i)
|
|
||||||
{
|
|
||||||
fnv_mix.uints[i] = fnv_reduce(mix.uint4s[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return final_hash(&init, &fnv_mix, isolate);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
hash64_t init;
|
|
||||||
uint pad; // avoid lds bank conflicts
|
|
||||||
};
|
|
||||||
hash32_t mix;
|
|
||||||
} compute_hash_share;
|
|
||||||
|
|
||||||
|
|
||||||
hash32_t compute_hash(
|
|
||||||
__local compute_hash_share* share,
|
|
||||||
__constant hash32_t const* g_header,
|
|
||||||
__global hash128_t const* g_dag,
|
|
||||||
ulong nonce,
|
|
||||||
uint isolate
|
|
||||||
)
|
|
||||||
{
|
|
||||||
uint const gid = get_global_id(0);
|
|
||||||
|
|
||||||
// Compute one init hash per work item.
|
|
||||||
hash64_t init = init_hash(g_header, nonce, isolate);
|
|
||||||
|
|
||||||
// Threads work together in this phase in groups of 8.
|
|
||||||
uint const thread_id = gid % THREADS_PER_HASH;
|
|
||||||
uint const hash_id = (gid % GROUP_SIZE) / THREADS_PER_HASH;
|
|
||||||
|
|
||||||
hash32_t mix;
|
|
||||||
uint i = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// share init with other threads
|
|
||||||
if (i == thread_id)
|
|
||||||
share[hash_id].init = init;
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
|
|
||||||
uint4 thread_init = share[hash_id].init.uint4s[thread_id % (64 / sizeof(uint4))];
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
|
|
||||||
uint thread_mix = inner_loop(thread_init, thread_id, share[hash_id].mix.uints, g_dag, isolate);
|
|
||||||
|
|
||||||
share[hash_id].mix.uints[thread_id] = thread_mix;
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
|
|
||||||
if (i == thread_id)
|
|
||||||
mix = share[hash_id].mix;
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
}
|
|
||||||
while (++i != (THREADS_PER_HASH & isolate));
|
|
||||||
|
|
||||||
return final_hash(&init, &mix, isolate);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
hash32_t compute_hash_chunks(
|
|
||||||
__local compute_hash_share* share,
|
|
||||||
__constant hash32_t const* g_header,
|
|
||||||
__global hash128_t const* g_dag,
|
|
||||||
__global hash128_t const* g_dag1,
|
|
||||||
__global hash128_t const* g_dag2,
|
|
||||||
__global hash128_t const* g_dag3,
|
|
||||||
ulong nonce,
|
|
||||||
uint isolate
|
|
||||||
)
|
|
||||||
{
|
|
||||||
uint const gid = get_global_id(0);
|
|
||||||
|
|
||||||
// Compute one init hash per work item.
|
|
||||||
hash64_t init = init_hash(g_header, nonce, isolate);
|
|
||||||
|
|
||||||
// Threads work together in this phase in groups of 8.
|
|
||||||
uint const thread_id = gid % THREADS_PER_HASH;
|
|
||||||
uint const hash_id = (gid % GROUP_SIZE) / THREADS_PER_HASH;
|
|
||||||
|
|
||||||
hash32_t mix;
|
|
||||||
uint i = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// share init with other threads
|
|
||||||
if (i == thread_id)
|
|
||||||
share[hash_id].init = init;
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
|
|
||||||
uint4 thread_init = share[hash_id].init.uint4s[thread_id % (64 / sizeof(uint4))];
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
|
|
||||||
uint thread_mix = inner_loop_chunks(thread_init, thread_id, share[hash_id].mix.uints, g_dag, g_dag1, g_dag2, g_dag3, isolate);
|
|
||||||
|
|
||||||
share[hash_id].mix.uints[thread_id] = thread_mix;
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
|
|
||||||
if (i == thread_id)
|
|
||||||
mix = share[hash_id].mix;
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
}
|
|
||||||
while (++i != (THREADS_PER_HASH & isolate));
|
|
||||||
|
|
||||||
return final_hash(&init, &mix, isolate);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((reqd_work_group_size(GROUP_SIZE, 1, 1)))
|
|
||||||
__kernel void ethash_hash_simple(
|
|
||||||
__global hash32_t* g_hashes,
|
|
||||||
__constant hash32_t const* g_header,
|
|
||||||
__global hash128_t const* g_dag,
|
|
||||||
ulong start_nonce,
|
|
||||||
uint isolate
|
|
||||||
)
|
|
||||||
{
|
|
||||||
uint const gid = get_global_id(0);
|
|
||||||
g_hashes[gid] = compute_hash_simple(g_header, g_dag, start_nonce + gid, isolate);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((reqd_work_group_size(GROUP_SIZE, 1, 1)))
|
|
||||||
__kernel void ethash_search_simple(
|
|
||||||
__global volatile uint* restrict g_output,
|
|
||||||
__constant hash32_t const* g_header,
|
|
||||||
__global hash128_t const* g_dag,
|
|
||||||
ulong start_nonce,
|
|
||||||
ulong target,
|
|
||||||
uint isolate
|
|
||||||
)
|
|
||||||
{
|
|
||||||
uint const gid = get_global_id(0);
|
|
||||||
hash32_t hash = compute_hash_simple(g_header, g_dag, start_nonce + gid, isolate);
|
|
||||||
|
|
||||||
if (hash.ulongs[countof(hash.ulongs)-1] < target)
|
|
||||||
{
|
|
||||||
uint slot = min(convert_uint(MAX_OUTPUTS), convert_uint(atomic_inc(&g_output[0]) + 1));
|
|
||||||
g_output[slot] = gid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
__attribute__((reqd_work_group_size(GROUP_SIZE, 1, 1)))
|
|
||||||
__kernel void ethash_hash(
|
|
||||||
__global hash32_t* g_hashes,
|
|
||||||
__constant hash32_t const* g_header,
|
|
||||||
__global hash128_t const* g_dag,
|
|
||||||
ulong start_nonce,
|
|
||||||
uint isolate
|
|
||||||
)
|
|
||||||
{
|
|
||||||
__local compute_hash_share share[HASHES_PER_LOOP];
|
|
||||||
|
|
||||||
uint const gid = get_global_id(0);
|
|
||||||
g_hashes[gid] = compute_hash(share, g_header, g_dag, start_nonce + gid, isolate);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((reqd_work_group_size(GROUP_SIZE, 1, 1)))
|
|
||||||
__kernel void ethash_search(
|
|
||||||
__global volatile uint* restrict g_output,
|
|
||||||
__constant hash32_t const* g_header,
|
|
||||||
__global hash128_t const* g_dag,
|
|
||||||
ulong start_nonce,
|
|
||||||
ulong target,
|
|
||||||
uint isolate
|
|
||||||
)
|
|
||||||
{
|
|
||||||
__local compute_hash_share share[HASHES_PER_LOOP];
|
|
||||||
|
|
||||||
uint const gid = get_global_id(0);
|
|
||||||
hash32_t hash = compute_hash(share, g_header, g_dag, start_nonce + gid, isolate);
|
|
||||||
|
|
||||||
if (as_ulong(as_uchar8(hash.ulongs[0]).s76543210) < target)
|
|
||||||
{
|
|
||||||
uint slot = min((uint)MAX_OUTPUTS, atomic_inc(&g_output[0]) + 1);
|
|
||||||
g_output[slot] = gid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((reqd_work_group_size(GROUP_SIZE, 1, 1)))
|
|
||||||
__kernel void ethash_hash_chunks(
|
|
||||||
__global hash32_t* g_hashes,
|
|
||||||
__constant hash32_t const* g_header,
|
|
||||||
__global hash128_t const* g_dag,
|
|
||||||
__global hash128_t const* g_dag1,
|
|
||||||
__global hash128_t const* g_dag2,
|
|
||||||
__global hash128_t const* g_dag3,
|
|
||||||
ulong start_nonce,
|
|
||||||
uint isolate
|
|
||||||
)
|
|
||||||
{
|
|
||||||
__local compute_hash_share share[HASHES_PER_LOOP];
|
|
||||||
|
|
||||||
uint const gid = get_global_id(0);
|
|
||||||
g_hashes[gid] = compute_hash_chunks(share, g_header, g_dag, g_dag1, g_dag2, g_dag3,start_nonce + gid, isolate);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((reqd_work_group_size(GROUP_SIZE, 1, 1)))
|
|
||||||
__kernel void ethash_search_chunks(
|
|
||||||
__global volatile uint* restrict g_output,
|
|
||||||
__constant hash32_t const* g_header,
|
|
||||||
__global hash128_t const* g_dag,
|
|
||||||
__global hash128_t const* g_dag1,
|
|
||||||
__global hash128_t const* g_dag2,
|
|
||||||
__global hash128_t const* g_dag3,
|
|
||||||
ulong start_nonce,
|
|
||||||
ulong target,
|
|
||||||
uint isolate
|
|
||||||
)
|
|
||||||
{
|
|
||||||
__local compute_hash_share share[HASHES_PER_LOOP];
|
|
||||||
|
|
||||||
uint const gid = get_global_id(0);
|
|
||||||
hash32_t hash = compute_hash_chunks(share, g_header, g_dag, g_dag1, g_dag2, g_dag3, start_nonce + gid, isolate);
|
|
||||||
|
|
||||||
if (as_ulong(as_uchar8(hash.ulongs[0]).s76543210) < target)
|
|
||||||
{
|
|
||||||
uint slot = min(convert_uint(MAX_OUTPUTS), convert_uint(atomic_inc(&g_output[0]) + 1));
|
|
||||||
g_output[slot] = gid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
3
Godeps/_workspace/src/github.com/fatih/color/.travis.yml
generated
vendored
3
Godeps/_workspace/src/github.com/fatih/color/.travis.yml
generated
vendored
@@ -1,3 +0,0 @@
|
|||||||
language: go
|
|
||||||
go: 1.3
|
|
||||||
|
|
||||||
26
Godeps/_workspace/src/github.com/gizak/termui/config
generated
vendored
26
Godeps/_workspace/src/github.com/gizak/termui/config
generated
vendored
@@ -1,26 +0,0 @@
|
|||||||
#!/usr/bin/env perl6
|
|
||||||
|
|
||||||
use v6;
|
|
||||||
|
|
||||||
my $copyright = '// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
|
|
||||||
';
|
|
||||||
|
|
||||||
sub MAIN('update-docstr', Str $srcp) {
|
|
||||||
if $srcp.IO.f {
|
|
||||||
$_ = $srcp.IO.slurp;
|
|
||||||
if m/^ \/\/\s Copyright .+? \n\n/ {
|
|
||||||
unless ~$/ eq $copyright {
|
|
||||||
s/^ \/\/\s Copyright .+? \n\n /$copyright/;
|
|
||||||
spurt $srcp, $_;
|
|
||||||
say "[updated] doc string for:"~$srcp;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
say "[added] doc string for "~$srcp~" (no match found)";
|
|
||||||
$_ = $copyright ~ $_;
|
|
||||||
spurt $srcp, $_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
117
Godeps/_workspace/src/github.com/gizak/termui/debug/debuger.go
generated
vendored
117
Godeps/_workspace/src/github.com/gizak/termui/debug/debuger.go
generated
vendored
@@ -1,117 +0,0 @@
|
|||||||
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
|
|
||||||
package debug
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"golang.org/x/net/websocket"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Server struct {
|
|
||||||
Port string
|
|
||||||
Addr string
|
|
||||||
Path string
|
|
||||||
Msg chan string
|
|
||||||
chs []chan string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Client struct {
|
|
||||||
Port string
|
|
||||||
Addr string
|
|
||||||
Path string
|
|
||||||
ws *websocket.Conn
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaultPort = ":8080"
|
|
||||||
|
|
||||||
func NewServer() *Server {
|
|
||||||
return &Server{
|
|
||||||
Port: defaultPort,
|
|
||||||
Addr: "localhost",
|
|
||||||
Path: "/echo",
|
|
||||||
Msg: make(chan string),
|
|
||||||
chs: make([]chan string, 0),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewClient() Client {
|
|
||||||
return Client{
|
|
||||||
Port: defaultPort,
|
|
||||||
Addr: "localhost",
|
|
||||||
Path: "/echo",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c Client) ConnectAndListen() error {
|
|
||||||
ws, err := websocket.Dial("ws://"+c.Addr+c.Port+c.Path, "", "http://"+c.Addr)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer ws.Close()
|
|
||||||
|
|
||||||
var m string
|
|
||||||
for {
|
|
||||||
err := websocket.Message.Receive(ws, &m)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Print(err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Print(m)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) ListenAndServe() error {
|
|
||||||
http.Handle(s.Path, websocket.Handler(func(ws *websocket.Conn) {
|
|
||||||
defer ws.Close()
|
|
||||||
|
|
||||||
mc := make(chan string)
|
|
||||||
s.chs = append(s.chs, mc)
|
|
||||||
|
|
||||||
for m := range mc {
|
|
||||||
websocket.Message.Send(ws, m)
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
for msg := range s.Msg {
|
|
||||||
for _, c := range s.chs {
|
|
||||||
go func(a chan string) {
|
|
||||||
a <- msg
|
|
||||||
}(c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
return http.ListenAndServe(s.Port, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) Log(msg string) {
|
|
||||||
go func() { s.Msg <- msg }()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) Logf(format string, a ...interface{}) {
|
|
||||||
s.Log(fmt.Sprintf(format, a...))
|
|
||||||
}
|
|
||||||
|
|
||||||
var DefaultServer = NewServer()
|
|
||||||
var DefaultClient = NewClient()
|
|
||||||
|
|
||||||
func ListenAndServe() error {
|
|
||||||
return DefaultServer.ListenAndServe()
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConnectAndListen() error {
|
|
||||||
return DefaultClient.ConnectAndListen()
|
|
||||||
}
|
|
||||||
|
|
||||||
func Log(msg string) {
|
|
||||||
DefaultServer.Log(msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Logf(format string, a ...interface{}) {
|
|
||||||
DefaultServer.Logf(format, a...)
|
|
||||||
}
|
|
||||||
66
Godeps/_workspace/src/github.com/gizak/termui/test/runtest.go
generated
vendored
66
Godeps/_workspace/src/github.com/gizak/termui/test/runtest.go
generated
vendored
@@ -1,66 +0,0 @@
|
|||||||
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/gizak/termui"
|
|
||||||
"github.com/gizak/termui/debug"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// run as client
|
|
||||||
if len(os.Args) > 1 {
|
|
||||||
fmt.Print(debug.ConnectAndListen())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// run as server
|
|
||||||
go func() { panic(debug.ListenAndServe()) }()
|
|
||||||
|
|
||||||
if err := termui.Init(); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer termui.Close()
|
|
||||||
|
|
||||||
//termui.UseTheme("helloworld")
|
|
||||||
b := termui.NewBlock()
|
|
||||||
b.Width = 20
|
|
||||||
b.Height = 20
|
|
||||||
b.Float = termui.AlignCenter
|
|
||||||
b.BorderLabel = "[HELLO](fg-red,bg-white) [WORLD](fg-blue,bg-green)"
|
|
||||||
|
|
||||||
termui.Render(b)
|
|
||||||
|
|
||||||
termui.Handle("/sys", func(e termui.Event) {
|
|
||||||
k, ok := e.Data.(termui.EvtKbd)
|
|
||||||
debug.Logf("->%v\n", e)
|
|
||||||
if ok && k.KeyStr == "q" {
|
|
||||||
termui.StopLoop()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
termui.Handle(("/usr"), func(e termui.Event) {
|
|
||||||
debug.Logf("->%v\n", e)
|
|
||||||
})
|
|
||||||
|
|
||||||
termui.Handle("/timer/1s", func(e termui.Event) {
|
|
||||||
t := e.Data.(termui.EvtTimer)
|
|
||||||
termui.SendCustomEvt("/usr/t", t.Count)
|
|
||||||
|
|
||||||
if t.Count%2 == 0 {
|
|
||||||
b.BorderLabel = "[HELLO](fg-red,bg-green) [WORLD](fg-blue,bg-white)"
|
|
||||||
} else {
|
|
||||||
b.BorderLabel = "[HELLO](fg-blue,bg-white) [WORLD](fg-red,bg-green)"
|
|
||||||
}
|
|
||||||
|
|
||||||
termui.Render(b)
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
termui.Loop()
|
|
||||||
}
|
|
||||||
7
Godeps/_workspace/src/github.com/golang/snappy/README
generated
vendored
7
Godeps/_workspace/src/github.com/golang/snappy/README
generated
vendored
@@ -1,7 +0,0 @@
|
|||||||
The Snappy compression format in the Go programming language.
|
|
||||||
|
|
||||||
To download and install from source:
|
|
||||||
$ go get github.com/golang/snappy
|
|
||||||
|
|
||||||
Unless otherwise noted, the Snappy-Go source files are distributed
|
|
||||||
under the BSD-style license found in the LICENSE file.
|
|
||||||
44
Godeps/_workspace/src/github.com/huin/goupnp/README.md
generated
vendored
44
Godeps/_workspace/src/github.com/huin/goupnp/README.md
generated
vendored
@@ -1,44 +0,0 @@
|
|||||||
goupnp is a UPnP client library for Go
|
|
||||||
|
|
||||||
Installation
|
|
||||||
------------
|
|
||||||
|
|
||||||
Run `go get -u github.com/huin/goupnp`.
|
|
||||||
|
|
||||||
Documentation
|
|
||||||
-------------
|
|
||||||
|
|
||||||
All doc links below are for .
|
|
||||||
|
|
||||||
Supported DCPs (you probably want to start with one of these):
|
|
||||||
* [av1](https://godoc.org/github.com/huin/goupnp/dcps/av1) - Client for UPnP Device Control Protocol MediaServer v1 and MediaRenderer v1.
|
|
||||||
* [internetgateway1](https://godoc.org/github.com/huin/goupnp/dcps/internetgateway1) - Client for UPnP Device Control Protocol Internet Gateway Device v1.
|
|
||||||
* [internetgateway2](https://godoc.org/github.com/huin/goupnp/dcps/internetgateway2) - Client for UPnP Device Control Protocol Internet Gateway Device v2.
|
|
||||||
|
|
||||||
Core components:
|
|
||||||
* [(goupnp)](https://godoc.org/github.com/huin/goupnp) core library - contains datastructures and utilities typically used by the implemented DCPs.
|
|
||||||
* [httpu](https://godoc.org/github.com/huin/goupnp/httpu) HTTPU implementation, underlies SSDP.
|
|
||||||
* [ssdp](https://godoc.org/github.com/huin/goupnp/ssdp) SSDP client implementation (simple service discovery protocol) - used to discover UPnP services on a network.
|
|
||||||
* [soap](https://godoc.org/github.com/huin/goupnp/soap) SOAP client implementation (simple object access protocol) - used to communicate with discovered services.
|
|
||||||
|
|
||||||
|
|
||||||
Regenerating dcps generated source code:
|
|
||||||
----------------------------------------
|
|
||||||
|
|
||||||
1. Install gotasks: `go get -u github.com/jingweno/gotask`
|
|
||||||
2. Change to the gotasks directory: `cd gotasks`
|
|
||||||
3. Run specgen task: `gotask specgen`
|
|
||||||
|
|
||||||
Supporting additional UPnP devices and services:
|
|
||||||
------------------------------------------------
|
|
||||||
|
|
||||||
Supporting additional services is, in the trivial case, simply a matter of
|
|
||||||
adding the service to the `dcpMetadata` whitelist in `gotasks/specgen_task.go`,
|
|
||||||
regenerating the source code (see above), and committing that source code.
|
|
||||||
|
|
||||||
However, it would be helpful if anyone needing such a service could test the
|
|
||||||
service against the service they have, and then reporting any trouble
|
|
||||||
encountered as an [issue on this
|
|
||||||
project](https://github.com/huin/goupnp/issues/new). If it just works, then
|
|
||||||
please report at least minimal working functionality as an issue, and
|
|
||||||
optionally contribute the metadata upstream.
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/huin/goupnp/httpu"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
srv := httpu.Server{
|
|
||||||
Addr: "239.255.255.250:1900",
|
|
||||||
Multicast: true,
|
|
||||||
Handler: httpu.HandlerFunc(func(r *http.Request) {
|
|
||||||
log.Printf("Got %s %s message from %v: %v", r.Method, r.URL.Path, r.RemoteAddr, r.Header)
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
err := srv.ListenAndServe()
|
|
||||||
log.Printf("Serving failed with error: %v", err)
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/huin/goupnp/dcps/internetgateway1"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
clients, errors, err := internetgateway1.NewWANPPPConnection1Clients()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Got %d errors finding servers and %d successfully discovered.\n",
|
|
||||||
len(errors), len(clients))
|
|
||||||
for i, e := range errors {
|
|
||||||
fmt.Printf("Error finding server #%d: %v\n", i+1, e)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, c := range clients {
|
|
||||||
dev := &c.ServiceClient.RootDevice.Device
|
|
||||||
srv := c.ServiceClient.Service
|
|
||||||
fmt.Println(dev.FriendlyName, " :: ", srv.String())
|
|
||||||
scpd, err := srv.RequestSCDP()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf(" Error requesting service SCPD: %v\n", err)
|
|
||||||
} else {
|
|
||||||
fmt.Println(" Available actions:")
|
|
||||||
for _, action := range scpd.Actions {
|
|
||||||
fmt.Printf(" * %s\n", action.Name)
|
|
||||||
for _, arg := range action.Arguments {
|
|
||||||
var varDesc string
|
|
||||||
if stateVar := scpd.GetStateVariable(arg.RelatedStateVariable); stateVar != nil {
|
|
||||||
varDesc = fmt.Sprintf(" (%s)", stateVar.DataType.Name)
|
|
||||||
}
|
|
||||||
fmt.Printf(" * [%s] %s%s\n", arg.Direction, arg.Name, varDesc)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if scpd == nil || scpd.GetAction("GetExternalIPAddress") != nil {
|
|
||||||
ip, err := c.GetExternalIPAddress()
|
|
||||||
fmt.Println("GetExternalIPAddress: ", ip, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if scpd == nil || scpd.GetAction("GetStatusInfo") != nil {
|
|
||||||
status, lastErr, uptime, err := c.GetStatusInfo()
|
|
||||||
fmt.Println("GetStatusInfo: ", status, lastErr, uptime, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if scpd == nil || scpd.GetAction("GetIdleDisconnectTime") != nil {
|
|
||||||
idleTime, err := c.GetIdleDisconnectTime()
|
|
||||||
fmt.Println("GetIdleDisconnectTime: ", idleTime, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if scpd == nil || scpd.GetAction("AddPortMapping") != nil {
|
|
||||||
err := c.AddPortMapping("", 5000, "TCP", 5001, "192.168.1.2", true, "Test port mapping", 0)
|
|
||||||
fmt.Println("AddPortMapping: ", err)
|
|
||||||
}
|
|
||||||
if scpd == nil || scpd.GetAction("DeletePortMapping") != nil {
|
|
||||||
err := c.DeletePortMapping("", 5000, "TCP")
|
|
||||||
fmt.Println("DeletePortMapping: ", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/huin/goupnp/ssdp"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
c := make(chan ssdp.Update)
|
|
||||||
srv, reg := ssdp.NewServerAndRegistry()
|
|
||||||
reg.AddListener(c)
|
|
||||||
go listener(c)
|
|
||||||
if err := srv.ListenAndServe(); err != nil {
|
|
||||||
log.Print("ListenAndServe failed: ", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func listener(c <-chan ssdp.Update) {
|
|
||||||
for u := range c {
|
|
||||||
if u.Entry != nil {
|
|
||||||
log.Printf("Event: %v USN: %s Entry: %#v", u.EventType, u.USN, *u.Entry)
|
|
||||||
} else {
|
|
||||||
log.Printf("Event: %v USN: %s Entry: <nil>", u.EventType, u.USN)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
8452
Godeps/_workspace/src/github.com/huin/goupnp/dcps/av1/av1.go
generated
vendored
8452
Godeps/_workspace/src/github.com/huin/goupnp/dcps/av1/av1.go
generated
vendored
File diff suppressed because it is too large
Load Diff
6
Godeps/_workspace/src/github.com/huin/goupnp/example/example.go
generated
vendored
6
Godeps/_workspace/src/github.com/huin/goupnp/example/example.go
generated
vendored
@@ -1,6 +0,0 @@
|
|||||||
// Serves as examples of using the goupnp library.
|
|
||||||
//
|
|
||||||
// To run examples and see the output for your local network, run the following
|
|
||||||
// command (specifically including the -v flag):
|
|
||||||
// go test -v github.com/huin/goupnp/example
|
|
||||||
package example
|
|
||||||
603
Godeps/_workspace/src/github.com/huin/goupnp/gotasks/specgen_task.go
generated
vendored
603
Godeps/_workspace/src/github.com/huin/goupnp/gotasks/specgen_task.go
generated
vendored
@@ -1,603 +0,0 @@
|
|||||||
// +build gotask
|
|
||||||
|
|
||||||
package gotasks
|
|
||||||
|
|
||||||
import (
|
|
||||||
"archive/zip"
|
|
||||||
"encoding/xml"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
"text/template"
|
|
||||||
|
|
||||||
"github.com/huin/goupnp"
|
|
||||||
"github.com/huin/goupnp/scpd"
|
|
||||||
"github.com/huin/goutil/codegen"
|
|
||||||
"github.com/jingweno/gotask/tasking"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
deviceURNPrefix = "urn:schemas-upnp-org:device:"
|
|
||||||
serviceURNPrefix = "urn:schemas-upnp-org:service:"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DCP contains extra metadata to use when generating DCP source files.
|
|
||||||
type DCPMetadata struct {
|
|
||||||
Name string // What to name the Go DCP package.
|
|
||||||
OfficialName string // Official name for the DCP.
|
|
||||||
DocURL string // Optional - URL for futher documentation about the DCP.
|
|
||||||
XMLSpecURL string // Where to download the XML spec from.
|
|
||||||
// Any special-case functions to run against the DCP before writing it out.
|
|
||||||
Hacks []DCPHackFn
|
|
||||||
}
|
|
||||||
|
|
||||||
var dcpMetadata = []DCPMetadata{
|
|
||||||
{
|
|
||||||
Name: "internetgateway1",
|
|
||||||
OfficialName: "Internet Gateway Device v1",
|
|
||||||
DocURL: "http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf",
|
|
||||||
XMLSpecURL: "http://upnp.org/specs/gw/UPnP-gw-IGD-TestFiles-20010921.zip",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "internetgateway2",
|
|
||||||
OfficialName: "Internet Gateway Device v2",
|
|
||||||
DocURL: "http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v2-Device.pdf",
|
|
||||||
XMLSpecURL: "http://upnp.org/specs/gw/UPnP-gw-IGD-Testfiles-20110224.zip",
|
|
||||||
Hacks: []DCPHackFn{
|
|
||||||
func(dcp *DCP) error {
|
|
||||||
missingURN := "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1"
|
|
||||||
if _, ok := dcp.ServiceTypes[missingURN]; ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
urnParts, err := extractURNParts(missingURN, serviceURNPrefix)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
dcp.ServiceTypes[missingURN] = urnParts
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "av1",
|
|
||||||
OfficialName: "MediaServer v1 and MediaRenderer v1",
|
|
||||||
DocURL: "http://upnp.org/specs/av/av1/",
|
|
||||||
XMLSpecURL: "http://upnp.org/specs/av/UPnP-av-TestFiles-20070927.zip",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
type DCPHackFn func(*DCP) error
|
|
||||||
|
|
||||||
// NAME
|
|
||||||
// specgen - generates Go code from the UPnP specification files.
|
|
||||||
//
|
|
||||||
// DESCRIPTION
|
|
||||||
// The specification is available for download from:
|
|
||||||
//
|
|
||||||
// OPTIONS
|
|
||||||
// -s, --specs_dir=<spec directory>
|
|
||||||
// Path to the specification storage directory. This is used to find (and download if not present) the specification ZIP files. Defaults to 'specs'
|
|
||||||
// -o, --out_dir=<output directory>
|
|
||||||
// Path to the output directory. This is is where the DCP source files will be placed. Should normally correspond to the directory for github.com/huin/goupnp/dcps. Defaults to '../dcps'
|
|
||||||
// --nogofmt
|
|
||||||
// Disable passing the output through gofmt. Do this if debugging code output problems and needing to see the generated code prior to being passed through gofmt.
|
|
||||||
func TaskSpecgen(t *tasking.T) {
|
|
||||||
specsDir := fallbackStrValue("specs", t.Flags.String("specs_dir"), t.Flags.String("s"))
|
|
||||||
if err := os.MkdirAll(specsDir, os.ModePerm); err != nil {
|
|
||||||
t.Fatalf("Could not create specs-dir %q: %v\n", specsDir, err)
|
|
||||||
}
|
|
||||||
outDir := fallbackStrValue("../dcps", t.Flags.String("out_dir"), t.Flags.String("o"))
|
|
||||||
useGofmt := !t.Flags.Bool("nogofmt")
|
|
||||||
|
|
||||||
NEXT_DCP:
|
|
||||||
for _, d := range dcpMetadata {
|
|
||||||
specFilename := filepath.Join(specsDir, d.Name+".zip")
|
|
||||||
err := acquireFile(specFilename, d.XMLSpecURL)
|
|
||||||
if err != nil {
|
|
||||||
t.Logf("Could not acquire spec for %s, skipping: %v\n", d.Name, err)
|
|
||||||
continue NEXT_DCP
|
|
||||||
}
|
|
||||||
dcp := newDCP(d)
|
|
||||||
if err := dcp.processZipFile(specFilename); err != nil {
|
|
||||||
log.Printf("Error processing spec for %s in file %q: %v", d.Name, specFilename, err)
|
|
||||||
continue NEXT_DCP
|
|
||||||
}
|
|
||||||
for i, hack := range d.Hacks {
|
|
||||||
if err := hack(dcp); err != nil {
|
|
||||||
log.Printf("Error with Hack[%d] for %s: %v", i, d.Name, err)
|
|
||||||
continue NEXT_DCP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dcp.writePackage(outDir, useGofmt)
|
|
||||||
if err := dcp.writePackage(outDir, useGofmt); err != nil {
|
|
||||||
log.Printf("Error writing package %q: %v", dcp.Metadata.Name, err)
|
|
||||||
continue NEXT_DCP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func fallbackStrValue(defaultValue string, values ...string) string {
|
|
||||||
for _, v := range values {
|
|
||||||
if v != "" {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
|
|
||||||
func acquireFile(specFilename string, xmlSpecURL string) error {
|
|
||||||
if f, err := os.Open(specFilename); err != nil {
|
|
||||||
if !os.IsNotExist(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
f.Close()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := http.Get(xmlSpecURL)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return fmt.Errorf("could not download spec %q from %q: ",
|
|
||||||
specFilename, xmlSpecURL, resp.Status)
|
|
||||||
}
|
|
||||||
|
|
||||||
tmpFilename := specFilename + ".download"
|
|
||||||
w, err := os.Create(tmpFilename)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer w.Close()
|
|
||||||
|
|
||||||
_, err = io.Copy(w, resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return os.Rename(tmpFilename, specFilename)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DCP collects together information about a UPnP Device Control Protocol.
|
|
||||||
type DCP struct {
|
|
||||||
Metadata DCPMetadata
|
|
||||||
DeviceTypes map[string]*URNParts
|
|
||||||
ServiceTypes map[string]*URNParts
|
|
||||||
Services []SCPDWithURN
|
|
||||||
}
|
|
||||||
|
|
||||||
func newDCP(metadata DCPMetadata) *DCP {
|
|
||||||
return &DCP{
|
|
||||||
Metadata: metadata,
|
|
||||||
DeviceTypes: make(map[string]*URNParts),
|
|
||||||
ServiceTypes: make(map[string]*URNParts),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dcp *DCP) processZipFile(filename string) error {
|
|
||||||
archive, err := zip.OpenReader(filename)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error reading zip file %q: %v", filename, err)
|
|
||||||
}
|
|
||||||
defer archive.Close()
|
|
||||||
for _, deviceFile := range globFiles("*/device/*.xml", archive) {
|
|
||||||
if err := dcp.processDeviceFile(deviceFile); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, scpdFile := range globFiles("*/service/*.xml", archive) {
|
|
||||||
if err := dcp.processSCPDFile(scpdFile); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dcp *DCP) processDeviceFile(file *zip.File) error {
|
|
||||||
var device goupnp.Device
|
|
||||||
if err := unmarshalXmlFile(file, &device); err != nil {
|
|
||||||
return fmt.Errorf("error decoding device XML from file %q: %v", file.Name, err)
|
|
||||||
}
|
|
||||||
var mainErr error
|
|
||||||
device.VisitDevices(func(d *goupnp.Device) {
|
|
||||||
t := strings.TrimSpace(d.DeviceType)
|
|
||||||
if t != "" {
|
|
||||||
u, err := extractURNParts(t, deviceURNPrefix)
|
|
||||||
if err != nil {
|
|
||||||
mainErr = err
|
|
||||||
}
|
|
||||||
dcp.DeviceTypes[t] = u
|
|
||||||
}
|
|
||||||
})
|
|
||||||
device.VisitServices(func(s *goupnp.Service) {
|
|
||||||
u, err := extractURNParts(s.ServiceType, serviceURNPrefix)
|
|
||||||
if err != nil {
|
|
||||||
mainErr = err
|
|
||||||
}
|
|
||||||
dcp.ServiceTypes[s.ServiceType] = u
|
|
||||||
})
|
|
||||||
return mainErr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dcp *DCP) writePackage(outDir string, useGofmt bool) error {
|
|
||||||
packageDirname := filepath.Join(outDir, dcp.Metadata.Name)
|
|
||||||
err := os.MkdirAll(packageDirname, os.ModePerm)
|
|
||||||
if err != nil && !os.IsExist(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
packageFilename := filepath.Join(packageDirname, dcp.Metadata.Name+".go")
|
|
||||||
packageFile, err := os.Create(packageFilename)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var output io.WriteCloser = packageFile
|
|
||||||
if useGofmt {
|
|
||||||
if output, err = codegen.NewGofmtWriteCloser(output); err != nil {
|
|
||||||
packageFile.Close()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err = packageTmpl.Execute(output, dcp); err != nil {
|
|
||||||
output.Close()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return output.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dcp *DCP) processSCPDFile(file *zip.File) error {
|
|
||||||
scpd := new(scpd.SCPD)
|
|
||||||
if err := unmarshalXmlFile(file, scpd); err != nil {
|
|
||||||
return fmt.Errorf("error decoding SCPD XML from file %q: %v", file.Name, err)
|
|
||||||
}
|
|
||||||
scpd.Clean()
|
|
||||||
urnParts, err := urnPartsFromSCPDFilename(file.Name)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("could not recognize SCPD filename %q: %v", file.Name, err)
|
|
||||||
}
|
|
||||||
dcp.Services = append(dcp.Services, SCPDWithURN{
|
|
||||||
URNParts: urnParts,
|
|
||||||
SCPD: scpd,
|
|
||||||
})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type SCPDWithURN struct {
|
|
||||||
*URNParts
|
|
||||||
SCPD *scpd.SCPD
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SCPDWithURN) WrapArguments(args []*scpd.Argument) (argumentWrapperList, error) {
|
|
||||||
wrappedArgs := make(argumentWrapperList, len(args))
|
|
||||||
for i, arg := range args {
|
|
||||||
wa, err := s.wrapArgument(arg)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
wrappedArgs[i] = wa
|
|
||||||
}
|
|
||||||
return wrappedArgs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SCPDWithURN) wrapArgument(arg *scpd.Argument) (*argumentWrapper, error) {
|
|
||||||
relVar := s.SCPD.GetStateVariable(arg.RelatedStateVariable)
|
|
||||||
if relVar == nil {
|
|
||||||
return nil, fmt.Errorf("no such state variable: %q, for argument %q", arg.RelatedStateVariable, arg.Name)
|
|
||||||
}
|
|
||||||
cnv, ok := typeConvs[relVar.DataType.Name]
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("unknown data type: %q, for state variable %q, for argument %q", relVar.DataType.Type, arg.RelatedStateVariable, arg.Name)
|
|
||||||
}
|
|
||||||
return &argumentWrapper{
|
|
||||||
Argument: *arg,
|
|
||||||
relVar: relVar,
|
|
||||||
conv: cnv,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type argumentWrapper struct {
|
|
||||||
scpd.Argument
|
|
||||||
relVar *scpd.StateVariable
|
|
||||||
conv conv
|
|
||||||
}
|
|
||||||
|
|
||||||
func (arg *argumentWrapper) AsParameter() string {
|
|
||||||
return fmt.Sprintf("%s %s", arg.Name, arg.conv.ExtType)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (arg *argumentWrapper) HasDoc() bool {
|
|
||||||
rng := arg.relVar.AllowedValueRange
|
|
||||||
return ((rng != nil && (rng.Minimum != "" || rng.Maximum != "" || rng.Step != "")) ||
|
|
||||||
len(arg.relVar.AllowedValues) > 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (arg *argumentWrapper) Document() string {
|
|
||||||
relVar := arg.relVar
|
|
||||||
if rng := relVar.AllowedValueRange; rng != nil {
|
|
||||||
var parts []string
|
|
||||||
if rng.Minimum != "" {
|
|
||||||
parts = append(parts, fmt.Sprintf("minimum=%s", rng.Minimum))
|
|
||||||
}
|
|
||||||
if rng.Maximum != "" {
|
|
||||||
parts = append(parts, fmt.Sprintf("maximum=%s", rng.Maximum))
|
|
||||||
}
|
|
||||||
if rng.Step != "" {
|
|
||||||
parts = append(parts, fmt.Sprintf("step=%s", rng.Step))
|
|
||||||
}
|
|
||||||
return "allowed value range: " + strings.Join(parts, ", ")
|
|
||||||
}
|
|
||||||
if len(relVar.AllowedValues) != 0 {
|
|
||||||
return "allowed values: " + strings.Join(relVar.AllowedValues, ", ")
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (arg *argumentWrapper) Marshal() string {
|
|
||||||
return fmt.Sprintf("soap.Marshal%s(%s)", arg.conv.FuncSuffix, arg.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (arg *argumentWrapper) Unmarshal(objVar string) string {
|
|
||||||
return fmt.Sprintf("soap.Unmarshal%s(%s.%s)", arg.conv.FuncSuffix, objVar, arg.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
type argumentWrapperList []*argumentWrapper
|
|
||||||
|
|
||||||
func (args argumentWrapperList) HasDoc() bool {
|
|
||||||
for _, arg := range args {
|
|
||||||
if arg.HasDoc() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
type conv struct {
|
|
||||||
FuncSuffix string
|
|
||||||
ExtType string
|
|
||||||
}
|
|
||||||
|
|
||||||
// typeConvs maps from a SOAP type (e.g "fixed.14.4") to the function name
|
|
||||||
// suffix inside the soap module (e.g "Fixed14_4") and the Go type.
|
|
||||||
var typeConvs = map[string]conv{
|
|
||||||
"ui1": conv{"Ui1", "uint8"},
|
|
||||||
"ui2": conv{"Ui2", "uint16"},
|
|
||||||
"ui4": conv{"Ui4", "uint32"},
|
|
||||||
"i1": conv{"I1", "int8"},
|
|
||||||
"i2": conv{"I2", "int16"},
|
|
||||||
"i4": conv{"I4", "int32"},
|
|
||||||
"int": conv{"Int", "int64"},
|
|
||||||
"r4": conv{"R4", "float32"},
|
|
||||||
"r8": conv{"R8", "float64"},
|
|
||||||
"number": conv{"R8", "float64"}, // Alias for r8.
|
|
||||||
"fixed.14.4": conv{"Fixed14_4", "float64"},
|
|
||||||
"float": conv{"R8", "float64"},
|
|
||||||
"char": conv{"Char", "rune"},
|
|
||||||
"string": conv{"String", "string"},
|
|
||||||
"date": conv{"Date", "time.Time"},
|
|
||||||
"dateTime": conv{"DateTime", "time.Time"},
|
|
||||||
"dateTime.tz": conv{"DateTimeTz", "time.Time"},
|
|
||||||
"time": conv{"TimeOfDay", "soap.TimeOfDay"},
|
|
||||||
"time.tz": conv{"TimeOfDayTz", "soap.TimeOfDay"},
|
|
||||||
"boolean": conv{"Boolean", "bool"},
|
|
||||||
"bin.base64": conv{"BinBase64", "[]byte"},
|
|
||||||
"bin.hex": conv{"BinHex", "[]byte"},
|
|
||||||
"uri": conv{"URI", "*url.URL"},
|
|
||||||
}
|
|
||||||
|
|
||||||
func globFiles(pattern string, archive *zip.ReadCloser) []*zip.File {
|
|
||||||
var files []*zip.File
|
|
||||||
for _, f := range archive.File {
|
|
||||||
if matched, err := path.Match(pattern, f.Name); err != nil {
|
|
||||||
// This shouldn't happen - all patterns are hard-coded, errors in them
|
|
||||||
// are a programming error.
|
|
||||||
panic(err)
|
|
||||||
} else if matched {
|
|
||||||
files = append(files, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return files
|
|
||||||
}
|
|
||||||
|
|
||||||
func unmarshalXmlFile(file *zip.File, data interface{}) error {
|
|
||||||
r, err := file.Open()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
decoder := xml.NewDecoder(r)
|
|
||||||
r.Close()
|
|
||||||
return decoder.Decode(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
type URNParts struct {
|
|
||||||
URN string
|
|
||||||
Name string
|
|
||||||
Version string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *URNParts) Const() string {
|
|
||||||
return fmt.Sprintf("URN_%s_%s", u.Name, u.Version)
|
|
||||||
}
|
|
||||||
|
|
||||||
// extractURNParts extracts the name and version from a URN string.
|
|
||||||
func extractURNParts(urn, expectedPrefix string) (*URNParts, error) {
|
|
||||||
if !strings.HasPrefix(urn, expectedPrefix) {
|
|
||||||
return nil, fmt.Errorf("%q does not have expected prefix %q", urn, expectedPrefix)
|
|
||||||
}
|
|
||||||
parts := strings.SplitN(strings.TrimPrefix(urn, expectedPrefix), ":", 2)
|
|
||||||
if len(parts) != 2 {
|
|
||||||
return nil, fmt.Errorf("%q does not have a name and version", urn)
|
|
||||||
}
|
|
||||||
name, version := parts[0], parts[1]
|
|
||||||
return &URNParts{urn, name, version}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var scpdFilenameRe = regexp.MustCompile(
|
|
||||||
`.*/([a-zA-Z0-9]+)([0-9]+)\.xml`)
|
|
||||||
|
|
||||||
func urnPartsFromSCPDFilename(filename string) (*URNParts, error) {
|
|
||||||
parts := scpdFilenameRe.FindStringSubmatch(filename)
|
|
||||||
if len(parts) != 3 {
|
|
||||||
return nil, fmt.Errorf("SCPD filename %q does not have expected number of parts", filename)
|
|
||||||
}
|
|
||||||
name, version := parts[1], parts[2]
|
|
||||||
return &URNParts{
|
|
||||||
URN: serviceURNPrefix + name + ":" + version,
|
|
||||||
Name: name,
|
|
||||||
Version: version,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var packageTmpl = template.Must(template.New("package").Parse(`{{$name := .Metadata.Name}}
|
|
||||||
// Client for UPnP Device Control Protocol {{.Metadata.OfficialName}}.
|
|
||||||
// {{if .Metadata.DocURL}}
|
|
||||||
// This DCP is documented in detail at: {{.Metadata.DocURL}}{{end}}
|
|
||||||
//
|
|
||||||
// Typically, use one of the New* functions to create clients for services.
|
|
||||||
package {{$name}}
|
|
||||||
|
|
||||||
// Generated file - do not edit by hand. See README.md
|
|
||||||
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/url"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/huin/goupnp"
|
|
||||||
"github.com/huin/goupnp/soap"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Hack to avoid Go complaining if time isn't used.
|
|
||||||
var _ time.Time
|
|
||||||
|
|
||||||
// Device URNs:
|
|
||||||
const ({{range .DeviceTypes}}
|
|
||||||
{{.Const}} = "{{.URN}}"{{end}}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Service URNs:
|
|
||||||
const ({{range .ServiceTypes}}
|
|
||||||
{{.Const}} = "{{.URN}}"{{end}}
|
|
||||||
)
|
|
||||||
|
|
||||||
{{range .Services}}
|
|
||||||
{{$srv := .}}
|
|
||||||
{{$srvIdent := printf "%s%s" .Name .Version}}
|
|
||||||
|
|
||||||
// {{$srvIdent}} is a client for UPnP SOAP service with URN "{{.URN}}". See
|
|
||||||
// goupnp.ServiceClient, which contains RootDevice and Service attributes which
|
|
||||||
// are provided for informational value.
|
|
||||||
type {{$srvIdent}} struct {
|
|
||||||
goupnp.ServiceClient
|
|
||||||
}
|
|
||||||
|
|
||||||
// New{{$srvIdent}}Clients discovers instances of the service on the network,
|
|
||||||
// and returns clients to any that are found. errors will contain an error for
|
|
||||||
// any devices that replied but which could not be queried, and err will be set
|
|
||||||
// if the discovery process failed outright.
|
|
||||||
//
|
|
||||||
// This is a typical entry calling point into this package.
|
|
||||||
func New{{$srvIdent}}Clients() (clients []*{{$srvIdent}}, errors []error, err error) {
|
|
||||||
var genericClients []goupnp.ServiceClient
|
|
||||||
if genericClients, errors, err = goupnp.NewServiceClients({{$srv.Const}}); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
clients = new{{$srvIdent}}ClientsFromGenericClients(genericClients)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// New{{$srvIdent}}ClientsByURL discovers instances of the service at the given
|
|
||||||
// URL, and returns clients to any that are found. An error is returned if
|
|
||||||
// there was an error probing the service.
|
|
||||||
//
|
|
||||||
// This is a typical entry calling point into this package when reusing an
|
|
||||||
// previously discovered service URL.
|
|
||||||
func New{{$srvIdent}}ClientsByURL(loc *url.URL) ([]*{{$srvIdent}}, error) {
|
|
||||||
genericClients, err := goupnp.NewServiceClientsByURL(loc, {{$srv.Const}})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return new{{$srvIdent}}ClientsFromGenericClients(genericClients), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// New{{$srvIdent}}ClientsFromRootDevice discovers instances of the service in
|
|
||||||
// a given root device, and returns clients to any that are found. An error is
|
|
||||||
// returned if there was not at least one instance of the service within the
|
|
||||||
// device. The location parameter is simply assigned to the Location attribute
|
|
||||||
// of the wrapped ServiceClient(s).
|
|
||||||
//
|
|
||||||
// This is a typical entry calling point into this package when reusing an
|
|
||||||
// previously discovered root device.
|
|
||||||
func New{{$srvIdent}}ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*{{$srvIdent}}, error) {
|
|
||||||
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, {{$srv.Const}})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return new{{$srvIdent}}ClientsFromGenericClients(genericClients), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func new{{$srvIdent}}ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*{{$srvIdent}} {
|
|
||||||
clients := make([]*{{$srvIdent}}, len(genericClients))
|
|
||||||
for i := range genericClients {
|
|
||||||
clients[i] = &{{$srvIdent}}{genericClients[i]}
|
|
||||||
}
|
|
||||||
return clients
|
|
||||||
}
|
|
||||||
|
|
||||||
{{range .SCPD.Actions}}{{/* loops over *SCPDWithURN values */}}
|
|
||||||
|
|
||||||
{{$winargs := $srv.WrapArguments .InputArguments}}
|
|
||||||
{{$woutargs := $srv.WrapArguments .OutputArguments}}
|
|
||||||
{{if $winargs.HasDoc}}
|
|
||||||
//
|
|
||||||
// Arguments:{{range $winargs}}{{if .HasDoc}}
|
|
||||||
//
|
|
||||||
// * {{.Name}}: {{.Document}}{{end}}{{end}}{{end}}
|
|
||||||
{{if $woutargs.HasDoc}}
|
|
||||||
//
|
|
||||||
// Return values:{{range $woutargs}}{{if .HasDoc}}
|
|
||||||
//
|
|
||||||
// * {{.Name}}: {{.Document}}{{end}}{{end}}{{end}}
|
|
||||||
func (client *{{$srvIdent}}) {{.Name}}({{range $winargs}}{{/*
|
|
||||||
*/}}{{.AsParameter}}, {{end}}{{/*
|
|
||||||
*/}}) ({{range $woutargs}}{{/*
|
|
||||||
*/}}{{.AsParameter}}, {{end}} err error) {
|
|
||||||
// Request structure.
|
|
||||||
request := {{if $winargs}}&{{template "argstruct" $winargs}}{{"{}"}}{{else}}{{"interface{}(nil)"}}{{end}}
|
|
||||||
// BEGIN Marshal arguments into request.
|
|
||||||
{{range $winargs}}
|
|
||||||
if request.{{.Name}}, err = {{.Marshal}}; err != nil {
|
|
||||||
return
|
|
||||||
}{{end}}
|
|
||||||
// END Marshal arguments into request.
|
|
||||||
|
|
||||||
// Response structure.
|
|
||||||
response := {{if $woutargs}}&{{template "argstruct" $woutargs}}{{"{}"}}{{else}}{{"interface{}(nil)"}}{{end}}
|
|
||||||
|
|
||||||
// Perform the SOAP call.
|
|
||||||
if err = client.SOAPClient.PerformAction({{$srv.URNParts.Const}}, "{{.Name}}", request, response); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// BEGIN Unmarshal arguments from response.
|
|
||||||
{{range $woutargs}}
|
|
||||||
if {{.Name}}, err = {{.Unmarshal "response"}}; err != nil {
|
|
||||||
return
|
|
||||||
}{{end}}
|
|
||||||
// END Unmarshal arguments from response.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
{{end}}{{/* range .SCPD.Actions */}}
|
|
||||||
{{end}}{{/* range .Services */}}
|
|
||||||
|
|
||||||
{{define "argstruct"}}struct {{"{"}}{{range .}}
|
|
||||||
{{.Name}} string
|
|
||||||
{{end}}{{"}"}}{{end}}
|
|
||||||
`))
|
|
||||||
27
Godeps/_workspace/src/github.com/jackpal/gateway/LICENSE
generated
vendored
27
Godeps/_workspace/src/github.com/jackpal/gateway/LICENSE
generated
vendored
@@ -1,27 +0,0 @@
|
|||||||
// Copyright (c) 2010 Jack Palevich. All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are
|
|
||||||
// met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following disclaimer
|
|
||||||
// in the documentation and/or other materials provided with the
|
|
||||||
// distribution.
|
|
||||||
// * Neither the name of Google Inc. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived from
|
|
||||||
// this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
7
Godeps/_workspace/src/github.com/jackpal/gateway/README.md
generated
vendored
7
Godeps/_workspace/src/github.com/jackpal/gateway/README.md
generated
vendored
@@ -1,7 +0,0 @@
|
|||||||
# gateway
|
|
||||||
|
|
||||||
A very simple library for discovering the IP address of the local LAN gateway.
|
|
||||||
|
|
||||||
Provides implementations for Linux, OS X (Darwin) and Windows.
|
|
||||||
|
|
||||||
Pull requests for other OSs happily considered!
|
|
||||||
40
Godeps/_workspace/src/github.com/jackpal/gateway/gateway_darwin.go
generated
vendored
40
Godeps/_workspace/src/github.com/jackpal/gateway/gateway_darwin.go
generated
vendored
@@ -1,40 +0,0 @@
|
|||||||
package gateway
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
|
||||||
"os/exec"
|
|
||||||
)
|
|
||||||
|
|
||||||
func DiscoverGateway() (ip net.IP, err error) {
|
|
||||||
routeCmd := exec.Command("route", "-n", "get", "0.0.0.0")
|
|
||||||
stdOut, err := routeCmd.StdoutPipe()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = routeCmd.Start(); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
output, err := ioutil.ReadAll(stdOut)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Darwin route out format is always like this:
|
|
||||||
// route to: default
|
|
||||||
// destination: default
|
|
||||||
// mask: default
|
|
||||||
// gateway: 192.168.1.1
|
|
||||||
outputLines := bytes.Split(output, []byte("\n"))
|
|
||||||
for _, line := range outputLines {
|
|
||||||
if bytes.Contains(line, []byte("gateway:")) {
|
|
||||||
gatewayFields := bytes.Fields(line)
|
|
||||||
ip = net.ParseIP(string(gatewayFields[1]))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = routeCmd.Wait()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
75
Godeps/_workspace/src/github.com/jackpal/gateway/gateway_linux.go
generated
vendored
75
Godeps/_workspace/src/github.com/jackpal/gateway/gateway_linux.go
generated
vendored
@@ -1,75 +0,0 @@
|
|||||||
package gateway
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
|
||||||
"os/exec"
|
|
||||||
)
|
|
||||||
|
|
||||||
func discoverGatewayUsingIp() (ip net.IP, err error) {
|
|
||||||
routeCmd := exec.Command("ip", "route", "show")
|
|
||||||
stdOut, err := routeCmd.StdoutPipe()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = routeCmd.Start(); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
output, err := ioutil.ReadAll(stdOut)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Linux 'ip route show' format looks like this:
|
|
||||||
// default via 192.168.178.1 dev wlp3s0 metric 303
|
|
||||||
// 192.168.178.0/24 dev wlp3s0 proto kernel scope link src 192.168.178.76 metric 303
|
|
||||||
outputLines := bytes.Split(output, []byte("\n"))
|
|
||||||
for _, line := range outputLines {
|
|
||||||
if bytes.Contains(line, []byte("default")) {
|
|
||||||
ipFields := bytes.Fields(line)
|
|
||||||
ip = net.ParseIP(string(ipFields[2]))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = routeCmd.Wait()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func discoverGatewayUsingRoute() (ip net.IP, err error) {
|
|
||||||
routeCmd := exec.Command("route", "-n")
|
|
||||||
stdOut, err := routeCmd.StdoutPipe()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = routeCmd.Start(); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
output, err := ioutil.ReadAll(stdOut)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Linux route out format is always like this:
|
|
||||||
// Kernel IP routing table
|
|
||||||
// Destination Gateway Genmask Flags Metric Ref Use Iface
|
|
||||||
// 0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
|
|
||||||
outputLines := bytes.Split(output, []byte("\n"))
|
|
||||||
for _, line := range outputLines {
|
|
||||||
if bytes.Contains(line, []byte("0.0.0.0")) {
|
|
||||||
ipFields := bytes.Fields(line)
|
|
||||||
ip = net.ParseIP(string(ipFields[1]))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = routeCmd.Wait()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func DiscoverGateway() (ip net.IP, err error) {
|
|
||||||
ip, err = discoverGatewayUsingRoute()
|
|
||||||
if err != nil {
|
|
||||||
ip, err = discoverGatewayUsingIp()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
14
Godeps/_workspace/src/github.com/jackpal/gateway/gateway_unimplemented.go
generated
vendored
14
Godeps/_workspace/src/github.com/jackpal/gateway/gateway_unimplemented.go
generated
vendored
@@ -1,14 +0,0 @@
|
|||||||
// +build !darwin,!linux,!windows
|
|
||||||
|
|
||||||
package gateway
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"runtime"
|
|
||||||
)
|
|
||||||
|
|
||||||
func DiscoverGateway() (ip net.IP, err error) {
|
|
||||||
err = fmt.Errorf("DiscoverGateway not implemented for OS %s", runtime.GOOS)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
43
Godeps/_workspace/src/github.com/jackpal/gateway/gateway_windows.go
generated
vendored
43
Godeps/_workspace/src/github.com/jackpal/gateway/gateway_windows.go
generated
vendored
@@ -1,43 +0,0 @@
|
|||||||
package gateway
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
|
||||||
"os/exec"
|
|
||||||
)
|
|
||||||
|
|
||||||
func DiscoverGateway() (ip net.IP, err error) {
|
|
||||||
routeCmd := exec.Command("route", "print", "0.0.0.0")
|
|
||||||
stdOut, err := routeCmd.StdoutPipe()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = routeCmd.Start(); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
output, err := ioutil.ReadAll(stdOut)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Windows route output format is always like this:
|
|
||||||
// ===========================================================================
|
|
||||||
// Active Routes:
|
|
||||||
// Network Destination Netmask Gateway Interface Metric
|
|
||||||
// 0.0.0.0 0.0.0.0 192.168.1.1 192.168.1.100 20
|
|
||||||
// ===========================================================================
|
|
||||||
// I'm trying to pick the active route,
|
|
||||||
// then jump 2 lines and pick the third IP
|
|
||||||
// Not using regex because output is quite standard from Windows XP to 8 (NEEDS TESTING)
|
|
||||||
outputLines := bytes.Split(output, []byte("\n"))
|
|
||||||
for idx, line := range outputLines {
|
|
||||||
if bytes.Contains(line, []byte("Active Routes:")) {
|
|
||||||
ipFields := bytes.Fields(outputLines[idx+2])
|
|
||||||
ip = net.ParseIP(string(ipFields[2]))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = routeCmd.Wait()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
16
Godeps/_workspace/src/github.com/mattn/go-colorable/colorable_others.go
generated
vendored
16
Godeps/_workspace/src/github.com/mattn/go-colorable/colorable_others.go
generated
vendored
@@ -1,16 +0,0 @@
|
|||||||
// +build !windows
|
|
||||||
|
|
||||||
package colorable
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewColorableStdout() io.Writer {
|
|
||||||
return os.Stdout
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewColorableStderr() io.Writer {
|
|
||||||
return os.Stderr
|
|
||||||
}
|
|
||||||
15
Godeps/_workspace/src/github.com/microsoft/go-winio/README.md
generated
vendored
15
Godeps/_workspace/src/github.com/microsoft/go-winio/README.md
generated
vendored
@@ -1,15 +0,0 @@
|
|||||||
# go-winio
|
|
||||||
|
|
||||||
This repository contains utilities for efficiently performing Win32 IO operations in
|
|
||||||
Go. Currently, this is focused on accessing named pipes and other file handles, and
|
|
||||||
for using named pipes as a net transport.
|
|
||||||
|
|
||||||
This code relies on IO completion ports to avoid blocking IO on system threads, allowing Go
|
|
||||||
to reuse the thread to schedule another goroutine. This limits support to Windows Vista and
|
|
||||||
newer operating systems. This is similar to the implementation of network sockets in Go's net
|
|
||||||
package.
|
|
||||||
|
|
||||||
Please see the LICENSE file for licensing information.
|
|
||||||
|
|
||||||
Thanks to natefinch for the inspiration for this library. See https://github.com/natefinch/npipe
|
|
||||||
for another named pipe implementation.
|
|
||||||
266
Godeps/_workspace/src/github.com/microsoft/go-winio/backup.go
generated
vendored
266
Godeps/_workspace/src/github.com/microsoft/go-winio/backup.go
generated
vendored
@@ -1,266 +0,0 @@
|
|||||||
package winio
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"syscall"
|
|
||||||
"unicode/utf16"
|
|
||||||
)
|
|
||||||
|
|
||||||
//sys backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupRead
|
|
||||||
//sys backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupWrite
|
|
||||||
|
|
||||||
const (
|
|
||||||
BackupData = uint32(iota + 1)
|
|
||||||
BackupEaData
|
|
||||||
BackupSecurity
|
|
||||||
BackupAlternateData
|
|
||||||
BackupLink
|
|
||||||
BackupPropertyData
|
|
||||||
BackupObjectId
|
|
||||||
BackupReparseData
|
|
||||||
BackupSparseBlock
|
|
||||||
BackupTxfsData
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
StreamSparseAttributes = uint32(8)
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
WRITE_DAC = 0x40000
|
|
||||||
WRITE_OWNER = 0x80000
|
|
||||||
ACCESS_SYSTEM_SECURITY = 0x1000000
|
|
||||||
)
|
|
||||||
|
|
||||||
// BackupHeader represents a backup stream of a file.
|
|
||||||
type BackupHeader struct {
|
|
||||||
Id uint32 // The backup stream ID
|
|
||||||
Attributes uint32 // Stream attributes
|
|
||||||
Size int64 // The size of the stream in bytes
|
|
||||||
Name string // The name of the stream (for BackupAlternateData only).
|
|
||||||
Offset int64 // The offset of the stream in the file (for BackupSparseBlock only).
|
|
||||||
}
|
|
||||||
|
|
||||||
type win32StreamId struct {
|
|
||||||
StreamId uint32
|
|
||||||
Attributes uint32
|
|
||||||
Size uint64
|
|
||||||
NameSize uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
// BackupStreamReader reads from a stream produced by the BackupRead Win32 API and produces a series
|
|
||||||
// of BackupHeader values.
|
|
||||||
type BackupStreamReader struct {
|
|
||||||
r io.Reader
|
|
||||||
bytesLeft int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBackupStreamReader produces a BackupStreamReader from any io.Reader.
|
|
||||||
func NewBackupStreamReader(r io.Reader) *BackupStreamReader {
|
|
||||||
return &BackupStreamReader{r, 0}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next returns the next backup stream and prepares for calls to Write(). It skips the remainder of the current stream if
|
|
||||||
// it was not completely read.
|
|
||||||
func (r *BackupStreamReader) Next() (*BackupHeader, error) {
|
|
||||||
if r.bytesLeft > 0 {
|
|
||||||
if _, err := io.Copy(ioutil.Discard, r); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var wsi win32StreamId
|
|
||||||
if err := binary.Read(r.r, binary.LittleEndian, &wsi); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
hdr := &BackupHeader{
|
|
||||||
Id: wsi.StreamId,
|
|
||||||
Attributes: wsi.Attributes,
|
|
||||||
Size: int64(wsi.Size),
|
|
||||||
}
|
|
||||||
if wsi.NameSize != 0 {
|
|
||||||
name := make([]uint16, int(wsi.NameSize/2))
|
|
||||||
if err := binary.Read(r.r, binary.LittleEndian, name); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
hdr.Name = syscall.UTF16ToString(name)
|
|
||||||
}
|
|
||||||
if wsi.StreamId == BackupSparseBlock {
|
|
||||||
if err := binary.Read(r.r, binary.LittleEndian, &hdr.Offset); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
hdr.Size -= 8
|
|
||||||
}
|
|
||||||
r.bytesLeft = hdr.Size
|
|
||||||
return hdr, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read reads from the current backup stream.
|
|
||||||
func (r *BackupStreamReader) Read(b []byte) (int, error) {
|
|
||||||
if r.bytesLeft == 0 {
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
if int64(len(b)) > r.bytesLeft {
|
|
||||||
b = b[:r.bytesLeft]
|
|
||||||
}
|
|
||||||
n, err := r.r.Read(b)
|
|
||||||
r.bytesLeft -= int64(n)
|
|
||||||
if err == io.EOF {
|
|
||||||
err = io.ErrUnexpectedEOF
|
|
||||||
} else if r.bytesLeft == 0 && err == nil {
|
|
||||||
err = io.EOF
|
|
||||||
}
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// BackupStreamWriter writes a stream compatible with the BackupWrite Win32 API.
|
|
||||||
type BackupStreamWriter struct {
|
|
||||||
w io.Writer
|
|
||||||
bytesLeft int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBackupStreamWriter produces a BackupStreamWriter on top of an io.Writer.
|
|
||||||
func NewBackupStreamWriter(w io.Writer) *BackupStreamWriter {
|
|
||||||
return &BackupStreamWriter{w, 0}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteHeader writes the next backup stream header and prepares for calls to Write().
|
|
||||||
func (w *BackupStreamWriter) WriteHeader(hdr *BackupHeader) error {
|
|
||||||
if w.bytesLeft != 0 {
|
|
||||||
return fmt.Errorf("missing %d bytes", w.bytesLeft)
|
|
||||||
}
|
|
||||||
name := utf16.Encode([]rune(hdr.Name))
|
|
||||||
wsi := win32StreamId{
|
|
||||||
StreamId: hdr.Id,
|
|
||||||
Attributes: hdr.Attributes,
|
|
||||||
Size: uint64(hdr.Size),
|
|
||||||
NameSize: uint32(len(name) * 2),
|
|
||||||
}
|
|
||||||
if hdr.Id == BackupSparseBlock {
|
|
||||||
// Include space for the int64 block offset
|
|
||||||
wsi.Size += 8
|
|
||||||
}
|
|
||||||
if err := binary.Write(w.w, binary.LittleEndian, &wsi); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if len(name) != 0 {
|
|
||||||
if err := binary.Write(w.w, binary.LittleEndian, name); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if hdr.Id == BackupSparseBlock {
|
|
||||||
if err := binary.Write(w.w, binary.LittleEndian, hdr.Offset); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.bytesLeft = hdr.Size
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write writes to the current backup stream.
|
|
||||||
func (w *BackupStreamWriter) Write(b []byte) (int, error) {
|
|
||||||
if w.bytesLeft < int64(len(b)) {
|
|
||||||
return 0, fmt.Errorf("too many bytes by %d", int64(len(b))-w.bytesLeft)
|
|
||||||
}
|
|
||||||
n, err := w.w.Write(b)
|
|
||||||
w.bytesLeft -= int64(n)
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// BackupFileReader provides an io.ReadCloser interface on top of the BackupRead Win32 API.
|
|
||||||
type BackupFileReader struct {
|
|
||||||
f *os.File
|
|
||||||
includeSecurity bool
|
|
||||||
ctx uintptr
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBackupFileReader returns a new BackupFileReader from a file handle. If includeSecurity is true,
|
|
||||||
// Read will attempt to read the security descriptor of the file.
|
|
||||||
func NewBackupFileReader(f *os.File, includeSecurity bool) *BackupFileReader {
|
|
||||||
r := &BackupFileReader{f, includeSecurity, 0}
|
|
||||||
runtime.SetFinalizer(r, func(r *BackupFileReader) { r.Close() })
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read reads a backup stream from the file by calling the Win32 API BackupRead().
|
|
||||||
func (r *BackupFileReader) Read(b []byte) (int, error) {
|
|
||||||
var bytesRead uint32
|
|
||||||
err := backupRead(syscall.Handle(r.f.Fd()), b, &bytesRead, false, r.includeSecurity, &r.ctx)
|
|
||||||
if err != nil {
|
|
||||||
return 0, &os.PathError{"BackupRead", r.f.Name(), err}
|
|
||||||
}
|
|
||||||
if bytesRead == 0 {
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
return int(bytesRead), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close frees Win32 resources associated with the BackupFileReader. It does not close
|
|
||||||
// the underlying file.
|
|
||||||
func (r *BackupFileReader) Close() error {
|
|
||||||
if r.ctx != 0 {
|
|
||||||
backupRead(syscall.Handle(r.f.Fd()), nil, nil, true, false, &r.ctx)
|
|
||||||
r.ctx = 0
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// BackupFileWriter provides an io.WriteCloser interface on top of the BackupWrite Win32 API.
|
|
||||||
type BackupFileWriter struct {
|
|
||||||
f *os.File
|
|
||||||
includeSecurity bool
|
|
||||||
ctx uintptr
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBackupFileWrtier returns a new BackupFileWriter from a file handle. If includeSecurity is true,
|
|
||||||
// Write() will attempt to restore the security descriptor from the stream.
|
|
||||||
func NewBackupFileWriter(f *os.File, includeSecurity bool) *BackupFileWriter {
|
|
||||||
w := &BackupFileWriter{f, includeSecurity, 0}
|
|
||||||
runtime.SetFinalizer(w, func(w *BackupFileWriter) { w.Close() })
|
|
||||||
return w
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write restores a portion of the file using the provided backup stream.
|
|
||||||
func (w *BackupFileWriter) Write(b []byte) (int, error) {
|
|
||||||
var bytesWritten uint32
|
|
||||||
err := backupWrite(syscall.Handle(w.f.Fd()), b, &bytesWritten, false, w.includeSecurity, &w.ctx)
|
|
||||||
if err != nil {
|
|
||||||
return 0, &os.PathError{"BackupWrite", w.f.Name(), err}
|
|
||||||
}
|
|
||||||
if int(bytesWritten) != len(b) {
|
|
||||||
return int(bytesWritten), errors.New("not all bytes could be written")
|
|
||||||
}
|
|
||||||
return len(b), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close frees Win32 resources associated with the BackupFileWriter. It does not
|
|
||||||
// close the underlying file.
|
|
||||||
func (w *BackupFileWriter) Close() error {
|
|
||||||
if w.ctx != 0 {
|
|
||||||
backupWrite(syscall.Handle(w.f.Fd()), nil, nil, true, false, &w.ctx)
|
|
||||||
w.ctx = 0
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenForBackup opens a file or directory, potentially skipping access checks if the backup
|
|
||||||
// or restore privileges have been acquired.
|
|
||||||
//
|
|
||||||
// If the file opened was a directory, it cannot be used with Readdir().
|
|
||||||
func OpenForBackup(path string, access uint32, share uint32, createmode uint32) (*os.File, error) {
|
|
||||||
winPath, err := syscall.UTF16FromString(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
h, err := syscall.CreateFile(&winPath[0], access, share, nil, createmode, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
|
|
||||||
if err != nil {
|
|
||||||
err = &os.PathError{Op: "open", Path: path, Err: err}
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return os.NewFile(uintptr(h), path), nil
|
|
||||||
}
|
|
||||||
219
Godeps/_workspace/src/github.com/microsoft/go-winio/file.go
generated
vendored
219
Godeps/_workspace/src/github.com/microsoft/go-winio/file.go
generated
vendored
@@ -1,219 +0,0 @@
|
|||||||
package winio
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"runtime"
|
|
||||||
"sync"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
//sys cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) = CancelIoEx
|
|
||||||
//sys createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) = CreateIoCompletionPort
|
|
||||||
//sys getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) = GetQueuedCompletionStatus
|
|
||||||
//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
|
|
||||||
//sys timeBeginPeriod(period uint32) (n int32) = winmm.timeBeginPeriod
|
|
||||||
|
|
||||||
const (
|
|
||||||
cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
|
|
||||||
cFILE_SKIP_SET_EVENT_ON_HANDLE = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrFileClosed = errors.New("file has already been closed")
|
|
||||||
ErrTimeout = &timeoutError{}
|
|
||||||
)
|
|
||||||
|
|
||||||
type timeoutError struct{}
|
|
||||||
|
|
||||||
func (e *timeoutError) Error() string { return "i/o timeout" }
|
|
||||||
func (e *timeoutError) Timeout() bool { return true }
|
|
||||||
func (e *timeoutError) Temporary() bool { return true }
|
|
||||||
|
|
||||||
var ioInitOnce sync.Once
|
|
||||||
var ioCompletionPort syscall.Handle
|
|
||||||
|
|
||||||
// ioResult contains the result of an asynchronous IO operation
|
|
||||||
type ioResult struct {
|
|
||||||
bytes uint32
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
// ioOperation represents an outstanding asynchronous Win32 IO
|
|
||||||
type ioOperation struct {
|
|
||||||
o syscall.Overlapped
|
|
||||||
ch chan ioResult
|
|
||||||
}
|
|
||||||
|
|
||||||
func initIo() {
|
|
||||||
h, err := createIoCompletionPort(syscall.InvalidHandle, 0, 0, 0xffffffff)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
ioCompletionPort = h
|
|
||||||
go ioCompletionProcessor(h)
|
|
||||||
}
|
|
||||||
|
|
||||||
// win32File implements Reader, Writer, and Closer on a Win32 handle without blocking in a syscall.
|
|
||||||
// It takes ownership of this handle and will close it if it is garbage collected.
|
|
||||||
type win32File struct {
|
|
||||||
handle syscall.Handle
|
|
||||||
wg sync.WaitGroup
|
|
||||||
closing bool
|
|
||||||
readDeadline time.Time
|
|
||||||
writeDeadline time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
// makeWin32File makes a new win32File from an existing file handle
|
|
||||||
func makeWin32File(h syscall.Handle) (*win32File, error) {
|
|
||||||
f := &win32File{handle: h}
|
|
||||||
ioInitOnce.Do(initIo)
|
|
||||||
_, err := createIoCompletionPort(h, ioCompletionPort, 0, 0xffffffff)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = setFileCompletionNotificationModes(h, cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS|cFILE_SKIP_SET_EVENT_ON_HANDLE)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
runtime.SetFinalizer(f, (*win32File).closeHandle)
|
|
||||||
return f, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) {
|
|
||||||
return makeWin32File(h)
|
|
||||||
}
|
|
||||||
|
|
||||||
// closeHandle closes the resources associated with a Win32 handle
|
|
||||||
func (f *win32File) closeHandle() {
|
|
||||||
if !f.closing {
|
|
||||||
// cancel all IO and wait for it to complete
|
|
||||||
f.closing = true
|
|
||||||
cancelIoEx(f.handle, nil)
|
|
||||||
f.wg.Wait()
|
|
||||||
// at this point, no new IO can start
|
|
||||||
syscall.Close(f.handle)
|
|
||||||
f.handle = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close closes a win32File.
|
|
||||||
func (f *win32File) Close() error {
|
|
||||||
f.closeHandle()
|
|
||||||
runtime.SetFinalizer(f, nil)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepareIo prepares for a new IO operation
|
|
||||||
func (f *win32File) prepareIo() (*ioOperation, error) {
|
|
||||||
f.wg.Add(1)
|
|
||||||
if f.closing {
|
|
||||||
return nil, ErrFileClosed
|
|
||||||
}
|
|
||||||
c := &ioOperation{}
|
|
||||||
c.ch = make(chan ioResult)
|
|
||||||
return c, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ioCompletionProcessor processes completed async IOs forever
|
|
||||||
func ioCompletionProcessor(h syscall.Handle) {
|
|
||||||
// Set the timer resolution to 1. This fixes a performance regression in golang 1.6.
|
|
||||||
timeBeginPeriod(1)
|
|
||||||
for {
|
|
||||||
var bytes uint32
|
|
||||||
var key uintptr
|
|
||||||
var op *ioOperation
|
|
||||||
err := getQueuedCompletionStatus(h, &bytes, &key, &op, syscall.INFINITE)
|
|
||||||
if op == nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
op.ch <- ioResult{bytes, err}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// asyncIo processes the return value from ReadFile or WriteFile, blocking until
|
|
||||||
// the operation has actually completed.
|
|
||||||
func (f *win32File) asyncIo(c *ioOperation, deadline time.Time, bytes uint32, err error) (int, error) {
|
|
||||||
if err != syscall.ERROR_IO_PENDING {
|
|
||||||
f.wg.Done()
|
|
||||||
return int(bytes), err
|
|
||||||
} else {
|
|
||||||
var r ioResult
|
|
||||||
wait := true
|
|
||||||
timedout := false
|
|
||||||
if f.closing {
|
|
||||||
cancelIoEx(f.handle, &c.o)
|
|
||||||
} else if !deadline.IsZero() {
|
|
||||||
now := time.Now()
|
|
||||||
if !deadline.After(now) {
|
|
||||||
timedout = true
|
|
||||||
} else {
|
|
||||||
timeout := time.After(deadline.Sub(now))
|
|
||||||
select {
|
|
||||||
case r = <-c.ch:
|
|
||||||
wait = false
|
|
||||||
case <-timeout:
|
|
||||||
timedout = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if timedout {
|
|
||||||
cancelIoEx(f.handle, &c.o)
|
|
||||||
}
|
|
||||||
if wait {
|
|
||||||
r = <-c.ch
|
|
||||||
}
|
|
||||||
err = r.err
|
|
||||||
if err == syscall.ERROR_OPERATION_ABORTED {
|
|
||||||
if f.closing {
|
|
||||||
err = ErrFileClosed
|
|
||||||
} else if timedout {
|
|
||||||
err = ErrTimeout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f.wg.Done()
|
|
||||||
return int(r.bytes), err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read reads from a file handle.
|
|
||||||
func (f *win32File) Read(b []byte) (int, error) {
|
|
||||||
c, err := f.prepareIo()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
var bytes uint32
|
|
||||||
err = syscall.ReadFile(f.handle, b, &bytes, &c.o)
|
|
||||||
n, err := f.asyncIo(c, f.readDeadline, bytes, err)
|
|
||||||
|
|
||||||
// Handle EOF conditions.
|
|
||||||
if err == nil && n == 0 && len(b) != 0 {
|
|
||||||
return 0, io.EOF
|
|
||||||
} else if err == syscall.ERROR_BROKEN_PIPE {
|
|
||||||
return 0, io.EOF
|
|
||||||
} else {
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write writes to a file handle.
|
|
||||||
func (f *win32File) Write(b []byte) (int, error) {
|
|
||||||
c, err := f.prepareIo()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
var bytes uint32
|
|
||||||
err = syscall.WriteFile(f.handle, b, &bytes, &c.o)
|
|
||||||
return f.asyncIo(c, f.writeDeadline, bytes, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *win32File) SetReadDeadline(t time.Time) error {
|
|
||||||
f.readDeadline = t
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *win32File) SetWriteDeadline(t time.Time) error {
|
|
||||||
f.writeDeadline = t
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
54
Godeps/_workspace/src/github.com/microsoft/go-winio/fileinfo.go
generated
vendored
54
Godeps/_workspace/src/github.com/microsoft/go-winio/fileinfo.go
generated
vendored
@@ -1,54 +0,0 @@
|
|||||||
package winio
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
//sys getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = GetFileInformationByHandleEx
|
|
||||||
//sys setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = SetFileInformationByHandle
|
|
||||||
|
|
||||||
const (
|
|
||||||
fileBasicInfo = 0
|
|
||||||
fileIDInfo = 0x12
|
|
||||||
)
|
|
||||||
|
|
||||||
// FileBasicInfo contains file access time and file attributes information.
|
|
||||||
type FileBasicInfo struct {
|
|
||||||
CreationTime, LastAccessTime, LastWriteTime, ChangeTime syscall.Filetime
|
|
||||||
FileAttributes uintptr // includes padding
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetFileBasicInfo retrieves times and attributes for a file.
|
|
||||||
func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) {
|
|
||||||
bi := &FileBasicInfo{}
|
|
||||||
if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
|
|
||||||
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
|
|
||||||
}
|
|
||||||
return bi, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetFileBasicInfo sets times and attributes for a file.
|
|
||||||
func SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error {
|
|
||||||
if err := setFileInformationByHandle(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
|
|
||||||
return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileIDInfo contains the volume serial number and file ID for a file. This pair should be
|
|
||||||
// unique on a system.
|
|
||||||
type FileIDInfo struct {
|
|
||||||
VolumeSerialNumber uint64
|
|
||||||
FileID [16]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetFileID retrieves the unique (volume, file ID) pair for a file.
|
|
||||||
func GetFileID(f *os.File) (*FileIDInfo, error) {
|
|
||||||
fileID := &FileIDInfo{}
|
|
||||||
if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileIDInfo, (*byte)(unsafe.Pointer(fileID)), uint32(unsafe.Sizeof(*fileID))); err != nil {
|
|
||||||
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
|
|
||||||
}
|
|
||||||
return fileID, nil
|
|
||||||
}
|
|
||||||
398
Godeps/_workspace/src/github.com/microsoft/go-winio/pipe.go
generated
vendored
398
Godeps/_workspace/src/github.com/microsoft/go-winio/pipe.go
generated
vendored
@@ -1,398 +0,0 @@
|
|||||||
package winio
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
//sys connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) = ConnectNamedPipe
|
|
||||||
//sys createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *securityAttributes) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateNamedPipeW
|
|
||||||
//sys createFile(name string, access uint32, mode uint32, sa *securityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateFileW
|
|
||||||
//sys waitNamedPipe(name string, timeout uint32) (err error) = WaitNamedPipeW
|
|
||||||
//sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo
|
|
||||||
//sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
|
|
||||||
|
|
||||||
type securityAttributes struct {
|
|
||||||
Length uint32
|
|
||||||
SecurityDescriptor *byte
|
|
||||||
InheritHandle uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
cERROR_PIPE_BUSY = syscall.Errno(231)
|
|
||||||
cERROR_PIPE_CONNECTED = syscall.Errno(535)
|
|
||||||
cERROR_SEM_TIMEOUT = syscall.Errno(121)
|
|
||||||
|
|
||||||
cPIPE_ACCESS_DUPLEX = 0x3
|
|
||||||
cFILE_FLAG_FIRST_PIPE_INSTANCE = 0x80000
|
|
||||||
cSECURITY_SQOS_PRESENT = 0x100000
|
|
||||||
cSECURITY_ANONYMOUS = 0
|
|
||||||
|
|
||||||
cPIPE_REJECT_REMOTE_CLIENTS = 0x8
|
|
||||||
|
|
||||||
cPIPE_UNLIMITED_INSTANCES = 255
|
|
||||||
|
|
||||||
cNMPWAIT_USE_DEFAULT_WAIT = 0
|
|
||||||
cNMPWAIT_NOWAIT = 1
|
|
||||||
|
|
||||||
cPIPE_TYPE_MESSAGE = 4
|
|
||||||
|
|
||||||
cPIPE_READMODE_MESSAGE = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrPipeListenerClosed is returned for pipe operations on listeners that have been closed.
|
|
||||||
// This error should match net.errClosing since docker takes a dependency on its text.
|
|
||||||
ErrPipeListenerClosed = errors.New("use of closed network connection")
|
|
||||||
|
|
||||||
errPipeWriteClosed = errors.New("pipe has been closed for write")
|
|
||||||
)
|
|
||||||
|
|
||||||
type win32Pipe struct {
|
|
||||||
*win32File
|
|
||||||
path string
|
|
||||||
}
|
|
||||||
|
|
||||||
type win32MessageBytePipe struct {
|
|
||||||
win32Pipe
|
|
||||||
writeClosed bool
|
|
||||||
readEOF bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type pipeAddress string
|
|
||||||
|
|
||||||
func (f *win32Pipe) LocalAddr() net.Addr {
|
|
||||||
return pipeAddress(f.path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *win32Pipe) RemoteAddr() net.Addr {
|
|
||||||
return pipeAddress(f.path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *win32Pipe) SetDeadline(t time.Time) error {
|
|
||||||
f.SetReadDeadline(t)
|
|
||||||
f.SetWriteDeadline(t)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CloseWrite closes the write side of a message pipe in byte mode.
|
|
||||||
func (f *win32MessageBytePipe) CloseWrite() error {
|
|
||||||
if f.writeClosed {
|
|
||||||
return errPipeWriteClosed
|
|
||||||
}
|
|
||||||
_, err := f.win32File.Write(nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
f.writeClosed = true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write writes bytes to a message pipe in byte mode. Zero-byte writes are ignored, since
|
|
||||||
// they are used to implement CloseWrite().
|
|
||||||
func (f *win32MessageBytePipe) Write(b []byte) (int, error) {
|
|
||||||
if f.writeClosed {
|
|
||||||
return 0, errPipeWriteClosed
|
|
||||||
}
|
|
||||||
if len(b) == 0 {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return f.win32File.Write(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read reads bytes from a message pipe in byte mode. A read of a zero-byte message on a message
|
|
||||||
// mode pipe will return io.EOF, as will all subsequent reads.
|
|
||||||
func (f *win32MessageBytePipe) Read(b []byte) (int, error) {
|
|
||||||
if f.readEOF {
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
n, err := f.win32File.Read(b)
|
|
||||||
if err == io.EOF {
|
|
||||||
// If this was the result of a zero-byte read, then
|
|
||||||
// it is possible that the read was due to a zero-size
|
|
||||||
// message. Since we are simulating CloseWrite with a
|
|
||||||
// zero-byte message, ensure that all future Read() calls
|
|
||||||
// also return EOF.
|
|
||||||
f.readEOF = true
|
|
||||||
}
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s pipeAddress) Network() string {
|
|
||||||
return "pipe"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s pipeAddress) String() string {
|
|
||||||
return string(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DialPipe connects to a named pipe by path, timing out if the connection
|
|
||||||
// takes longer than the specified duration. If timeout is nil, then the timeout
|
|
||||||
// is the default timeout established by the pipe server.
|
|
||||||
func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
|
|
||||||
var absTimeout time.Time
|
|
||||||
if timeout != nil {
|
|
||||||
absTimeout = time.Now().Add(*timeout)
|
|
||||||
}
|
|
||||||
var err error
|
|
||||||
var h syscall.Handle
|
|
||||||
for {
|
|
||||||
h, err = createFile(path, syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_OVERLAPPED|cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0)
|
|
||||||
if err != cERROR_PIPE_BUSY {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
now := time.Now()
|
|
||||||
var ms uint32
|
|
||||||
if absTimeout.IsZero() {
|
|
||||||
ms = cNMPWAIT_USE_DEFAULT_WAIT
|
|
||||||
} else if now.After(absTimeout) {
|
|
||||||
ms = cNMPWAIT_NOWAIT
|
|
||||||
} else {
|
|
||||||
ms = uint32(absTimeout.Sub(now).Nanoseconds() / 1000 / 1000)
|
|
||||||
}
|
|
||||||
err = waitNamedPipe(path, ms)
|
|
||||||
if err != nil {
|
|
||||||
if err == cERROR_SEM_TIMEOUT {
|
|
||||||
return nil, ErrTimeout
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, &os.PathError{Op: "open", Path: path, Err: err}
|
|
||||||
}
|
|
||||||
|
|
||||||
var flags uint32
|
|
||||||
err = getNamedPipeInfo(h, &flags, nil, nil, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var state uint32
|
|
||||||
err = getNamedPipeHandleState(h, &state, nil, nil, nil, nil, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if state&cPIPE_READMODE_MESSAGE != 0 {
|
|
||||||
return nil, &os.PathError{Op: "open", Path: path, Err: errors.New("message readmode pipes not supported")}
|
|
||||||
}
|
|
||||||
|
|
||||||
f, err := makeWin32File(h)
|
|
||||||
if err != nil {
|
|
||||||
syscall.Close(h)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the pipe is in message mode, return a message byte pipe, which
|
|
||||||
// supports CloseWrite().
|
|
||||||
if flags&cPIPE_TYPE_MESSAGE != 0 {
|
|
||||||
return &win32MessageBytePipe{
|
|
||||||
win32Pipe: win32Pipe{win32File: f, path: path},
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
return &win32Pipe{win32File: f, path: path}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type acceptResponse struct {
|
|
||||||
f *win32File
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
type win32PipeListener struct {
|
|
||||||
firstHandle syscall.Handle
|
|
||||||
path string
|
|
||||||
securityDescriptor []byte
|
|
||||||
config PipeConfig
|
|
||||||
acceptCh chan (chan acceptResponse)
|
|
||||||
closeCh chan int
|
|
||||||
doneCh chan int
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeServerPipeHandle(path string, securityDescriptor []byte, c *PipeConfig, first bool) (syscall.Handle, error) {
|
|
||||||
var flags uint32 = cPIPE_ACCESS_DUPLEX | syscall.FILE_FLAG_OVERLAPPED
|
|
||||||
if first {
|
|
||||||
flags |= cFILE_FLAG_FIRST_PIPE_INSTANCE
|
|
||||||
}
|
|
||||||
|
|
||||||
var mode uint32 = cPIPE_REJECT_REMOTE_CLIENTS
|
|
||||||
if c.MessageMode {
|
|
||||||
mode |= cPIPE_TYPE_MESSAGE
|
|
||||||
}
|
|
||||||
|
|
||||||
var sa securityAttributes
|
|
||||||
sa.Length = uint32(unsafe.Sizeof(sa))
|
|
||||||
if securityDescriptor != nil {
|
|
||||||
sa.SecurityDescriptor = &securityDescriptor[0]
|
|
||||||
}
|
|
||||||
h, err := createNamedPipe(path, flags, mode, cPIPE_UNLIMITED_INSTANCES, uint32(c.OutputBufferSize), uint32(c.InputBufferSize), 0, &sa)
|
|
||||||
if err != nil {
|
|
||||||
return 0, &os.PathError{Op: "open", Path: path, Err: err}
|
|
||||||
}
|
|
||||||
return h, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *win32PipeListener) makeServerPipe() (*win32File, error) {
|
|
||||||
h, err := makeServerPipeHandle(l.path, l.securityDescriptor, &l.config, false)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
f, err := makeWin32File(h)
|
|
||||||
if err != nil {
|
|
||||||
syscall.Close(h)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return f, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *win32PipeListener) listenerRoutine() {
|
|
||||||
closed := false
|
|
||||||
for !closed {
|
|
||||||
select {
|
|
||||||
case <-l.closeCh:
|
|
||||||
closed = true
|
|
||||||
case responseCh := <-l.acceptCh:
|
|
||||||
p, err := l.makeServerPipe()
|
|
||||||
if err == nil {
|
|
||||||
// Wait for the client to connect.
|
|
||||||
ch := make(chan error)
|
|
||||||
go func() {
|
|
||||||
ch <- connectPipe(p)
|
|
||||||
}()
|
|
||||||
select {
|
|
||||||
case err = <-ch:
|
|
||||||
if err != nil {
|
|
||||||
p.Close()
|
|
||||||
p = nil
|
|
||||||
}
|
|
||||||
case <-l.closeCh:
|
|
||||||
// Abort the connect request by closing the handle.
|
|
||||||
p.Close()
|
|
||||||
p = nil
|
|
||||||
err = <-ch
|
|
||||||
if err == nil || err == ErrFileClosed {
|
|
||||||
err = ErrPipeListenerClosed
|
|
||||||
}
|
|
||||||
closed = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
responseCh <- acceptResponse{p, err}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
syscall.Close(l.firstHandle)
|
|
||||||
l.firstHandle = 0
|
|
||||||
// Notify Close() and Accept() callers that the handle has been closed.
|
|
||||||
close(l.doneCh)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PipeConfig contain configuration for the pipe listener.
|
|
||||||
type PipeConfig struct {
|
|
||||||
// SecurityDescriptor contains a Windows security descriptor in SDDL format.
|
|
||||||
SecurityDescriptor string
|
|
||||||
|
|
||||||
// MessageMode determines whether the pipe is in byte or message mode. In either
|
|
||||||
// case the pipe is read in byte mode by default. The only practical difference in
|
|
||||||
// this implementation is that CloseWrite() is only supported for message mode pipes;
|
|
||||||
// CloseWrite() is implemented as a zero-byte write, but zero-byte writes are only
|
|
||||||
// transferred to the reader (and returned as io.EOF in this implementation)
|
|
||||||
// when the pipe is in message mode.
|
|
||||||
MessageMode bool
|
|
||||||
|
|
||||||
// InputBufferSize specifies the size the input buffer, in bytes.
|
|
||||||
InputBufferSize int32
|
|
||||||
|
|
||||||
// OutputBufferSize specifies the size the input buffer, in bytes.
|
|
||||||
OutputBufferSize int32
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListenPipe creates a listener on a Windows named pipe path, e.g. \\.\pipe\mypipe.
|
|
||||||
// The pipe must not already exist.
|
|
||||||
func ListenPipe(path string, c *PipeConfig) (net.Listener, error) {
|
|
||||||
var (
|
|
||||||
sd []byte
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
if c == nil {
|
|
||||||
c = &PipeConfig{}
|
|
||||||
}
|
|
||||||
if c.SecurityDescriptor != "" {
|
|
||||||
sd, err = SddlToSecurityDescriptor(c.SecurityDescriptor)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
h, err := makeServerPipeHandle(path, sd, c, true)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// Immediately open and then close a client handle so that the named pipe is
|
|
||||||
// created but not currently accepting connections.
|
|
||||||
h2, err := createFile(path, 0, 0, nil, syscall.OPEN_EXISTING, cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0)
|
|
||||||
if err != nil {
|
|
||||||
syscall.Close(h)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
syscall.Close(h2)
|
|
||||||
l := &win32PipeListener{
|
|
||||||
firstHandle: h,
|
|
||||||
path: path,
|
|
||||||
securityDescriptor: sd,
|
|
||||||
config: *c,
|
|
||||||
acceptCh: make(chan (chan acceptResponse)),
|
|
||||||
closeCh: make(chan int),
|
|
||||||
doneCh: make(chan int),
|
|
||||||
}
|
|
||||||
go l.listenerRoutine()
|
|
||||||
return l, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func connectPipe(p *win32File) error {
|
|
||||||
c, err := p.prepareIo()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = connectNamedPipe(p.handle, &c.o)
|
|
||||||
_, err = p.asyncIo(c, time.Time{}, 0, err)
|
|
||||||
if err != nil && err != cERROR_PIPE_CONNECTED {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *win32PipeListener) Accept() (net.Conn, error) {
|
|
||||||
ch := make(chan acceptResponse)
|
|
||||||
select {
|
|
||||||
case l.acceptCh <- ch:
|
|
||||||
response := <-ch
|
|
||||||
err := response.err
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if l.config.MessageMode {
|
|
||||||
return &win32MessageBytePipe{
|
|
||||||
win32Pipe: win32Pipe{win32File: response.f, path: l.path},
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
return &win32Pipe{win32File: response.f, path: l.path}, nil
|
|
||||||
case <-l.doneCh:
|
|
||||||
return nil, ErrPipeListenerClosed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *win32PipeListener) Close() error {
|
|
||||||
select {
|
|
||||||
case l.closeCh <- 1:
|
|
||||||
<-l.doneCh
|
|
||||||
case <-l.doneCh:
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *win32PipeListener) Addr() net.Addr {
|
|
||||||
return pipeAddress(l.path)
|
|
||||||
}
|
|
||||||
150
Godeps/_workspace/src/github.com/microsoft/go-winio/privilege.go
generated
vendored
150
Godeps/_workspace/src/github.com/microsoft/go-winio/privilege.go
generated
vendored
@@ -1,150 +0,0 @@
|
|||||||
package winio
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
|
||||||
"runtime"
|
|
||||||
"syscall"
|
|
||||||
"unicode/utf16"
|
|
||||||
)
|
|
||||||
|
|
||||||
//sys adjustTokenPrivileges(token syscall.Handle, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) [true] = advapi32.AdjustTokenPrivileges
|
|
||||||
//sys impersonateSelf(level uint32) (err error) = advapi32.ImpersonateSelf
|
|
||||||
//sys revertToSelf() (err error) = advapi32.RevertToSelf
|
|
||||||
//sys openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *syscall.Handle) (err error) = advapi32.OpenThreadToken
|
|
||||||
//sys getCurrentThread() (h syscall.Handle) = GetCurrentThread
|
|
||||||
//sys lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) = advapi32.LookupPrivilegeValueW
|
|
||||||
//sys lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) = advapi32.LookupPrivilegeNameW
|
|
||||||
//sys lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) = advapi32.LookupPrivilegeDisplayNameW
|
|
||||||
|
|
||||||
const (
|
|
||||||
SE_PRIVILEGE_ENABLED = 2
|
|
||||||
|
|
||||||
ERROR_NOT_ALL_ASSIGNED syscall.Errno = 1300
|
|
||||||
|
|
||||||
SeBackupPrivilege = "SeBackupPrivilege"
|
|
||||||
SeRestorePrivilege = "SeRestorePrivilege"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
securityAnonymous = iota
|
|
||||||
securityIdentification
|
|
||||||
securityImpersonation
|
|
||||||
securityDelegation
|
|
||||||
)
|
|
||||||
|
|
||||||
type PrivilegeError struct {
|
|
||||||
privileges []uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *PrivilegeError) Error() string {
|
|
||||||
s := ""
|
|
||||||
if len(e.privileges) > 1 {
|
|
||||||
s = "Could not enable privileges "
|
|
||||||
} else {
|
|
||||||
s = "Could not enable privilege "
|
|
||||||
}
|
|
||||||
for i, p := range e.privileges {
|
|
||||||
if i != 0 {
|
|
||||||
s += ", "
|
|
||||||
}
|
|
||||||
s += `"`
|
|
||||||
s += getPrivilegeName(p)
|
|
||||||
s += `"`
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func RunWithPrivilege(name string, fn func() error) error {
|
|
||||||
return RunWithPrivileges([]string{name}, fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
func RunWithPrivileges(names []string, fn func() error) error {
|
|
||||||
var privileges []uint64
|
|
||||||
for _, name := range names {
|
|
||||||
p := uint64(0)
|
|
||||||
err := lookupPrivilegeValue("", name, &p)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
privileges = append(privileges, p)
|
|
||||||
}
|
|
||||||
runtime.LockOSThread()
|
|
||||||
defer runtime.UnlockOSThread()
|
|
||||||
token, err := newThreadToken()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer releaseThreadToken(token)
|
|
||||||
err = adjustPrivileges(token, privileges)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return fn()
|
|
||||||
}
|
|
||||||
|
|
||||||
func adjustPrivileges(token syscall.Handle, privileges []uint64) error {
|
|
||||||
var b bytes.Buffer
|
|
||||||
binary.Write(&b, binary.LittleEndian, uint32(len(privileges)))
|
|
||||||
for _, p := range privileges {
|
|
||||||
binary.Write(&b, binary.LittleEndian, p)
|
|
||||||
binary.Write(&b, binary.LittleEndian, uint32(SE_PRIVILEGE_ENABLED))
|
|
||||||
}
|
|
||||||
prevState := make([]byte, b.Len())
|
|
||||||
reqSize := uint32(0)
|
|
||||||
success, err := adjustTokenPrivileges(token, false, &b.Bytes()[0], uint32(len(prevState)), &prevState[0], &reqSize)
|
|
||||||
if !success {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err == ERROR_NOT_ALL_ASSIGNED {
|
|
||||||
return &PrivilegeError{privileges}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getPrivilegeName(luid uint64) string {
|
|
||||||
var nameBuffer [256]uint16
|
|
||||||
bufSize := uint32(len(nameBuffer))
|
|
||||||
err := lookupPrivilegeName("", &luid, &nameBuffer[0], &bufSize)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("<unknown privilege %d>", luid)
|
|
||||||
}
|
|
||||||
|
|
||||||
var displayNameBuffer [256]uint16
|
|
||||||
displayBufSize := uint32(len(displayNameBuffer))
|
|
||||||
var langId uint32
|
|
||||||
err = lookupPrivilegeDisplayName("", &nameBuffer[0], &displayNameBuffer[0], &displayBufSize, &langId)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("<unknown privilege %s>", utf16.Decode(nameBuffer[:bufSize]))
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(utf16.Decode(displayNameBuffer[:displayBufSize]))
|
|
||||||
}
|
|
||||||
|
|
||||||
func newThreadToken() (syscall.Handle, error) {
|
|
||||||
err := impersonateSelf(securityImpersonation)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var token syscall.Handle
|
|
||||||
err = openThreadToken(getCurrentThread(), syscall.TOKEN_ADJUST_PRIVILEGES|syscall.TOKEN_QUERY, false, &token)
|
|
||||||
if err != nil {
|
|
||||||
rerr := revertToSelf()
|
|
||||||
if rerr != nil {
|
|
||||||
panic(rerr)
|
|
||||||
}
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return token, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func releaseThreadToken(h syscall.Handle) {
|
|
||||||
err := revertToSelf()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
syscall.Close(h)
|
|
||||||
}
|
|
||||||
124
Godeps/_workspace/src/github.com/microsoft/go-winio/reparse.go
generated
vendored
124
Godeps/_workspace/src/github.com/microsoft/go-winio/reparse.go
generated
vendored
@@ -1,124 +0,0 @@
|
|||||||
package winio
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"unicode/utf16"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
reparseTagMountPoint = 0xA0000003
|
|
||||||
reparseTagSymlink = 0xA000000C
|
|
||||||
)
|
|
||||||
|
|
||||||
type reparseDataBuffer struct {
|
|
||||||
ReparseTag uint32
|
|
||||||
ReparseDataLength uint16
|
|
||||||
Reserved uint16
|
|
||||||
SubstituteNameOffset uint16
|
|
||||||
SubstituteNameLength uint16
|
|
||||||
PrintNameOffset uint16
|
|
||||||
PrintNameLength uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReparsePoint describes a Win32 symlink or mount point.
|
|
||||||
type ReparsePoint struct {
|
|
||||||
Target string
|
|
||||||
IsMountPoint bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnsupportedReparsePointError is returned when trying to decode a non-symlink or
|
|
||||||
// mount point reparse point.
|
|
||||||
type UnsupportedReparsePointError struct {
|
|
||||||
Tag uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *UnsupportedReparsePointError) Error() string {
|
|
||||||
return fmt.Sprintf("unsupported reparse point %x", e.Tag)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeReparsePoint decodes a Win32 REPARSE_DATA_BUFFER structure containing either a symlink
|
|
||||||
// or a mount point.
|
|
||||||
func DecodeReparsePoint(b []byte) (*ReparsePoint, error) {
|
|
||||||
isMountPoint := false
|
|
||||||
tag := binary.LittleEndian.Uint32(b[0:4])
|
|
||||||
switch tag {
|
|
||||||
case reparseTagMountPoint:
|
|
||||||
isMountPoint = true
|
|
||||||
case reparseTagSymlink:
|
|
||||||
default:
|
|
||||||
return nil, &UnsupportedReparsePointError{tag}
|
|
||||||
}
|
|
||||||
nameOffset := 16 + binary.LittleEndian.Uint16(b[12:14])
|
|
||||||
if !isMountPoint {
|
|
||||||
nameOffset += 4
|
|
||||||
}
|
|
||||||
nameLength := binary.LittleEndian.Uint16(b[14:16])
|
|
||||||
name := make([]uint16, nameLength/2)
|
|
||||||
err := binary.Read(bytes.NewReader(b[nameOffset:nameOffset+nameLength]), binary.LittleEndian, &name)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &ReparsePoint{string(utf16.Decode(name)), isMountPoint}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func isDriveLetter(c byte) bool {
|
|
||||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeReparsePoint encodes a Win32 REPARSE_DATA_BUFFER structure describing a symlink or
|
|
||||||
// mount point.
|
|
||||||
func EncodeReparsePoint(rp *ReparsePoint) []byte {
|
|
||||||
// Generate an NT path and determine if this is a relative path.
|
|
||||||
var ntTarget string
|
|
||||||
relative := false
|
|
||||||
if strings.HasPrefix(rp.Target, `\\?\`) {
|
|
||||||
ntTarget = rp.Target
|
|
||||||
} else if strings.HasPrefix(rp.Target, `\\`) {
|
|
||||||
ntTarget = `\??\UNC\` + rp.Target[2:]
|
|
||||||
} else if len(rp.Target) >= 2 && isDriveLetter(rp.Target[0]) && rp.Target[1] == ':' {
|
|
||||||
ntTarget = `\??\` + rp.Target
|
|
||||||
} else {
|
|
||||||
ntTarget = rp.Target
|
|
||||||
relative = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// The paths must be NUL-terminated even though they are counted strings.
|
|
||||||
target16 := utf16.Encode([]rune(rp.Target + "\x00"))
|
|
||||||
ntTarget16 := utf16.Encode([]rune(ntTarget + "\x00"))
|
|
||||||
|
|
||||||
size := int(unsafe.Sizeof(reparseDataBuffer{})) - 8
|
|
||||||
size += len(ntTarget16)*2 + len(target16)*2
|
|
||||||
|
|
||||||
tag := uint32(reparseTagMountPoint)
|
|
||||||
if !rp.IsMountPoint {
|
|
||||||
tag = reparseTagSymlink
|
|
||||||
size += 4 // Add room for symlink flags
|
|
||||||
}
|
|
||||||
|
|
||||||
data := reparseDataBuffer{
|
|
||||||
ReparseTag: tag,
|
|
||||||
ReparseDataLength: uint16(size),
|
|
||||||
SubstituteNameOffset: 0,
|
|
||||||
SubstituteNameLength: uint16((len(ntTarget16) - 1) * 2),
|
|
||||||
PrintNameOffset: uint16(len(ntTarget16) * 2),
|
|
||||||
PrintNameLength: uint16((len(target16) - 1) * 2),
|
|
||||||
}
|
|
||||||
|
|
||||||
var b bytes.Buffer
|
|
||||||
binary.Write(&b, binary.LittleEndian, &data)
|
|
||||||
if !rp.IsMountPoint {
|
|
||||||
flags := uint32(0)
|
|
||||||
if relative {
|
|
||||||
flags |= 1
|
|
||||||
}
|
|
||||||
binary.Write(&b, binary.LittleEndian, flags)
|
|
||||||
}
|
|
||||||
|
|
||||||
binary.Write(&b, binary.LittleEndian, ntTarget16)
|
|
||||||
binary.Write(&b, binary.LittleEndian, target16)
|
|
||||||
return b.Bytes()
|
|
||||||
}
|
|
||||||
96
Godeps/_workspace/src/github.com/microsoft/go-winio/sd.go
generated
vendored
96
Godeps/_workspace/src/github.com/microsoft/go-winio/sd.go
generated
vendored
@@ -1,96 +0,0 @@
|
|||||||
package winio
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
//sys lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) = advapi32.LookupAccountNameW
|
|
||||||
//sys convertSidToStringSid(sid *byte, str **uint16) (err error) = advapi32.ConvertSidToStringSidW
|
|
||||||
//sys convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) = advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW
|
|
||||||
//sys convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) = advapi32.ConvertSecurityDescriptorToStringSecurityDescriptorW
|
|
||||||
//sys localFree(mem uintptr) = LocalFree
|
|
||||||
//sys getSecurityDescriptorLength(sd uintptr) (len uint32) = advapi32.GetSecurityDescriptorLength
|
|
||||||
|
|
||||||
const (
|
|
||||||
cERROR_NONE_MAPPED = syscall.Errno(1332)
|
|
||||||
)
|
|
||||||
|
|
||||||
type AccountLookupError struct {
|
|
||||||
Name string
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *AccountLookupError) Error() string {
|
|
||||||
if e.Name == "" {
|
|
||||||
return "lookup account: empty account name specified"
|
|
||||||
}
|
|
||||||
var s string
|
|
||||||
switch e.Err {
|
|
||||||
case cERROR_NONE_MAPPED:
|
|
||||||
s = "not found"
|
|
||||||
default:
|
|
||||||
s = e.Err.Error()
|
|
||||||
}
|
|
||||||
return "lookup account " + e.Name + ": " + s
|
|
||||||
}
|
|
||||||
|
|
||||||
type SddlConversionError struct {
|
|
||||||
Sddl string
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *SddlConversionError) Error() string {
|
|
||||||
return "convert " + e.Sddl + ": " + e.Err.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// LookupSidByName looks up the SID of an account by name
|
|
||||||
func LookupSidByName(name string) (sid string, err error) {
|
|
||||||
if name == "" {
|
|
||||||
return "", &AccountLookupError{name, cERROR_NONE_MAPPED}
|
|
||||||
}
|
|
||||||
|
|
||||||
var sidSize, sidNameUse, refDomainSize uint32
|
|
||||||
err = lookupAccountName(nil, name, nil, &sidSize, nil, &refDomainSize, &sidNameUse)
|
|
||||||
if err != nil && err != syscall.ERROR_INSUFFICIENT_BUFFER {
|
|
||||||
return "", &AccountLookupError{name, err}
|
|
||||||
}
|
|
||||||
sidBuffer := make([]byte, sidSize)
|
|
||||||
refDomainBuffer := make([]uint16, refDomainSize)
|
|
||||||
err = lookupAccountName(nil, name, &sidBuffer[0], &sidSize, &refDomainBuffer[0], &refDomainSize, &sidNameUse)
|
|
||||||
if err != nil {
|
|
||||||
return "", &AccountLookupError{name, err}
|
|
||||||
}
|
|
||||||
var strBuffer *uint16
|
|
||||||
err = convertSidToStringSid(&sidBuffer[0], &strBuffer)
|
|
||||||
if err != nil {
|
|
||||||
return "", &AccountLookupError{name, err}
|
|
||||||
}
|
|
||||||
sid = syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(strBuffer))[:])
|
|
||||||
localFree(uintptr(unsafe.Pointer(strBuffer)))
|
|
||||||
return sid, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func SddlToSecurityDescriptor(sddl string) ([]byte, error) {
|
|
||||||
var sdBuffer uintptr
|
|
||||||
err := convertStringSecurityDescriptorToSecurityDescriptor(sddl, 1, &sdBuffer, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, &SddlConversionError{sddl, err}
|
|
||||||
}
|
|
||||||
defer localFree(sdBuffer)
|
|
||||||
sd := make([]byte, getSecurityDescriptorLength(sdBuffer))
|
|
||||||
copy(sd, (*[0xffff]byte)(unsafe.Pointer(sdBuffer))[:len(sd)])
|
|
||||||
return sd, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func SecurityDescriptorToSddl(sd []byte) (string, error) {
|
|
||||||
var sddl *uint16
|
|
||||||
// The returned string length seems to including an aribtrary number of terminating NULs.
|
|
||||||
// Don't use it.
|
|
||||||
err := convertSecurityDescriptorToStringSecurityDescriptor(&sd[0], 1, 0xff, &sddl, nil)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
defer localFree(uintptr(unsafe.Pointer(sddl)))
|
|
||||||
return syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(sddl))[:]), nil
|
|
||||||
}
|
|
||||||
3
Godeps/_workspace/src/github.com/microsoft/go-winio/syscall.go
generated
vendored
3
Godeps/_workspace/src/github.com/microsoft/go-winio/syscall.go
generated
vendored
@@ -1,3 +0,0 @@
|
|||||||
package winio
|
|
||||||
|
|
||||||
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall.go file.go pipe.go sd.go fileinfo.go privilege.go backup.go
|
|
||||||
492
Godeps/_workspace/src/github.com/microsoft/go-winio/zsyscall.go
generated
vendored
492
Godeps/_workspace/src/github.com/microsoft/go-winio/zsyscall.go
generated
vendored
@@ -1,492 +0,0 @@
|
|||||||
// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
|
|
||||||
|
|
||||||
package winio
|
|
||||||
|
|
||||||
import "unsafe"
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
var _ unsafe.Pointer
|
|
||||||
|
|
||||||
var (
|
|
||||||
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
|
|
||||||
modwinmm = syscall.NewLazyDLL("winmm.dll")
|
|
||||||
modadvapi32 = syscall.NewLazyDLL("advapi32.dll")
|
|
||||||
|
|
||||||
procCancelIoEx = modkernel32.NewProc("CancelIoEx")
|
|
||||||
procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort")
|
|
||||||
procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
|
|
||||||
procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
|
|
||||||
proctimeBeginPeriod = modwinmm.NewProc("timeBeginPeriod")
|
|
||||||
procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
|
|
||||||
procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW")
|
|
||||||
procCreateFileW = modkernel32.NewProc("CreateFileW")
|
|
||||||
procWaitNamedPipeW = modkernel32.NewProc("WaitNamedPipeW")
|
|
||||||
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
|
|
||||||
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
|
|
||||||
procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
|
|
||||||
procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW")
|
|
||||||
procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW")
|
|
||||||
procConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc("ConvertSecurityDescriptorToStringSecurityDescriptorW")
|
|
||||||
procLocalFree = modkernel32.NewProc("LocalFree")
|
|
||||||
procGetSecurityDescriptorLength = modadvapi32.NewProc("GetSecurityDescriptorLength")
|
|
||||||
procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx")
|
|
||||||
procSetFileInformationByHandle = modkernel32.NewProc("SetFileInformationByHandle")
|
|
||||||
procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
|
|
||||||
procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf")
|
|
||||||
procRevertToSelf = modadvapi32.NewProc("RevertToSelf")
|
|
||||||
procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken")
|
|
||||||
procGetCurrentThread = modkernel32.NewProc("GetCurrentThread")
|
|
||||||
procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW")
|
|
||||||
procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW")
|
|
||||||
procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW")
|
|
||||||
procBackupRead = modkernel32.NewProc("BackupRead")
|
|
||||||
procBackupWrite = modkernel32.NewProc("BackupWrite")
|
|
||||||
)
|
|
||||||
|
|
||||||
func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) {
|
|
||||||
r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0)
|
|
||||||
newport = syscall.Handle(r0)
|
|
||||||
if newport == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func timeBeginPeriod(period uint32) (n int32) {
|
|
||||||
r0, _, _ := syscall.Syscall(proctimeBeginPeriod.Addr(), 1, uintptr(period), 0, 0)
|
|
||||||
n = int32(r0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *securityAttributes) (handle syscall.Handle, err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(name)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *securityAttributes) (handle syscall.Handle, err error) {
|
|
||||||
r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0)
|
|
||||||
handle = syscall.Handle(r0)
|
|
||||||
if handle == syscall.InvalidHandle {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func createFile(name string, access uint32, mode uint32, sa *securityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(name)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _createFile(_p0, access, mode, sa, createmode, attrs, templatefile)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _createFile(name *uint16, access uint32, mode uint32, sa *securityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
|
|
||||||
r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
|
|
||||||
handle = syscall.Handle(r0)
|
|
||||||
if handle == syscall.InvalidHandle {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func waitNamedPipe(name string, timeout uint32) (err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(name)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _waitNamedPipe(_p0, timeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _waitNamedPipe(name *uint16, timeout uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall(procWaitNamedPipeW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(timeout), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(accountName)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _lookupAccountName(systemName, _p0, sid, sidSize, refDomain, refDomainSize, sidNameUse)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertSidToStringSid(sid *byte, str **uint16) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(str)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _convertStringSecurityDescriptorToSecurityDescriptor(_p0, revision, sd, size)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd *uintptr, size *uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func localFree(mem uintptr) {
|
|
||||||
syscall.Syscall(procLocalFree.Addr(), 1, uintptr(mem), 0, 0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSecurityDescriptorLength(sd uintptr) (len uint32) {
|
|
||||||
r0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(sd), 0, 0)
|
|
||||||
len = uint32(r0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func adjustTokenPrivileges(token syscall.Handle, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) {
|
|
||||||
var _p0 uint32
|
|
||||||
if releaseAll {
|
|
||||||
_p0 = 1
|
|
||||||
} else {
|
|
||||||
_p0 = 0
|
|
||||||
}
|
|
||||||
r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize)))
|
|
||||||
success = r0 != 0
|
|
||||||
if true {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func impersonateSelf(level uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func revertToSelf() (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *syscall.Handle) (err error) {
|
|
||||||
var _p0 uint32
|
|
||||||
if openAsSelf {
|
|
||||||
_p0 = 1
|
|
||||||
} else {
|
|
||||||
_p0 = 0
|
|
||||||
}
|
|
||||||
r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getCurrentThread() (h syscall.Handle) {
|
|
||||||
r0, _, _ := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0)
|
|
||||||
h = syscall.Handle(r0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(systemName)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var _p1 *uint16
|
|
||||||
_p1, err = syscall.UTF16PtrFromString(name)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _lookupPrivilegeValue(_p0, _p1, luid)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(systemName)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _lookupPrivilegeName(_p0, luid, buffer, size)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(systemName)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _lookupPrivilegeDisplayName(_p0, name, buffer, size, languageId)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {
|
|
||||||
var _p0 *byte
|
|
||||||
if len(b) > 0 {
|
|
||||||
_p0 = &b[0]
|
|
||||||
}
|
|
||||||
var _p1 uint32
|
|
||||||
if abort {
|
|
||||||
_p1 = 1
|
|
||||||
} else {
|
|
||||||
_p1 = 0
|
|
||||||
}
|
|
||||||
var _p2 uint32
|
|
||||||
if processSecurity {
|
|
||||||
_p2 = 1
|
|
||||||
} else {
|
|
||||||
_p2 = 0
|
|
||||||
}
|
|
||||||
r1, _, e1 := syscall.Syscall9(procBackupRead.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {
|
|
||||||
var _p0 *byte
|
|
||||||
if len(b) > 0 {
|
|
||||||
_p0 = &b[0]
|
|
||||||
}
|
|
||||||
var _p1 uint32
|
|
||||||
if abort {
|
|
||||||
_p1 = 1
|
|
||||||
} else {
|
|
||||||
_p1 = 0
|
|
||||||
}
|
|
||||||
var _p2 uint32
|
|
||||||
if processSecurity {
|
|
||||||
_p2 = 1
|
|
||||||
} else {
|
|
||||||
_p2 = 0
|
|
||||||
}
|
|
||||||
r1, _, e1 := syscall.Syscall9(procBackupWrite.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
12
Godeps/_workspace/src/github.com/peterh/liner/signal.go
generated
vendored
12
Godeps/_workspace/src/github.com/peterh/liner/signal.go
generated
vendored
@@ -1,12 +0,0 @@
|
|||||||
// +build go1.1,!windows
|
|
||||||
|
|
||||||
package liner
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
)
|
|
||||||
|
|
||||||
func stopSignal(c chan<- os.Signal) {
|
|
||||||
signal.Stop(c)
|
|
||||||
}
|
|
||||||
11
Godeps/_workspace/src/github.com/peterh/liner/signal_legacy.go
generated
vendored
11
Godeps/_workspace/src/github.com/peterh/liner/signal_legacy.go
generated
vendored
@@ -1,11 +0,0 @@
|
|||||||
// +build !go1.1,!windows
|
|
||||||
|
|
||||||
package liner
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
func stopSignal(c chan<- os.Signal) {
|
|
||||||
// signal.Stop does not exist before Go 1.1
|
|
||||||
}
|
|
||||||
20
Godeps/_workspace/src/github.com/rcrowley/go-metrics/cmd/metrics-bench/metrics-bench.go
generated
vendored
20
Godeps/_workspace/src/github.com/rcrowley/go-metrics/cmd/metrics-bench/metrics-bench.go
generated
vendored
@@ -1,20 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/rcrowley/go-metrics"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
r := metrics.NewRegistry()
|
|
||||||
for i := 0; i < 10000; i++ {
|
|
||||||
r.Register(fmt.Sprintf("counter-%d", i), metrics.NewCounter())
|
|
||||||
r.Register(fmt.Sprintf("gauge-%d", i), metrics.NewGauge())
|
|
||||||
r.Register(fmt.Sprintf("gaugefloat64-%d", i), metrics.NewGaugeFloat64())
|
|
||||||
r.Register(fmt.Sprintf("histogram-uniform-%d", i), metrics.NewHistogram(metrics.NewUniformSample(1028)))
|
|
||||||
r.Register(fmt.Sprintf("histogram-exp-%d", i), metrics.NewHistogram(metrics.NewExpDecaySample(1028, 0.015)))
|
|
||||||
r.Register(fmt.Sprintf("meter-%d", i), metrics.NewMeter())
|
|
||||||
}
|
|
||||||
time.Sleep(600e9)
|
|
||||||
}
|
|
||||||
154
Godeps/_workspace/src/github.com/rcrowley/go-metrics/cmd/metrics-example/metrics-example.go
generated
vendored
154
Godeps/_workspace/src/github.com/rcrowley/go-metrics/cmd/metrics-example/metrics-example.go
generated
vendored
@@ -1,154 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"github.com/rcrowley/go-metrics"
|
|
||||||
// "github.com/rcrowley/go-metrics/stathat"
|
|
||||||
"log"
|
|
||||||
"math/rand"
|
|
||||||
"os"
|
|
||||||
// "syslog"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
const fanout = 10
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
|
|
||||||
r := metrics.NewRegistry()
|
|
||||||
|
|
||||||
c := metrics.NewCounter()
|
|
||||||
r.Register("foo", c)
|
|
||||||
for i := 0; i < fanout; i++ {
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
c.Dec(19)
|
|
||||||
time.Sleep(300e6)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
c.Inc(47)
|
|
||||||
time.Sleep(400e6)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
g := metrics.NewGauge()
|
|
||||||
r.Register("bar", g)
|
|
||||||
for i := 0; i < fanout; i++ {
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
g.Update(19)
|
|
||||||
time.Sleep(300e6)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
g.Update(47)
|
|
||||||
time.Sleep(400e6)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
gf := metrics.NewGaugeFloat64()
|
|
||||||
r.Register("barfloat64", gf)
|
|
||||||
for i := 0; i < fanout; i++ {
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
g.Update(19.0)
|
|
||||||
time.Sleep(300e6)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
g.Update(47.0)
|
|
||||||
time.Sleep(400e6)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
hc := metrics.NewHealthcheck(func(h metrics.Healthcheck) {
|
|
||||||
if 0 < rand.Intn(2) {
|
|
||||||
h.Healthy()
|
|
||||||
} else {
|
|
||||||
h.Unhealthy(errors.New("baz"))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
r.Register("baz", hc)
|
|
||||||
|
|
||||||
s := metrics.NewExpDecaySample(1028, 0.015)
|
|
||||||
//s := metrics.NewUniformSample(1028)
|
|
||||||
h := metrics.NewHistogram(s)
|
|
||||||
r.Register("bang", h)
|
|
||||||
for i := 0; i < fanout; i++ {
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
h.Update(19)
|
|
||||||
time.Sleep(300e6)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
h.Update(47)
|
|
||||||
time.Sleep(400e6)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
m := metrics.NewMeter()
|
|
||||||
r.Register("quux", m)
|
|
||||||
for i := 0; i < fanout; i++ {
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
m.Mark(19)
|
|
||||||
time.Sleep(300e6)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
m.Mark(47)
|
|
||||||
time.Sleep(400e6)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
t := metrics.NewTimer()
|
|
||||||
r.Register("hooah", t)
|
|
||||||
for i := 0; i < fanout; i++ {
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
t.Time(func() { time.Sleep(300e6) })
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
t.Time(func() { time.Sleep(400e6) })
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
metrics.RegisterDebugGCStats(r)
|
|
||||||
go metrics.CaptureDebugGCStats(r, 5e9)
|
|
||||||
|
|
||||||
metrics.RegisterRuntimeMemStats(r)
|
|
||||||
go metrics.CaptureRuntimeMemStats(r, 5e9)
|
|
||||||
|
|
||||||
metrics.Log(r, 60e9, log.New(os.Stderr, "metrics: ", log.Lmicroseconds))
|
|
||||||
|
|
||||||
/*
|
|
||||||
w, err := syslog.Dial("unixgram", "/dev/log", syslog.LOG_INFO, "metrics")
|
|
||||||
if nil != err { log.Fatalln(err) }
|
|
||||||
metrics.Syslog(r, 60e9, w)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
addr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:2003")
|
|
||||||
metrics.Graphite(r, 10e9, "metrics", addr)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
stathat.Stathat(r, 10e9, "example@example.com")
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
|
||||||
22
Godeps/_workspace/src/github.com/rcrowley/go-metrics/cmd/never-read/never-read.go
generated
vendored
22
Godeps/_workspace/src/github.com/rcrowley/go-metrics/cmd/never-read/never-read.go
generated
vendored
@@ -1,22 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"net"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
addr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:2003")
|
|
||||||
l, err := net.ListenTCP("tcp", addr)
|
|
||||||
if nil != err {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
log.Println("listening", l.Addr())
|
|
||||||
for {
|
|
||||||
c, err := l.AcceptTCP()
|
|
||||||
if nil != err {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
log.Println("accepted", c.RemoteAddr())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
102
Godeps/_workspace/src/github.com/rcrowley/go-metrics/librato/client.go
generated
vendored
102
Godeps/_workspace/src/github.com/rcrowley/go-metrics/librato/client.go
generated
vendored
@@ -1,102 +0,0 @@
|
|||||||
package librato
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
const Operations = "operations"
|
|
||||||
const OperationsShort = "ops"
|
|
||||||
|
|
||||||
type LibratoClient struct {
|
|
||||||
Email, Token string
|
|
||||||
}
|
|
||||||
|
|
||||||
// property strings
|
|
||||||
const (
|
|
||||||
// display attributes
|
|
||||||
Color = "color"
|
|
||||||
DisplayMax = "display_max"
|
|
||||||
DisplayMin = "display_min"
|
|
||||||
DisplayUnitsLong = "display_units_long"
|
|
||||||
DisplayUnitsShort = "display_units_short"
|
|
||||||
DisplayStacked = "display_stacked"
|
|
||||||
DisplayTransform = "display_transform"
|
|
||||||
// special gauge display attributes
|
|
||||||
SummarizeFunction = "summarize_function"
|
|
||||||
Aggregate = "aggregate"
|
|
||||||
|
|
||||||
// metric keys
|
|
||||||
Name = "name"
|
|
||||||
Period = "period"
|
|
||||||
Description = "description"
|
|
||||||
DisplayName = "display_name"
|
|
||||||
Attributes = "attributes"
|
|
||||||
|
|
||||||
// measurement keys
|
|
||||||
MeasureTime = "measure_time"
|
|
||||||
Source = "source"
|
|
||||||
Value = "value"
|
|
||||||
|
|
||||||
// special gauge keys
|
|
||||||
Count = "count"
|
|
||||||
Sum = "sum"
|
|
||||||
Max = "max"
|
|
||||||
Min = "min"
|
|
||||||
SumSquares = "sum_squares"
|
|
||||||
|
|
||||||
// batch keys
|
|
||||||
Counters = "counters"
|
|
||||||
Gauges = "gauges"
|
|
||||||
|
|
||||||
MetricsPostUrl = "https://metrics-api.librato.com/v1/metrics"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Measurement map[string]interface{}
|
|
||||||
type Metric map[string]interface{}
|
|
||||||
|
|
||||||
type Batch struct {
|
|
||||||
Gauges []Measurement `json:"gauges,omitempty"`
|
|
||||||
Counters []Measurement `json:"counters,omitempty"`
|
|
||||||
MeasureTime int64 `json:"measure_time"`
|
|
||||||
Source string `json:"source"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *LibratoClient) PostMetrics(batch Batch) (err error) {
|
|
||||||
var (
|
|
||||||
js []byte
|
|
||||||
req *http.Request
|
|
||||||
resp *http.Response
|
|
||||||
)
|
|
||||||
|
|
||||||
if len(batch.Counters) == 0 && len(batch.Gauges) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if js, err = json.Marshal(batch); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if req, err = http.NewRequest("POST", MetricsPostUrl, bytes.NewBuffer(js)); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
|
||||||
req.SetBasicAuth(self.Email, self.Token)
|
|
||||||
|
|
||||||
if resp, err = http.DefaultClient.Do(req); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
var body []byte
|
|
||||||
if body, err = ioutil.ReadAll(resp.Body); err != nil {
|
|
||||||
body = []byte(fmt.Sprintf("(could not fetch response body for error: %s)", err))
|
|
||||||
}
|
|
||||||
err = fmt.Errorf("Unable to post to Librato: %d %s %s", resp.StatusCode, resp.Status, string(body))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
235
Godeps/_workspace/src/github.com/rcrowley/go-metrics/librato/librato.go
generated
vendored
235
Godeps/_workspace/src/github.com/rcrowley/go-metrics/librato/librato.go
generated
vendored
@@ -1,235 +0,0 @@
|
|||||||
package librato
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"math"
|
|
||||||
"regexp"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/rcrowley/go-metrics"
|
|
||||||
)
|
|
||||||
|
|
||||||
// a regexp for extracting the unit from time.Duration.String
|
|
||||||
var unitRegexp = regexp.MustCompile("[^\\d]+$")
|
|
||||||
|
|
||||||
// a helper that turns a time.Duration into librato display attributes for timer metrics
|
|
||||||
func translateTimerAttributes(d time.Duration) (attrs map[string]interface{}) {
|
|
||||||
attrs = make(map[string]interface{})
|
|
||||||
attrs[DisplayTransform] = fmt.Sprintf("x/%d", int64(d))
|
|
||||||
attrs[DisplayUnitsShort] = string(unitRegexp.Find([]byte(d.String())))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type Reporter struct {
|
|
||||||
Email, Token string
|
|
||||||
Namespace string
|
|
||||||
Source string
|
|
||||||
Interval time.Duration
|
|
||||||
Registry metrics.Registry
|
|
||||||
Percentiles []float64 // percentiles to report on histogram metrics
|
|
||||||
TimerAttributes map[string]interface{} // units in which timers will be displayed
|
|
||||||
intervalSec int64
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewReporter(r metrics.Registry, d time.Duration, e string, t string, s string, p []float64, u time.Duration) *Reporter {
|
|
||||||
return &Reporter{e, t, "", s, d, r, p, translateTimerAttributes(u), int64(d / time.Second)}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Librato(r metrics.Registry, d time.Duration, e string, t string, s string, p []float64, u time.Duration) {
|
|
||||||
NewReporter(r, d, e, t, s, p, u).Run()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Reporter) Run() {
|
|
||||||
log.Printf("WARNING: This client has been DEPRECATED! It has been moved to https://github.com/mihasya/go-metrics-librato and will be removed from rcrowley/go-metrics on August 5th 2015")
|
|
||||||
ticker := time.Tick(self.Interval)
|
|
||||||
metricsApi := &LibratoClient{self.Email, self.Token}
|
|
||||||
for now := range ticker {
|
|
||||||
var metrics Batch
|
|
||||||
var err error
|
|
||||||
if metrics, err = self.BuildRequest(now, self.Registry); err != nil {
|
|
||||||
log.Printf("ERROR constructing librato request body %s", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := metricsApi.PostMetrics(metrics); err != nil {
|
|
||||||
log.Printf("ERROR sending metrics to librato %s", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate sum of squares from data provided by metrics.Histogram
|
|
||||||
// see http://en.wikipedia.org/wiki/Standard_deviation#Rapid_calculation_methods
|
|
||||||
func sumSquares(s metrics.Sample) float64 {
|
|
||||||
count := float64(s.Count())
|
|
||||||
sumSquared := math.Pow(count*s.Mean(), 2)
|
|
||||||
sumSquares := math.Pow(count*s.StdDev(), 2) + sumSquared/count
|
|
||||||
if math.IsNaN(sumSquares) {
|
|
||||||
return 0.0
|
|
||||||
}
|
|
||||||
return sumSquares
|
|
||||||
}
|
|
||||||
func sumSquaresTimer(t metrics.Timer) float64 {
|
|
||||||
count := float64(t.Count())
|
|
||||||
sumSquared := math.Pow(count*t.Mean(), 2)
|
|
||||||
sumSquares := math.Pow(count*t.StdDev(), 2) + sumSquared/count
|
|
||||||
if math.IsNaN(sumSquares) {
|
|
||||||
return 0.0
|
|
||||||
}
|
|
||||||
return sumSquares
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Reporter) BuildRequest(now time.Time, r metrics.Registry) (snapshot Batch, err error) {
|
|
||||||
snapshot = Batch{
|
|
||||||
// coerce timestamps to a stepping fn so that they line up in Librato graphs
|
|
||||||
MeasureTime: (now.Unix() / self.intervalSec) * self.intervalSec,
|
|
||||||
Source: self.Source,
|
|
||||||
}
|
|
||||||
snapshot.Gauges = make([]Measurement, 0)
|
|
||||||
snapshot.Counters = make([]Measurement, 0)
|
|
||||||
histogramGaugeCount := 1 + len(self.Percentiles)
|
|
||||||
r.Each(func(name string, metric interface{}) {
|
|
||||||
if self.Namespace != "" {
|
|
||||||
name = fmt.Sprintf("%s.%s", self.Namespace, name)
|
|
||||||
}
|
|
||||||
measurement := Measurement{}
|
|
||||||
measurement[Period] = self.Interval.Seconds()
|
|
||||||
switch m := metric.(type) {
|
|
||||||
case metrics.Counter:
|
|
||||||
if m.Count() > 0 {
|
|
||||||
measurement[Name] = fmt.Sprintf("%s.%s", name, "count")
|
|
||||||
measurement[Value] = float64(m.Count())
|
|
||||||
measurement[Attributes] = map[string]interface{}{
|
|
||||||
DisplayUnitsLong: Operations,
|
|
||||||
DisplayUnitsShort: OperationsShort,
|
|
||||||
DisplayMin: "0",
|
|
||||||
}
|
|
||||||
snapshot.Counters = append(snapshot.Counters, measurement)
|
|
||||||
}
|
|
||||||
case metrics.Gauge:
|
|
||||||
measurement[Name] = name
|
|
||||||
measurement[Value] = float64(m.Value())
|
|
||||||
snapshot.Gauges = append(snapshot.Gauges, measurement)
|
|
||||||
case metrics.GaugeFloat64:
|
|
||||||
measurement[Name] = name
|
|
||||||
measurement[Value] = float64(m.Value())
|
|
||||||
snapshot.Gauges = append(snapshot.Gauges, measurement)
|
|
||||||
case metrics.Histogram:
|
|
||||||
if m.Count() > 0 {
|
|
||||||
gauges := make([]Measurement, histogramGaugeCount, histogramGaugeCount)
|
|
||||||
s := m.Sample()
|
|
||||||
measurement[Name] = fmt.Sprintf("%s.%s", name, "hist")
|
|
||||||
measurement[Count] = uint64(s.Count())
|
|
||||||
measurement[Max] = float64(s.Max())
|
|
||||||
measurement[Min] = float64(s.Min())
|
|
||||||
measurement[Sum] = float64(s.Sum())
|
|
||||||
measurement[SumSquares] = sumSquares(s)
|
|
||||||
gauges[0] = measurement
|
|
||||||
for i, p := range self.Percentiles {
|
|
||||||
gauges[i+1] = Measurement{
|
|
||||||
Name: fmt.Sprintf("%s.%.2f", measurement[Name], p),
|
|
||||||
Value: s.Percentile(p),
|
|
||||||
Period: measurement[Period],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
snapshot.Gauges = append(snapshot.Gauges, gauges...)
|
|
||||||
}
|
|
||||||
case metrics.Meter:
|
|
||||||
measurement[Name] = name
|
|
||||||
measurement[Value] = float64(m.Count())
|
|
||||||
snapshot.Counters = append(snapshot.Counters, measurement)
|
|
||||||
snapshot.Gauges = append(snapshot.Gauges,
|
|
||||||
Measurement{
|
|
||||||
Name: fmt.Sprintf("%s.%s", name, "1min"),
|
|
||||||
Value: m.Rate1(),
|
|
||||||
Period: int64(self.Interval.Seconds()),
|
|
||||||
Attributes: map[string]interface{}{
|
|
||||||
DisplayUnitsLong: Operations,
|
|
||||||
DisplayUnitsShort: OperationsShort,
|
|
||||||
DisplayMin: "0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Measurement{
|
|
||||||
Name: fmt.Sprintf("%s.%s", name, "5min"),
|
|
||||||
Value: m.Rate5(),
|
|
||||||
Period: int64(self.Interval.Seconds()),
|
|
||||||
Attributes: map[string]interface{}{
|
|
||||||
DisplayUnitsLong: Operations,
|
|
||||||
DisplayUnitsShort: OperationsShort,
|
|
||||||
DisplayMin: "0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Measurement{
|
|
||||||
Name: fmt.Sprintf("%s.%s", name, "15min"),
|
|
||||||
Value: m.Rate15(),
|
|
||||||
Period: int64(self.Interval.Seconds()),
|
|
||||||
Attributes: map[string]interface{}{
|
|
||||||
DisplayUnitsLong: Operations,
|
|
||||||
DisplayUnitsShort: OperationsShort,
|
|
||||||
DisplayMin: "0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
case metrics.Timer:
|
|
||||||
measurement[Name] = name
|
|
||||||
measurement[Value] = float64(m.Count())
|
|
||||||
snapshot.Counters = append(snapshot.Counters, measurement)
|
|
||||||
if m.Count() > 0 {
|
|
||||||
libratoName := fmt.Sprintf("%s.%s", name, "timer.mean")
|
|
||||||
gauges := make([]Measurement, histogramGaugeCount, histogramGaugeCount)
|
|
||||||
gauges[0] = Measurement{
|
|
||||||
Name: libratoName,
|
|
||||||
Count: uint64(m.Count()),
|
|
||||||
Sum: m.Mean() * float64(m.Count()),
|
|
||||||
Max: float64(m.Max()),
|
|
||||||
Min: float64(m.Min()),
|
|
||||||
SumSquares: sumSquaresTimer(m),
|
|
||||||
Period: int64(self.Interval.Seconds()),
|
|
||||||
Attributes: self.TimerAttributes,
|
|
||||||
}
|
|
||||||
for i, p := range self.Percentiles {
|
|
||||||
gauges[i+1] = Measurement{
|
|
||||||
Name: fmt.Sprintf("%s.timer.%2.0f", name, p*100),
|
|
||||||
Value: m.Percentile(p),
|
|
||||||
Period: int64(self.Interval.Seconds()),
|
|
||||||
Attributes: self.TimerAttributes,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
snapshot.Gauges = append(snapshot.Gauges, gauges...)
|
|
||||||
snapshot.Gauges = append(snapshot.Gauges,
|
|
||||||
Measurement{
|
|
||||||
Name: fmt.Sprintf("%s.%s", name, "rate.1min"),
|
|
||||||
Value: m.Rate1(),
|
|
||||||
Period: int64(self.Interval.Seconds()),
|
|
||||||
Attributes: map[string]interface{}{
|
|
||||||
DisplayUnitsLong: Operations,
|
|
||||||
DisplayUnitsShort: OperationsShort,
|
|
||||||
DisplayMin: "0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Measurement{
|
|
||||||
Name: fmt.Sprintf("%s.%s", name, "rate.5min"),
|
|
||||||
Value: m.Rate5(),
|
|
||||||
Period: int64(self.Interval.Seconds()),
|
|
||||||
Attributes: map[string]interface{}{
|
|
||||||
DisplayUnitsLong: Operations,
|
|
||||||
DisplayUnitsShort: OperationsShort,
|
|
||||||
DisplayMin: "0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Measurement{
|
|
||||||
Name: fmt.Sprintf("%s.%s", name, "rate.15min"),
|
|
||||||
Value: m.Rate15(),
|
|
||||||
Period: int64(self.Interval.Seconds()),
|
|
||||||
Attributes: map[string]interface{}{
|
|
||||||
DisplayUnitsLong: Operations,
|
|
||||||
DisplayUnitsShort: OperationsShort,
|
|
||||||
DisplayMin: "0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
69
Godeps/_workspace/src/github.com/rcrowley/go-metrics/stathat/stathat.go
generated
vendored
69
Godeps/_workspace/src/github.com/rcrowley/go-metrics/stathat/stathat.go
generated
vendored
@@ -1,69 +0,0 @@
|
|||||||
// Metrics output to StatHat.
|
|
||||||
package stathat
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/rcrowley/go-metrics"
|
|
||||||
"github.com/stathat/go"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Stathat(r metrics.Registry, d time.Duration, userkey string) {
|
|
||||||
for {
|
|
||||||
if err := sh(r, userkey); nil != err {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
time.Sleep(d)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func sh(r metrics.Registry, userkey string) error {
|
|
||||||
r.Each(func(name string, i interface{}) {
|
|
||||||
switch metric := i.(type) {
|
|
||||||
case metrics.Counter:
|
|
||||||
stathat.PostEZCount(name, userkey, int(metric.Count()))
|
|
||||||
case metrics.Gauge:
|
|
||||||
stathat.PostEZValue(name, userkey, float64(metric.Value()))
|
|
||||||
case metrics.GaugeFloat64:
|
|
||||||
stathat.PostEZValue(name, userkey, float64(metric.Value()))
|
|
||||||
case metrics.Histogram:
|
|
||||||
h := metric.Snapshot()
|
|
||||||
ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
|
|
||||||
stathat.PostEZCount(name+".count", userkey, int(h.Count()))
|
|
||||||
stathat.PostEZValue(name+".min", userkey, float64(h.Min()))
|
|
||||||
stathat.PostEZValue(name+".max", userkey, float64(h.Max()))
|
|
||||||
stathat.PostEZValue(name+".mean", userkey, float64(h.Mean()))
|
|
||||||
stathat.PostEZValue(name+".std-dev", userkey, float64(h.StdDev()))
|
|
||||||
stathat.PostEZValue(name+".50-percentile", userkey, float64(ps[0]))
|
|
||||||
stathat.PostEZValue(name+".75-percentile", userkey, float64(ps[1]))
|
|
||||||
stathat.PostEZValue(name+".95-percentile", userkey, float64(ps[2]))
|
|
||||||
stathat.PostEZValue(name+".99-percentile", userkey, float64(ps[3]))
|
|
||||||
stathat.PostEZValue(name+".999-percentile", userkey, float64(ps[4]))
|
|
||||||
case metrics.Meter:
|
|
||||||
m := metric.Snapshot()
|
|
||||||
stathat.PostEZCount(name+".count", userkey, int(m.Count()))
|
|
||||||
stathat.PostEZValue(name+".one-minute", userkey, float64(m.Rate1()))
|
|
||||||
stathat.PostEZValue(name+".five-minute", userkey, float64(m.Rate5()))
|
|
||||||
stathat.PostEZValue(name+".fifteen-minute", userkey, float64(m.Rate15()))
|
|
||||||
stathat.PostEZValue(name+".mean", userkey, float64(m.RateMean()))
|
|
||||||
case metrics.Timer:
|
|
||||||
t := metric.Snapshot()
|
|
||||||
ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
|
|
||||||
stathat.PostEZCount(name+".count", userkey, int(t.Count()))
|
|
||||||
stathat.PostEZValue(name+".min", userkey, float64(t.Min()))
|
|
||||||
stathat.PostEZValue(name+".max", userkey, float64(t.Max()))
|
|
||||||
stathat.PostEZValue(name+".mean", userkey, float64(t.Mean()))
|
|
||||||
stathat.PostEZValue(name+".std-dev", userkey, float64(t.StdDev()))
|
|
||||||
stathat.PostEZValue(name+".50-percentile", userkey, float64(ps[0]))
|
|
||||||
stathat.PostEZValue(name+".75-percentile", userkey, float64(ps[1]))
|
|
||||||
stathat.PostEZValue(name+".95-percentile", userkey, float64(ps[2]))
|
|
||||||
stathat.PostEZValue(name+".99-percentile", userkey, float64(ps[3]))
|
|
||||||
stathat.PostEZValue(name+".999-percentile", userkey, float64(ps[4]))
|
|
||||||
stathat.PostEZValue(name+".one-minute", userkey, float64(t.Rate1()))
|
|
||||||
stathat.PostEZValue(name+".five-minute", userkey, float64(t.Rate5()))
|
|
||||||
stathat.PostEZValue(name+".fifteen-minute", userkey, float64(t.Rate15()))
|
|
||||||
stathat.PostEZValue(name+".mean-rate", userkey, float64(t.RateMean()))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
92
Godeps/_workspace/src/github.com/robertkrimen/otto/ast/comments.go
generated
vendored
92
Godeps/_workspace/src/github.com/robertkrimen/otto/ast/comments.go
generated
vendored
@@ -1,92 +0,0 @@
|
|||||||
package ast
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/robertkrimen/otto/file"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CommentPosition determines where the comment is in a given context
|
|
||||||
type CommentPosition int
|
|
||||||
|
|
||||||
const (
|
|
||||||
_ CommentPosition = iota
|
|
||||||
LEADING // Before the pertinent expression
|
|
||||||
TRAILING // After the pertinent expression
|
|
||||||
KEY // After a key or keyword
|
|
||||||
COLON // After a colon in a field declaration
|
|
||||||
FINAL // Final comments in a block, not belonging to a specific expression or the comment after a trailing , in an array or object literal
|
|
||||||
TBD
|
|
||||||
)
|
|
||||||
|
|
||||||
// Comment contains the data of the comment
|
|
||||||
type Comment struct {
|
|
||||||
Begin file.Idx
|
|
||||||
Text string
|
|
||||||
Position CommentPosition
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a stringified version of the position
|
|
||||||
func (cp CommentPosition) String() string {
|
|
||||||
switch cp {
|
|
||||||
case LEADING:
|
|
||||||
return "Leading"
|
|
||||||
case TRAILING:
|
|
||||||
return "Trailing"
|
|
||||||
case KEY:
|
|
||||||
return "Key"
|
|
||||||
case COLON:
|
|
||||||
return "Colon"
|
|
||||||
case FINAL:
|
|
||||||
return "Final"
|
|
||||||
default:
|
|
||||||
return "???"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a stringified version of the comment
|
|
||||||
func (c Comment) String() string {
|
|
||||||
return fmt.Sprintf("Comment: %v", c.Text)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CommentMap is the data structure where all found comments are stored
|
|
||||||
type CommentMap map[Node][]*Comment
|
|
||||||
|
|
||||||
// AddComment adds a single comment to the map
|
|
||||||
func (cm CommentMap) AddComment(node Node, comment *Comment) {
|
|
||||||
list := cm[node]
|
|
||||||
list = append(list, comment)
|
|
||||||
|
|
||||||
cm[node] = list
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddComments adds a slice of comments, given a node and an updated position
|
|
||||||
func (cm CommentMap) AddComments(node Node, comments []*Comment, position CommentPosition) {
|
|
||||||
for _, comment := range comments {
|
|
||||||
comment.Position = position
|
|
||||||
cm.AddComment(node, comment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Size returns the size of the map
|
|
||||||
func (cm CommentMap) Size() int {
|
|
||||||
size := 0
|
|
||||||
for _, comments := range cm {
|
|
||||||
size += len(comments)
|
|
||||||
}
|
|
||||||
|
|
||||||
return size
|
|
||||||
}
|
|
||||||
|
|
||||||
// MoveComments moves comments with a given position from a node to another
|
|
||||||
func (cm CommentMap) MoveComments(from, to Node, position CommentPosition) {
|
|
||||||
for i, c := range cm[from] {
|
|
||||||
if c.Position == position {
|
|
||||||
cm.AddComment(to, c)
|
|
||||||
|
|
||||||
// Remove the comment from the "from" slice
|
|
||||||
cm[from][i] = cm[from][len(cm[from])-1]
|
|
||||||
cm[from][len(cm[from])-1] = nil
|
|
||||||
cm[from] = cm[from][:len(cm[from])-1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
5
Godeps/_workspace/src/github.com/robertkrimen/otto/otto/Makefile
generated
vendored
5
Godeps/_workspace/src/github.com/robertkrimen/otto/otto/Makefile
generated
vendored
@@ -1,5 +0,0 @@
|
|||||||
.PHONY: build
|
|
||||||
|
|
||||||
build:
|
|
||||||
go build -a
|
|
||||||
-gxc build-darwin-386 -a
|
|
||||||
48
Godeps/_workspace/src/github.com/robertkrimen/otto/otto/main.go
generated
vendored
48
Godeps/_workspace/src/github.com/robertkrimen/otto/otto/main.go
generated
vendored
@@ -1,48 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/robertkrimen/otto"
|
|
||||||
"github.com/robertkrimen/otto/underscore"
|
|
||||||
)
|
|
||||||
|
|
||||||
var flag_underscore *bool = flag.Bool("underscore", true, "Load underscore into the runtime environment")
|
|
||||||
|
|
||||||
func readSource(filename string) ([]byte, error) {
|
|
||||||
if filename == "" || filename == "-" {
|
|
||||||
return ioutil.ReadAll(os.Stdin)
|
|
||||||
}
|
|
||||||
return ioutil.ReadFile(filename)
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
if !*flag_underscore {
|
|
||||||
underscore.Disable()
|
|
||||||
}
|
|
||||||
|
|
||||||
err := func() error {
|
|
||||||
src, err := readSource(flag.Arg(0))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
vm := otto.New()
|
|
||||||
_, err = vm.Run(src)
|
|
||||||
return err
|
|
||||||
}()
|
|
||||||
if err != nil {
|
|
||||||
switch err := err.(type) {
|
|
||||||
case *otto.Error:
|
|
||||||
fmt.Print(err.String())
|
|
||||||
default:
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
os.Exit(64)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
115
Godeps/_workspace/src/github.com/robertkrimen/otto/repl/repl.go
generated
vendored
115
Godeps/_workspace/src/github.com/robertkrimen/otto/repl/repl.go
generated
vendored
@@ -1,115 +0,0 @@
|
|||||||
// Package repl implements a REPL (read-eval-print loop) for otto.
|
|
||||||
package repl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"strings"
|
|
||||||
"sync/atomic"
|
|
||||||
|
|
||||||
"github.com/robertkrimen/otto"
|
|
||||||
"gopkg.in/readline.v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
var counter uint32
|
|
||||||
|
|
||||||
// DebuggerHandler implements otto's debugger handler signature, providing a
|
|
||||||
// simple drop-in debugger implementation.
|
|
||||||
func DebuggerHandler(vm *otto.Otto) {
|
|
||||||
i := atomic.AddUint32(&counter, 1)
|
|
||||||
|
|
||||||
// purposefully ignoring the error here - we can't do anything useful with
|
|
||||||
// it except panicking, and that'd be pretty rude. it'd be easy enough for a
|
|
||||||
// consumer to define an equivalent function that _does_ panic if desired.
|
|
||||||
_ = RunWithPrompt(vm, fmt.Sprintf("DEBUGGER[%d]>", i))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run creates a REPL with the default prompt and no prelude.
|
|
||||||
func Run(vm *otto.Otto) error {
|
|
||||||
return RunWithPromptAndPrelude(vm, "", "")
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunWithPrompt runs a REPL with the given prompt and no prelude.
|
|
||||||
func RunWithPrompt(vm *otto.Otto, prompt string) error {
|
|
||||||
return RunWithPromptAndPrelude(vm, prompt, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunWithPrelude runs a REPL with the default prompt and the given prelude.
|
|
||||||
func RunWithPrelude(vm *otto.Otto, prelude string) error {
|
|
||||||
return RunWithPromptAndPrelude(vm, "", prelude)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunWithPromptAndPrelude runs a REPL with the given prompt and prelude.
|
|
||||||
func RunWithPromptAndPrelude(vm *otto.Otto, prompt, prelude string) error {
|
|
||||||
if prompt == "" {
|
|
||||||
prompt = ">"
|
|
||||||
}
|
|
||||||
|
|
||||||
prompt = strings.Trim(prompt, " ")
|
|
||||||
prompt += " "
|
|
||||||
|
|
||||||
rl, err := readline.New(prompt)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if prelude != "" {
|
|
||||||
if _, err := io.Copy(rl.Stderr(), strings.NewReader(prelude+"\n")); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
rl.Refresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
var d []string
|
|
||||||
|
|
||||||
for {
|
|
||||||
l, err := rl.Readline()
|
|
||||||
if err != nil {
|
|
||||||
if err == readline.ErrInterrupt {
|
|
||||||
if d != nil {
|
|
||||||
d = nil
|
|
||||||
|
|
||||||
rl.SetPrompt(prompt)
|
|
||||||
rl.Refresh()
|
|
||||||
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if l == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
d = append(d, l)
|
|
||||||
|
|
||||||
s, err := vm.Compile("repl", strings.Join(d, "\n"))
|
|
||||||
if err != nil {
|
|
||||||
rl.SetPrompt(strings.Repeat(" ", len(prompt)))
|
|
||||||
} else {
|
|
||||||
rl.SetPrompt(prompt)
|
|
||||||
|
|
||||||
d = nil
|
|
||||||
|
|
||||||
v, err := vm.Eval(s)
|
|
||||||
if err != nil {
|
|
||||||
if oerr, ok := err.(*otto.Error); ok {
|
|
||||||
io.Copy(rl.Stdout(), strings.NewReader(oerr.String()))
|
|
||||||
} else {
|
|
||||||
io.Copy(rl.Stdout(), strings.NewReader(err.Error()))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rl.Stdout().Write([]byte(v.String() + "\n"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rl.Refresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
return rl.Close()
|
|
||||||
}
|
|
||||||
669
Godeps/_workspace/src/github.com/robertkrimen/otto/terst/terst.go
generated
vendored
669
Godeps/_workspace/src/github.com/robertkrimen/otto/terst/terst.go
generated
vendored
@@ -1,669 +0,0 @@
|
|||||||
// This file was AUTOMATICALLY GENERATED by terst-import (smuggol) from github.com/robertkrimen/terst
|
|
||||||
|
|
||||||
/*
|
|
||||||
Package terst is a terse (terst = test + terse), easy-to-use testing library for Go.
|
|
||||||
|
|
||||||
terst is compatible with (and works via) the standard testing package: http://golang.org/pkg/testing
|
|
||||||
|
|
||||||
var is = terst.Is
|
|
||||||
|
|
||||||
func Test(t *testing.T) {
|
|
||||||
terst.Terst(t, func() {
|
|
||||||
is("abc", "abc")
|
|
||||||
|
|
||||||
is(1, ">", 0)
|
|
||||||
|
|
||||||
var abc []int
|
|
||||||
is(abc, nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Do not import terst directly, instead use `terst-import` to copy it into your testing environment:
|
|
||||||
|
|
||||||
https://github.com/robertkrimen/terst/tree/master/terst-import
|
|
||||||
|
|
||||||
$ go get github.com/robertkrimen/terst/terst-import
|
|
||||||
|
|
||||||
$ terst-import
|
|
||||||
|
|
||||||
*/
|
|
||||||
package terst
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"math/big"
|
|
||||||
"reflect"
|
|
||||||
"regexp"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Is compares two values (got & expect) and returns true if the comparison is true,
|
|
||||||
// false otherwise. In addition, if the comparison is false, Is will report the error
|
|
||||||
// in a manner similar to testing.T.Error(...). Is also takes an optional argument,
|
|
||||||
// a comparator, that changes how the comparison is made. The following
|
|
||||||
// comparators are available:
|
|
||||||
//
|
|
||||||
// == # got == expect (default)
|
|
||||||
// != # got != expect
|
|
||||||
//
|
|
||||||
// > # got > expect (float32, uint, uint16, int, int64, ...)
|
|
||||||
// >= # got >= expect
|
|
||||||
// < # got < expect
|
|
||||||
// <= # got <= expect
|
|
||||||
//
|
|
||||||
// =~ # regexp.MustCompile(expect).Match{String}(got)
|
|
||||||
// !~ # !regexp.MustCompile(expect).Match{String}(got)
|
|
||||||
//
|
|
||||||
// Basic usage with the default comparator (==):
|
|
||||||
//
|
|
||||||
// Is(<got>, <expect>)
|
|
||||||
//
|
|
||||||
// Specifying a different comparator:
|
|
||||||
//
|
|
||||||
// Is(<got>, <comparator>, <expect>)
|
|
||||||
//
|
|
||||||
// A simple comparison:
|
|
||||||
//
|
|
||||||
// Is(2 + 2, 4)
|
|
||||||
//
|
|
||||||
// A bit trickier:
|
|
||||||
//
|
|
||||||
// Is(1, ">", 0)
|
|
||||||
// Is(2 + 2, "!=", 5)
|
|
||||||
// Is("Nothing happens.", "=~", `ing(\s+)happens\.$`)
|
|
||||||
//
|
|
||||||
// Is should only be called under a Terst(t, ...) call. For a standalone version,
|
|
||||||
// use IsErr. If no scope is found and the comparison is false, then Is will panic the error.
|
|
||||||
//
|
|
||||||
func Is(arguments ...interface{}) bool {
|
|
||||||
err := IsErr(arguments...)
|
|
||||||
if err != nil {
|
|
||||||
call := Caller()
|
|
||||||
if call == nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
call.Error(err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
type (
|
|
||||||
// ErrFail indicates a comparison failure (e.g. 0 > 1).
|
|
||||||
ErrFail error
|
|
||||||
|
|
||||||
// ErrInvalid indicates an invalid comparison (e.g. bool == string).
|
|
||||||
ErrInvalid error
|
|
||||||
)
|
|
||||||
|
|
||||||
var errInvalid = errors.New("invalid")
|
|
||||||
|
|
||||||
var registry = struct {
|
|
||||||
table map[uintptr]*_scope
|
|
||||||
lock sync.RWMutex
|
|
||||||
}{
|
|
||||||
table: map[uintptr]*_scope{},
|
|
||||||
}
|
|
||||||
|
|
||||||
func registerScope(pc uintptr, scope *_scope) {
|
|
||||||
registry.lock.Lock()
|
|
||||||
defer registry.lock.Unlock()
|
|
||||||
registry.table[pc] = scope
|
|
||||||
}
|
|
||||||
|
|
||||||
func scope() *_scope {
|
|
||||||
scope, _ := findScope()
|
|
||||||
return scope
|
|
||||||
}
|
|
||||||
|
|
||||||
func floatCompare(a float64, b float64) int {
|
|
||||||
if a > b {
|
|
||||||
return 1
|
|
||||||
} else if a < b {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
// NaN == NaN
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func bigIntCompare(a *big.Int, b *big.Int) int {
|
|
||||||
return a.Cmp(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func bigInt(value int64) *big.Int {
|
|
||||||
return big.NewInt(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
func bigUint(value uint64) *big.Int {
|
|
||||||
return big.NewInt(0).SetUint64(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
type _toString interface {
|
|
||||||
String() string
|
|
||||||
}
|
|
||||||
|
|
||||||
func toString(value interface{}) (string, error) {
|
|
||||||
switch value := value.(type) {
|
|
||||||
case string:
|
|
||||||
return value, nil
|
|
||||||
case _toString:
|
|
||||||
return value.String(), nil
|
|
||||||
case error:
|
|
||||||
return value.Error(), nil
|
|
||||||
}
|
|
||||||
return "", errInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
func matchString(got string, expect *regexp.Regexp) (int, error) {
|
|
||||||
if expect.MatchString(got) {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return -1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func match(got []byte, expect *regexp.Regexp) (int, error) {
|
|
||||||
if expect.Match(got) {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return -1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func compareMatch(got, expect interface{}) (int, error) {
|
|
||||||
switch got := got.(type) {
|
|
||||||
case []byte:
|
|
||||||
switch expect := expect.(type) {
|
|
||||||
case string:
|
|
||||||
matcher, err := regexp.Compile(expect)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return match(got, matcher)
|
|
||||||
case *regexp.Regexp:
|
|
||||||
return match(got, expect)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
if got, err := toString(got); err == nil {
|
|
||||||
switch expect := expect.(type) {
|
|
||||||
case string:
|
|
||||||
matcher, err := regexp.Compile(expect)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return matchString(got, matcher)
|
|
||||||
case *regexp.Regexp:
|
|
||||||
return matchString(got, expect)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0, errInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
func floatPromote(value reflect.Value) (float64, error) {
|
|
||||||
kind := value.Kind()
|
|
||||||
if reflect.Int <= kind && kind <= reflect.Int64 {
|
|
||||||
return float64(value.Int()), nil
|
|
||||||
}
|
|
||||||
if reflect.Uint <= kind && kind <= reflect.Uint64 {
|
|
||||||
return float64(value.Uint()), nil
|
|
||||||
}
|
|
||||||
if reflect.Float32 <= kind && kind <= reflect.Float64 {
|
|
||||||
return value.Float(), nil
|
|
||||||
}
|
|
||||||
return 0, errInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
func bigIntPromote(value reflect.Value) (*big.Int, error) {
|
|
||||||
kind := value.Kind()
|
|
||||||
if reflect.Int <= kind && kind <= reflect.Int64 {
|
|
||||||
return bigInt(value.Int()), nil
|
|
||||||
}
|
|
||||||
if reflect.Uint <= kind && kind <= reflect.Uint64 {
|
|
||||||
return bigUint(value.Uint()), nil
|
|
||||||
}
|
|
||||||
return nil, errInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
func compareOther(got, expect interface{}) (int, error) {
|
|
||||||
{
|
|
||||||
switch expect.(type) {
|
|
||||||
case float32, float64:
|
|
||||||
return compareNumber(got, expect)
|
|
||||||
case uint, uint8, uint16, uint32, uint64:
|
|
||||||
return compareNumber(got, expect)
|
|
||||||
case int, int8, int16, int32, int64:
|
|
||||||
return compareNumber(got, expect)
|
|
||||||
case string:
|
|
||||||
var err error
|
|
||||||
got, err = toString(got)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
case nil:
|
|
||||||
got := reflect.ValueOf(got)
|
|
||||||
switch got.Kind() {
|
|
||||||
case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.Interface:
|
|
||||||
if got.IsNil() {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return -1, nil
|
|
||||||
case reflect.Invalid: // reflect.Invalid: var abc interface{} = nil
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return 0, errInvalid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if reflect.ValueOf(got).Type() != reflect.ValueOf(expect).Type() {
|
|
||||||
return 0, errInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
if reflect.DeepEqual(got, expect) {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return -1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func compareNumber(got, expect interface{}) (int, error) {
|
|
||||||
{
|
|
||||||
got := reflect.ValueOf(got)
|
|
||||||
k0 := got.Kind()
|
|
||||||
expect := reflect.ValueOf(expect)
|
|
||||||
k1 := expect.Kind()
|
|
||||||
if reflect.Float32 <= k0 && k0 <= reflect.Float64 ||
|
|
||||||
reflect.Float32 <= k1 && k1 <= reflect.Float64 {
|
|
||||||
got, err := floatPromote(got)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
expect, err := floatPromote(expect)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return floatCompare(got, expect), nil
|
|
||||||
} else {
|
|
||||||
got, err := bigIntPromote(got)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
expect, err := bigIntPromote(expect)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return got.Cmp(expect), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0, errInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsErr compares two values (got & expect) and returns nil if the comparison is true, an ErrFail if
|
|
||||||
// the comparison is false, or an ErrInvalid if the comparison is invalid. IsErr also
|
|
||||||
// takes an optional argument, a comparator, that changes how the comparison is made.
|
|
||||||
//
|
|
||||||
// Is & IsErr are similar but different:
|
|
||||||
//
|
|
||||||
// Is(...) // Should only be called within a Terst(...) call
|
|
||||||
// IsErr(...) // A standalone comparator, the same as Is, just without the automatic reporting
|
|
||||||
//
|
|
||||||
func IsErr(arguments ...interface{}) error {
|
|
||||||
var got, expect interface{}
|
|
||||||
comparator := "=="
|
|
||||||
switch len(arguments) {
|
|
||||||
case 0, 1:
|
|
||||||
return fmt.Errorf("invalid number of arguments to IsErr: %d", len(arguments))
|
|
||||||
case 2:
|
|
||||||
got, expect = arguments[0], arguments[1]
|
|
||||||
default:
|
|
||||||
if value, ok := arguments[1].(string); ok {
|
|
||||||
comparator = value
|
|
||||||
} else {
|
|
||||||
return fmt.Errorf("invalid comparator: %v", arguments[1])
|
|
||||||
}
|
|
||||||
got, expect = arguments[0], arguments[2]
|
|
||||||
}
|
|
||||||
|
|
||||||
var result int
|
|
||||||
var err error
|
|
||||||
|
|
||||||
switch comparator {
|
|
||||||
case "<", "<=", ">", ">=":
|
|
||||||
result, err = compareNumber(got, expect)
|
|
||||||
case "=~", "!~":
|
|
||||||
result, err = compareMatch(got, expect)
|
|
||||||
case "==", "!=":
|
|
||||||
result, err = compareOther(got, expect)
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("invalid comparator: %s", comparator)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err == errInvalid {
|
|
||||||
return ErrInvalid(fmt.Errorf(
|
|
||||||
"\nINVALID (%s):\n got: %v (%T)\n expected: %v (%T)",
|
|
||||||
comparator,
|
|
||||||
got, got,
|
|
||||||
expect, expect,
|
|
||||||
))
|
|
||||||
} else if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
equality, pass := false, false
|
|
||||||
|
|
||||||
switch comparator {
|
|
||||||
case "==", "=~":
|
|
||||||
equality = true
|
|
||||||
pass = result == 0
|
|
||||||
case "!=", "!~":
|
|
||||||
equality = true
|
|
||||||
pass = result != 0
|
|
||||||
case "<":
|
|
||||||
pass = result < 0
|
|
||||||
case "<=":
|
|
||||||
pass = result <= 0
|
|
||||||
case ">":
|
|
||||||
pass = result > 0
|
|
||||||
case ">=":
|
|
||||||
pass = result >= 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pass {
|
|
||||||
if equality {
|
|
||||||
if comparator[1] == '~' {
|
|
||||||
if value, ok := got.([]byte); ok {
|
|
||||||
return ErrFail(fmt.Errorf(
|
|
||||||
"\nFAIL (%s)\n got: %s %v%s\nexpected: %v%s",
|
|
||||||
comparator,
|
|
||||||
value, got, typeKindString(got),
|
|
||||||
expect, typeKindString(expect),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ErrFail(fmt.Errorf(
|
|
||||||
"\nFAIL (%s)\n got: %v%s\nexpected: %v%s",
|
|
||||||
comparator,
|
|
||||||
got, typeKindString(got),
|
|
||||||
expect, typeKindString(expect),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
return ErrFail(fmt.Errorf(
|
|
||||||
"\nFAIL (%s)\n got: %v%s\nexpected: %s %v%s",
|
|
||||||
comparator,
|
|
||||||
got, typeKindString(got),
|
|
||||||
comparator, expect, typeKindString(expect),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func typeKindString(value interface{}) string {
|
|
||||||
reflectValue := reflect.ValueOf(value)
|
|
||||||
kind := reflectValue.Kind().String()
|
|
||||||
result := fmt.Sprintf("%T", value)
|
|
||||||
if kind == result {
|
|
||||||
if kind == "string" {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return fmt.Sprintf(" (%T)", value)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf(" (%T=%s)", value, kind)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (scope *_scope) reset() {
|
|
||||||
scope.name = ""
|
|
||||||
scope.output = scope.output[:]
|
|
||||||
scope.start = time.Time{}
|
|
||||||
scope.duration = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Terst creates a testing scope, where Is can be called and errors will be reported
|
|
||||||
// according to the top-level location of the comparison, and not where the Is call
|
|
||||||
// actually takes place. For example:
|
|
||||||
//
|
|
||||||
// func test(value int) {
|
|
||||||
// Is(value, 5) // <--- This failure is reported below.
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Terst(t, func(){
|
|
||||||
//
|
|
||||||
// Is(2, ">", 3) // <--- An error is reported here.
|
|
||||||
//
|
|
||||||
// test(5) // <--- An error is reported here.
|
|
||||||
//
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
func Terst(t *testing.T, arguments ...func()) {
|
|
||||||
scope := &_scope{
|
|
||||||
t: t,
|
|
||||||
}
|
|
||||||
|
|
||||||
pc, _, _, ok := runtime.Caller(1) // TODO Associate with the Test... func
|
|
||||||
if !ok {
|
|
||||||
panic("Here be dragons.")
|
|
||||||
}
|
|
||||||
|
|
||||||
_, scope.testFunc = findTestFunc()
|
|
||||||
|
|
||||||
registerScope(pc, scope)
|
|
||||||
|
|
||||||
for _, fn := range arguments {
|
|
||||||
func() {
|
|
||||||
scope.reset()
|
|
||||||
name := scope.testFunc.Name()
|
|
||||||
index := strings.LastIndex(scope.testFunc.Name(), ".")
|
|
||||||
if index >= 0 {
|
|
||||||
name = name[index+1:] + "(Terst)"
|
|
||||||
} else {
|
|
||||||
name = "(Terst)"
|
|
||||||
}
|
|
||||||
name = "(Terst)"
|
|
||||||
scope.name = name
|
|
||||||
scope.start = time.Now()
|
|
||||||
defer func() {
|
|
||||||
scope.duration = time.Now().Sub(scope.start)
|
|
||||||
if err := recover(); err != nil {
|
|
||||||
scope.t.Fail()
|
|
||||||
scope.report()
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
scope.report()
|
|
||||||
}()
|
|
||||||
fn()
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// From "testing"
|
|
||||||
func (scope *_scope) report() {
|
|
||||||
format := "~~~ %s: (Terst)\n%s"
|
|
||||||
if scope.t.Failed() {
|
|
||||||
fmt.Printf(format, "FAIL", scope.output)
|
|
||||||
} else if testing.Verbose() && len(scope.output) > 0 {
|
|
||||||
fmt.Printf(format, "PASS", scope.output)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (scope *_scope) log(call _entry, str string) {
|
|
||||||
scope.mu.Lock()
|
|
||||||
defer scope.mu.Unlock()
|
|
||||||
scope.output = append(scope.output, decorate(call, str)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// decorate prefixes the string with the file and line of the call site
|
|
||||||
// and inserts the final newline if needed and indentation tabs for formascing.
|
|
||||||
func decorate(call _entry, s string) string {
|
|
||||||
|
|
||||||
file, line := call.File, call.Line
|
|
||||||
if call.PC > 0 {
|
|
||||||
// Truncate file name at last file name separator.
|
|
||||||
if index := strings.LastIndex(file, "/"); index >= 0 {
|
|
||||||
file = file[index+1:]
|
|
||||||
} else if index = strings.LastIndex(file, "\\"); index >= 0 {
|
|
||||||
file = file[index+1:]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
file = "???"
|
|
||||||
line = 1
|
|
||||||
}
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
// Every line is indented at least one tab.
|
|
||||||
buf.WriteByte('\t')
|
|
||||||
fmt.Fprintf(buf, "%s:%d: ", file, line)
|
|
||||||
lines := strings.Split(s, "\n")
|
|
||||||
if l := len(lines); l > 1 && lines[l-1] == "" {
|
|
||||||
lines = lines[:l-1]
|
|
||||||
}
|
|
||||||
for i, line := range lines {
|
|
||||||
if i > 0 {
|
|
||||||
// Second and subsequent lines are indented an extra tab.
|
|
||||||
buf.WriteString("\n\t\t")
|
|
||||||
}
|
|
||||||
buf.WriteString(line)
|
|
||||||
}
|
|
||||||
buf.WriteByte('\n')
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func findScope() (*_scope, _entry) {
|
|
||||||
registry.lock.RLock()
|
|
||||||
defer registry.lock.RUnlock()
|
|
||||||
table := registry.table
|
|
||||||
depth := 2 // Starting depth
|
|
||||||
call := _entry{}
|
|
||||||
for {
|
|
||||||
pc, _, _, ok := runtime.Caller(depth)
|
|
||||||
if !ok {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if scope, exists := table[pc]; exists {
|
|
||||||
pc, file, line, _ := runtime.Caller(depth - 3) // Terst(...) + func(){}() + fn() => ???()
|
|
||||||
call.PC = pc
|
|
||||||
call.File = file
|
|
||||||
call.Line = line
|
|
||||||
return scope, call
|
|
||||||
}
|
|
||||||
depth++
|
|
||||||
}
|
|
||||||
return nil, _entry{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call is a reference to a line immediately under a Terst testing scope.
|
|
||||||
type Call struct {
|
|
||||||
scope *_scope
|
|
||||||
entry _entry
|
|
||||||
}
|
|
||||||
|
|
||||||
// Caller will search the stack, looking for a Terst testing scope. If a scope
|
|
||||||
// is found, then Caller returns a Call for logging errors, accessing testing.T, etc.
|
|
||||||
// If no scope is found, Caller returns nil.
|
|
||||||
func Caller() *Call {
|
|
||||||
scope, entry := findScope()
|
|
||||||
if scope == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &Call{
|
|
||||||
scope: scope,
|
|
||||||
entry: entry,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestFunc returns the *runtime.Func entry for the top-level Test...(t testing.T)
|
|
||||||
// function.
|
|
||||||
func (cl *Call) TestFunc() *runtime.Func {
|
|
||||||
return cl.scope.testFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
// T returns the original testing.T passed to Terst(...)
|
|
||||||
func (cl *Call) T() *testing.T {
|
|
||||||
return cl.scope.t
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log is the terst version of `testing.T.Log`
|
|
||||||
func (cl *Call) Log(arguments ...interface{}) {
|
|
||||||
cl.scope.log(cl.entry, fmt.Sprintln(arguments...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logf is the terst version of `testing.T.Logf`
|
|
||||||
func (cl *Call) Logf(format string, arguments ...interface{}) {
|
|
||||||
cl.scope.log(cl.entry, fmt.Sprintf(format, arguments...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error is the terst version of `testing.T.Error`
|
|
||||||
func (cl *Call) Error(arguments ...interface{}) {
|
|
||||||
cl.scope.log(cl.entry, fmt.Sprintln(arguments...))
|
|
||||||
cl.scope.t.Fail()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Errorf is the terst version of `testing.T.Errorf`
|
|
||||||
func (cl *Call) Errorf(format string, arguments ...interface{}) {
|
|
||||||
cl.scope.log(cl.entry, fmt.Sprintf(format, arguments...))
|
|
||||||
cl.scope.t.Fail()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip is the terst version of `testing.T.Skip`
|
|
||||||
func (cl *Call) Skip(arguments ...interface{}) {
|
|
||||||
cl.scope.log(cl.entry, fmt.Sprintln(arguments...))
|
|
||||||
cl.scope.t.SkipNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skipf is the terst version of `testing.T.Skipf`
|
|
||||||
func (cl *Call) Skipf(format string, arguments ...interface{}) {
|
|
||||||
cl.scope.log(cl.entry, fmt.Sprintf(format, arguments...))
|
|
||||||
cl.scope.t.SkipNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
type _scope struct {
|
|
||||||
t *testing.T
|
|
||||||
testFunc *runtime.Func
|
|
||||||
name string
|
|
||||||
mu sync.RWMutex
|
|
||||||
output []byte
|
|
||||||
start time.Time
|
|
||||||
duration time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
type _entry struct {
|
|
||||||
PC uintptr
|
|
||||||
File string
|
|
||||||
Line int
|
|
||||||
Func *runtime.Func
|
|
||||||
}
|
|
||||||
|
|
||||||
func _findFunc(match string) (_entry, *runtime.Func) {
|
|
||||||
depth := 2 // Starting depth
|
|
||||||
for {
|
|
||||||
pc, file, line, ok := runtime.Caller(depth)
|
|
||||||
if !ok {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
fn := runtime.FuncForPC(pc)
|
|
||||||
name := fn.Name()
|
|
||||||
if index := strings.LastIndex(name, match); index >= 0 {
|
|
||||||
// Assume we have an instance of TestXyzzy in a _test file
|
|
||||||
return _entry{
|
|
||||||
PC: pc,
|
|
||||||
File: file,
|
|
||||||
Line: line,
|
|
||||||
Func: fn,
|
|
||||||
}, fn
|
|
||||||
}
|
|
||||||
depth++
|
|
||||||
}
|
|
||||||
return _entry{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func findTestFunc() (_entry, *runtime.Func) {
|
|
||||||
return _findFunc(".Test")
|
|
||||||
}
|
|
||||||
|
|
||||||
func findTerstFunc() (_entry, *runtime.Func) {
|
|
||||||
return _findFunc(".Terst")
|
|
||||||
}
|
|
||||||
26
Godeps/_workspace/src/github.com/robertkrimen/otto/test/Makefile
generated
vendored
26
Godeps/_workspace/src/github.com/robertkrimen/otto/test/Makefile
generated
vendored
@@ -1,26 +0,0 @@
|
|||||||
.PHONY: test fetch clean build err report
|
|
||||||
|
|
||||||
TESTER := tester
|
|
||||||
|
|
||||||
test: $(TESTER)
|
|
||||||
for test in test-*.js; do ./$^ -test=true $$test 1>/dev/null || exit 1; done
|
|
||||||
@echo PASS
|
|
||||||
|
|
||||||
report: $(TESTER)
|
|
||||||
./$^ -report | grep -v "MT READY"
|
|
||||||
|
|
||||||
fetch: $(TESTER)
|
|
||||||
./$^ fetch
|
|
||||||
|
|
||||||
build:
|
|
||||||
go build -a -o $(TESTER)
|
|
||||||
|
|
||||||
$(TESTER): tester.go
|
|
||||||
$(MAKE) build
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f test-*.js
|
|
||||||
rm -f $(TESTER)
|
|
||||||
|
|
||||||
err: $(TESTER)
|
|
||||||
for test in test-*.js; do ./$^ $$test; done 2>$@
|
|
||||||
196
Godeps/_workspace/src/github.com/robertkrimen/otto/test/tester.go
generated
vendored
196
Godeps/_workspace/src/github.com/robertkrimen/otto/test/tester.go
generated
vendored
@@ -1,196 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"text/tabwriter"
|
|
||||||
|
|
||||||
"github.com/robertkrimen/otto"
|
|
||||||
"github.com/robertkrimen/otto/parser"
|
|
||||||
)
|
|
||||||
|
|
||||||
var flag_test *bool = flag.Bool("test", false, "")
|
|
||||||
var flag_report *bool = flag.Bool("report", false, "")
|
|
||||||
|
|
||||||
var match_ReferenceError_not_defined = regexp.MustCompile(`^ReferenceError: \S+ is not defined$`)
|
|
||||||
var match_lookahead = regexp.MustCompile(`Invalid regular expression: re2: Invalid \(\?[=!]\) <lookahead>`)
|
|
||||||
var match_backreference = regexp.MustCompile(`Invalid regular expression: re2: Invalid \\\d <backreference>`)
|
|
||||||
var match_TypeError_undefined = regexp.MustCompile(`^TypeError: Cannot access member '[^']+' of undefined$`)
|
|
||||||
|
|
||||||
var target = map[string]string{
|
|
||||||
"test-angular-bindonce.js": "fail", // (anonymous): Line 1:944 Unexpected token ( (and 40 more errors)
|
|
||||||
"test-jsforce.js": "fail", // (anonymous): Line 9:28329 RuneError (and 5 more errors)
|
|
||||||
"test-chaplin.js": "parse", // Error: Chaplin requires Common.js or AMD modules
|
|
||||||
"test-dropbox.js.js": "parse", // Error: dropbox.js loaded in an unsupported JavaScript environment.
|
|
||||||
"test-epitome.js": "parse", // TypeError: undefined is not a function
|
|
||||||
"test-portal.js": "parse", // TypeError
|
|
||||||
"test-reactive-coffee.js": "parse", // Dependencies are not met for reactive: _ and $ not found
|
|
||||||
"test-scriptaculous.js": "parse", // script.aculo.us requires the Prototype JavaScript framework >= 1.6.0.3
|
|
||||||
"test-waypoints.js": "parse", // TypeError: undefined is not a function
|
|
||||||
"test-webuploader.js": "parse", // Error: `jQuery` is undefined
|
|
||||||
"test-xuijs.js": "parse", // TypeError: undefined is not a function
|
|
||||||
}
|
|
||||||
|
|
||||||
// http://cdnjs.com/
|
|
||||||
// http://api.cdnjs.com/libraries
|
|
||||||
|
|
||||||
func fetch(name, location string) error {
|
|
||||||
response, err := http.Get(location)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer response.Body.Close()
|
|
||||||
body, err := ioutil.ReadAll(response.Body)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.HasSuffix(location, ".js") {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
filename := "test-" + name + ".js"
|
|
||||||
fmt.Println(filename, len(body))
|
|
||||||
return ioutil.WriteFile(filename, body, 0644)
|
|
||||||
}
|
|
||||||
|
|
||||||
func test(filename string) error {
|
|
||||||
script, err := ioutil.ReadFile(filename)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !*flag_report {
|
|
||||||
fmt.Fprintln(os.Stdout, filename, len(script))
|
|
||||||
}
|
|
||||||
|
|
||||||
parse := false
|
|
||||||
option := target[filename]
|
|
||||||
|
|
||||||
if option != "parse" {
|
|
||||||
vm := otto.New()
|
|
||||||
_, err = vm.Run(string(script))
|
|
||||||
if err != nil {
|
|
||||||
value := err.Error()
|
|
||||||
switch {
|
|
||||||
case match_ReferenceError_not_defined.MatchString(value):
|
|
||||||
case match_TypeError_undefined.MatchString(value):
|
|
||||||
case match_lookahead.MatchString(value):
|
|
||||||
case match_backreference.MatchString(value):
|
|
||||||
default:
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
parse = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if parse {
|
|
||||||
_, err = parser.ParseFile(nil, filename, string(script), parser.IgnoreRegExpErrors)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
target[filename] = "parse"
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
filename := ""
|
|
||||||
|
|
||||||
err := func() error {
|
|
||||||
|
|
||||||
if flag.Arg(0) == "fetch" {
|
|
||||||
response, err := http.Get("http://api.cdnjs.com/libraries")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer response.Body.Close()
|
|
||||||
body, err := ioutil.ReadAll(response.Body)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tmp map[string]interface{}
|
|
||||||
|
|
||||||
err = json.Unmarshal(body, &tmp)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
|
|
||||||
for _, value := range tmp["results"].([]interface{}) {
|
|
||||||
wg.Add(1)
|
|
||||||
library := value.(map[string]interface{})
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
fetch(library["name"].(string), library["latest"].(string))
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if *flag_report {
|
|
||||||
files, err := ioutil.ReadDir(".")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
writer := tabwriter.NewWriter(os.Stdout, 0, 8, 0, '\t', 0)
|
|
||||||
fmt.Fprintln(writer, "", "\t| Status")
|
|
||||||
fmt.Fprintln(writer, "---", "\t| ---")
|
|
||||||
for _, file := range files {
|
|
||||||
filename := file.Name()
|
|
||||||
if !strings.HasPrefix(filename, "test-") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
err := test(filename)
|
|
||||||
option := target[filename]
|
|
||||||
name := strings.TrimPrefix(strings.TrimSuffix(filename, ".js"), "test-")
|
|
||||||
if err == nil {
|
|
||||||
switch option {
|
|
||||||
case "":
|
|
||||||
fmt.Fprintln(writer, name, "\t| pass")
|
|
||||||
case "parse":
|
|
||||||
fmt.Fprintln(writer, name, "\t| pass (parse)")
|
|
||||||
case "re2":
|
|
||||||
continue
|
|
||||||
fmt.Fprintln(writer, name, "\t| unknown (re2)")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Fprintln(writer, name, "\t| fail")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writer.Flush()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
filename = flag.Arg(0)
|
|
||||||
return test(filename)
|
|
||||||
|
|
||||||
}()
|
|
||||||
if err != nil {
|
|
||||||
if filename != "" {
|
|
||||||
if *flag_test && target[filename] == "fail" {
|
|
||||||
goto exit
|
|
||||||
}
|
|
||||||
fmt.Fprintf(os.Stderr, "%s: %s\n", filename, err.Error())
|
|
||||||
} else {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
}
|
|
||||||
os.Exit(64)
|
|
||||||
}
|
|
||||||
exit:
|
|
||||||
}
|
|
||||||
13
Godeps/_workspace/src/github.com/robertkrimen/otto/type_error.go
generated
vendored
13
Godeps/_workspace/src/github.com/robertkrimen/otto/type_error.go
generated
vendored
@@ -1,13 +0,0 @@
|
|||||||
package otto
|
|
||||||
|
|
||||||
func (rt *_runtime) newErrorObject(name string, message Value) *_object {
|
|
||||||
self := rt.newClassObject("Error")
|
|
||||||
if message.IsDefined() {
|
|
||||||
msg := message.string()
|
|
||||||
self.defineProperty("message", toValue_string(msg), 0111, false)
|
|
||||||
self.value = newError(rt, name, msg)
|
|
||||||
} else {
|
|
||||||
self.value = newError(rt, name)
|
|
||||||
}
|
|
||||||
return self
|
|
||||||
}
|
|
||||||
11
Godeps/_workspace/src/github.com/robertkrimen/otto/underscore/Makefile
generated
vendored
11
Godeps/_workspace/src/github.com/robertkrimen/otto/underscore/Makefile
generated
vendored
@@ -1,11 +0,0 @@
|
|||||||
.PHONY: source
|
|
||||||
|
|
||||||
source: source.go
|
|
||||||
|
|
||||||
underscore.js:
|
|
||||||
curl -kL http://underscorejs.org/underscore.js > $@
|
|
||||||
|
|
||||||
source.go: underscore.js
|
|
||||||
go-bindata -f underscore -p underscore -u true < $< 2>/dev/null | grep -v '^//' | gofmt > $@
|
|
||||||
head -4 $< >> $@
|
|
||||||
mv $< ..
|
|
||||||
53
Godeps/_workspace/src/github.com/robertkrimen/otto/underscore/README.markdown
generated
vendored
53
Godeps/_workspace/src/github.com/robertkrimen/otto/underscore/README.markdown
generated
vendored
@@ -1,53 +0,0 @@
|
|||||||
# underscore
|
|
||||||
--
|
|
||||||
import "github.com/robertkrimen/otto/underscore"
|
|
||||||
|
|
||||||
Package underscore contains the source for the JavaScript utility-belt library.
|
|
||||||
|
|
||||||
import (
|
|
||||||
_ "github.com/robertkrimen/otto/underscore"
|
|
||||||
)
|
|
||||||
// Every Otto runtime will now include underscore
|
|
||||||
|
|
||||||
http://underscorejs.org
|
|
||||||
|
|
||||||
https://github.com/documentcloud/underscore
|
|
||||||
|
|
||||||
By importing this package, you'll automatically load underscore every time you
|
|
||||||
create a new Otto runtime.
|
|
||||||
|
|
||||||
To prevent this behavior, you can do the following:
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/robertkrimen/otto/underscore"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
underscore.Disable()
|
|
||||||
}
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
#### func Disable
|
|
||||||
|
|
||||||
```go
|
|
||||||
func Disable()
|
|
||||||
```
|
|
||||||
Disable underscore runtime inclusion.
|
|
||||||
|
|
||||||
#### func Enable
|
|
||||||
|
|
||||||
```go
|
|
||||||
func Enable()
|
|
||||||
```
|
|
||||||
Enable underscore runtime inclusion.
|
|
||||||
|
|
||||||
#### func Source
|
|
||||||
|
|
||||||
```go
|
|
||||||
func Source() string
|
|
||||||
```
|
|
||||||
Source returns the underscore source.
|
|
||||||
|
|
||||||
--
|
|
||||||
**godocdown** http://github.com/robertkrimen/godocdown
|
|
||||||
3463
Godeps/_workspace/src/github.com/robertkrimen/otto/underscore/source.go
generated
vendored
3463
Godeps/_workspace/src/github.com/robertkrimen/otto/underscore/source.go
generated
vendored
File diff suppressed because it is too large
Load Diff
84
Godeps/_workspace/src/github.com/robertkrimen/otto/underscore/testify
generated
vendored
84
Godeps/_workspace/src/github.com/robertkrimen/otto/underscore/testify
generated
vendored
@@ -1,84 +0,0 @@
|
|||||||
#!/usr/bin/env perl
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use warnings;
|
|
||||||
|
|
||||||
my $underscore_test = shift @ARGV || "";
|
|
||||||
if (!-d $underscore_test) {
|
|
||||||
print <<_END_;
|
|
||||||
Usage:
|
|
||||||
|
|
||||||
testify ./underscore/test
|
|
||||||
|
|
||||||
# Should look something like:
|
|
||||||
arrays.js
|
|
||||||
chaining.js
|
|
||||||
collections.js
|
|
||||||
functions.js
|
|
||||||
index.html
|
|
||||||
objects.js
|
|
||||||
speed.js
|
|
||||||
utility.js
|
|
||||||
vendor
|
|
||||||
|
|
||||||
_END_
|
|
||||||
if ($underscore_test) {
|
|
||||||
die "!: Not a directory: $underscore_test\n"
|
|
||||||
}
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
chdir $underscore_test or die "!: $!";
|
|
||||||
|
|
||||||
my @js = <*.js>;
|
|
||||||
|
|
||||||
for my $file (@js) {
|
|
||||||
open my $fh, '<', $file or die "!: $!";
|
|
||||||
my $tests = join "", <$fh>;
|
|
||||||
my @tests = $tests =~ m/
|
|
||||||
^(\s{2}test\(.*?
|
|
||||||
^\s{2}}\);)$
|
|
||||||
/mgxs;
|
|
||||||
close $fh;
|
|
||||||
next unless @tests;
|
|
||||||
print "$file: ", scalar(@tests), "\n";
|
|
||||||
my $underscore_name = "underscore_$file";
|
|
||||||
$underscore_name =~ s/.js$//;
|
|
||||||
my $go_file = "${underscore_name}_test.go";
|
|
||||||
$go_file =~ s/.js$/.go/;
|
|
||||||
open $fh, '>', $go_file or die "!: $!";
|
|
||||||
|
|
||||||
$fh->print(<<_END_);
|
|
||||||
package otto
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
_END_
|
|
||||||
|
|
||||||
my $count = 0;
|
|
||||||
for my $test (@tests) {
|
|
||||||
$test =~ s/`([^`]+)`/<$1>/g;
|
|
||||||
my ($name) = $test =~ m/^\s*test\(['"]([^'"]+)['"]/;
|
|
||||||
$fh->print(<<_END_);
|
|
||||||
// $name
|
|
||||||
func Test_${underscore_name}_$count(t *testing.T) {
|
|
||||||
tt(t, func(){
|
|
||||||
test := underscoreTest()
|
|
||||||
|
|
||||||
test(`
|
|
||||||
$test
|
|
||||||
`)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
_END_
|
|
||||||
$count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# test('#779 - delimeters are applied to unescaped text.', 1, function() {
|
|
||||||
# var template = _.template('<<\nx\n>>', null, {evaluate: /<<(.*?)>>/g});
|
|
||||||
# strictEqual(template(), '<<\nx\n>>');
|
|
||||||
# });
|
|
||||||
49
Godeps/_workspace/src/github.com/robertkrimen/otto/underscore/underscore.go
generated
vendored
49
Godeps/_workspace/src/github.com/robertkrimen/otto/underscore/underscore.go
generated
vendored
@@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
Package underscore contains the source for the JavaScript utility-belt library.
|
|
||||||
|
|
||||||
import (
|
|
||||||
_ "github.com/robertkrimen/otto/underscore"
|
|
||||||
)
|
|
||||||
// Every Otto runtime will now include underscore
|
|
||||||
|
|
||||||
http://underscorejs.org
|
|
||||||
|
|
||||||
https://github.com/documentcloud/underscore
|
|
||||||
|
|
||||||
By importing this package, you'll automatically load underscore every time you create a new Otto runtime.
|
|
||||||
|
|
||||||
To prevent this behavior, you can do the following:
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/robertkrimen/otto/underscore"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
underscore.Disable()
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
package underscore
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/robertkrimen/otto/registry"
|
|
||||||
)
|
|
||||||
|
|
||||||
var entry *registry.Entry = registry.Register(func() string {
|
|
||||||
return Source()
|
|
||||||
})
|
|
||||||
|
|
||||||
// Enable underscore runtime inclusion.
|
|
||||||
func Enable() {
|
|
||||||
entry.Enable()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable underscore runtime inclusion.
|
|
||||||
func Disable() {
|
|
||||||
entry.Disable()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Source returns the underscore source.
|
|
||||||
func Source() string {
|
|
||||||
return string(underscore())
|
|
||||||
}
|
|
||||||
308
Godeps/_workspace/src/github.com/rs/cors/cors.go
generated
vendored
308
Godeps/_workspace/src/github.com/rs/cors/cors.go
generated
vendored
@@ -1,308 +0,0 @@
|
|||||||
/*
|
|
||||||
Package cors is net/http handler to handle CORS related requests
|
|
||||||
as defined by http://www.w3.org/TR/cors/
|
|
||||||
|
|
||||||
You can configure it by passing an option struct to cors.New:
|
|
||||||
|
|
||||||
c := cors.New(cors.Options{
|
|
||||||
AllowedOrigins: []string{"foo.com"},
|
|
||||||
AllowedMethods: []string{"GET", "POST", "DELETE"},
|
|
||||||
AllowCredentials: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
Then insert the handler in the chain:
|
|
||||||
|
|
||||||
handler = c.Handler(handler)
|
|
||||||
|
|
||||||
See Options documentation for more options.
|
|
||||||
|
|
||||||
The resulting handler is a standard net/http handler.
|
|
||||||
*/
|
|
||||||
package cors
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Options is a configuration container to setup the CORS middleware.
|
|
||||||
type Options struct {
|
|
||||||
// AllowedOrigins is a list of origins a cross-domain request can be executed from.
|
|
||||||
// If the special "*" value is present in the list, all origins will be allowed.
|
|
||||||
// Default value is ["*"]
|
|
||||||
AllowedOrigins []string
|
|
||||||
// AllowedMethods is a list of methods the client is allowed to use with
|
|
||||||
// cross-domain requests. Default value is simple methods (GET and POST)
|
|
||||||
AllowedMethods []string
|
|
||||||
// AllowedHeaders is list of non simple headers the client is allowed to use with
|
|
||||||
// cross-domain requests.
|
|
||||||
// If the special "*" value is present in the list, all headers will be allowed.
|
|
||||||
// Default value is [] but "Origin" is always appended to the list.
|
|
||||||
AllowedHeaders []string
|
|
||||||
// ExposedHeaders indicates which headers are safe to expose to the API of a CORS
|
|
||||||
// API specification
|
|
||||||
ExposedHeaders []string
|
|
||||||
// AllowCredentials indicates whether the request can include user credentials like
|
|
||||||
// cookies, HTTP authentication or client side SSL certificates.
|
|
||||||
AllowCredentials bool
|
|
||||||
// MaxAge indicates how long (in seconds) the results of a preflight request
|
|
||||||
// can be cached
|
|
||||||
MaxAge int
|
|
||||||
// Debugging flag adds additional output to debug server side CORS issues
|
|
||||||
Debug bool
|
|
||||||
// log object to use when debugging
|
|
||||||
log *log.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
type Cors struct {
|
|
||||||
// The CORS Options
|
|
||||||
options Options
|
|
||||||
}
|
|
||||||
|
|
||||||
// New creates a new Cors handler with the provided options.
|
|
||||||
func New(options Options) *Cors {
|
|
||||||
// Normalize options
|
|
||||||
// Note: for origins and methods matching, the spec requires a case-sensitive matching.
|
|
||||||
// As it may error prone, we chose to ignore the spec here.
|
|
||||||
normOptions := Options{
|
|
||||||
AllowedOrigins: convert(options.AllowedOrigins, strings.ToLower),
|
|
||||||
AllowedMethods: convert(options.AllowedMethods, strings.ToUpper),
|
|
||||||
// Origin is always appended as some browsers will always request
|
|
||||||
// for this header at preflight
|
|
||||||
AllowedHeaders: convert(append(options.AllowedHeaders, "Origin"), http.CanonicalHeaderKey),
|
|
||||||
ExposedHeaders: convert(options.ExposedHeaders, http.CanonicalHeaderKey),
|
|
||||||
AllowCredentials: options.AllowCredentials,
|
|
||||||
MaxAge: options.MaxAge,
|
|
||||||
Debug: options.Debug,
|
|
||||||
log: log.New(os.Stdout, "[cors] ", log.LstdFlags),
|
|
||||||
}
|
|
||||||
if len(normOptions.AllowedOrigins) == 0 {
|
|
||||||
// Default is all origins
|
|
||||||
normOptions.AllowedOrigins = []string{"*"}
|
|
||||||
}
|
|
||||||
if len(normOptions.AllowedHeaders) == 1 {
|
|
||||||
// Add some sensible defaults
|
|
||||||
normOptions.AllowedHeaders = []string{"Origin", "Accept", "Content-Type"}
|
|
||||||
}
|
|
||||||
if len(normOptions.AllowedMethods) == 0 {
|
|
||||||
// Default is simple methods
|
|
||||||
normOptions.AllowedMethods = []string{"GET", "POST"}
|
|
||||||
}
|
|
||||||
|
|
||||||
if normOptions.Debug {
|
|
||||||
normOptions.log.Printf("Options: %v", normOptions)
|
|
||||||
}
|
|
||||||
return &Cors{
|
|
||||||
options: normOptions,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default creates a new Cors handler with default options
|
|
||||||
func Default() *Cors {
|
|
||||||
return New(Options{})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handler apply the CORS specification on the request, and add relevant CORS headers
|
|
||||||
// as necessary.
|
|
||||||
func (cors *Cors) Handler(h http.Handler) http.Handler {
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method == "OPTIONS" {
|
|
||||||
cors.logf("Handler: Preflight request")
|
|
||||||
cors.handlePreflight(w, r)
|
|
||||||
// Preflight requests are standalone and should stop the chain as some other
|
|
||||||
// middleware may not handle OPTIONS requests correctly. One typical example
|
|
||||||
// is authentication middleware ; OPTIONS requests won't carry authentication
|
|
||||||
// headers (see #1)
|
|
||||||
} else {
|
|
||||||
cors.logf("Handler: Actual request")
|
|
||||||
cors.handleActualRequest(w, r)
|
|
||||||
h.ServeHTTP(w, r)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Martini compatible handler
|
|
||||||
func (cors *Cors) HandlerFunc(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method == "OPTIONS" {
|
|
||||||
cors.logf("HandlerFunc: Preflight request")
|
|
||||||
cors.handlePreflight(w, r)
|
|
||||||
} else {
|
|
||||||
cors.logf("HandlerFunc: Actual request")
|
|
||||||
cors.handleActualRequest(w, r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Negroni compatible interface
|
|
||||||
func (cors *Cors) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
|
|
||||||
if r.Method == "OPTIONS" {
|
|
||||||
cors.logf("ServeHTTP: Preflight request")
|
|
||||||
cors.handlePreflight(w, r)
|
|
||||||
// Preflight requests are standalone and should stop the chain as some other
|
|
||||||
// middleware may not handle OPTIONS requests correctly. One typical example
|
|
||||||
// is authentication middleware ; OPTIONS requests won't carry authentication
|
|
||||||
// headers (see #1)
|
|
||||||
} else {
|
|
||||||
cors.logf("ServeHTTP: Actual request")
|
|
||||||
cors.handleActualRequest(w, r)
|
|
||||||
next(w, r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// handlePreflight handles pre-flight CORS requests
|
|
||||||
func (cors *Cors) handlePreflight(w http.ResponseWriter, r *http.Request) {
|
|
||||||
options := cors.options
|
|
||||||
headers := w.Header()
|
|
||||||
origin := r.Header.Get("Origin")
|
|
||||||
|
|
||||||
if r.Method != "OPTIONS" {
|
|
||||||
cors.logf(" Preflight aborted: %s!=OPTIONS", r.Method)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if origin == "" {
|
|
||||||
cors.logf(" Preflight aborted: empty origin")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !cors.isOriginAllowed(origin) {
|
|
||||||
cors.logf(" Preflight aborted: origin '%s' not allowed", origin)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
reqMethod := r.Header.Get("Access-Control-Request-Method")
|
|
||||||
if !cors.isMethodAllowed(reqMethod) {
|
|
||||||
cors.logf(" Preflight aborted: method '%s' not allowed", reqMethod)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
reqHeaders := parseHeaderList(r.Header.Get("Access-Control-Request-Headers"))
|
|
||||||
if !cors.areHeadersAllowed(reqHeaders) {
|
|
||||||
cors.logf(" Preflight aborted: headers '%v' not allowed", reqHeaders)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
headers.Set("Access-Control-Allow-Origin", origin)
|
|
||||||
headers.Add("Vary", "Origin")
|
|
||||||
// Spec says: Since the list of methods can be unbounded, simply returning the method indicated
|
|
||||||
// by Access-Control-Request-Method (if supported) can be enough
|
|
||||||
headers.Set("Access-Control-Allow-Methods", strings.ToUpper(reqMethod))
|
|
||||||
if len(reqHeaders) > 0 {
|
|
||||||
|
|
||||||
// Spec says: Since the list of headers can be unbounded, simply returning supported headers
|
|
||||||
// from Access-Control-Request-Headers can be enough
|
|
||||||
headers.Set("Access-Control-Allow-Headers", strings.Join(reqHeaders, ", "))
|
|
||||||
}
|
|
||||||
if options.AllowCredentials {
|
|
||||||
headers.Set("Access-Control-Allow-Credentials", "true")
|
|
||||||
}
|
|
||||||
if options.MaxAge > 0 {
|
|
||||||
headers.Set("Access-Control-Max-Age", strconv.Itoa(options.MaxAge))
|
|
||||||
}
|
|
||||||
cors.logf(" Preflight response headers: %v", headers)
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleActualRequest handles simple cross-origin requests, actual request or redirects
|
|
||||||
func (cors *Cors) handleActualRequest(w http.ResponseWriter, r *http.Request) {
|
|
||||||
options := cors.options
|
|
||||||
headers := w.Header()
|
|
||||||
origin := r.Header.Get("Origin")
|
|
||||||
|
|
||||||
if r.Method == "OPTIONS" {
|
|
||||||
cors.logf(" Actual request no headers added: method == %s", r.Method)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if origin == "" {
|
|
||||||
cors.logf(" Actual request no headers added: missing origin")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !cors.isOriginAllowed(origin) {
|
|
||||||
cors.logf(" Actual request no headers added: origin '%s' not allowed", origin)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note that spec does define a way to specifically disallow a simple method like GET or
|
|
||||||
// POST. Access-Control-Allow-Methods is only used for pre-flight requests and the
|
|
||||||
// spec doesn't instruct to check the allowed methods for simple cross-origin requests.
|
|
||||||
// We think it's a nice feature to be able to have control on those methods though.
|
|
||||||
if !cors.isMethodAllowed(r.Method) {
|
|
||||||
if cors.options.Debug {
|
|
||||||
cors.logf(" Actual request no headers added: method '%s' not allowed",
|
|
||||||
r.Method)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
headers.Set("Access-Control-Allow-Origin", origin)
|
|
||||||
headers.Add("Vary", "Origin")
|
|
||||||
if len(options.ExposedHeaders) > 0 {
|
|
||||||
headers.Set("Access-Control-Expose-Headers", strings.Join(options.ExposedHeaders, ", "))
|
|
||||||
}
|
|
||||||
if options.AllowCredentials {
|
|
||||||
headers.Set("Access-Control-Allow-Credentials", "true")
|
|
||||||
}
|
|
||||||
cors.logf(" Actual response added headers: %v", headers)
|
|
||||||
}
|
|
||||||
|
|
||||||
// convenience method. checks if debugging is turned on before printing
|
|
||||||
func (cors *Cors) logf(format string, a ...interface{}) {
|
|
||||||
if cors.options.Debug {
|
|
||||||
cors.options.log.Printf(format, a...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// isOriginAllowed checks if a given origin is allowed to perform cross-domain requests
|
|
||||||
// on the endpoint
|
|
||||||
func (cors *Cors) isOriginAllowed(origin string) bool {
|
|
||||||
allowedOrigins := cors.options.AllowedOrigins
|
|
||||||
origin = strings.ToLower(origin)
|
|
||||||
for _, allowedOrigin := range allowedOrigins {
|
|
||||||
switch allowedOrigin {
|
|
||||||
case "*":
|
|
||||||
return true
|
|
||||||
case origin:
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// isMethodAllowed checks if a given method can be used as part of a cross-domain request
|
|
||||||
// on the endpoing
|
|
||||||
func (cors *Cors) isMethodAllowed(method string) bool {
|
|
||||||
allowedMethods := cors.options.AllowedMethods
|
|
||||||
if len(allowedMethods) == 0 {
|
|
||||||
// If no method allowed, always return false, even for preflight request
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
method = strings.ToUpper(method)
|
|
||||||
if method == "OPTIONS" {
|
|
||||||
// Always allow preflight requests
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
for _, allowedMethod := range allowedMethods {
|
|
||||||
if allowedMethod == method {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// areHeadersAllowed checks if a given list of headers are allowed to used within
|
|
||||||
// a cross-domain request.
|
|
||||||
func (cors *Cors) areHeadersAllowed(requestedHeaders []string) bool {
|
|
||||||
if len(requestedHeaders) == 0 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
for _, header := range requestedHeaders {
|
|
||||||
found := false
|
|
||||||
for _, allowedHeader := range cors.options.AllowedHeaders {
|
|
||||||
if allowedHeader == "*" || allowedHeader == header {
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
27
Godeps/_workspace/src/github.com/rs/cors/utils.go
generated
vendored
27
Godeps/_workspace/src/github.com/rs/cors/utils.go
generated
vendored
@@ -1,27 +0,0 @@
|
|||||||
package cors
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type converter func(string) string
|
|
||||||
|
|
||||||
// convert converts a list of string using the passed converter function
|
|
||||||
func convert(s []string, c converter) []string {
|
|
||||||
out := []string{}
|
|
||||||
for _, i := range s {
|
|
||||||
out = append(out, c(i))
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseHeaderList(headerList string) (headers []string) {
|
|
||||||
for _, header := range strings.Split(headerList, ",") {
|
|
||||||
header = http.CanonicalHeaderKey(strings.TrimSpace(header))
|
|
||||||
if header != "" {
|
|
||||||
headers = append(headers, header)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return headers
|
|
||||||
}
|
|
||||||
261
Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/batch.go
generated
vendored
261
Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/batch.go
generated
vendored
@@ -1,261 +0,0 @@
|
|||||||
// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
package leveldb
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/syndtr/goleveldb/leveldb/errors"
|
|
||||||
"github.com/syndtr/goleveldb/leveldb/memdb"
|
|
||||||
"github.com/syndtr/goleveldb/leveldb/storage"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ErrBatchCorrupted records reason of batch corruption.
|
|
||||||
type ErrBatchCorrupted struct {
|
|
||||||
Reason string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *ErrBatchCorrupted) Error() string {
|
|
||||||
return fmt.Sprintf("leveldb: batch corrupted: %s", e.Reason)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newErrBatchCorrupted(reason string) error {
|
|
||||||
return errors.NewErrCorrupted(storage.FileDesc{}, &ErrBatchCorrupted{reason})
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
batchHdrLen = 8 + 4
|
|
||||||
batchGrowRec = 3000
|
|
||||||
)
|
|
||||||
|
|
||||||
// BatchReplay wraps basic batch operations.
|
|
||||||
type BatchReplay interface {
|
|
||||||
Put(key, value []byte)
|
|
||||||
Delete(key []byte)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Batch is a write batch.
|
|
||||||
type Batch struct {
|
|
||||||
data []byte
|
|
||||||
rLen, bLen int
|
|
||||||
seq uint64
|
|
||||||
sync bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Batch) grow(n int) {
|
|
||||||
off := len(b.data)
|
|
||||||
if off == 0 {
|
|
||||||
off = batchHdrLen
|
|
||||||
if b.data != nil {
|
|
||||||
b.data = b.data[:off]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if cap(b.data)-off < n {
|
|
||||||
if b.data == nil {
|
|
||||||
b.data = make([]byte, off, off+n)
|
|
||||||
} else {
|
|
||||||
odata := b.data
|
|
||||||
div := 1
|
|
||||||
if b.rLen > batchGrowRec {
|
|
||||||
div = b.rLen / batchGrowRec
|
|
||||||
}
|
|
||||||
b.data = make([]byte, off, off+n+(off-batchHdrLen)/div)
|
|
||||||
copy(b.data, odata)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Batch) appendRec(kt keyType, key, value []byte) {
|
|
||||||
n := 1 + binary.MaxVarintLen32 + len(key)
|
|
||||||
if kt == keyTypeVal {
|
|
||||||
n += binary.MaxVarintLen32 + len(value)
|
|
||||||
}
|
|
||||||
b.grow(n)
|
|
||||||
off := len(b.data)
|
|
||||||
data := b.data[:off+n]
|
|
||||||
data[off] = byte(kt)
|
|
||||||
off++
|
|
||||||
off += binary.PutUvarint(data[off:], uint64(len(key)))
|
|
||||||
copy(data[off:], key)
|
|
||||||
off += len(key)
|
|
||||||
if kt == keyTypeVal {
|
|
||||||
off += binary.PutUvarint(data[off:], uint64(len(value)))
|
|
||||||
copy(data[off:], value)
|
|
||||||
off += len(value)
|
|
||||||
}
|
|
||||||
b.data = data[:off]
|
|
||||||
b.rLen++
|
|
||||||
// Include 8-byte ikey header
|
|
||||||
b.bLen += len(key) + len(value) + 8
|
|
||||||
}
|
|
||||||
|
|
||||||
// Put appends 'put operation' of the given key/value pair to the batch.
|
|
||||||
// It is safe to modify the contents of the argument after Put returns.
|
|
||||||
func (b *Batch) Put(key, value []byte) {
|
|
||||||
b.appendRec(keyTypeVal, key, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete appends 'delete operation' of the given key to the batch.
|
|
||||||
// It is safe to modify the contents of the argument after Delete returns.
|
|
||||||
func (b *Batch) Delete(key []byte) {
|
|
||||||
b.appendRec(keyTypeDel, key, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dump dumps batch contents. The returned slice can be loaded into the
|
|
||||||
// batch using Load method.
|
|
||||||
// The returned slice is not its own copy, so the contents should not be
|
|
||||||
// modified.
|
|
||||||
func (b *Batch) Dump() []byte {
|
|
||||||
return b.encode()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load loads given slice into the batch. Previous contents of the batch
|
|
||||||
// will be discarded.
|
|
||||||
// The given slice will not be copied and will be used as batch buffer, so
|
|
||||||
// it is not safe to modify the contents of the slice.
|
|
||||||
func (b *Batch) Load(data []byte) error {
|
|
||||||
return b.decode(0, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replay replays batch contents.
|
|
||||||
func (b *Batch) Replay(r BatchReplay) error {
|
|
||||||
return b.decodeRec(func(i int, kt keyType, key, value []byte) error {
|
|
||||||
switch kt {
|
|
||||||
case keyTypeVal:
|
|
||||||
r.Put(key, value)
|
|
||||||
case keyTypeDel:
|
|
||||||
r.Delete(key)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Len returns number of records in the batch.
|
|
||||||
func (b *Batch) Len() int {
|
|
||||||
return b.rLen
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset resets the batch.
|
|
||||||
func (b *Batch) Reset() {
|
|
||||||
b.data = b.data[:0]
|
|
||||||
b.seq = 0
|
|
||||||
b.rLen = 0
|
|
||||||
b.bLen = 0
|
|
||||||
b.sync = false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Batch) init(sync bool) {
|
|
||||||
b.sync = sync
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Batch) append(p *Batch) {
|
|
||||||
if p.rLen > 0 {
|
|
||||||
b.grow(len(p.data) - batchHdrLen)
|
|
||||||
b.data = append(b.data, p.data[batchHdrLen:]...)
|
|
||||||
b.rLen += p.rLen
|
|
||||||
}
|
|
||||||
if p.sync {
|
|
||||||
b.sync = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// size returns sums of key/value pair length plus 8-bytes ikey.
|
|
||||||
func (b *Batch) size() int {
|
|
||||||
return b.bLen
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Batch) encode() []byte {
|
|
||||||
b.grow(0)
|
|
||||||
binary.LittleEndian.PutUint64(b.data, b.seq)
|
|
||||||
binary.LittleEndian.PutUint32(b.data[8:], uint32(b.rLen))
|
|
||||||
|
|
||||||
return b.data
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Batch) decode(prevSeq uint64, data []byte) error {
|
|
||||||
if len(data) < batchHdrLen {
|
|
||||||
return newErrBatchCorrupted("too short")
|
|
||||||
}
|
|
||||||
|
|
||||||
b.seq = binary.LittleEndian.Uint64(data)
|
|
||||||
if b.seq < prevSeq {
|
|
||||||
return newErrBatchCorrupted("invalid sequence number")
|
|
||||||
}
|
|
||||||
b.rLen = int(binary.LittleEndian.Uint32(data[8:]))
|
|
||||||
if b.rLen < 0 {
|
|
||||||
return newErrBatchCorrupted("invalid records length")
|
|
||||||
}
|
|
||||||
// No need to be precise at this point, it won't be used anyway
|
|
||||||
b.bLen = len(data) - batchHdrLen
|
|
||||||
b.data = data
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Batch) decodeRec(f func(i int, kt keyType, key, value []byte) error) error {
|
|
||||||
off := batchHdrLen
|
|
||||||
for i := 0; i < b.rLen; i++ {
|
|
||||||
if off >= len(b.data) {
|
|
||||||
return newErrBatchCorrupted("invalid records length")
|
|
||||||
}
|
|
||||||
|
|
||||||
kt := keyType(b.data[off])
|
|
||||||
if kt > keyTypeVal {
|
|
||||||
panic(kt)
|
|
||||||
return newErrBatchCorrupted("bad record: invalid type")
|
|
||||||
}
|
|
||||||
off++
|
|
||||||
|
|
||||||
x, n := binary.Uvarint(b.data[off:])
|
|
||||||
off += n
|
|
||||||
if n <= 0 || off+int(x) > len(b.data) {
|
|
||||||
return newErrBatchCorrupted("bad record: invalid key length")
|
|
||||||
}
|
|
||||||
key := b.data[off : off+int(x)]
|
|
||||||
off += int(x)
|
|
||||||
var value []byte
|
|
||||||
if kt == keyTypeVal {
|
|
||||||
x, n := binary.Uvarint(b.data[off:])
|
|
||||||
off += n
|
|
||||||
if n <= 0 || off+int(x) > len(b.data) {
|
|
||||||
return newErrBatchCorrupted("bad record: invalid value length")
|
|
||||||
}
|
|
||||||
value = b.data[off : off+int(x)]
|
|
||||||
off += int(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := f(i, kt, key, value); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Batch) memReplay(to *memdb.DB) error {
|
|
||||||
var ikScratch []byte
|
|
||||||
return b.decodeRec(func(i int, kt keyType, key, value []byte) error {
|
|
||||||
ikScratch = makeInternalKey(ikScratch, key, b.seq+uint64(i), kt)
|
|
||||||
return to.Put(ikScratch, value)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Batch) memDecodeAndReplay(prevSeq uint64, data []byte, to *memdb.DB) error {
|
|
||||||
if err := b.decode(prevSeq, data); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return b.memReplay(to)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Batch) revertMemReplay(to *memdb.DB) error {
|
|
||||||
var ikScratch []byte
|
|
||||||
return b.decodeRec(func(i int, kt keyType, key, value []byte) error {
|
|
||||||
ikScratch := makeInternalKey(ikScratch, key, b.seq+uint64(i), kt)
|
|
||||||
return to.Delete(ikScratch)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
358
Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_write.go
generated
vendored
358
Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_write.go
generated
vendored
@@ -1,358 +0,0 @@
|
|||||||
// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
package leveldb
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/syndtr/goleveldb/leveldb/memdb"
|
|
||||||
"github.com/syndtr/goleveldb/leveldb/opt"
|
|
||||||
"github.com/syndtr/goleveldb/leveldb/util"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (db *DB) writeJournal(b *Batch) error {
|
|
||||||
w, err := db.journal.Next()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := w.Write(b.encode()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := db.journal.Flush(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if b.sync {
|
|
||||||
return db.journalWriter.Sync()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *DB) jWriter() {
|
|
||||||
defer db.closeW.Done()
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case b := <-db.journalC:
|
|
||||||
if b != nil {
|
|
||||||
db.journalAckC <- db.writeJournal(b)
|
|
||||||
}
|
|
||||||
case _, _ = <-db.closeC:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *DB) rotateMem(n int, wait bool) (mem *memDB, err error) {
|
|
||||||
// Wait for pending memdb compaction.
|
|
||||||
err = db.compTriggerWait(db.mcompCmdC)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create new memdb and journal.
|
|
||||||
mem, err = db.newMem(n)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Schedule memdb compaction.
|
|
||||||
if wait {
|
|
||||||
err = db.compTriggerWait(db.mcompCmdC)
|
|
||||||
} else {
|
|
||||||
db.compTrigger(db.mcompCmdC)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *DB) flush(n int) (mdb *memDB, mdbFree int, err error) {
|
|
||||||
delayed := false
|
|
||||||
flush := func() (retry bool) {
|
|
||||||
v := db.s.version()
|
|
||||||
defer v.release()
|
|
||||||
mdb = db.getEffectiveMem()
|
|
||||||
defer func() {
|
|
||||||
if retry {
|
|
||||||
mdb.decref()
|
|
||||||
mdb = nil
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
mdbFree = mdb.Free()
|
|
||||||
switch {
|
|
||||||
case v.tLen(0) >= db.s.o.GetWriteL0SlowdownTrigger() && !delayed:
|
|
||||||
delayed = true
|
|
||||||
time.Sleep(time.Millisecond)
|
|
||||||
case mdbFree >= n:
|
|
||||||
return false
|
|
||||||
case v.tLen(0) >= db.s.o.GetWriteL0PauseTrigger():
|
|
||||||
delayed = true
|
|
||||||
err = db.compTriggerWait(db.tcompCmdC)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
// Allow memdb to grow if it has no entry.
|
|
||||||
if mdb.Len() == 0 {
|
|
||||||
mdbFree = n
|
|
||||||
} else {
|
|
||||||
mdb.decref()
|
|
||||||
mdb, err = db.rotateMem(n, false)
|
|
||||||
if err == nil {
|
|
||||||
mdbFree = mdb.Free()
|
|
||||||
} else {
|
|
||||||
mdbFree = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
start := time.Now()
|
|
||||||
for flush() {
|
|
||||||
}
|
|
||||||
if delayed {
|
|
||||||
db.writeDelay += time.Since(start)
|
|
||||||
db.writeDelayN++
|
|
||||||
} else if db.writeDelayN > 0 {
|
|
||||||
db.logf("db@write was delayed N·%d T·%v", db.writeDelayN, db.writeDelay)
|
|
||||||
db.writeDelay = 0
|
|
||||||
db.writeDelayN = 0
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write apply the given batch to the DB. The batch will be applied
|
|
||||||
// sequentially.
|
|
||||||
//
|
|
||||||
// It is safe to modify the contents of the arguments after Write returns.
|
|
||||||
func (db *DB) Write(b *Batch, wo *opt.WriteOptions) (err error) {
|
|
||||||
err = db.ok()
|
|
||||||
if err != nil || b == nil || b.Len() == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
b.init(wo.GetSync() && !db.s.o.GetNoSync())
|
|
||||||
|
|
||||||
if b.size() > db.s.o.GetWriteBuffer() && !db.s.o.GetDisableLargeBatchTransaction() {
|
|
||||||
// Writes using transaction.
|
|
||||||
tr, err1 := db.OpenTransaction()
|
|
||||||
if err1 != nil {
|
|
||||||
return err1
|
|
||||||
}
|
|
||||||
if err1 := tr.Write(b, wo); err1 != nil {
|
|
||||||
tr.Discard()
|
|
||||||
return err1
|
|
||||||
}
|
|
||||||
return tr.Commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
// The write happen synchronously.
|
|
||||||
select {
|
|
||||||
case db.writeC <- b:
|
|
||||||
if <-db.writeMergedC {
|
|
||||||
return <-db.writeAckC
|
|
||||||
}
|
|
||||||
// Continue, the write lock already acquired by previous writer
|
|
||||||
// and handed out to us.
|
|
||||||
case db.writeLockC <- struct{}{}:
|
|
||||||
case err = <-db.compPerErrC:
|
|
||||||
return
|
|
||||||
case _, _ = <-db.closeC:
|
|
||||||
return ErrClosed
|
|
||||||
}
|
|
||||||
|
|
||||||
merged := 0
|
|
||||||
danglingMerge := false
|
|
||||||
defer func() {
|
|
||||||
for i := 0; i < merged; i++ {
|
|
||||||
db.writeAckC <- err
|
|
||||||
}
|
|
||||||
if danglingMerge {
|
|
||||||
// Only one dangling merge at most, so this is safe.
|
|
||||||
db.writeMergedC <- false
|
|
||||||
} else {
|
|
||||||
<-db.writeLockC
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
mdb, mdbFree, err := db.flush(b.size())
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer mdb.decref()
|
|
||||||
|
|
||||||
// Calculate maximum size of the batch.
|
|
||||||
m := 1 << 20
|
|
||||||
if x := b.size(); x <= 128<<10 {
|
|
||||||
m = x + (128 << 10)
|
|
||||||
}
|
|
||||||
m = minInt(m, mdbFree)
|
|
||||||
|
|
||||||
// Merge with other batch.
|
|
||||||
drain:
|
|
||||||
for b.size() < m && !b.sync {
|
|
||||||
select {
|
|
||||||
case nb := <-db.writeC:
|
|
||||||
if b.size()+nb.size() <= m {
|
|
||||||
b.append(nb)
|
|
||||||
db.writeMergedC <- true
|
|
||||||
merged++
|
|
||||||
} else {
|
|
||||||
danglingMerge = true
|
|
||||||
break drain
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break drain
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set batch first seq number relative from last seq.
|
|
||||||
b.seq = db.seq + 1
|
|
||||||
|
|
||||||
// Write journal concurrently if it is large enough.
|
|
||||||
if b.size() >= (128 << 10) {
|
|
||||||
// Push the write batch to the journal writer
|
|
||||||
select {
|
|
||||||
case db.journalC <- b:
|
|
||||||
// Write into memdb
|
|
||||||
if berr := b.memReplay(mdb.DB); berr != nil {
|
|
||||||
panic(berr)
|
|
||||||
}
|
|
||||||
case err = <-db.compPerErrC:
|
|
||||||
return
|
|
||||||
case _, _ = <-db.closeC:
|
|
||||||
err = ErrClosed
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Wait for journal writer
|
|
||||||
select {
|
|
||||||
case err = <-db.journalAckC:
|
|
||||||
if err != nil {
|
|
||||||
// Revert memdb if error detected
|
|
||||||
if berr := b.revertMemReplay(mdb.DB); berr != nil {
|
|
||||||
panic(berr)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case _, _ = <-db.closeC:
|
|
||||||
err = ErrClosed
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = db.writeJournal(b)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if berr := b.memReplay(mdb.DB); berr != nil {
|
|
||||||
panic(berr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set last seq number.
|
|
||||||
db.addSeq(uint64(b.Len()))
|
|
||||||
|
|
||||||
if b.size() >= mdbFree {
|
|
||||||
db.rotateMem(0, false)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Put sets the value for the given key. It overwrites any previous value
|
|
||||||
// for that key; a DB is not a multi-map.
|
|
||||||
//
|
|
||||||
// It is safe to modify the contents of the arguments after Put returns.
|
|
||||||
func (db *DB) Put(key, value []byte, wo *opt.WriteOptions) error {
|
|
||||||
b := new(Batch)
|
|
||||||
b.Put(key, value)
|
|
||||||
return db.Write(b, wo)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete deletes the value for the given key.
|
|
||||||
//
|
|
||||||
// It is safe to modify the contents of the arguments after Delete returns.
|
|
||||||
func (db *DB) Delete(key []byte, wo *opt.WriteOptions) error {
|
|
||||||
b := new(Batch)
|
|
||||||
b.Delete(key)
|
|
||||||
return db.Write(b, wo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func isMemOverlaps(icmp *iComparer, mem *memdb.DB, min, max []byte) bool {
|
|
||||||
iter := mem.NewIterator(nil)
|
|
||||||
defer iter.Release()
|
|
||||||
return (max == nil || (iter.First() && icmp.uCompare(max, internalKey(iter.Key()).ukey()) >= 0)) &&
|
|
||||||
(min == nil || (iter.Last() && icmp.uCompare(min, internalKey(iter.Key()).ukey()) <= 0))
|
|
||||||
}
|
|
||||||
|
|
||||||
// CompactRange compacts the underlying DB for the given key range.
|
|
||||||
// In particular, deleted and overwritten versions are discarded,
|
|
||||||
// and the data is rearranged to reduce the cost of operations
|
|
||||||
// needed to access the data. This operation should typically only
|
|
||||||
// be invoked by users who understand the underlying implementation.
|
|
||||||
//
|
|
||||||
// A nil Range.Start is treated as a key before all keys in the DB.
|
|
||||||
// And a nil Range.Limit is treated as a key after all keys in the DB.
|
|
||||||
// Therefore if both is nil then it will compact entire DB.
|
|
||||||
func (db *DB) CompactRange(r util.Range) error {
|
|
||||||
if err := db.ok(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lock writer.
|
|
||||||
select {
|
|
||||||
case db.writeLockC <- struct{}{}:
|
|
||||||
case err := <-db.compPerErrC:
|
|
||||||
return err
|
|
||||||
case _, _ = <-db.closeC:
|
|
||||||
return ErrClosed
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for overlaps in memdb.
|
|
||||||
mdb := db.getEffectiveMem()
|
|
||||||
defer mdb.decref()
|
|
||||||
if isMemOverlaps(db.s.icmp, mdb.DB, r.Start, r.Limit) {
|
|
||||||
// Memdb compaction.
|
|
||||||
if _, err := db.rotateMem(0, false); err != nil {
|
|
||||||
<-db.writeLockC
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
<-db.writeLockC
|
|
||||||
if err := db.compTriggerWait(db.mcompCmdC); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
<-db.writeLockC
|
|
||||||
}
|
|
||||||
|
|
||||||
// Table compaction.
|
|
||||||
return db.compTriggerRange(db.tcompCmdC, -1, r.Start, r.Limit)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetReadOnly makes DB read-only. It will stay read-only until reopened.
|
|
||||||
func (db *DB) SetReadOnly() error {
|
|
||||||
if err := db.ok(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lock writer.
|
|
||||||
select {
|
|
||||||
case db.writeLockC <- struct{}{}:
|
|
||||||
db.compWriteLocking = true
|
|
||||||
case err := <-db.compPerErrC:
|
|
||||||
return err
|
|
||||||
case _, _ = <-db.closeC:
|
|
||||||
return ErrClosed
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set compaction read-only.
|
|
||||||
select {
|
|
||||||
case db.compErrSetC <- ErrReadOnly:
|
|
||||||
case perr := <-db.compPerErrC:
|
|
||||||
return perr
|
|
||||||
case _, _ = <-db.closeC:
|
|
||||||
return ErrClosed
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
19
Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq.go
generated
vendored
19
Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq.go
generated
vendored
@@ -1,19 +0,0 @@
|
|||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build go1.5
|
|
||||||
|
|
||||||
package ctxhttp
|
|
||||||
|
|
||||||
import "net/http"
|
|
||||||
|
|
||||||
func canceler(client *http.Client, req *http.Request) func() {
|
|
||||||
// TODO(djd): Respect any existing value of req.Cancel.
|
|
||||||
ch := make(chan struct{})
|
|
||||||
req.Cancel = ch
|
|
||||||
|
|
||||||
return func() {
|
|
||||||
close(ch)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
23
Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq_go14.go
generated
vendored
23
Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq_go14.go
generated
vendored
@@ -1,23 +0,0 @@
|
|||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !go1.5
|
|
||||||
|
|
||||||
package ctxhttp
|
|
||||||
|
|
||||||
import "net/http"
|
|
||||||
|
|
||||||
type requestCanceler interface {
|
|
||||||
CancelRequest(*http.Request)
|
|
||||||
}
|
|
||||||
|
|
||||||
func canceler(client *http.Client, req *http.Request) func() {
|
|
||||||
rc, ok := client.Transport.(requestCanceler)
|
|
||||||
if !ok {
|
|
||||||
return func() {}
|
|
||||||
}
|
|
||||||
return func() {
|
|
||||||
rc.CancelRequest(req)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
140
Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/ctxhttp.go
generated
vendored
140
Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/ctxhttp.go
generated
vendored
@@ -1,140 +0,0 @@
|
|||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package ctxhttp provides helper functions for performing context-aware HTTP requests.
|
|
||||||
package ctxhttp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func nop() {}
|
|
||||||
|
|
||||||
var (
|
|
||||||
testHookContextDoneBeforeHeaders = nop
|
|
||||||
testHookDoReturned = nop
|
|
||||||
testHookDidBodyClose = nop
|
|
||||||
)
|
|
||||||
|
|
||||||
// Do sends an HTTP request with the provided http.Client and returns an HTTP response.
|
|
||||||
// If the client is nil, http.DefaultClient is used.
|
|
||||||
// If the context is canceled or times out, ctx.Err() will be returned.
|
|
||||||
func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) {
|
|
||||||
if client == nil {
|
|
||||||
client = http.DefaultClient
|
|
||||||
}
|
|
||||||
|
|
||||||
// Request cancelation changed in Go 1.5, see cancelreq.go and cancelreq_go14.go.
|
|
||||||
cancel := canceler(client, req)
|
|
||||||
|
|
||||||
type responseAndError struct {
|
|
||||||
resp *http.Response
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
result := make(chan responseAndError, 1)
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
resp, err := client.Do(req)
|
|
||||||
testHookDoReturned()
|
|
||||||
result <- responseAndError{resp, err}
|
|
||||||
}()
|
|
||||||
|
|
||||||
var resp *http.Response
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
testHookContextDoneBeforeHeaders()
|
|
||||||
cancel()
|
|
||||||
// Clean up after the goroutine calling client.Do:
|
|
||||||
go func() {
|
|
||||||
if r := <-result; r.resp != nil {
|
|
||||||
testHookDidBodyClose()
|
|
||||||
r.resp.Body.Close()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
return nil, ctx.Err()
|
|
||||||
case r := <-result:
|
|
||||||
var err error
|
|
||||||
resp, err = r.resp, r.err
|
|
||||||
if err != nil {
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
cancel()
|
|
||||||
case <-c:
|
|
||||||
// The response's Body is closed.
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
resp.Body = ¬ifyingReader{resp.Body, c}
|
|
||||||
|
|
||||||
return resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get issues a GET request via the Do function.
|
|
||||||
func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
|
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return Do(ctx, client, req)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Head issues a HEAD request via the Do function.
|
|
||||||
func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
|
|
||||||
req, err := http.NewRequest("HEAD", url, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return Do(ctx, client, req)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Post issues a POST request via the Do function.
|
|
||||||
func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) {
|
|
||||||
req, err := http.NewRequest("POST", url, body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req.Header.Set("Content-Type", bodyType)
|
|
||||||
return Do(ctx, client, req)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PostForm issues a POST request via the Do function.
|
|
||||||
func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) {
|
|
||||||
return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
|
|
||||||
}
|
|
||||||
|
|
||||||
// notifyingReader is an io.ReadCloser that closes the notify channel after
|
|
||||||
// Close is called or a Read fails on the underlying ReadCloser.
|
|
||||||
type notifyingReader struct {
|
|
||||||
io.ReadCloser
|
|
||||||
notify chan<- struct{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *notifyingReader) Read(p []byte) (int, error) {
|
|
||||||
n, err := r.ReadCloser.Read(p)
|
|
||||||
if err != nil && r.notify != nil {
|
|
||||||
close(r.notify)
|
|
||||||
r.notify = nil
|
|
||||||
}
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *notifyingReader) Close() error {
|
|
||||||
err := r.ReadCloser.Close()
|
|
||||||
if r.notify != nil {
|
|
||||||
close(r.notify)
|
|
||||||
r.notify = nil
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
63
Godeps/_workspace/src/golang.org/x/sys/unix/syscall_dragonfly_386.go
generated
vendored
63
Godeps/_workspace/src/golang.org/x/sys/unix/syscall_dragonfly_386.go
generated
vendored
@@ -1,63 +0,0 @@
|
|||||||
// Copyright 2009 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build 386,dragonfly
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Getpagesize() int { return 4096 }
|
|
||||||
|
|
||||||
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
|
||||||
|
|
||||||
func NsecToTimespec(nsec int64) (ts Timespec) {
|
|
||||||
ts.Sec = int32(nsec / 1e9)
|
|
||||||
ts.Nsec = int32(nsec % 1e9)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
|
|
||||||
|
|
||||||
func NsecToTimeval(nsec int64) (tv Timeval) {
|
|
||||||
nsec += 999 // round up to microsecond
|
|
||||||
tv.Usec = int32(nsec % 1e9 / 1e3)
|
|
||||||
tv.Sec = int32(nsec / 1e9)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
|
||||||
k.Ident = uint32(fd)
|
|
||||||
k.Filter = int16(mode)
|
|
||||||
k.Flags = uint16(flags)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (iov *Iovec) SetLen(length int) {
|
|
||||||
iov.Len = uint32(length)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (msghdr *Msghdr) SetControllen(length int) {
|
|
||||||
msghdr.Controllen = uint32(length)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cmsg *Cmsghdr) SetLen(length int) {
|
|
||||||
cmsg.Len = uint32(length)
|
|
||||||
}
|
|
||||||
|
|
||||||
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
|
|
||||||
var writtenOut uint64 = 0
|
|
||||||
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr((*offset)>>32), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0)
|
|
||||||
|
|
||||||
written = int(writtenOut)
|
|
||||||
|
|
||||||
if e1 != 0 {
|
|
||||||
err = e1
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
|
||||||
1530
Godeps/_workspace/src/golang.org/x/sys/unix/zerrors_dragonfly_386.go
generated
vendored
1530
Godeps/_workspace/src/golang.org/x/sys/unix/zerrors_dragonfly_386.go
generated
vendored
File diff suppressed because it is too large
Load Diff
304
Godeps/_workspace/src/golang.org/x/sys/unix/zsysnum_dragonfly_386.go
generated
vendored
304
Godeps/_workspace/src/golang.org/x/sys/unix/zsysnum_dragonfly_386.go
generated
vendored
@@ -1,304 +0,0 @@
|
|||||||
// mksysnum_dragonfly.pl
|
|
||||||
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
|
|
||||||
|
|
||||||
// +build 386,dragonfly
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
const (
|
|
||||||
// SYS_NOSYS = 0; // { int nosys(void); } syscall nosys_args int
|
|
||||||
SYS_EXIT = 1 // { void exit(int rval); }
|
|
||||||
SYS_FORK = 2 // { int fork(void); }
|
|
||||||
SYS_READ = 3 // { ssize_t read(int fd, void *buf, size_t nbyte); }
|
|
||||||
SYS_WRITE = 4 // { ssize_t write(int fd, const void *buf, size_t nbyte); }
|
|
||||||
SYS_OPEN = 5 // { int open(char *path, int flags, int mode); }
|
|
||||||
SYS_CLOSE = 6 // { int close(int fd); }
|
|
||||||
SYS_WAIT4 = 7 // { int wait4(int pid, int *status, int options, \
|
|
||||||
SYS_LINK = 9 // { int link(char *path, char *link); }
|
|
||||||
SYS_UNLINK = 10 // { int unlink(char *path); }
|
|
||||||
SYS_CHDIR = 12 // { int chdir(char *path); }
|
|
||||||
SYS_FCHDIR = 13 // { int fchdir(int fd); }
|
|
||||||
SYS_MKNOD = 14 // { int mknod(char *path, int mode, int dev); }
|
|
||||||
SYS_CHMOD = 15 // { int chmod(char *path, int mode); }
|
|
||||||
SYS_CHOWN = 16 // { int chown(char *path, int uid, int gid); }
|
|
||||||
SYS_OBREAK = 17 // { int obreak(char *nsize); } break obreak_args int
|
|
||||||
SYS_GETFSSTAT = 18 // { int getfsstat(struct statfs *buf, long bufsize, \
|
|
||||||
SYS_GETPID = 20 // { pid_t getpid(void); }
|
|
||||||
SYS_MOUNT = 21 // { int mount(char *type, char *path, int flags, \
|
|
||||||
SYS_UNMOUNT = 22 // { int unmount(char *path, int flags); }
|
|
||||||
SYS_SETUID = 23 // { int setuid(uid_t uid); }
|
|
||||||
SYS_GETUID = 24 // { uid_t getuid(void); }
|
|
||||||
SYS_GETEUID = 25 // { uid_t geteuid(void); }
|
|
||||||
SYS_PTRACE = 26 // { int ptrace(int req, pid_t pid, caddr_t addr, \
|
|
||||||
SYS_RECVMSG = 27 // { int recvmsg(int s, struct msghdr *msg, int flags); }
|
|
||||||
SYS_SENDMSG = 28 // { int sendmsg(int s, caddr_t msg, int flags); }
|
|
||||||
SYS_RECVFROM = 29 // { int recvfrom(int s, caddr_t buf, size_t len, \
|
|
||||||
SYS_ACCEPT = 30 // { int accept(int s, caddr_t name, int *anamelen); }
|
|
||||||
SYS_GETPEERNAME = 31 // { int getpeername(int fdes, caddr_t asa, int *alen); }
|
|
||||||
SYS_GETSOCKNAME = 32 // { int getsockname(int fdes, caddr_t asa, int *alen); }
|
|
||||||
SYS_ACCESS = 33 // { int access(char *path, int flags); }
|
|
||||||
SYS_CHFLAGS = 34 // { int chflags(char *path, int flags); }
|
|
||||||
SYS_FCHFLAGS = 35 // { int fchflags(int fd, int flags); }
|
|
||||||
SYS_SYNC = 36 // { int sync(void); }
|
|
||||||
SYS_KILL = 37 // { int kill(int pid, int signum); }
|
|
||||||
SYS_GETPPID = 39 // { pid_t getppid(void); }
|
|
||||||
SYS_DUP = 41 // { int dup(u_int fd); }
|
|
||||||
SYS_PIPE = 42 // { int pipe(void); }
|
|
||||||
SYS_GETEGID = 43 // { gid_t getegid(void); }
|
|
||||||
SYS_PROFIL = 44 // { int profil(caddr_t samples, size_t size, \
|
|
||||||
SYS_KTRACE = 45 // { int ktrace(const char *fname, int ops, int facs, \
|
|
||||||
SYS_GETGID = 47 // { gid_t getgid(void); }
|
|
||||||
SYS_GETLOGIN = 49 // { int getlogin(char *namebuf, u_int namelen); }
|
|
||||||
SYS_SETLOGIN = 50 // { int setlogin(char *namebuf); }
|
|
||||||
SYS_ACCT = 51 // { int acct(char *path); }
|
|
||||||
SYS_SIGALTSTACK = 53 // { int sigaltstack(stack_t *ss, stack_t *oss); }
|
|
||||||
SYS_IOCTL = 54 // { int ioctl(int fd, u_long com, caddr_t data); }
|
|
||||||
SYS_REBOOT = 55 // { int reboot(int opt); }
|
|
||||||
SYS_REVOKE = 56 // { int revoke(char *path); }
|
|
||||||
SYS_SYMLINK = 57 // { int symlink(char *path, char *link); }
|
|
||||||
SYS_READLINK = 58 // { int readlink(char *path, char *buf, int count); }
|
|
||||||
SYS_EXECVE = 59 // { int execve(char *fname, char **argv, char **envv); }
|
|
||||||
SYS_UMASK = 60 // { int umask(int newmask); } umask umask_args int
|
|
||||||
SYS_CHROOT = 61 // { int chroot(char *path); }
|
|
||||||
SYS_MSYNC = 65 // { int msync(void *addr, size_t len, int flags); }
|
|
||||||
SYS_VFORK = 66 // { pid_t vfork(void); }
|
|
||||||
SYS_SBRK = 69 // { int sbrk(int incr); }
|
|
||||||
SYS_SSTK = 70 // { int sstk(int incr); }
|
|
||||||
SYS_MUNMAP = 73 // { int munmap(void *addr, size_t len); }
|
|
||||||
SYS_MPROTECT = 74 // { int mprotect(void *addr, size_t len, int prot); }
|
|
||||||
SYS_MADVISE = 75 // { int madvise(void *addr, size_t len, int behav); }
|
|
||||||
SYS_MINCORE = 78 // { int mincore(const void *addr, size_t len, \
|
|
||||||
SYS_GETGROUPS = 79 // { int getgroups(u_int gidsetsize, gid_t *gidset); }
|
|
||||||
SYS_SETGROUPS = 80 // { int setgroups(u_int gidsetsize, gid_t *gidset); }
|
|
||||||
SYS_GETPGRP = 81 // { int getpgrp(void); }
|
|
||||||
SYS_SETPGID = 82 // { int setpgid(int pid, int pgid); }
|
|
||||||
SYS_SETITIMER = 83 // { int setitimer(u_int which, struct itimerval *itv, \
|
|
||||||
SYS_SWAPON = 85 // { int swapon(char *name); }
|
|
||||||
SYS_GETITIMER = 86 // { int getitimer(u_int which, struct itimerval *itv); }
|
|
||||||
SYS_GETDTABLESIZE = 89 // { int getdtablesize(void); }
|
|
||||||
SYS_DUP2 = 90 // { int dup2(u_int from, u_int to); }
|
|
||||||
SYS_FCNTL = 92 // { int fcntl(int fd, int cmd, long arg); }
|
|
||||||
SYS_SELECT = 93 // { int select(int nd, fd_set *in, fd_set *ou, \
|
|
||||||
SYS_FSYNC = 95 // { int fsync(int fd); }
|
|
||||||
SYS_SETPRIORITY = 96 // { int setpriority(int which, int who, int prio); }
|
|
||||||
SYS_SOCKET = 97 // { int socket(int domain, int type, int protocol); }
|
|
||||||
SYS_CONNECT = 98 // { int connect(int s, caddr_t name, int namelen); }
|
|
||||||
SYS_GETPRIORITY = 100 // { int getpriority(int which, int who); }
|
|
||||||
SYS_BIND = 104 // { int bind(int s, caddr_t name, int namelen); }
|
|
||||||
SYS_SETSOCKOPT = 105 // { int setsockopt(int s, int level, int name, \
|
|
||||||
SYS_LISTEN = 106 // { int listen(int s, int backlog); }
|
|
||||||
SYS_GETTIMEOFDAY = 116 // { int gettimeofday(struct timeval *tp, \
|
|
||||||
SYS_GETRUSAGE = 117 // { int getrusage(int who, struct rusage *rusage); }
|
|
||||||
SYS_GETSOCKOPT = 118 // { int getsockopt(int s, int level, int name, \
|
|
||||||
SYS_READV = 120 // { int readv(int fd, struct iovec *iovp, u_int iovcnt); }
|
|
||||||
SYS_WRITEV = 121 // { int writev(int fd, struct iovec *iovp, \
|
|
||||||
SYS_SETTIMEOFDAY = 122 // { int settimeofday(struct timeval *tv, \
|
|
||||||
SYS_FCHOWN = 123 // { int fchown(int fd, int uid, int gid); }
|
|
||||||
SYS_FCHMOD = 124 // { int fchmod(int fd, int mode); }
|
|
||||||
SYS_SETREUID = 126 // { int setreuid(int ruid, int euid); }
|
|
||||||
SYS_SETREGID = 127 // { int setregid(int rgid, int egid); }
|
|
||||||
SYS_RENAME = 128 // { int rename(char *from, char *to); }
|
|
||||||
SYS_FLOCK = 131 // { int flock(int fd, int how); }
|
|
||||||
SYS_MKFIFO = 132 // { int mkfifo(char *path, int mode); }
|
|
||||||
SYS_SENDTO = 133 // { int sendto(int s, caddr_t buf, size_t len, \
|
|
||||||
SYS_SHUTDOWN = 134 // { int shutdown(int s, int how); }
|
|
||||||
SYS_SOCKETPAIR = 135 // { int socketpair(int domain, int type, int protocol, \
|
|
||||||
SYS_MKDIR = 136 // { int mkdir(char *path, int mode); }
|
|
||||||
SYS_RMDIR = 137 // { int rmdir(char *path); }
|
|
||||||
SYS_UTIMES = 138 // { int utimes(char *path, struct timeval *tptr); }
|
|
||||||
SYS_ADJTIME = 140 // { int adjtime(struct timeval *delta, \
|
|
||||||
SYS_SETSID = 147 // { int setsid(void); }
|
|
||||||
SYS_QUOTACTL = 148 // { int quotactl(char *path, int cmd, int uid, \
|
|
||||||
SYS_STATFS = 157 // { int statfs(char *path, struct statfs *buf); }
|
|
||||||
SYS_FSTATFS = 158 // { int fstatfs(int fd, struct statfs *buf); }
|
|
||||||
SYS_GETFH = 161 // { int getfh(char *fname, struct fhandle *fhp); }
|
|
||||||
SYS_GETDOMAINNAME = 162 // { int getdomainname(char *domainname, int len); }
|
|
||||||
SYS_SETDOMAINNAME = 163 // { int setdomainname(char *domainname, int len); }
|
|
||||||
SYS_UNAME = 164 // { int uname(struct utsname *name); }
|
|
||||||
SYS_SYSARCH = 165 // { int sysarch(int op, char *parms); }
|
|
||||||
SYS_RTPRIO = 166 // { int rtprio(int function, pid_t pid, \
|
|
||||||
SYS_EXTPREAD = 173 // { ssize_t extpread(int fd, void *buf, \
|
|
||||||
SYS_EXTPWRITE = 174 // { ssize_t extpwrite(int fd, const void *buf, \
|
|
||||||
SYS_NTP_ADJTIME = 176 // { int ntp_adjtime(struct timex *tp); }
|
|
||||||
SYS_SETGID = 181 // { int setgid(gid_t gid); }
|
|
||||||
SYS_SETEGID = 182 // { int setegid(gid_t egid); }
|
|
||||||
SYS_SETEUID = 183 // { int seteuid(uid_t euid); }
|
|
||||||
SYS_PATHCONF = 191 // { int pathconf(char *path, int name); }
|
|
||||||
SYS_FPATHCONF = 192 // { int fpathconf(int fd, int name); }
|
|
||||||
SYS_GETRLIMIT = 194 // { int getrlimit(u_int which, \
|
|
||||||
SYS_SETRLIMIT = 195 // { int setrlimit(u_int which, \
|
|
||||||
SYS_MMAP = 197 // { caddr_t mmap(caddr_t addr, size_t len, int prot, \
|
|
||||||
// SYS_NOSYS = 198; // { int nosys(void); } __syscall __syscall_args int
|
|
||||||
SYS_LSEEK = 199 // { off_t lseek(int fd, int pad, off_t offset, \
|
|
||||||
SYS_TRUNCATE = 200 // { int truncate(char *path, int pad, off_t length); }
|
|
||||||
SYS_FTRUNCATE = 201 // { int ftruncate(int fd, int pad, off_t length); }
|
|
||||||
SYS___SYSCTL = 202 // { int __sysctl(int *name, u_int namelen, void *old, \
|
|
||||||
SYS_MLOCK = 203 // { int mlock(const void *addr, size_t len); }
|
|
||||||
SYS_MUNLOCK = 204 // { int munlock(const void *addr, size_t len); }
|
|
||||||
SYS_UNDELETE = 205 // { int undelete(char *path); }
|
|
||||||
SYS_FUTIMES = 206 // { int futimes(int fd, struct timeval *tptr); }
|
|
||||||
SYS_GETPGID = 207 // { int getpgid(pid_t pid); }
|
|
||||||
SYS_POLL = 209 // { int poll(struct pollfd *fds, u_int nfds, \
|
|
||||||
SYS___SEMCTL = 220 // { int __semctl(int semid, int semnum, int cmd, \
|
|
||||||
SYS_SEMGET = 221 // { int semget(key_t key, int nsems, int semflg); }
|
|
||||||
SYS_SEMOP = 222 // { int semop(int semid, struct sembuf *sops, \
|
|
||||||
SYS_MSGCTL = 224 // { int msgctl(int msqid, int cmd, \
|
|
||||||
SYS_MSGGET = 225 // { int msgget(key_t key, int msgflg); }
|
|
||||||
SYS_MSGSND = 226 // { int msgsnd(int msqid, void *msgp, size_t msgsz, \
|
|
||||||
SYS_MSGRCV = 227 // { int msgrcv(int msqid, void *msgp, size_t msgsz, \
|
|
||||||
SYS_SHMAT = 228 // { caddr_t shmat(int shmid, const void *shmaddr, \
|
|
||||||
SYS_SHMCTL = 229 // { int shmctl(int shmid, int cmd, \
|
|
||||||
SYS_SHMDT = 230 // { int shmdt(const void *shmaddr); }
|
|
||||||
SYS_SHMGET = 231 // { int shmget(key_t key, size_t size, int shmflg); }
|
|
||||||
SYS_CLOCK_GETTIME = 232 // { int clock_gettime(clockid_t clock_id, \
|
|
||||||
SYS_CLOCK_SETTIME = 233 // { int clock_settime(clockid_t clock_id, \
|
|
||||||
SYS_CLOCK_GETRES = 234 // { int clock_getres(clockid_t clock_id, \
|
|
||||||
SYS_NANOSLEEP = 240 // { int nanosleep(const struct timespec *rqtp, \
|
|
||||||
SYS_MINHERIT = 250 // { int minherit(void *addr, size_t len, int inherit); }
|
|
||||||
SYS_RFORK = 251 // { int rfork(int flags); }
|
|
||||||
SYS_OPENBSD_POLL = 252 // { int openbsd_poll(struct pollfd *fds, u_int nfds, \
|
|
||||||
SYS_ISSETUGID = 253 // { int issetugid(void); }
|
|
||||||
SYS_LCHOWN = 254 // { int lchown(char *path, int uid, int gid); }
|
|
||||||
SYS_LCHMOD = 274 // { int lchmod(char *path, mode_t mode); }
|
|
||||||
SYS_LUTIMES = 276 // { int lutimes(char *path, struct timeval *tptr); }
|
|
||||||
SYS_EXTPREADV = 289 // { ssize_t extpreadv(int fd, struct iovec *iovp, \
|
|
||||||
SYS_EXTPWRITEV = 290 // { ssize_t extpwritev(int fd, struct iovec *iovp,\
|
|
||||||
SYS_FHSTATFS = 297 // { int fhstatfs(const struct fhandle *u_fhp, struct statfs *buf); }
|
|
||||||
SYS_FHOPEN = 298 // { int fhopen(const struct fhandle *u_fhp, int flags); }
|
|
||||||
SYS_MODNEXT = 300 // { int modnext(int modid); }
|
|
||||||
SYS_MODSTAT = 301 // { int modstat(int modid, struct module_stat* stat); }
|
|
||||||
SYS_MODFNEXT = 302 // { int modfnext(int modid); }
|
|
||||||
SYS_MODFIND = 303 // { int modfind(const char *name); }
|
|
||||||
SYS_KLDLOAD = 304 // { int kldload(const char *file); }
|
|
||||||
SYS_KLDUNLOAD = 305 // { int kldunload(int fileid); }
|
|
||||||
SYS_KLDFIND = 306 // { int kldfind(const char *file); }
|
|
||||||
SYS_KLDNEXT = 307 // { int kldnext(int fileid); }
|
|
||||||
SYS_KLDSTAT = 308 // { int kldstat(int fileid, struct kld_file_stat* stat); }
|
|
||||||
SYS_KLDFIRSTMOD = 309 // { int kldfirstmod(int fileid); }
|
|
||||||
SYS_GETSID = 310 // { int getsid(pid_t pid); }
|
|
||||||
SYS_SETRESUID = 311 // { int setresuid(uid_t ruid, uid_t euid, uid_t suid); }
|
|
||||||
SYS_SETRESGID = 312 // { int setresgid(gid_t rgid, gid_t egid, gid_t sgid); }
|
|
||||||
SYS_AIO_RETURN = 314 // { int aio_return(struct aiocb *aiocbp); }
|
|
||||||
SYS_AIO_SUSPEND = 315 // { int aio_suspend(struct aiocb * const * aiocbp, int nent, const struct timespec *timeout); }
|
|
||||||
SYS_AIO_CANCEL = 316 // { int aio_cancel(int fd, struct aiocb *aiocbp); }
|
|
||||||
SYS_AIO_ERROR = 317 // { int aio_error(struct aiocb *aiocbp); }
|
|
||||||
SYS_AIO_READ = 318 // { int aio_read(struct aiocb *aiocbp); }
|
|
||||||
SYS_AIO_WRITE = 319 // { int aio_write(struct aiocb *aiocbp); }
|
|
||||||
SYS_LIO_LISTIO = 320 // { int lio_listio(int mode, struct aiocb * const *acb_list, int nent, struct sigevent *sig); }
|
|
||||||
SYS_YIELD = 321 // { int yield(void); }
|
|
||||||
SYS_MLOCKALL = 324 // { int mlockall(int how); }
|
|
||||||
SYS_MUNLOCKALL = 325 // { int munlockall(void); }
|
|
||||||
SYS___GETCWD = 326 // { int __getcwd(u_char *buf, u_int buflen); }
|
|
||||||
SYS_SCHED_SETPARAM = 327 // { int sched_setparam (pid_t pid, const struct sched_param *param); }
|
|
||||||
SYS_SCHED_GETPARAM = 328 // { int sched_getparam (pid_t pid, struct sched_param *param); }
|
|
||||||
SYS_SCHED_SETSCHEDULER = 329 // { int sched_setscheduler (pid_t pid, int policy, const struct sched_param *param); }
|
|
||||||
SYS_SCHED_GETSCHEDULER = 330 // { int sched_getscheduler (pid_t pid); }
|
|
||||||
SYS_SCHED_YIELD = 331 // { int sched_yield (void); }
|
|
||||||
SYS_SCHED_GET_PRIORITY_MAX = 332 // { int sched_get_priority_max (int policy); }
|
|
||||||
SYS_SCHED_GET_PRIORITY_MIN = 333 // { int sched_get_priority_min (int policy); }
|
|
||||||
SYS_SCHED_RR_GET_INTERVAL = 334 // { int sched_rr_get_interval (pid_t pid, struct timespec *interval); }
|
|
||||||
SYS_UTRACE = 335 // { int utrace(const void *addr, size_t len); }
|
|
||||||
SYS_KLDSYM = 337 // { int kldsym(int fileid, int cmd, void *data); }
|
|
||||||
SYS_JAIL = 338 // { int jail(struct jail *jail); }
|
|
||||||
SYS_SIGPROCMASK = 340 // { int sigprocmask(int how, const sigset_t *set, \
|
|
||||||
SYS_SIGSUSPEND = 341 // { int sigsuspend(const sigset_t *sigmask); }
|
|
||||||
SYS_SIGACTION = 342 // { int sigaction(int sig, const struct sigaction *act, \
|
|
||||||
SYS_SIGPENDING = 343 // { int sigpending(sigset_t *set); }
|
|
||||||
SYS_SIGRETURN = 344 // { int sigreturn(ucontext_t *sigcntxp); }
|
|
||||||
SYS_SIGTIMEDWAIT = 345 // { int sigtimedwait(const sigset_t *set,\
|
|
||||||
SYS_SIGWAITINFO = 346 // { int sigwaitinfo(const sigset_t *set,\
|
|
||||||
SYS___ACL_GET_FILE = 347 // { int __acl_get_file(const char *path, \
|
|
||||||
SYS___ACL_SET_FILE = 348 // { int __acl_set_file(const char *path, \
|
|
||||||
SYS___ACL_GET_FD = 349 // { int __acl_get_fd(int filedes, acl_type_t type, \
|
|
||||||
SYS___ACL_SET_FD = 350 // { int __acl_set_fd(int filedes, acl_type_t type, \
|
|
||||||
SYS___ACL_DELETE_FILE = 351 // { int __acl_delete_file(const char *path, \
|
|
||||||
SYS___ACL_DELETE_FD = 352 // { int __acl_delete_fd(int filedes, acl_type_t type); }
|
|
||||||
SYS___ACL_ACLCHECK_FILE = 353 // { int __acl_aclcheck_file(const char *path, \
|
|
||||||
SYS___ACL_ACLCHECK_FD = 354 // { int __acl_aclcheck_fd(int filedes, acl_type_t type, \
|
|
||||||
SYS_EXTATTRCTL = 355 // { int extattrctl(const char *path, int cmd, \
|
|
||||||
SYS_EXTATTR_SET_FILE = 356 // { int extattr_set_file(const char *path, \
|
|
||||||
SYS_EXTATTR_GET_FILE = 357 // { int extattr_get_file(const char *path, \
|
|
||||||
SYS_EXTATTR_DELETE_FILE = 358 // { int extattr_delete_file(const char *path, \
|
|
||||||
SYS_AIO_WAITCOMPLETE = 359 // { int aio_waitcomplete(struct aiocb **aiocbp, struct timespec *timeout); }
|
|
||||||
SYS_GETRESUID = 360 // { int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); }
|
|
||||||
SYS_GETRESGID = 361 // { int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); }
|
|
||||||
SYS_KQUEUE = 362 // { int kqueue(void); }
|
|
||||||
SYS_KEVENT = 363 // { int kevent(int fd, \
|
|
||||||
SYS_SCTP_PEELOFF = 364 // { int sctp_peeloff(int sd, caddr_t name ); }
|
|
||||||
SYS_LCHFLAGS = 391 // { int lchflags(char *path, int flags); }
|
|
||||||
SYS_UUIDGEN = 392 // { int uuidgen(struct uuid *store, int count); }
|
|
||||||
SYS_SENDFILE = 393 // { int sendfile(int fd, int s, off_t offset, size_t nbytes, \
|
|
||||||
SYS_VARSYM_SET = 450 // { int varsym_set(int level, const char *name, const char *data); }
|
|
||||||
SYS_VARSYM_GET = 451 // { int varsym_get(int mask, const char *wild, char *buf, int bufsize); }
|
|
||||||
SYS_VARSYM_LIST = 452 // { int varsym_list(int level, char *buf, int maxsize, int *marker); }
|
|
||||||
SYS_EXEC_SYS_REGISTER = 465 // { int exec_sys_register(void *entry); }
|
|
||||||
SYS_EXEC_SYS_UNREGISTER = 466 // { int exec_sys_unregister(int id); }
|
|
||||||
SYS_SYS_CHECKPOINT = 467 // { int sys_checkpoint(int type, int fd, pid_t pid, int retval); }
|
|
||||||
SYS_MOUNTCTL = 468 // { int mountctl(const char *path, int op, int fd, const void *ctl, int ctllen, void *buf, int buflen); }
|
|
||||||
SYS_UMTX_SLEEP = 469 // { int umtx_sleep(volatile const int *ptr, int value, int timeout); }
|
|
||||||
SYS_UMTX_WAKEUP = 470 // { int umtx_wakeup(volatile const int *ptr, int count); }
|
|
||||||
SYS_JAIL_ATTACH = 471 // { int jail_attach(int jid); }
|
|
||||||
SYS_SET_TLS_AREA = 472 // { int set_tls_area(int which, struct tls_info *info, size_t infosize); }
|
|
||||||
SYS_GET_TLS_AREA = 473 // { int get_tls_area(int which, struct tls_info *info, size_t infosize); }
|
|
||||||
SYS_CLOSEFROM = 474 // { int closefrom(int fd); }
|
|
||||||
SYS_STAT = 475 // { int stat(const char *path, struct stat *ub); }
|
|
||||||
SYS_FSTAT = 476 // { int fstat(int fd, struct stat *sb); }
|
|
||||||
SYS_LSTAT = 477 // { int lstat(const char *path, struct stat *ub); }
|
|
||||||
SYS_FHSTAT = 478 // { int fhstat(const struct fhandle *u_fhp, struct stat *sb); }
|
|
||||||
SYS_GETDIRENTRIES = 479 // { int getdirentries(int fd, char *buf, u_int count, \
|
|
||||||
SYS_GETDENTS = 480 // { int getdents(int fd, char *buf, size_t count); }
|
|
||||||
SYS_USCHED_SET = 481 // { int usched_set(pid_t pid, int cmd, void *data, \
|
|
||||||
SYS_EXTACCEPT = 482 // { int extaccept(int s, int flags, caddr_t name, int *anamelen); }
|
|
||||||
SYS_EXTCONNECT = 483 // { int extconnect(int s, int flags, caddr_t name, int namelen); }
|
|
||||||
SYS_MCONTROL = 485 // { int mcontrol(void *addr, size_t len, int behav, off_t value); }
|
|
||||||
SYS_VMSPACE_CREATE = 486 // { int vmspace_create(void *id, int type, void *data); }
|
|
||||||
SYS_VMSPACE_DESTROY = 487 // { int vmspace_destroy(void *id); }
|
|
||||||
SYS_VMSPACE_CTL = 488 // { int vmspace_ctl(void *id, int cmd, \
|
|
||||||
SYS_VMSPACE_MMAP = 489 // { int vmspace_mmap(void *id, void *addr, size_t len, \
|
|
||||||
SYS_VMSPACE_MUNMAP = 490 // { int vmspace_munmap(void *id, void *addr, \
|
|
||||||
SYS_VMSPACE_MCONTROL = 491 // { int vmspace_mcontrol(void *id, void *addr, \
|
|
||||||
SYS_VMSPACE_PREAD = 492 // { ssize_t vmspace_pread(void *id, void *buf, \
|
|
||||||
SYS_VMSPACE_PWRITE = 493 // { ssize_t vmspace_pwrite(void *id, const void *buf, \
|
|
||||||
SYS_EXTEXIT = 494 // { void extexit(int how, int status, void *addr); }
|
|
||||||
SYS_LWP_CREATE = 495 // { int lwp_create(struct lwp_params *params); }
|
|
||||||
SYS_LWP_GETTID = 496 // { lwpid_t lwp_gettid(void); }
|
|
||||||
SYS_LWP_KILL = 497 // { int lwp_kill(pid_t pid, lwpid_t tid, int signum); }
|
|
||||||
SYS_LWP_RTPRIO = 498 // { int lwp_rtprio(int function, pid_t pid, lwpid_t tid, struct rtprio *rtp); }
|
|
||||||
SYS_PSELECT = 499 // { int pselect(int nd, fd_set *in, fd_set *ou, \
|
|
||||||
SYS_STATVFS = 500 // { int statvfs(const char *path, struct statvfs *buf); }
|
|
||||||
SYS_FSTATVFS = 501 // { int fstatvfs(int fd, struct statvfs *buf); }
|
|
||||||
SYS_FHSTATVFS = 502 // { int fhstatvfs(const struct fhandle *u_fhp, struct statvfs *buf); }
|
|
||||||
SYS_GETVFSSTAT = 503 // { int getvfsstat(struct statfs *buf, \
|
|
||||||
SYS_OPENAT = 504 // { int openat(int fd, char *path, int flags, int mode); }
|
|
||||||
SYS_FSTATAT = 505 // { int fstatat(int fd, char *path, \
|
|
||||||
SYS_FCHMODAT = 506 // { int fchmodat(int fd, char *path, int mode, \
|
|
||||||
SYS_FCHOWNAT = 507 // { int fchownat(int fd, char *path, int uid, int gid, \
|
|
||||||
SYS_UNLINKAT = 508 // { int unlinkat(int fd, char *path, int flags); }
|
|
||||||
SYS_FACCESSAT = 509 // { int faccessat(int fd, char *path, int amode, \
|
|
||||||
SYS_MQ_OPEN = 510 // { mqd_t mq_open(const char * name, int oflag, \
|
|
||||||
SYS_MQ_CLOSE = 511 // { int mq_close(mqd_t mqdes); }
|
|
||||||
SYS_MQ_UNLINK = 512 // { int mq_unlink(const char *name); }
|
|
||||||
SYS_MQ_GETATTR = 513 // { int mq_getattr(mqd_t mqdes, \
|
|
||||||
SYS_MQ_SETATTR = 514 // { int mq_setattr(mqd_t mqdes, \
|
|
||||||
SYS_MQ_NOTIFY = 515 // { int mq_notify(mqd_t mqdes, \
|
|
||||||
SYS_MQ_SEND = 516 // { int mq_send(mqd_t mqdes, const char *msg_ptr, \
|
|
||||||
SYS_MQ_RECEIVE = 517 // { ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, \
|
|
||||||
SYS_MQ_TIMEDSEND = 518 // { int mq_timedsend(mqd_t mqdes, \
|
|
||||||
SYS_MQ_TIMEDRECEIVE = 519 // { ssize_t mq_timedreceive(mqd_t mqdes, \
|
|
||||||
SYS_IOPRIO_SET = 520 // { int ioprio_set(int which, int who, int prio); }
|
|
||||||
SYS_IOPRIO_GET = 521 // { int ioprio_get(int which, int who); }
|
|
||||||
SYS_CHROOT_KERNEL = 522 // { int chroot_kernel(char *path); }
|
|
||||||
SYS_RENAMEAT = 523 // { int renameat(int oldfd, char *old, int newfd, \
|
|
||||||
SYS_MKDIRAT = 524 // { int mkdirat(int fd, char *path, mode_t mode); }
|
|
||||||
SYS_MKFIFOAT = 525 // { int mkfifoat(int fd, char *path, mode_t mode); }
|
|
||||||
SYS_MKNODAT = 526 // { int mknodat(int fd, char *path, mode_t mode, \
|
|
||||||
SYS_READLINKAT = 527 // { int readlinkat(int fd, char *path, char *buf, \
|
|
||||||
SYS_SYMLINKAT = 528 // { int symlinkat(char *path1, int fd, char *path2); }
|
|
||||||
SYS_SWAPOFF = 529 // { int swapoff(char *name); }
|
|
||||||
SYS_VQUOTACTL = 530 // { int vquotactl(const char *path, \
|
|
||||||
SYS_LINKAT = 531 // { int linkat(int fd1, char *path1, int fd2, \
|
|
||||||
SYS_EACCESS = 532 // { int eaccess(char *path, int flags); }
|
|
||||||
SYS_LPATHCONF = 533 // { int lpathconf(char *path, int name); }
|
|
||||||
SYS_VMM_GUEST_CTL = 534 // { int vmm_guest_ctl(int op, struct vmm_guest_options *options); }
|
|
||||||
SYS_VMM_GUEST_SYNC_ADDR = 535 // { int vmm_guest_sync_addr(long *dstaddr, long *srcaddr); }
|
|
||||||
)
|
|
||||||
437
Godeps/_workspace/src/golang.org/x/sys/unix/ztypes_dragonfly_386.go
generated
vendored
437
Godeps/_workspace/src/golang.org/x/sys/unix/ztypes_dragonfly_386.go
generated
vendored
@@ -1,437 +0,0 @@
|
|||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs types_dragonfly.go
|
|
||||||
|
|
||||||
// +build 386,dragonfly
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
const (
|
|
||||||
sizeofPtr = 0x4
|
|
||||||
sizeofShort = 0x2
|
|
||||||
sizeofInt = 0x4
|
|
||||||
sizeofLong = 0x4
|
|
||||||
sizeofLongLong = 0x8
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
_C_short int16
|
|
||||||
_C_int int32
|
|
||||||
_C_long int32
|
|
||||||
_C_long_long int64
|
|
||||||
)
|
|
||||||
|
|
||||||
type Timespec struct {
|
|
||||||
Sec int32
|
|
||||||
Nsec int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type Timeval struct {
|
|
||||||
Sec int32
|
|
||||||
Usec int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type Rusage struct {
|
|
||||||
Utime Timeval
|
|
||||||
Stime Timeval
|
|
||||||
Maxrss int32
|
|
||||||
Ixrss int32
|
|
||||||
Idrss int32
|
|
||||||
Isrss int32
|
|
||||||
Minflt int32
|
|
||||||
Majflt int32
|
|
||||||
Nswap int32
|
|
||||||
Inblock int32
|
|
||||||
Oublock int32
|
|
||||||
Msgsnd int32
|
|
||||||
Msgrcv int32
|
|
||||||
Nsignals int32
|
|
||||||
Nvcsw int32
|
|
||||||
Nivcsw int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type Rlimit struct {
|
|
||||||
Cur int64
|
|
||||||
Max int64
|
|
||||||
}
|
|
||||||
|
|
||||||
type _Gid_t uint32
|
|
||||||
|
|
||||||
const (
|
|
||||||
S_IFMT = 0xf000
|
|
||||||
S_IFIFO = 0x1000
|
|
||||||
S_IFCHR = 0x2000
|
|
||||||
S_IFDIR = 0x4000
|
|
||||||
S_IFBLK = 0x6000
|
|
||||||
S_IFREG = 0x8000
|
|
||||||
S_IFLNK = 0xa000
|
|
||||||
S_IFSOCK = 0xc000
|
|
||||||
S_ISUID = 0x800
|
|
||||||
S_ISGID = 0x400
|
|
||||||
S_ISVTX = 0x200
|
|
||||||
S_IRUSR = 0x100
|
|
||||||
S_IWUSR = 0x80
|
|
||||||
S_IXUSR = 0x40
|
|
||||||
)
|
|
||||||
|
|
||||||
type Stat_t struct {
|
|
||||||
Ino uint64
|
|
||||||
Nlink uint32
|
|
||||||
Dev uint32
|
|
||||||
Mode uint16
|
|
||||||
Padding1 uint16
|
|
||||||
Uid uint32
|
|
||||||
Gid uint32
|
|
||||||
Rdev uint32
|
|
||||||
Atim Timespec
|
|
||||||
Mtim Timespec
|
|
||||||
Ctim Timespec
|
|
||||||
Size int64
|
|
||||||
Blocks int64
|
|
||||||
Blksize uint32
|
|
||||||
Flags uint32
|
|
||||||
Gen uint32
|
|
||||||
Lspare int32
|
|
||||||
Qspare1 int64
|
|
||||||
Qspare2 int64
|
|
||||||
}
|
|
||||||
|
|
||||||
type Statfs_t struct {
|
|
||||||
Spare2 int32
|
|
||||||
Bsize int32
|
|
||||||
Iosize int32
|
|
||||||
Blocks int32
|
|
||||||
Bfree int32
|
|
||||||
Bavail int32
|
|
||||||
Files int32
|
|
||||||
Ffree int32
|
|
||||||
Fsid Fsid
|
|
||||||
Owner uint32
|
|
||||||
Type int32
|
|
||||||
Flags int32
|
|
||||||
Syncwrites int32
|
|
||||||
Asyncwrites int32
|
|
||||||
Fstypename [16]int8
|
|
||||||
Mntonname [80]int8
|
|
||||||
Syncreads int32
|
|
||||||
Asyncreads int32
|
|
||||||
Spares1 int16
|
|
||||||
Mntfromname [80]int8
|
|
||||||
Spares2 int16
|
|
||||||
Spare [2]int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type Flock_t struct {
|
|
||||||
Start int64
|
|
||||||
Len int64
|
|
||||||
Pid int32
|
|
||||||
Type int16
|
|
||||||
Whence int16
|
|
||||||
}
|
|
||||||
|
|
||||||
type Dirent struct {
|
|
||||||
Fileno uint64
|
|
||||||
Namlen uint16
|
|
||||||
Type uint8
|
|
||||||
Unused1 uint8
|
|
||||||
Unused2 uint32
|
|
||||||
Name [256]int8
|
|
||||||
}
|
|
||||||
|
|
||||||
type Fsid struct {
|
|
||||||
Val [2]int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type RawSockaddrInet4 struct {
|
|
||||||
Len uint8
|
|
||||||
Family uint8
|
|
||||||
Port uint16
|
|
||||||
Addr [4]byte /* in_addr */
|
|
||||||
Zero [8]int8
|
|
||||||
}
|
|
||||||
|
|
||||||
type RawSockaddrInet6 struct {
|
|
||||||
Len uint8
|
|
||||||
Family uint8
|
|
||||||
Port uint16
|
|
||||||
Flowinfo uint32
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Scope_id uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type RawSockaddrUnix struct {
|
|
||||||
Len uint8
|
|
||||||
Family uint8
|
|
||||||
Path [104]int8
|
|
||||||
}
|
|
||||||
|
|
||||||
type RawSockaddrDatalink struct {
|
|
||||||
Len uint8
|
|
||||||
Family uint8
|
|
||||||
Index uint16
|
|
||||||
Type uint8
|
|
||||||
Nlen uint8
|
|
||||||
Alen uint8
|
|
||||||
Slen uint8
|
|
||||||
Data [12]int8
|
|
||||||
Rcf uint16
|
|
||||||
Route [16]uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
type RawSockaddr struct {
|
|
||||||
Len uint8
|
|
||||||
Family uint8
|
|
||||||
Data [14]int8
|
|
||||||
}
|
|
||||||
|
|
||||||
type RawSockaddrAny struct {
|
|
||||||
Addr RawSockaddr
|
|
||||||
Pad [92]int8
|
|
||||||
}
|
|
||||||
|
|
||||||
type _Socklen uint32
|
|
||||||
|
|
||||||
type Linger struct {
|
|
||||||
Onoff int32
|
|
||||||
Linger int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type Iovec struct {
|
|
||||||
Base *byte
|
|
||||||
Len uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type IPMreq struct {
|
|
||||||
Multiaddr [4]byte /* in_addr */
|
|
||||||
Interface [4]byte /* in_addr */
|
|
||||||
}
|
|
||||||
|
|
||||||
type IPv6Mreq struct {
|
|
||||||
Multiaddr [16]byte /* in6_addr */
|
|
||||||
Interface uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type Msghdr struct {
|
|
||||||
Name *byte
|
|
||||||
Namelen uint32
|
|
||||||
Iov *Iovec
|
|
||||||
Iovlen int32
|
|
||||||
Control *byte
|
|
||||||
Controllen uint32
|
|
||||||
Flags int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type Cmsghdr struct {
|
|
||||||
Len uint32
|
|
||||||
Level int32
|
|
||||||
Type int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type Inet6Pktinfo struct {
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Ifindex uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type IPv6MTUInfo struct {
|
|
||||||
Addr RawSockaddrInet6
|
|
||||||
Mtu uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type ICMPv6Filter struct {
|
|
||||||
Filt [8]uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
SizeofSockaddrInet4 = 0x10
|
|
||||||
SizeofSockaddrInet6 = 0x1c
|
|
||||||
SizeofSockaddrAny = 0x6c
|
|
||||||
SizeofSockaddrUnix = 0x6a
|
|
||||||
SizeofSockaddrDatalink = 0x36
|
|
||||||
SizeofLinger = 0x8
|
|
||||||
SizeofIPMreq = 0x8
|
|
||||||
SizeofIPv6Mreq = 0x14
|
|
||||||
SizeofMsghdr = 0x1c
|
|
||||||
SizeofCmsghdr = 0xc
|
|
||||||
SizeofInet6Pktinfo = 0x14
|
|
||||||
SizeofIPv6MTUInfo = 0x20
|
|
||||||
SizeofICMPv6Filter = 0x20
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
PTRACE_TRACEME = 0x0
|
|
||||||
PTRACE_CONT = 0x7
|
|
||||||
PTRACE_KILL = 0x8
|
|
||||||
)
|
|
||||||
|
|
||||||
type Kevent_t struct {
|
|
||||||
Ident uint32
|
|
||||||
Filter int16
|
|
||||||
Flags uint16
|
|
||||||
Fflags uint32
|
|
||||||
Data int32
|
|
||||||
Udata *byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type FdSet struct {
|
|
||||||
Bits [32]uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
SizeofIfMsghdr = 0x68
|
|
||||||
SizeofIfData = 0x58
|
|
||||||
SizeofIfaMsghdr = 0x14
|
|
||||||
SizeofIfmaMsghdr = 0x10
|
|
||||||
SizeofIfAnnounceMsghdr = 0x18
|
|
||||||
SizeofRtMsghdr = 0x5c
|
|
||||||
SizeofRtMetrics = 0x38
|
|
||||||
)
|
|
||||||
|
|
||||||
type IfMsghdr struct {
|
|
||||||
Msglen uint16
|
|
||||||
Version uint8
|
|
||||||
Type uint8
|
|
||||||
Addrs int32
|
|
||||||
Flags int32
|
|
||||||
Index uint16
|
|
||||||
Pad_cgo_0 [2]byte
|
|
||||||
Data IfData
|
|
||||||
}
|
|
||||||
|
|
||||||
type IfData struct {
|
|
||||||
Type uint8
|
|
||||||
Physical uint8
|
|
||||||
Addrlen uint8
|
|
||||||
Hdrlen uint8
|
|
||||||
Recvquota uint8
|
|
||||||
Xmitquota uint8
|
|
||||||
Pad_cgo_0 [2]byte
|
|
||||||
Mtu uint32
|
|
||||||
Metric uint32
|
|
||||||
Link_state uint32
|
|
||||||
Baudrate uint64
|
|
||||||
Ipackets uint32
|
|
||||||
Ierrors uint32
|
|
||||||
Opackets uint32
|
|
||||||
Oerrors uint32
|
|
||||||
Collisions uint32
|
|
||||||
Ibytes uint32
|
|
||||||
Obytes uint32
|
|
||||||
Imcasts uint32
|
|
||||||
Omcasts uint32
|
|
||||||
Iqdrops uint32
|
|
||||||
Noproto uint32
|
|
||||||
Hwassist uint32
|
|
||||||
Unused uint32
|
|
||||||
Lastchange Timeval
|
|
||||||
}
|
|
||||||
|
|
||||||
type IfaMsghdr struct {
|
|
||||||
Msglen uint16
|
|
||||||
Version uint8
|
|
||||||
Type uint8
|
|
||||||
Addrs int32
|
|
||||||
Flags int32
|
|
||||||
Index uint16
|
|
||||||
Pad_cgo_0 [2]byte
|
|
||||||
Metric int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type IfmaMsghdr struct {
|
|
||||||
Msglen uint16
|
|
||||||
Version uint8
|
|
||||||
Type uint8
|
|
||||||
Addrs int32
|
|
||||||
Flags int32
|
|
||||||
Index uint16
|
|
||||||
Pad_cgo_0 [2]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type IfAnnounceMsghdr struct {
|
|
||||||
Msglen uint16
|
|
||||||
Version uint8
|
|
||||||
Type uint8
|
|
||||||
Index uint16
|
|
||||||
Name [16]int8
|
|
||||||
What uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
type RtMsghdr struct {
|
|
||||||
Msglen uint16
|
|
||||||
Version uint8
|
|
||||||
Type uint8
|
|
||||||
Index uint16
|
|
||||||
Pad_cgo_0 [2]byte
|
|
||||||
Flags int32
|
|
||||||
Addrs int32
|
|
||||||
Pid int32
|
|
||||||
Seq int32
|
|
||||||
Errno int32
|
|
||||||
Use int32
|
|
||||||
Inits uint32
|
|
||||||
Rmx RtMetrics
|
|
||||||
}
|
|
||||||
|
|
||||||
type RtMetrics struct {
|
|
||||||
Locks uint32
|
|
||||||
Mtu uint32
|
|
||||||
Pksent uint32
|
|
||||||
Expire uint32
|
|
||||||
Sendpipe uint32
|
|
||||||
Ssthresh uint32
|
|
||||||
Rtt uint32
|
|
||||||
Rttvar uint32
|
|
||||||
Recvpipe uint32
|
|
||||||
Hopcount uint32
|
|
||||||
Mssopt uint16
|
|
||||||
Pad uint16
|
|
||||||
Msl uint32
|
|
||||||
Iwmaxsegs uint32
|
|
||||||
Iwcapsegs uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
SizeofBpfVersion = 0x4
|
|
||||||
SizeofBpfStat = 0x8
|
|
||||||
SizeofBpfProgram = 0x8
|
|
||||||
SizeofBpfInsn = 0x8
|
|
||||||
SizeofBpfHdr = 0x14
|
|
||||||
)
|
|
||||||
|
|
||||||
type BpfVersion struct {
|
|
||||||
Major uint16
|
|
||||||
Minor uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
type BpfStat struct {
|
|
||||||
Recv uint32
|
|
||||||
Drop uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type BpfProgram struct {
|
|
||||||
Len uint32
|
|
||||||
Insns *BpfInsn
|
|
||||||
}
|
|
||||||
|
|
||||||
type BpfInsn struct {
|
|
||||||
Code uint16
|
|
||||||
Jt uint8
|
|
||||||
Jf uint8
|
|
||||||
K uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type BpfHdr struct {
|
|
||||||
Tstamp Timeval
|
|
||||||
Caplen uint32
|
|
||||||
Datalen uint32
|
|
||||||
Hdrlen uint16
|
|
||||||
Pad_cgo_0 [2]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type Termios struct {
|
|
||||||
Iflag uint32
|
|
||||||
Oflag uint32
|
|
||||||
Cflag uint32
|
|
||||||
Lflag uint32
|
|
||||||
Cc [20]uint8
|
|
||||||
Ispeed uint32
|
|
||||||
Ospeed uint32
|
|
||||||
}
|
|
||||||
64
Godeps/_workspace/src/golang.org/x/text/encoding/ianaindex/ianaindex.go
generated
vendored
64
Godeps/_workspace/src/golang.org/x/text/encoding/ianaindex/ianaindex.go
generated
vendored
@@ -1,64 +0,0 @@
|
|||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package ianaindex maps names to Encodings as specified by the IANA registry.
|
|
||||||
// This includes both the MIME and IANA names.
|
|
||||||
//
|
|
||||||
// See http://www.iana.org/assignments/character-sets/character-sets.xhtml for
|
|
||||||
// more details.
|
|
||||||
package ianaindex
|
|
||||||
|
|
||||||
import (
|
|
||||||
"golang.org/x/text/encoding"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO: allow users to specify their own aliases?
|
|
||||||
// TODO: allow users to specify their own indexes?
|
|
||||||
// TODO: allow canonicalizing names
|
|
||||||
|
|
||||||
// NOTE: only use these top-level variables if we can get the linker to drop
|
|
||||||
// the indexes when they are not used. Make them a function or perhaps only
|
|
||||||
// support MIME otherwise.
|
|
||||||
|
|
||||||
var (
|
|
||||||
// MIME is an index to map MIME names. It does not support aliases.
|
|
||||||
MIME *Index
|
|
||||||
|
|
||||||
// IANA is an index that supports all names and aliases using IANA names as
|
|
||||||
// the canonical identifier.
|
|
||||||
IANA *Index
|
|
||||||
)
|
|
||||||
|
|
||||||
// Index maps names registered by IANA to Encodings.
|
|
||||||
type Index struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns an Encoding for IANA-registered names. Matching is
|
|
||||||
// case-insensitive.
|
|
||||||
func (x *Index) Get(name string) (encoding.Encoding, error) {
|
|
||||||
panic("TODO: implement")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name reports the canonical name of the given Encoding. It will return an
|
|
||||||
// error if the e is not associated with a known encoding scheme.
|
|
||||||
func (x *Index) Name(e encoding.Encoding) (string, error) {
|
|
||||||
panic("TODO: implement")
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: the coverage of this index is rather spotty. Allowing users to set
|
|
||||||
// encodings would allow:
|
|
||||||
// - users to increase coverage
|
|
||||||
// - allow a partially loaded set of encodings in case the user doesn't need to
|
|
||||||
// them all.
|
|
||||||
// - write an OS-specific wrapper for supported encodings and set them.
|
|
||||||
// The exact definition of Set depends a bit on if and how we want to let users
|
|
||||||
// write their own Encoding implementations. Also, it is not possible yet to
|
|
||||||
// only partially load the encodings without doing some refactoring. Until this
|
|
||||||
// is solved, we might as well not support Set.
|
|
||||||
// // Set sets the e to be used for the encoding scheme identified by name. Only
|
|
||||||
// // canonical names may be used. An empty name assigns e to its internally
|
|
||||||
// // associated encoding scheme.
|
|
||||||
// func (x *Index) Set(name string, e encoding.Encoding) error {
|
|
||||||
// panic("TODO: implement")
|
|
||||||
// }
|
|
||||||
92
Godeps/_workspace/src/golang.org/x/text/language/display/dict.go
generated
vendored
92
Godeps/_workspace/src/golang.org/x/text/language/display/dict.go
generated
vendored
@@ -1,92 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package display
|
|
||||||
|
|
||||||
// This file contains sets of data for specific languages. Users can use these
|
|
||||||
// to create smaller collections of supported languages and reduce total table
|
|
||||||
// size.
|
|
||||||
|
|
||||||
// The variable names defined here correspond to those in package language.
|
|
||||||
|
|
||||||
var (
|
|
||||||
Afrikaans *Dictionary = &af // af
|
|
||||||
Amharic *Dictionary = &am // am
|
|
||||||
Arabic *Dictionary = &ar // ar
|
|
||||||
ModernStandardArabic *Dictionary = Arabic // ar-001
|
|
||||||
Azerbaijani *Dictionary = &az // az
|
|
||||||
Bulgarian *Dictionary = &bg // bg
|
|
||||||
Bengali *Dictionary = &bn // bn
|
|
||||||
Catalan *Dictionary = &ca // ca
|
|
||||||
Czech *Dictionary = &cs // cs
|
|
||||||
Danish *Dictionary = &da // da
|
|
||||||
German *Dictionary = &de // de
|
|
||||||
Greek *Dictionary = &el // el
|
|
||||||
English *Dictionary = &en // en
|
|
||||||
AmericanEnglish *Dictionary = English // en-US
|
|
||||||
BritishEnglish *Dictionary = English // en-GB
|
|
||||||
Spanish *Dictionary = &es // es
|
|
||||||
EuropeanSpanish *Dictionary = Spanish // es-ES
|
|
||||||
LatinAmericanSpanish *Dictionary = Spanish // es-419
|
|
||||||
Estonian *Dictionary = &et // et
|
|
||||||
Persian *Dictionary = &fa // fa
|
|
||||||
Finnish *Dictionary = &fi // fi
|
|
||||||
Filipino *Dictionary = &fil // fil
|
|
||||||
French *Dictionary = &fr // fr
|
|
||||||
Gujarati *Dictionary = &gu // gu
|
|
||||||
Hebrew *Dictionary = &he // he
|
|
||||||
Hindi *Dictionary = &hi // hi
|
|
||||||
Croatian *Dictionary = &hr // hr
|
|
||||||
Hungarian *Dictionary = &hu // hu
|
|
||||||
Armenian *Dictionary = &hy // hy
|
|
||||||
Indonesian *Dictionary = &id // id
|
|
||||||
Icelandic *Dictionary = &is // is
|
|
||||||
Italian *Dictionary = &it // it
|
|
||||||
Japanese *Dictionary = &ja // ja
|
|
||||||
Georgian *Dictionary = &ka // ka
|
|
||||||
Kazakh *Dictionary = &kk // kk
|
|
||||||
Khmer *Dictionary = &km // km
|
|
||||||
Kannada *Dictionary = &kn // kn
|
|
||||||
Korean *Dictionary = &ko // ko
|
|
||||||
Kirghiz *Dictionary = &ky // ky
|
|
||||||
Lao *Dictionary = &lo // lo
|
|
||||||
Lithuanian *Dictionary = < // lt
|
|
||||||
Latvian *Dictionary = &lv // lv
|
|
||||||
Macedonian *Dictionary = &mk // mk
|
|
||||||
Malayalam *Dictionary = &ml // ml
|
|
||||||
Mongolian *Dictionary = &mn // mn
|
|
||||||
Marathi *Dictionary = &mr // mr
|
|
||||||
Malay *Dictionary = &ms // ms
|
|
||||||
Burmese *Dictionary = &my // my
|
|
||||||
Nepali *Dictionary = &ne // ne
|
|
||||||
Dutch *Dictionary = &nl // nl
|
|
||||||
Norwegian *Dictionary = &no // no
|
|
||||||
Punjabi *Dictionary = &pa // pa
|
|
||||||
Polish *Dictionary = &pl // pl
|
|
||||||
Portuguese *Dictionary = &pt // pt
|
|
||||||
BrazilianPortuguese *Dictionary = Portuguese // pt-BR
|
|
||||||
EuropeanPortuguese *Dictionary = &ptPT // pt-PT
|
|
||||||
Romanian *Dictionary = &ro // ro
|
|
||||||
Russian *Dictionary = &ru // ru
|
|
||||||
Sinhala *Dictionary = &si // si
|
|
||||||
Slovak *Dictionary = &sk // sk
|
|
||||||
Slovenian *Dictionary = &sl // sl
|
|
||||||
Albanian *Dictionary = &sq // sq
|
|
||||||
Serbian *Dictionary = &sr // sr
|
|
||||||
SerbianLatin *Dictionary = &srLatn // sr
|
|
||||||
Swedish *Dictionary = &sv // sv
|
|
||||||
Swahili *Dictionary = &sw // sw
|
|
||||||
Tamil *Dictionary = &ta // ta
|
|
||||||
Telugu *Dictionary = &te // te
|
|
||||||
Thai *Dictionary = &th // th
|
|
||||||
Turkish *Dictionary = &tr // tr
|
|
||||||
Ukrainian *Dictionary = &uk // uk
|
|
||||||
Urdu *Dictionary = &ur // ur
|
|
||||||
Uzbek *Dictionary = &uz // uz
|
|
||||||
Vietnamese *Dictionary = &vi // vi
|
|
||||||
Chinese *Dictionary = &zh // zh
|
|
||||||
SimplifiedChinese *Dictionary = Chinese // zh-Hans
|
|
||||||
TraditionalChinese *Dictionary = &zhHant // zh-Hant
|
|
||||||
Zulu *Dictionary = &zu // zu
|
|
||||||
)
|
|
||||||
343
Godeps/_workspace/src/golang.org/x/text/language/display/display.go
generated
vendored
343
Godeps/_workspace/src/golang.org/x/text/language/display/display.go
generated
vendored
@@ -1,343 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
//go:generate go run maketables.go -output tables.go
|
|
||||||
|
|
||||||
// Package display provides display names for languages, scripts and regions in
|
|
||||||
// a requested language.
|
|
||||||
//
|
|
||||||
// The data is based on CLDR's localeDisplayNames. It includes the names of the
|
|
||||||
// draft level "contributed" or "approved". The resulting tables are quite
|
|
||||||
// large. The display package is designed so that users can reduce the linked-in
|
|
||||||
// table sizes by cherry picking the languages one wishes to support. There is a
|
|
||||||
// Dictionary defined for a selected set of common languages for this purpose.
|
|
||||||
package display
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"golang.org/x/text/language"
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
TODO:
|
|
||||||
All fairly low priority at the moment:
|
|
||||||
- Include alternative and variants as an option (using func options).
|
|
||||||
- Option for returning the empty string for undefined values.
|
|
||||||
- Support variants, currencies, time zones, option names and other data
|
|
||||||
provided in CLDR.
|
|
||||||
- Do various optimizations:
|
|
||||||
- Reduce size of offset tables.
|
|
||||||
- Consider compressing infrequently used languages and decompress on demand.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// A Namer is used to get the name for a given value, such as a Tag, Language,
|
|
||||||
// Script or Region.
|
|
||||||
type Namer interface {
|
|
||||||
// Name returns a display string for the given value. A Namer returns an
|
|
||||||
// empty string for values it does not support. A Namer may support naming
|
|
||||||
// an unspecified value. For example, when getting the name for a region for
|
|
||||||
// a tag that does not have a defined Region, it may return the name for an
|
|
||||||
// unknown region. It is up to the user to filter calls to Name for values
|
|
||||||
// for which one does not want to have a name string.
|
|
||||||
Name(x interface{}) string
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
// Supported lists the languages for which names are defined.
|
|
||||||
Supported language.Coverage
|
|
||||||
|
|
||||||
// The set of all possible values for which names are defined. Note that not
|
|
||||||
// all Namer implementations will cover all the values of a given type.
|
|
||||||
// A Namer will return the empty string for unsupported values.
|
|
||||||
Values language.Coverage
|
|
||||||
|
|
||||||
matcher language.Matcher
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
tags := make([]language.Tag, numSupported)
|
|
||||||
s := supported
|
|
||||||
for i := range tags {
|
|
||||||
p := strings.IndexByte(s, '|')
|
|
||||||
tags[i] = language.Raw.Make(s[:p])
|
|
||||||
s = s[p+1:]
|
|
||||||
}
|
|
||||||
matcher = language.NewMatcher(tags)
|
|
||||||
Supported = language.NewCoverage(tags)
|
|
||||||
|
|
||||||
Values = language.NewCoverage(langTagSet.Tags, supportedScripts, supportedRegions)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Languages returns a Namer for naming languages. It returns nil if there is no
|
|
||||||
// data for the given tag. The type passed to Name must be either language.Base
|
|
||||||
// or language.Tag. Note that the result may differ between passing a tag or its
|
|
||||||
// base language. For example, for English, passing "nl-BE" would return Flemish
|
|
||||||
// whereas passing "nl" returns "Dutch".
|
|
||||||
func Languages(t language.Tag) Namer {
|
|
||||||
if _, index, conf := matcher.Match(t); conf != language.No {
|
|
||||||
return languageNamer(index)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type languageNamer int
|
|
||||||
|
|
||||||
func (n languageNamer) name(i int) string {
|
|
||||||
return lookup(langHeaders[:], int(n), i)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name implements the Namer interface for language names.
|
|
||||||
func (n languageNamer) Name(x interface{}) string {
|
|
||||||
return nameLanguage(n, x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// nonEmptyIndex walks up the parent chain until a non-empty header is found.
|
|
||||||
// It returns -1 if no index could be found.
|
|
||||||
func nonEmptyIndex(h []header, index int) int {
|
|
||||||
for ; index != -1 && h[index].data == ""; index = int(parents[index]) {
|
|
||||||
}
|
|
||||||
return index
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scripts returns a Namer for naming scripts. It returns nil if there is no
|
|
||||||
// data for the given tag. The type passed to Name must be either a
|
|
||||||
// language.Script or a language.Tag. It will not attempt to infer a script for
|
|
||||||
// tags with an unspecified script.
|
|
||||||
func Scripts(t language.Tag) Namer {
|
|
||||||
if _, index, conf := matcher.Match(t); conf != language.No {
|
|
||||||
if index = nonEmptyIndex(scriptHeaders[:], index); index != -1 {
|
|
||||||
return scriptNamer(index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type scriptNamer int
|
|
||||||
|
|
||||||
func (n scriptNamer) name(i int) string {
|
|
||||||
return lookup(scriptHeaders[:], int(n), i)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name implements the Namer interface for script names.
|
|
||||||
func (n scriptNamer) Name(x interface{}) string {
|
|
||||||
return nameScript(n, x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Regions returns a Namer for naming regions. It returns nil if there is no
|
|
||||||
// data for the given tag. The type passed to Name must be either a
|
|
||||||
// language.Region or a language.Tag. It will not attempt to infer a region for
|
|
||||||
// tags with an unspecified region.
|
|
||||||
func Regions(t language.Tag) Namer {
|
|
||||||
if _, index, conf := matcher.Match(t); conf != language.No {
|
|
||||||
if index = nonEmptyIndex(regionHeaders[:], index); index != -1 {
|
|
||||||
return regionNamer(index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type regionNamer int
|
|
||||||
|
|
||||||
func (n regionNamer) name(i int) string {
|
|
||||||
return lookup(regionHeaders[:], int(n), i)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name implements the Namer interface for region names.
|
|
||||||
func (n regionNamer) Name(x interface{}) string {
|
|
||||||
return nameRegion(n, x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tags returns a Namer for giving a full description of a tag. The names of
|
|
||||||
// scripts and regions that are not already implied by the language name will
|
|
||||||
// in appended within parentheses. It returns nil if there is not data for the
|
|
||||||
// given tag. The type passed to Name must be a tag.
|
|
||||||
func Tags(t language.Tag) Namer {
|
|
||||||
if _, index, conf := matcher.Match(t); conf != language.No {
|
|
||||||
return tagNamer(index)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type tagNamer int
|
|
||||||
|
|
||||||
// Name implements the Namer interface for tag names.
|
|
||||||
func (n tagNamer) Name(x interface{}) string {
|
|
||||||
return nameTag(languageNamer(n), scriptNamer(n), regionNamer(n), x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// lookup finds the name for an entry in a global table, traversing the
|
|
||||||
// inheritance hierarchy if needed.
|
|
||||||
func lookup(table []header, dict, want int) string {
|
|
||||||
for dict != -1 {
|
|
||||||
if s := table[dict].name(want); s != "" {
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
dict = int(parents[dict])
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Dictionary holds a collection of Namers for a single language. One can
|
|
||||||
// reduce the amount of data linked in to a binary by only referencing
|
|
||||||
// Dictionaries for the languages one needs to support instead of using the
|
|
||||||
// generic Namer factories.
|
|
||||||
type Dictionary struct {
|
|
||||||
parent *Dictionary
|
|
||||||
lang header
|
|
||||||
script header
|
|
||||||
region header
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tags returns a Namer for giving a full description of a tag. The names of
|
|
||||||
// scripts and regions that are not already implied by the language name will
|
|
||||||
// in appended within parentheses. It returns nil if there is not data for the
|
|
||||||
// given tag. The type passed to Name must be a tag.
|
|
||||||
func (d *Dictionary) Tags() Namer {
|
|
||||||
return dictTags{d}
|
|
||||||
}
|
|
||||||
|
|
||||||
type dictTags struct {
|
|
||||||
d *Dictionary
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name implements the Namer interface for tag names.
|
|
||||||
func (n dictTags) Name(x interface{}) string {
|
|
||||||
return nameTag(dictLanguages{n.d}, dictScripts{n.d}, dictRegions{n.d}, x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Languages returns a Namer for naming languages. It returns nil if there is no
|
|
||||||
// data for the given tag. The type passed to Name must be either language.Base
|
|
||||||
// or language.Tag. Note that the result may differ between passing a tag or its
|
|
||||||
// base language. For example, for English, passing "nl-BE" would return Flemish
|
|
||||||
// whereas passing "nl" returns "Dutch".
|
|
||||||
func (d *Dictionary) Languages() Namer {
|
|
||||||
return dictLanguages{d}
|
|
||||||
}
|
|
||||||
|
|
||||||
type dictLanguages struct {
|
|
||||||
d *Dictionary
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n dictLanguages) name(i int) string {
|
|
||||||
for d := n.d; d != nil; d = d.parent {
|
|
||||||
if s := d.lang.name(i); s != "" {
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name implements the Namer interface for language names.
|
|
||||||
func (n dictLanguages) Name(x interface{}) string {
|
|
||||||
return nameLanguage(n, x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scripts returns a Namer for naming scripts. It returns nil if there is no
|
|
||||||
// data for the given tag. The type passed to Name must be either a
|
|
||||||
// language.Script or a language.Tag. It will not attempt to infer a script for
|
|
||||||
// tags with an unspecified script.
|
|
||||||
func (d *Dictionary) Scripts() Namer {
|
|
||||||
return dictScripts{d}
|
|
||||||
}
|
|
||||||
|
|
||||||
type dictScripts struct {
|
|
||||||
d *Dictionary
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n dictScripts) name(i int) string {
|
|
||||||
for d := n.d; d != nil; d = d.parent {
|
|
||||||
if s := d.script.name(i); s != "" {
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name implements the Namer interface for script names.
|
|
||||||
func (n dictScripts) Name(x interface{}) string {
|
|
||||||
return nameScript(n, x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Regions returns a Namer for naming regions. It returns nil if there is no
|
|
||||||
// data for the given tag. The type passed to Name must be either a
|
|
||||||
// language.Region or a language.Tag. It will not attempt to infer a region for
|
|
||||||
// tags with an unspecified region.
|
|
||||||
func (d *Dictionary) Regions() Namer {
|
|
||||||
return dictRegions{d}
|
|
||||||
}
|
|
||||||
|
|
||||||
type dictRegions struct {
|
|
||||||
d *Dictionary
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n dictRegions) name(i int) string {
|
|
||||||
for d := n.d; d != nil; d = d.parent {
|
|
||||||
if s := d.region.name(i); s != "" {
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name implements the Namer interface for region names.
|
|
||||||
func (n dictRegions) Name(x interface{}) string {
|
|
||||||
return nameRegion(n, x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// A SelfNamer implements a Namer that returns the name of language in this same
|
|
||||||
// language. It provides a very compact mechanism to provide a comprehensive
|
|
||||||
// list of languages to users in their native language.
|
|
||||||
type SelfNamer struct {
|
|
||||||
// Supported defines the values supported by this Namer.
|
|
||||||
Supported language.Coverage
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
// Self is a shared instance of a SelfNamer.
|
|
||||||
Self *SelfNamer = &self
|
|
||||||
|
|
||||||
self = SelfNamer{language.NewCoverage(selfTagSet.Tags)}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Name returns the name of a given language tag in the language identified by
|
|
||||||
// this tag. It supports both the language.Base and language.Tag types.
|
|
||||||
func (n SelfNamer) Name(x interface{}) string {
|
|
||||||
t, _ := language.All.Compose(x)
|
|
||||||
base, scr, reg := t.Raw()
|
|
||||||
baseScript := language.Script{}
|
|
||||||
if (scr == language.Script{} && reg != language.Region{}) {
|
|
||||||
// For looking up in the self dictionary, we need to select the
|
|
||||||
// maximized script. This is even the case if the script isn't
|
|
||||||
// specified.
|
|
||||||
s1, _ := t.Script()
|
|
||||||
if baseScript = getScript(base); baseScript != s1 {
|
|
||||||
scr = s1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
i, scr, reg := selfTagSet.index(base, scr, reg)
|
|
||||||
if i == -1 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only return the display name if the script matches the expected script.
|
|
||||||
if (scr != language.Script{}) {
|
|
||||||
if (baseScript == language.Script{}) {
|
|
||||||
baseScript = getScript(base)
|
|
||||||
}
|
|
||||||
if baseScript != scr {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return selfHeaders[0].name(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
// getScript returns the maximized script for a base language.
|
|
||||||
func getScript(b language.Base) language.Script {
|
|
||||||
tag, _ := language.Raw.Compose(b)
|
|
||||||
scr, _ := tag.Script()
|
|
||||||
return scr
|
|
||||||
}
|
|
||||||
238
Godeps/_workspace/src/golang.org/x/text/language/display/lookup.go
generated
vendored
238
Godeps/_workspace/src/golang.org/x/text/language/display/lookup.go
generated
vendored
@@ -1,238 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package display
|
|
||||||
|
|
||||||
// This file contains common lookup code that is shared between the various
|
|
||||||
// implementations of Namer and Dictionaries.
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"golang.org/x/text/language"
|
|
||||||
)
|
|
||||||
|
|
||||||
type namer interface {
|
|
||||||
// name gets the string for the given index. It should walk the
|
|
||||||
// inheritance chain if a value is not present in the base index.
|
|
||||||
name(idx int) string
|
|
||||||
}
|
|
||||||
|
|
||||||
func nameLanguage(n namer, x interface{}) string {
|
|
||||||
t, _ := language.All.Compose(x)
|
|
||||||
i, _, _ := langTagSet.index(t.Raw())
|
|
||||||
return n.name(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
func nameScript(n namer, x interface{}) string {
|
|
||||||
t, _ := language.DeprecatedScript.Compose(x)
|
|
||||||
_, s, _ := t.Raw()
|
|
||||||
return n.name(scriptIndex.index(s.String()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func nameRegion(n namer, x interface{}) string {
|
|
||||||
t, _ := language.DeprecatedRegion.Compose(x)
|
|
||||||
_, _, r := t.Raw()
|
|
||||||
return n.name(regionIndex.index(r.String()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func nameTag(langN, scrN, regN namer, x interface{}) string {
|
|
||||||
t, ok := x.(language.Tag)
|
|
||||||
if !ok {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
const form = language.All &^ language.SuppressScript
|
|
||||||
if c, err := form.Canonicalize(t); err == nil {
|
|
||||||
t = c
|
|
||||||
}
|
|
||||||
i, scr, reg := langTagSet.index(t.Raw())
|
|
||||||
if i == -1 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
str := langN.name(i)
|
|
||||||
if hasS, hasR := (scr != language.Script{}), (reg != language.Region{}); hasS || hasR {
|
|
||||||
ss, sr := "", ""
|
|
||||||
if hasS {
|
|
||||||
ss = scrN.name(scriptIndex.index(scr.String()))
|
|
||||||
}
|
|
||||||
if hasR {
|
|
||||||
sr = regN.name(regionIndex.index(reg.String()))
|
|
||||||
}
|
|
||||||
// TODO: use patterns in CLDR or at least confirm they are the same for
|
|
||||||
// all languages.
|
|
||||||
if ss != "" && sr != "" {
|
|
||||||
return fmt.Sprintf("%s (%s, %s)", str, ss, sr)
|
|
||||||
}
|
|
||||||
if ss != "" || sr != "" {
|
|
||||||
return fmt.Sprintf("%s (%s%s)", str, ss, sr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
// header contains the data and indexes for a single namer.
|
|
||||||
// data contains a series of strings concatenated into one. index contains the
|
|
||||||
// offsets for a string in data. For example, consider a header that defines
|
|
||||||
// strings for the languages de, el, en, fi, and nl:
|
|
||||||
//
|
|
||||||
// header{
|
|
||||||
// data: "GermanGreekEnglishDutch",
|
|
||||||
// index: []uint16{ 0, 6, 11, 18, 18, 23 },
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// For a language with index i, the string is defined by
|
|
||||||
// data[index[i]:index[i+1]]. So the number of elements in index is always one
|
|
||||||
// greater than the number of languages for which header defines a value.
|
|
||||||
// A string for a language may be empty, which means the name is undefined. In
|
|
||||||
// the above example, the name for fi (Finnish) is undefined.
|
|
||||||
type header struct {
|
|
||||||
data string
|
|
||||||
index []uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
// name looks up the name for a tag in the dictionary, given its index.
|
|
||||||
func (h *header) name(i int) string {
|
|
||||||
if 0 <= i && i < len(h.index)-1 {
|
|
||||||
return h.data[h.index[i]:h.index[i+1]]
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// tagSet is used to find the index of a language in a set of tags.
|
|
||||||
type tagSet struct {
|
|
||||||
single tagIndex
|
|
||||||
long []string
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
langTagSet = tagSet{
|
|
||||||
single: langIndex,
|
|
||||||
long: langTagsLong,
|
|
||||||
}
|
|
||||||
|
|
||||||
// selfTagSet is used for indexing the language strings in their own
|
|
||||||
// language.
|
|
||||||
selfTagSet = tagSet{
|
|
||||||
single: selfIndex,
|
|
||||||
long: selfTagsLong,
|
|
||||||
}
|
|
||||||
|
|
||||||
zzzz = language.MustParseScript("Zzzz")
|
|
||||||
zz = language.MustParseRegion("ZZ")
|
|
||||||
)
|
|
||||||
|
|
||||||
// index returns the index of the tag for the given base, script and region or
|
|
||||||
// its parent if the tag is not available. If the match is for a parent entry,
|
|
||||||
// the excess script and region are returned.
|
|
||||||
func (ts *tagSet) index(base language.Base, scr language.Script, reg language.Region) (int, language.Script, language.Region) {
|
|
||||||
lang := base.String()
|
|
||||||
index := -1
|
|
||||||
if (scr != language.Script{} || reg != language.Region{}) {
|
|
||||||
if scr == zzzz {
|
|
||||||
scr = language.Script{}
|
|
||||||
}
|
|
||||||
if reg == zz {
|
|
||||||
reg = language.Region{}
|
|
||||||
}
|
|
||||||
|
|
||||||
i := sort.SearchStrings(ts.long, lang)
|
|
||||||
// All entries have either a script or a region and not both.
|
|
||||||
scrStr, regStr := scr.String(), reg.String()
|
|
||||||
for ; i < len(ts.long) && strings.HasPrefix(ts.long[i], lang); i++ {
|
|
||||||
if s := ts.long[i][len(lang)+1:]; s == scrStr {
|
|
||||||
scr = language.Script{}
|
|
||||||
index = i + ts.single.len()
|
|
||||||
break
|
|
||||||
} else if s == regStr {
|
|
||||||
reg = language.Region{}
|
|
||||||
index = i + ts.single.len()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if index == -1 {
|
|
||||||
index = ts.single.index(lang)
|
|
||||||
}
|
|
||||||
return index, scr, reg
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ts *tagSet) Tags() []language.Tag {
|
|
||||||
tags := make([]language.Tag, 0, ts.single.len()+len(ts.long))
|
|
||||||
ts.single.keys(func(s string) {
|
|
||||||
tags = append(tags, language.Raw.MustParse(s))
|
|
||||||
})
|
|
||||||
for _, s := range ts.long {
|
|
||||||
tags = append(tags, language.Raw.MustParse(s))
|
|
||||||
}
|
|
||||||
return tags
|
|
||||||
}
|
|
||||||
|
|
||||||
func supportedScripts() []language.Script {
|
|
||||||
scr := make([]language.Script, 0, scriptIndex.len())
|
|
||||||
scriptIndex.keys(func(s string) {
|
|
||||||
scr = append(scr, language.MustParseScript(s))
|
|
||||||
})
|
|
||||||
return scr
|
|
||||||
}
|
|
||||||
|
|
||||||
func supportedRegions() []language.Region {
|
|
||||||
reg := make([]language.Region, 0, regionIndex.len())
|
|
||||||
regionIndex.keys(func(s string) {
|
|
||||||
reg = append(reg, language.MustParseRegion(s))
|
|
||||||
})
|
|
||||||
return reg
|
|
||||||
}
|
|
||||||
|
|
||||||
// tagIndex holds a concatenated lists of subtags of length 2 to 4, one string
|
|
||||||
// for each length, which can be used in combination with binary search to get
|
|
||||||
// the index associated with a tag.
|
|
||||||
// For example, a tagIndex{
|
|
||||||
// "arenesfrruzh", // 6 2-byte tags.
|
|
||||||
// "barwae", // 2 3-byte tags.
|
|
||||||
// "",
|
|
||||||
// }
|
|
||||||
// would mean that the 2-byte tag "fr" had an index of 3, and the 3-byte tag
|
|
||||||
// "wae" had an index of 7.
|
|
||||||
type tagIndex [3]string
|
|
||||||
|
|
||||||
func (t *tagIndex) index(s string) int {
|
|
||||||
sz := len(s)
|
|
||||||
if sz < 2 || 4 < sz {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
a := t[sz-2]
|
|
||||||
index := sort.Search(len(a)/sz, func(i int) bool {
|
|
||||||
p := i * sz
|
|
||||||
return a[p:p+sz] >= s
|
|
||||||
})
|
|
||||||
p := index * sz
|
|
||||||
if end := p + sz; end > len(a) || a[p:end] != s {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
// Add the number of tags for smaller sizes.
|
|
||||||
for i := 0; i < sz-2; i++ {
|
|
||||||
index += len(t[i]) / (i + 2)
|
|
||||||
}
|
|
||||||
return index
|
|
||||||
}
|
|
||||||
|
|
||||||
// len returns the number of tags that are contained in the tagIndex.
|
|
||||||
func (t *tagIndex) len() (n int) {
|
|
||||||
for i, s := range t {
|
|
||||||
n += len(s) / (i + 2)
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
// keys calls f for each tag.
|
|
||||||
func (t *tagIndex) keys(f func(key string)) {
|
|
||||||
for i, s := range *t {
|
|
||||||
for ; s != ""; s = s[i+2:] {
|
|
||||||
f(s[:i+2])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
596
Godeps/_workspace/src/golang.org/x/text/language/display/maketables.go
generated
vendored
596
Godeps/_workspace/src/golang.org/x/text/language/display/maketables.go
generated
vendored
@@ -1,596 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
// Generator for display name tables.
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"reflect"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"golang.org/x/text/internal/gen"
|
|
||||||
"golang.org/x/text/language"
|
|
||||||
"golang.org/x/text/unicode/cldr"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
test = flag.Bool("test", false,
|
|
||||||
"test existing tables; can be used to compare web data with package data.")
|
|
||||||
outputFile = flag.String("output", "tables.go", "output file")
|
|
||||||
|
|
||||||
stats = flag.Bool("stats", false, "prints statistics to stderr")
|
|
||||||
|
|
||||||
short = flag.Bool("short", false, `Use "short" alternatives, when available.`)
|
|
||||||
draft = flag.String("draft",
|
|
||||||
"contributed",
|
|
||||||
`Minimal draft requirements (approved, contributed, provisional, unconfirmed).`)
|
|
||||||
pkg = flag.String("package",
|
|
||||||
"display",
|
|
||||||
"the name of the package in which the generated file is to be included")
|
|
||||||
|
|
||||||
tags = newTagSet("tags",
|
|
||||||
[]language.Tag{},
|
|
||||||
"space-separated list of tags to include or empty for all")
|
|
||||||
dict = newTagSet("dict",
|
|
||||||
dictTags(),
|
|
||||||
"space-separated list or tags for which to include a Dictionary. "+
|
|
||||||
`"" means the common list from go.text/language.`)
|
|
||||||
)
|
|
||||||
|
|
||||||
func dictTags() (tag []language.Tag) {
|
|
||||||
// TODO: replace with language.Common.Tags() once supported.
|
|
||||||
const str = "af am ar ar-001 az bg bn ca cs da de el en en-US en-GB " +
|
|
||||||
"es es-ES es-419 et fa fi fil fr fr-CA gu he hi hr hu hy id is it ja " +
|
|
||||||
"ka kk km kn ko ky lo lt lv mk ml mn mr ms my ne nl no pa pl pt pt-BR " +
|
|
||||||
"pt-PT ro ru si sk sl sq sr sr-Latn sv sw ta te th tr uk ur uz vi " +
|
|
||||||
"zh zh-Hans zh-Hant zu"
|
|
||||||
|
|
||||||
for _, s := range strings.Split(str, " ") {
|
|
||||||
tag = append(tag, language.MustParse(s))
|
|
||||||
}
|
|
||||||
return tag
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
gen.Init()
|
|
||||||
|
|
||||||
// Read the CLDR zip file.
|
|
||||||
r := gen.OpenCLDRCoreZip()
|
|
||||||
defer r.Close()
|
|
||||||
|
|
||||||
d := &cldr.Decoder{}
|
|
||||||
d.SetDirFilter("main", "supplemental")
|
|
||||||
d.SetSectionFilter("localeDisplayNames")
|
|
||||||
data, err := d.DecodeZip(r)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("DecodeZip: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
w := gen.NewCodeWriter()
|
|
||||||
defer w.WriteGoFile(*outputFile, "display")
|
|
||||||
|
|
||||||
gen.WriteCLDRVersion(w)
|
|
||||||
|
|
||||||
b := builder{
|
|
||||||
w: w,
|
|
||||||
data: data,
|
|
||||||
group: make(map[string]*group),
|
|
||||||
}
|
|
||||||
b.generate()
|
|
||||||
}
|
|
||||||
|
|
||||||
const tagForm = language.All
|
|
||||||
|
|
||||||
// tagSet is used to parse command line flags of tags. It implements the
|
|
||||||
// flag.Value interface.
|
|
||||||
type tagSet map[language.Tag]bool
|
|
||||||
|
|
||||||
func newTagSet(name string, tags []language.Tag, usage string) tagSet {
|
|
||||||
f := tagSet(make(map[language.Tag]bool))
|
|
||||||
for _, t := range tags {
|
|
||||||
f[t] = true
|
|
||||||
}
|
|
||||||
flag.Var(f, name, usage)
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
|
|
||||||
// String implements the String method of the flag.Value interface.
|
|
||||||
func (f tagSet) String() string {
|
|
||||||
tags := []string{}
|
|
||||||
for t := range f {
|
|
||||||
tags = append(tags, t.String())
|
|
||||||
}
|
|
||||||
sort.Strings(tags)
|
|
||||||
return strings.Join(tags, " ")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set implements Set from the flag.Value interface.
|
|
||||||
func (f tagSet) Set(s string) error {
|
|
||||||
if s != "" {
|
|
||||||
for _, s := range strings.Split(s, " ") {
|
|
||||||
if s != "" {
|
|
||||||
tag, err := tagForm.Parse(s)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
f[tag] = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f tagSet) contains(t language.Tag) bool {
|
|
||||||
if len(f) == 0 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return f[t]
|
|
||||||
}
|
|
||||||
|
|
||||||
// builder is used to create all tables with display name information.
|
|
||||||
type builder struct {
|
|
||||||
w *gen.CodeWriter
|
|
||||||
|
|
||||||
data *cldr.CLDR
|
|
||||||
|
|
||||||
fromLocs []string
|
|
||||||
|
|
||||||
// destination tags for the current locale.
|
|
||||||
toTags []string
|
|
||||||
toTagIndex map[string]int
|
|
||||||
|
|
||||||
// list of supported tags
|
|
||||||
supported []language.Tag
|
|
||||||
|
|
||||||
// key-value pairs per group
|
|
||||||
group map[string]*group
|
|
||||||
|
|
||||||
// statistics
|
|
||||||
sizeIndex int // total size of all indexes of headers
|
|
||||||
sizeData int // total size of all data of headers
|
|
||||||
totalSize int
|
|
||||||
}
|
|
||||||
|
|
||||||
type group struct {
|
|
||||||
// Maps from a given language to the Namer data for this language.
|
|
||||||
lang map[language.Tag]keyValues
|
|
||||||
headers []header
|
|
||||||
|
|
||||||
toTags []string
|
|
||||||
threeStart int
|
|
||||||
fourPlusStart int
|
|
||||||
}
|
|
||||||
|
|
||||||
// set sets the typ to the name for locale loc.
|
|
||||||
func (g *group) set(t language.Tag, typ, name string) {
|
|
||||||
kv := g.lang[t]
|
|
||||||
if kv == nil {
|
|
||||||
kv = make(keyValues)
|
|
||||||
g.lang[t] = kv
|
|
||||||
}
|
|
||||||
if kv[typ] == "" {
|
|
||||||
kv[typ] = name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type keyValues map[string]string
|
|
||||||
|
|
||||||
type header struct {
|
|
||||||
tag language.Tag
|
|
||||||
data string
|
|
||||||
index []uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
var versionInfo = `// Version is deprecated. Use CLDRVersion.
|
|
||||||
const Version = %#v
|
|
||||||
|
|
||||||
`
|
|
||||||
|
|
||||||
var self = language.MustParse("mul")
|
|
||||||
|
|
||||||
// generate builds and writes all tables.
|
|
||||||
func (b *builder) generate() {
|
|
||||||
fmt.Fprintf(b.w, versionInfo, cldr.Version)
|
|
||||||
|
|
||||||
b.filter()
|
|
||||||
b.setData("lang", func(g *group, loc language.Tag, ldn *cldr.LocaleDisplayNames) {
|
|
||||||
if ldn.Languages != nil {
|
|
||||||
for _, v := range ldn.Languages.Language {
|
|
||||||
tag := tagForm.MustParse(v.Type)
|
|
||||||
if tags.contains(tag) {
|
|
||||||
g.set(loc, tag.String(), v.Data())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
b.setData("script", func(g *group, loc language.Tag, ldn *cldr.LocaleDisplayNames) {
|
|
||||||
if ldn.Scripts != nil {
|
|
||||||
for _, v := range ldn.Scripts.Script {
|
|
||||||
code := language.MustParseScript(v.Type)
|
|
||||||
if code.IsPrivateUse() { // Qaaa..Qabx
|
|
||||||
// TODO: data currently appears to be very meager.
|
|
||||||
// Reconsider if we have data for English.
|
|
||||||
if loc == language.English {
|
|
||||||
log.Fatal("Consider including data for private use scripts.")
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
g.set(loc, code.String(), v.Data())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
b.setData("region", func(g *group, loc language.Tag, ldn *cldr.LocaleDisplayNames) {
|
|
||||||
if ldn.Territories != nil {
|
|
||||||
for _, v := range ldn.Territories.Territory {
|
|
||||||
g.set(loc, language.MustParseRegion(v.Type).String(), v.Data())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
b.makeSupported()
|
|
||||||
|
|
||||||
b.writeParents()
|
|
||||||
|
|
||||||
b.writeGroup("lang")
|
|
||||||
b.writeGroup("script")
|
|
||||||
b.writeGroup("region")
|
|
||||||
|
|
||||||
b.w.WriteConst("numSupported", len(b.supported))
|
|
||||||
buf := bytes.Buffer{}
|
|
||||||
for _, tag := range b.supported {
|
|
||||||
fmt.Fprint(&buf, tag.String(), "|")
|
|
||||||
}
|
|
||||||
b.w.WriteConst("supported", buf.String())
|
|
||||||
|
|
||||||
b.writeDictionaries()
|
|
||||||
|
|
||||||
b.supported = []language.Tag{self}
|
|
||||||
|
|
||||||
// Compute the names of locales in their own language. Some of these names
|
|
||||||
// may be specified in their parent locales. We iterate the maximum depth
|
|
||||||
// of the parent three times to match successive parents of tags until a
|
|
||||||
// possible match is found.
|
|
||||||
for i := 0; i < 4; i++ {
|
|
||||||
b.setData("self", func(g *group, tag language.Tag, ldn *cldr.LocaleDisplayNames) {
|
|
||||||
parent := tag
|
|
||||||
if b, s, r := tag.Raw(); i > 0 && (s != language.Script{} && r == language.Region{}) {
|
|
||||||
parent, _ = language.Raw.Compose(b)
|
|
||||||
}
|
|
||||||
if ldn.Languages != nil {
|
|
||||||
for _, v := range ldn.Languages.Language {
|
|
||||||
key := tagForm.MustParse(v.Type)
|
|
||||||
saved := key
|
|
||||||
if key == parent {
|
|
||||||
g.set(self, tag.String(), v.Data())
|
|
||||||
}
|
|
||||||
for k := 0; k < i; k++ {
|
|
||||||
key = key.Parent()
|
|
||||||
}
|
|
||||||
if key == tag {
|
|
||||||
g.set(self, saved.String(), v.Data()) // set does not overwrite a value.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
b.writeGroup("self")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *builder) setData(name string, f func(*group, language.Tag, *cldr.LocaleDisplayNames)) {
|
|
||||||
b.sizeIndex = 0
|
|
||||||
b.sizeData = 0
|
|
||||||
b.toTags = nil
|
|
||||||
b.fromLocs = nil
|
|
||||||
b.toTagIndex = make(map[string]int)
|
|
||||||
|
|
||||||
g := b.group[name]
|
|
||||||
if g == nil {
|
|
||||||
g = &group{lang: make(map[language.Tag]keyValues)}
|
|
||||||
b.group[name] = g
|
|
||||||
}
|
|
||||||
for _, loc := range b.data.Locales() {
|
|
||||||
// We use RawLDML instead of LDML as we are managing our own inheritance
|
|
||||||
// in this implementation.
|
|
||||||
ldml := b.data.RawLDML(loc)
|
|
||||||
|
|
||||||
// We do not support the POSIX variant (it is not a supported BCP 47
|
|
||||||
// variant). This locale also doesn't happen to contain any data, so
|
|
||||||
// we'll skip it by checking for this.
|
|
||||||
tag, err := tagForm.Parse(loc)
|
|
||||||
if err != nil {
|
|
||||||
if ldml.LocaleDisplayNames != nil {
|
|
||||||
log.Fatalf("setData: %v", err)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if ldml.LocaleDisplayNames != nil && tags.contains(tag) {
|
|
||||||
f(g, tag, ldml.LocaleDisplayNames)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *builder) filter() {
|
|
||||||
filter := func(s *cldr.Slice) {
|
|
||||||
if *short {
|
|
||||||
s.SelectOnePerGroup("alt", []string{"short", ""})
|
|
||||||
} else {
|
|
||||||
s.SelectOnePerGroup("alt", []string{"stand-alone", ""})
|
|
||||||
}
|
|
||||||
d, err := cldr.ParseDraft(*draft)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("filter: %v", err)
|
|
||||||
}
|
|
||||||
s.SelectDraft(d)
|
|
||||||
}
|
|
||||||
for _, loc := range b.data.Locales() {
|
|
||||||
if ldn := b.data.RawLDML(loc).LocaleDisplayNames; ldn != nil {
|
|
||||||
if ldn.Languages != nil {
|
|
||||||
s := cldr.MakeSlice(&ldn.Languages.Language)
|
|
||||||
if filter(&s); len(ldn.Languages.Language) == 0 {
|
|
||||||
ldn.Languages = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ldn.Scripts != nil {
|
|
||||||
s := cldr.MakeSlice(&ldn.Scripts.Script)
|
|
||||||
if filter(&s); len(ldn.Scripts.Script) == 0 {
|
|
||||||
ldn.Scripts = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ldn.Territories != nil {
|
|
||||||
s := cldr.MakeSlice(&ldn.Territories.Territory)
|
|
||||||
if filter(&s); len(ldn.Territories.Territory) == 0 {
|
|
||||||
ldn.Territories = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// makeSupported creates a list of all supported locales.
|
|
||||||
func (b *builder) makeSupported() {
|
|
||||||
// tags across groups
|
|
||||||
for _, g := range b.group {
|
|
||||||
for t, _ := range g.lang {
|
|
||||||
b.supported = append(b.supported, t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
b.supported = b.supported[:unique(tagsSorter(b.supported))]
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
type tagsSorter []language.Tag
|
|
||||||
|
|
||||||
func (a tagsSorter) Len() int { return len(a) }
|
|
||||||
func (a tagsSorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
|
||||||
func (a tagsSorter) Less(i, j int) bool { return a[i].String() < a[j].String() }
|
|
||||||
|
|
||||||
func (b *builder) writeGroup(name string) {
|
|
||||||
g := b.group[name]
|
|
||||||
|
|
||||||
for _, kv := range g.lang {
|
|
||||||
for t, _ := range kv {
|
|
||||||
g.toTags = append(g.toTags, t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g.toTags = g.toTags[:unique(tagsBySize(g.toTags))]
|
|
||||||
|
|
||||||
// Allocate header per supported value.
|
|
||||||
g.headers = make([]header, len(b.supported))
|
|
||||||
for i, sup := range b.supported {
|
|
||||||
kv, ok := g.lang[sup]
|
|
||||||
if !ok {
|
|
||||||
g.headers[i].tag = sup
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
data := []byte{}
|
|
||||||
index := make([]uint16, len(g.toTags), len(g.toTags)+1)
|
|
||||||
for j, t := range g.toTags {
|
|
||||||
index[j] = uint16(len(data))
|
|
||||||
data = append(data, kv[t]...)
|
|
||||||
}
|
|
||||||
index = append(index, uint16(len(data)))
|
|
||||||
|
|
||||||
// Trim the tail of the index.
|
|
||||||
// TODO: indexes can be reduced in size quite a bit more.
|
|
||||||
n := len(index)
|
|
||||||
for ; n >= 2 && index[n-2] == index[n-1]; n-- {
|
|
||||||
}
|
|
||||||
index = index[:n]
|
|
||||||
|
|
||||||
// Workaround for a bug in CLDR 26.
|
|
||||||
// See http://unicode.org/cldr/trac/ticket/8042.
|
|
||||||
if cldr.Version == "26" && sup.String() == "hsb" {
|
|
||||||
data = bytes.Replace(data, []byte{'"'}, nil, 1)
|
|
||||||
}
|
|
||||||
g.headers[i] = header{sup, string(data), index}
|
|
||||||
}
|
|
||||||
g.writeTable(b.w, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
type tagsBySize []string
|
|
||||||
|
|
||||||
func (l tagsBySize) Len() int { return len(l) }
|
|
||||||
func (l tagsBySize) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
|
|
||||||
func (l tagsBySize) Less(i, j int) bool {
|
|
||||||
a, b := l[i], l[j]
|
|
||||||
// Sort single-tag entries based on size first. Otherwise alphabetic.
|
|
||||||
if len(a) != len(b) && (len(a) <= 4 || len(b) <= 4) {
|
|
||||||
return len(a) < len(b)
|
|
||||||
}
|
|
||||||
return a < b
|
|
||||||
}
|
|
||||||
|
|
||||||
// parentIndices returns slice a of len(tags) where tags[a[i]] is the parent
|
|
||||||
// of tags[i].
|
|
||||||
func parentIndices(tags []language.Tag) []int16 {
|
|
||||||
index := make(map[language.Tag]int16)
|
|
||||||
for i, t := range tags {
|
|
||||||
index[t] = int16(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct default parents.
|
|
||||||
parents := make([]int16, len(tags))
|
|
||||||
for i, t := range tags {
|
|
||||||
parents[i] = -1
|
|
||||||
for t = t.Parent(); t != language.Und; t = t.Parent() {
|
|
||||||
if j, ok := index[t]; ok {
|
|
||||||
parents[i] = j
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return parents
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *builder) writeParents() {
|
|
||||||
parents := parentIndices(b.supported)
|
|
||||||
fmt.Fprintf(b.w, "var parents = ")
|
|
||||||
b.w.WriteArray(parents)
|
|
||||||
}
|
|
||||||
|
|
||||||
// writeKeys writes keys to a special index used by the display package.
|
|
||||||
// tags are assumed to be sorted by length.
|
|
||||||
func writeKeys(w *gen.CodeWriter, name string, keys []string) {
|
|
||||||
w.Size += int(3 * reflect.TypeOf("").Size())
|
|
||||||
w.WriteComment("Number of keys: %d", len(keys))
|
|
||||||
fmt.Fprintf(w, "var (\n\t%sIndex = tagIndex{\n", name)
|
|
||||||
for i := 2; i <= 4; i++ {
|
|
||||||
sub := []string{}
|
|
||||||
for _, t := range keys {
|
|
||||||
if len(t) != i {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
sub = append(sub, t)
|
|
||||||
}
|
|
||||||
s := strings.Join(sub, "")
|
|
||||||
w.WriteString(s)
|
|
||||||
fmt.Fprintf(w, ",\n")
|
|
||||||
keys = keys[len(sub):]
|
|
||||||
}
|
|
||||||
fmt.Fprintln(w, "\t}")
|
|
||||||
if len(keys) > 0 {
|
|
||||||
w.Size += int(reflect.TypeOf([]string{}).Size())
|
|
||||||
fmt.Fprintf(w, "\t%sTagsLong = ", name)
|
|
||||||
w.WriteSlice(keys)
|
|
||||||
}
|
|
||||||
fmt.Fprintln(w, ")\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
// identifier creates an identifier from the given tag.
|
|
||||||
func identifier(t language.Tag) string {
|
|
||||||
return strings.Replace(t.String(), "-", "", -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *header) writeEntry(w *gen.CodeWriter, name string) {
|
|
||||||
if len(dict) > 0 && dict.contains(h.tag) {
|
|
||||||
fmt.Fprintf(w, "\t{ // %s\n", h.tag)
|
|
||||||
fmt.Fprintf(w, "\t\t%[1]s%[2]sStr,\n\t\t%[1]s%[2]sIdx,\n", identifier(h.tag), name)
|
|
||||||
fmt.Fprintln(w, "\t},")
|
|
||||||
} else if len(h.data) == 0 {
|
|
||||||
fmt.Fprintln(w, "\t\t{}, //", h.tag)
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(w, "\t{ // %s\n", h.tag)
|
|
||||||
w.WriteString(h.data)
|
|
||||||
fmt.Fprintln(w, ",")
|
|
||||||
w.WriteSlice(h.index)
|
|
||||||
fmt.Fprintln(w, ",\n\t},")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// write the data for the given header as single entries. The size for this data
|
|
||||||
// was already accounted for in writeEntry.
|
|
||||||
func (h *header) writeSingle(w *gen.CodeWriter, name string) {
|
|
||||||
if len(dict) > 0 && dict.contains(h.tag) {
|
|
||||||
tag := identifier(h.tag)
|
|
||||||
w.WriteConst(tag+name+"Str", h.data)
|
|
||||||
|
|
||||||
// Note that we create a slice instead of an array. If we use an array
|
|
||||||
// we need to refer to it as a[:] in other tables, which will cause the
|
|
||||||
// array to always be included by the linker. See Issue 7651.
|
|
||||||
w.WriteVar(tag+name+"Idx", h.index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteTable writes an entry for a single Namer.
|
|
||||||
func (g *group) writeTable(w *gen.CodeWriter, name string) {
|
|
||||||
start := w.Size
|
|
||||||
writeKeys(w, name, g.toTags)
|
|
||||||
w.Size += len(g.headers) * int(reflect.ValueOf(g.headers[0]).Type().Size())
|
|
||||||
|
|
||||||
fmt.Fprintf(w, "var %sHeaders = [%d]header{\n", name, len(g.headers))
|
|
||||||
|
|
||||||
title := strings.Title(name)
|
|
||||||
for _, h := range g.headers {
|
|
||||||
h.writeEntry(w, title)
|
|
||||||
}
|
|
||||||
fmt.Fprintln(w, "}\n")
|
|
||||||
|
|
||||||
for _, h := range g.headers {
|
|
||||||
h.writeSingle(w, title)
|
|
||||||
}
|
|
||||||
n := w.Size - start
|
|
||||||
fmt.Fprintf(w, "// Total size for %s: %d bytes (%d KB)\n\n", name, n, n/1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *builder) writeDictionaries() {
|
|
||||||
fmt.Fprintln(b.w, "// Dictionary entries of frequent languages")
|
|
||||||
fmt.Fprintln(b.w, "var (")
|
|
||||||
parents := parentIndices(b.supported)
|
|
||||||
|
|
||||||
for i, t := range b.supported {
|
|
||||||
if dict.contains(t) {
|
|
||||||
ident := identifier(t)
|
|
||||||
fmt.Fprintf(b.w, "\t%s = Dictionary{ // %s\n", ident, t)
|
|
||||||
if p := parents[i]; p == -1 {
|
|
||||||
fmt.Fprintln(b.w, "\t\tnil,")
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(b.w, "\t\t&%s,\n", identifier(b.supported[p]))
|
|
||||||
}
|
|
||||||
fmt.Fprintf(b.w, "\t\theader{%[1]sLangStr, %[1]sLangIdx},\n", ident)
|
|
||||||
fmt.Fprintf(b.w, "\t\theader{%[1]sScriptStr, %[1]sScriptIdx},\n", ident)
|
|
||||||
fmt.Fprintf(b.w, "\t\theader{%[1]sRegionStr, %[1]sRegionIdx},\n", ident)
|
|
||||||
fmt.Fprintln(b.w, "\t}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fmt.Fprintln(b.w, ")")
|
|
||||||
|
|
||||||
var s string
|
|
||||||
var a []uint16
|
|
||||||
sz := reflect.TypeOf(s).Size()
|
|
||||||
sz += reflect.TypeOf(a).Size()
|
|
||||||
sz *= 3
|
|
||||||
sz += reflect.TypeOf(&a).Size()
|
|
||||||
n := int(sz) * len(dict)
|
|
||||||
fmt.Fprintf(b.w, "// Total size for %d entries: %d bytes (%d KB)\n\n", len(dict), n, n/1000)
|
|
||||||
|
|
||||||
b.w.Size += n
|
|
||||||
}
|
|
||||||
|
|
||||||
// unique sorts the given lists and removes duplicate entries by swapping them
|
|
||||||
// past position k, where k is the number of unique values. It returns k.
|
|
||||||
func unique(a sort.Interface) int {
|
|
||||||
if a.Len() == 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
sort.Sort(a)
|
|
||||||
k := 1
|
|
||||||
for i := 1; i < a.Len(); i++ {
|
|
||||||
if a.Less(k-1, i) {
|
|
||||||
if k != i {
|
|
||||||
a.Swap(k, i)
|
|
||||||
}
|
|
||||||
k++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return k
|
|
||||||
}
|
|
||||||
44965
Godeps/_workspace/src/golang.org/x/text/language/display/tables.go
generated
vendored
44965
Godeps/_workspace/src/golang.org/x/text/language/display/tables.go
generated
vendored
File diff suppressed because it is too large
Load Diff
757
Godeps/_workspace/src/golang.org/x/text/language/index.go
generated
vendored
757
Godeps/_workspace/src/golang.org/x/text/language/index.go
generated
vendored
@@ -1,757 +0,0 @@
|
|||||||
// This file was generated by go generate; DO NOT EDIT
|
|
||||||
|
|
||||||
package language
|
|
||||||
|
|
||||||
// NumCompactTags is the number of common tags. The maximum tag is
|
|
||||||
// NumCompactTags-1.
|
|
||||||
const NumCompactTags = 742
|
|
||||||
|
|
||||||
var specialTags = []Tag{ // 2 elements
|
|
||||||
0: {lang: 0x61, region: 0x6d, script: 0x0, pVariant: 0x5, pExt: 0xe, str: "ca-ES-valencia"},
|
|
||||||
1: {lang: 0x9a, region: 0x132, script: 0x0, pVariant: 0x5, pExt: 0x5, str: "en-US-u-va-posix"},
|
|
||||||
} // Size: 72 bytes
|
|
||||||
|
|
||||||
var coreTags = map[uint32]uint16{
|
|
||||||
0x0: 0, // und
|
|
||||||
0x00a00000: 3, // af
|
|
||||||
0x00a000d0: 4, // af-NA
|
|
||||||
0x00a0015e: 5, // af-ZA
|
|
||||||
0x00b00000: 6, // agq
|
|
||||||
0x00b00051: 7, // agq-CM
|
|
||||||
0x00d00000: 8, // ak
|
|
||||||
0x00d0007e: 9, // ak-GH
|
|
||||||
0x01100000: 10, // am
|
|
||||||
0x0110006e: 11, // am-ET
|
|
||||||
0x01500000: 12, // ar
|
|
||||||
0x01500001: 13, // ar-001
|
|
||||||
0x01500022: 14, // ar-AE
|
|
||||||
0x01500038: 15, // ar-BH
|
|
||||||
0x01500061: 16, // ar-DJ
|
|
||||||
0x01500066: 17, // ar-DZ
|
|
||||||
0x0150006a: 18, // ar-EG
|
|
||||||
0x0150006b: 19, // ar-EH
|
|
||||||
0x0150006c: 20, // ar-ER
|
|
||||||
0x01500095: 21, // ar-IL
|
|
||||||
0x01500099: 22, // ar-IQ
|
|
||||||
0x0150009f: 23, // ar-JO
|
|
||||||
0x015000a6: 24, // ar-KM
|
|
||||||
0x015000aa: 25, // ar-KW
|
|
||||||
0x015000ae: 26, // ar-LB
|
|
||||||
0x015000b7: 27, // ar-LY
|
|
||||||
0x015000b8: 28, // ar-MA
|
|
||||||
0x015000c7: 29, // ar-MR
|
|
||||||
0x015000df: 30, // ar-OM
|
|
||||||
0x015000eb: 31, // ar-PS
|
|
||||||
0x015000f1: 32, // ar-QA
|
|
||||||
0x01500106: 33, // ar-SA
|
|
||||||
0x01500109: 34, // ar-SD
|
|
||||||
0x01500113: 35, // ar-SO
|
|
||||||
0x01500115: 36, // ar-SS
|
|
||||||
0x0150011a: 37, // ar-SY
|
|
||||||
0x0150011e: 38, // ar-TD
|
|
||||||
0x01500126: 39, // ar-TN
|
|
||||||
0x0150015b: 40, // ar-YE
|
|
||||||
0x01c00000: 41, // as
|
|
||||||
0x01c00097: 42, // as-IN
|
|
||||||
0x01d00000: 43, // asa
|
|
||||||
0x01d0012d: 44, // asa-TZ
|
|
||||||
0x01f00000: 45, // ast
|
|
||||||
0x01f0006d: 46, // ast-ES
|
|
||||||
0x02400000: 47, // az
|
|
||||||
0x0241d000: 48, // az-Cyrl
|
|
||||||
0x0241d031: 49, // az-Cyrl-AZ
|
|
||||||
0x0244f000: 50, // az-Latn
|
|
||||||
0x0244f031: 51, // az-Latn-AZ
|
|
||||||
0x02a00000: 52, // bas
|
|
||||||
0x02a00051: 53, // bas-CM
|
|
||||||
0x02f00000: 54, // be
|
|
||||||
0x02f00046: 55, // be-BY
|
|
||||||
0x03100000: 56, // bem
|
|
||||||
0x0310015f: 57, // bem-ZM
|
|
||||||
0x03300000: 58, // bez
|
|
||||||
0x0330012d: 59, // bez-TZ
|
|
||||||
0x03800000: 60, // bg
|
|
||||||
0x03800037: 61, // bg-BG
|
|
||||||
0x03c00000: 62, // bh
|
|
||||||
0x04900000: 63, // bm
|
|
||||||
0x049000c1: 64, // bm-ML
|
|
||||||
0x04b00000: 65, // bn
|
|
||||||
0x04b00034: 66, // bn-BD
|
|
||||||
0x04b00097: 67, // bn-IN
|
|
||||||
0x04c00000: 68, // bo
|
|
||||||
0x04c00052: 69, // bo-CN
|
|
||||||
0x04c00097: 70, // bo-IN
|
|
||||||
0x05000000: 71, // br
|
|
||||||
0x05000076: 72, // br-FR
|
|
||||||
0x05300000: 73, // brx
|
|
||||||
0x05300097: 74, // brx-IN
|
|
||||||
0x05400000: 75, // bs
|
|
||||||
0x0541d000: 76, // bs-Cyrl
|
|
||||||
0x0541d032: 77, // bs-Cyrl-BA
|
|
||||||
0x0544f000: 78, // bs-Latn
|
|
||||||
0x0544f032: 79, // bs-Latn-BA
|
|
||||||
0x06100000: 80, // ca
|
|
||||||
0x06100021: 81, // ca-AD
|
|
||||||
0x0610006d: 82, // ca-ES
|
|
||||||
0x06100076: 83, // ca-FR
|
|
||||||
0x0610009c: 84, // ca-IT
|
|
||||||
0x06400000: 85, // ce
|
|
||||||
0x06400104: 86, // ce-RU
|
|
||||||
0x06600000: 87, // cgg
|
|
||||||
0x0660012f: 88, // cgg-UG
|
|
||||||
0x06c00000: 89, // chr
|
|
||||||
0x06c00132: 90, // chr-US
|
|
||||||
0x06f00000: 91, // ckb
|
|
||||||
0x06f00099: 92, // ckb-IQ
|
|
||||||
0x06f0009a: 93, // ckb-IR
|
|
||||||
0x07900000: 94, // cs
|
|
||||||
0x0790005d: 95, // cs-CZ
|
|
||||||
0x07d00000: 96, // cu
|
|
||||||
0x07d00104: 97, // cu-RU
|
|
||||||
0x07f00000: 98, // cy
|
|
||||||
0x07f00079: 99, // cy-GB
|
|
||||||
0x08000000: 100, // da
|
|
||||||
0x08000062: 101, // da-DK
|
|
||||||
0x08000080: 102, // da-GL
|
|
||||||
0x08300000: 103, // dav
|
|
||||||
0x083000a2: 104, // dav-KE
|
|
||||||
0x08500000: 105, // de
|
|
||||||
0x0850002d: 106, // de-AT
|
|
||||||
0x08500035: 107, // de-BE
|
|
||||||
0x0850004d: 108, // de-CH
|
|
||||||
0x0850005f: 109, // de-DE
|
|
||||||
0x085000b0: 110, // de-LI
|
|
||||||
0x085000b5: 111, // de-LU
|
|
||||||
0x08800000: 112, // dje
|
|
||||||
0x088000d2: 113, // dje-NE
|
|
||||||
0x08b00000: 114, // dsb
|
|
||||||
0x08b0005f: 115, // dsb-DE
|
|
||||||
0x08e00000: 116, // dua
|
|
||||||
0x08e00051: 117, // dua-CM
|
|
||||||
0x08f00000: 118, // dv
|
|
||||||
0x09000000: 119, // dyo
|
|
||||||
0x09000112: 120, // dyo-SN
|
|
||||||
0x09200000: 121, // dz
|
|
||||||
0x09200042: 122, // dz-BT
|
|
||||||
0x09300000: 123, // ebu
|
|
||||||
0x093000a2: 124, // ebu-KE
|
|
||||||
0x09400000: 125, // ee
|
|
||||||
0x0940007e: 126, // ee-GH
|
|
||||||
0x09400120: 127, // ee-TG
|
|
||||||
0x09900000: 128, // el
|
|
||||||
0x0990005c: 129, // el-CY
|
|
||||||
0x09900085: 130, // el-GR
|
|
||||||
0x09a00000: 131, // en
|
|
||||||
0x09a00001: 132, // en-001
|
|
||||||
0x09a0001a: 133, // en-150
|
|
||||||
0x09a00024: 134, // en-AG
|
|
||||||
0x09a00025: 135, // en-AI
|
|
||||||
0x09a0002c: 136, // en-AS
|
|
||||||
0x09a0002d: 137, // en-AT
|
|
||||||
0x09a0002e: 138, // en-AU
|
|
||||||
0x09a00033: 139, // en-BB
|
|
||||||
0x09a00035: 140, // en-BE
|
|
||||||
0x09a00039: 141, // en-BI
|
|
||||||
0x09a0003c: 142, // en-BM
|
|
||||||
0x09a00041: 143, // en-BS
|
|
||||||
0x09a00045: 144, // en-BW
|
|
||||||
0x09a00047: 145, // en-BZ
|
|
||||||
0x09a00048: 146, // en-CA
|
|
||||||
0x09a00049: 147, // en-CC
|
|
||||||
0x09a0004d: 148, // en-CH
|
|
||||||
0x09a0004f: 149, // en-CK
|
|
||||||
0x09a00051: 150, // en-CM
|
|
||||||
0x09a0005b: 151, // en-CX
|
|
||||||
0x09a0005c: 152, // en-CY
|
|
||||||
0x09a0005f: 153, // en-DE
|
|
||||||
0x09a00060: 154, // en-DG
|
|
||||||
0x09a00062: 155, // en-DK
|
|
||||||
0x09a00063: 156, // en-DM
|
|
||||||
0x09a0006c: 157, // en-ER
|
|
||||||
0x09a00070: 158, // en-FI
|
|
||||||
0x09a00071: 159, // en-FJ
|
|
||||||
0x09a00072: 160, // en-FK
|
|
||||||
0x09a00073: 161, // en-FM
|
|
||||||
0x09a00079: 162, // en-GB
|
|
||||||
0x09a0007a: 163, // en-GD
|
|
||||||
0x09a0007d: 164, // en-GG
|
|
||||||
0x09a0007e: 165, // en-GH
|
|
||||||
0x09a0007f: 166, // en-GI
|
|
||||||
0x09a00081: 167, // en-GM
|
|
||||||
0x09a00088: 168, // en-GU
|
|
||||||
0x09a0008a: 169, // en-GY
|
|
||||||
0x09a0008b: 170, // en-HK
|
|
||||||
0x09a00094: 171, // en-IE
|
|
||||||
0x09a00095: 172, // en-IL
|
|
||||||
0x09a00096: 173, // en-IM
|
|
||||||
0x09a00097: 174, // en-IN
|
|
||||||
0x09a00098: 175, // en-IO
|
|
||||||
0x09a0009d: 176, // en-JE
|
|
||||||
0x09a0009e: 177, // en-JM
|
|
||||||
0x09a000a2: 178, // en-KE
|
|
||||||
0x09a000a5: 179, // en-KI
|
|
||||||
0x09a000a7: 180, // en-KN
|
|
||||||
0x09a000ab: 181, // en-KY
|
|
||||||
0x09a000af: 182, // en-LC
|
|
||||||
0x09a000b2: 183, // en-LR
|
|
||||||
0x09a000b3: 184, // en-LS
|
|
||||||
0x09a000bd: 185, // en-MG
|
|
||||||
0x09a000be: 186, // en-MH
|
|
||||||
0x09a000c4: 187, // en-MO
|
|
||||||
0x09a000c5: 188, // en-MP
|
|
||||||
0x09a000c8: 189, // en-MS
|
|
||||||
0x09a000c9: 190, // en-MT
|
|
||||||
0x09a000ca: 191, // en-MU
|
|
||||||
0x09a000cc: 192, // en-MW
|
|
||||||
0x09a000ce: 193, // en-MY
|
|
||||||
0x09a000d0: 194, // en-NA
|
|
||||||
0x09a000d3: 195, // en-NF
|
|
||||||
0x09a000d4: 196, // en-NG
|
|
||||||
0x09a000d7: 197, // en-NL
|
|
||||||
0x09a000db: 198, // en-NR
|
|
||||||
0x09a000dd: 199, // en-NU
|
|
||||||
0x09a000de: 200, // en-NZ
|
|
||||||
0x09a000e4: 201, // en-PG
|
|
||||||
0x09a000e5: 202, // en-PH
|
|
||||||
0x09a000e6: 203, // en-PK
|
|
||||||
0x09a000e9: 204, // en-PN
|
|
||||||
0x09a000ea: 205, // en-PR
|
|
||||||
0x09a000ee: 206, // en-PW
|
|
||||||
0x09a00105: 207, // en-RW
|
|
||||||
0x09a00107: 208, // en-SB
|
|
||||||
0x09a00108: 209, // en-SC
|
|
||||||
0x09a00109: 210, // en-SD
|
|
||||||
0x09a0010a: 211, // en-SE
|
|
||||||
0x09a0010b: 212, // en-SG
|
|
||||||
0x09a0010c: 213, // en-SH
|
|
||||||
0x09a0010d: 214, // en-SI
|
|
||||||
0x09a00110: 215, // en-SL
|
|
||||||
0x09a00115: 216, // en-SS
|
|
||||||
0x09a00119: 217, // en-SX
|
|
||||||
0x09a0011b: 218, // en-SZ
|
|
||||||
0x09a0011d: 219, // en-TC
|
|
||||||
0x09a00123: 220, // en-TK
|
|
||||||
0x09a00127: 221, // en-TO
|
|
||||||
0x09a0012a: 222, // en-TT
|
|
||||||
0x09a0012b: 223, // en-TV
|
|
||||||
0x09a0012d: 224, // en-TZ
|
|
||||||
0x09a0012f: 225, // en-UG
|
|
||||||
0x09a00131: 226, // en-UM
|
|
||||||
0x09a00132: 227, // en-US
|
|
||||||
0x09a00136: 228, // en-VC
|
|
||||||
0x09a00139: 229, // en-VG
|
|
||||||
0x09a0013a: 230, // en-VI
|
|
||||||
0x09a0013c: 231, // en-VU
|
|
||||||
0x09a0013f: 232, // en-WS
|
|
||||||
0x09a0015e: 233, // en-ZA
|
|
||||||
0x09a0015f: 234, // en-ZM
|
|
||||||
0x09a00161: 235, // en-ZW
|
|
||||||
0x09b00000: 236, // eo
|
|
||||||
0x09b00001: 237, // eo-001
|
|
||||||
0x09c00000: 238, // es
|
|
||||||
0x09c00003: 239, // es-003
|
|
||||||
0x09c0001e: 240, // es-419
|
|
||||||
0x09c0002b: 241, // es-AR
|
|
||||||
0x09c0003e: 242, // es-BO
|
|
||||||
0x09c00050: 243, // es-CL
|
|
||||||
0x09c00053: 244, // es-CO
|
|
||||||
0x09c00055: 245, // es-CR
|
|
||||||
0x09c00058: 246, // es-CU
|
|
||||||
0x09c00064: 247, // es-DO
|
|
||||||
0x09c00067: 248, // es-EA
|
|
||||||
0x09c00068: 249, // es-EC
|
|
||||||
0x09c0006d: 250, // es-ES
|
|
||||||
0x09c00084: 251, // es-GQ
|
|
||||||
0x09c00087: 252, // es-GT
|
|
||||||
0x09c0008d: 253, // es-HN
|
|
||||||
0x09c00092: 254, // es-IC
|
|
||||||
0x09c000cd: 255, // es-MX
|
|
||||||
0x09c000d6: 256, // es-NI
|
|
||||||
0x09c000e0: 257, // es-PA
|
|
||||||
0x09c000e2: 258, // es-PE
|
|
||||||
0x09c000e5: 259, // es-PH
|
|
||||||
0x09c000ea: 260, // es-PR
|
|
||||||
0x09c000ef: 261, // es-PY
|
|
||||||
0x09c00118: 262, // es-SV
|
|
||||||
0x09c00132: 263, // es-US
|
|
||||||
0x09c00133: 264, // es-UY
|
|
||||||
0x09c00138: 265, // es-VE
|
|
||||||
0x09e00000: 266, // et
|
|
||||||
0x09e00069: 267, // et-EE
|
|
||||||
0x0a000000: 268, // eu
|
|
||||||
0x0a00006d: 269, // eu-ES
|
|
||||||
0x0a100000: 270, // ewo
|
|
||||||
0x0a100051: 271, // ewo-CM
|
|
||||||
0x0a300000: 272, // fa
|
|
||||||
0x0a300023: 273, // fa-AF
|
|
||||||
0x0a30009a: 274, // fa-IR
|
|
||||||
0x0a500000: 275, // ff
|
|
||||||
0x0a500051: 276, // ff-CM
|
|
||||||
0x0a500082: 277, // ff-GN
|
|
||||||
0x0a5000c7: 278, // ff-MR
|
|
||||||
0x0a500112: 279, // ff-SN
|
|
||||||
0x0a700000: 280, // fi
|
|
||||||
0x0a700070: 281, // fi-FI
|
|
||||||
0x0a900000: 282, // fil
|
|
||||||
0x0a9000e5: 283, // fil-PH
|
|
||||||
0x0ac00000: 284, // fo
|
|
||||||
0x0ac00062: 285, // fo-DK
|
|
||||||
0x0ac00074: 286, // fo-FO
|
|
||||||
0x0ae00000: 287, // fr
|
|
||||||
0x0ae00035: 288, // fr-BE
|
|
||||||
0x0ae00036: 289, // fr-BF
|
|
||||||
0x0ae00039: 290, // fr-BI
|
|
||||||
0x0ae0003a: 291, // fr-BJ
|
|
||||||
0x0ae0003b: 292, // fr-BL
|
|
||||||
0x0ae00048: 293, // fr-CA
|
|
||||||
0x0ae0004a: 294, // fr-CD
|
|
||||||
0x0ae0004b: 295, // fr-CF
|
|
||||||
0x0ae0004c: 296, // fr-CG
|
|
||||||
0x0ae0004d: 297, // fr-CH
|
|
||||||
0x0ae0004e: 298, // fr-CI
|
|
||||||
0x0ae00051: 299, // fr-CM
|
|
||||||
0x0ae00061: 300, // fr-DJ
|
|
||||||
0x0ae00066: 301, // fr-DZ
|
|
||||||
0x0ae00076: 302, // fr-FR
|
|
||||||
0x0ae00078: 303, // fr-GA
|
|
||||||
0x0ae0007c: 304, // fr-GF
|
|
||||||
0x0ae00082: 305, // fr-GN
|
|
||||||
0x0ae00083: 306, // fr-GP
|
|
||||||
0x0ae00084: 307, // fr-GQ
|
|
||||||
0x0ae0008f: 308, // fr-HT
|
|
||||||
0x0ae000a6: 309, // fr-KM
|
|
||||||
0x0ae000b5: 310, // fr-LU
|
|
||||||
0x0ae000b8: 311, // fr-MA
|
|
||||||
0x0ae000b9: 312, // fr-MC
|
|
||||||
0x0ae000bc: 313, // fr-MF
|
|
||||||
0x0ae000bd: 314, // fr-MG
|
|
||||||
0x0ae000c1: 315, // fr-ML
|
|
||||||
0x0ae000c6: 316, // fr-MQ
|
|
||||||
0x0ae000c7: 317, // fr-MR
|
|
||||||
0x0ae000ca: 318, // fr-MU
|
|
||||||
0x0ae000d1: 319, // fr-NC
|
|
||||||
0x0ae000d2: 320, // fr-NE
|
|
||||||
0x0ae000e3: 321, // fr-PF
|
|
||||||
0x0ae000e8: 322, // fr-PM
|
|
||||||
0x0ae00100: 323, // fr-RE
|
|
||||||
0x0ae00105: 324, // fr-RW
|
|
||||||
0x0ae00108: 325, // fr-SC
|
|
||||||
0x0ae00112: 326, // fr-SN
|
|
||||||
0x0ae0011a: 327, // fr-SY
|
|
||||||
0x0ae0011e: 328, // fr-TD
|
|
||||||
0x0ae00120: 329, // fr-TG
|
|
||||||
0x0ae00126: 330, // fr-TN
|
|
||||||
0x0ae0013c: 331, // fr-VU
|
|
||||||
0x0ae0013d: 332, // fr-WF
|
|
||||||
0x0ae0015c: 333, // fr-YT
|
|
||||||
0x0b500000: 334, // fur
|
|
||||||
0x0b50009c: 335, // fur-IT
|
|
||||||
0x0b800000: 336, // fy
|
|
||||||
0x0b8000d7: 337, // fy-NL
|
|
||||||
0x0b900000: 338, // ga
|
|
||||||
0x0b900094: 339, // ga-IE
|
|
||||||
0x0c100000: 340, // gd
|
|
||||||
0x0c100079: 341, // gd-GB
|
|
||||||
0x0c700000: 342, // gl
|
|
||||||
0x0c70006d: 343, // gl-ES
|
|
||||||
0x0d100000: 344, // gsw
|
|
||||||
0x0d10004d: 345, // gsw-CH
|
|
||||||
0x0d100076: 346, // gsw-FR
|
|
||||||
0x0d1000b0: 347, // gsw-LI
|
|
||||||
0x0d200000: 348, // gu
|
|
||||||
0x0d200097: 349, // gu-IN
|
|
||||||
0x0d600000: 350, // guw
|
|
||||||
0x0d700000: 351, // guz
|
|
||||||
0x0d7000a2: 352, // guz-KE
|
|
||||||
0x0d800000: 353, // gv
|
|
||||||
0x0d800096: 354, // gv-IM
|
|
||||||
0x0db00000: 355, // ha
|
|
||||||
0x0db0007e: 356, // ha-GH
|
|
||||||
0x0db000d2: 357, // ha-NE
|
|
||||||
0x0db000d4: 358, // ha-NG
|
|
||||||
0x0dd00000: 359, // haw
|
|
||||||
0x0dd00132: 360, // haw-US
|
|
||||||
0x0df00000: 361, // he
|
|
||||||
0x0df00095: 362, // he-IL
|
|
||||||
0x0e000000: 363, // hi
|
|
||||||
0x0e000097: 364, // hi-IN
|
|
||||||
0x0ed00000: 365, // hr
|
|
||||||
0x0ed00032: 366, // hr-BA
|
|
||||||
0x0ed0008e: 367, // hr-HR
|
|
||||||
0x0ee00000: 368, // hsb
|
|
||||||
0x0ee0005f: 369, // hsb-DE
|
|
||||||
0x0f100000: 370, // hu
|
|
||||||
0x0f100090: 371, // hu-HU
|
|
||||||
0x0f200000: 372, // hy
|
|
||||||
0x0f200027: 373, // hy-AM
|
|
||||||
0x0f700000: 374, // id
|
|
||||||
0x0f700093: 375, // id-ID
|
|
||||||
0x0f900000: 376, // ig
|
|
||||||
0x0f9000d4: 377, // ig-NG
|
|
||||||
0x0fa00000: 378, // ii
|
|
||||||
0x0fa00052: 379, // ii-CN
|
|
||||||
0x10100000: 380, // is
|
|
||||||
0x1010009b: 381, // is-IS
|
|
||||||
0x10200000: 382, // it
|
|
||||||
0x1020004d: 383, // it-CH
|
|
||||||
0x1020009c: 384, // it-IT
|
|
||||||
0x10200111: 385, // it-SM
|
|
||||||
0x10300000: 386, // iu
|
|
||||||
0x10600000: 387, // ja
|
|
||||||
0x106000a0: 388, // ja-JP
|
|
||||||
0x10800000: 389, // jbo
|
|
||||||
0x10900000: 390, // jgo
|
|
||||||
0x10900051: 391, // jgo-CM
|
|
||||||
0x10b00000: 392, // jmc
|
|
||||||
0x10b0012d: 393, // jmc-TZ
|
|
||||||
0x10e00000: 394, // jv
|
|
||||||
0x11000000: 395, // ka
|
|
||||||
0x1100007b: 396, // ka-GE
|
|
||||||
0x11200000: 397, // kab
|
|
||||||
0x11200066: 398, // kab-DZ
|
|
||||||
0x11400000: 399, // kaj
|
|
||||||
0x11500000: 400, // kam
|
|
||||||
0x115000a2: 401, // kam-KE
|
|
||||||
0x11800000: 402, // kcg
|
|
||||||
0x11a00000: 403, // kde
|
|
||||||
0x11a0012d: 404, // kde-TZ
|
|
||||||
0x11c00000: 405, // kea
|
|
||||||
0x11c00059: 406, // kea-CV
|
|
||||||
0x12700000: 407, // khq
|
|
||||||
0x127000c1: 408, // khq-ML
|
|
||||||
0x12a00000: 409, // ki
|
|
||||||
0x12a000a2: 410, // ki-KE
|
|
||||||
0x12e00000: 411, // kk
|
|
||||||
0x12e000ac: 412, // kk-KZ
|
|
||||||
0x12f00000: 413, // kkj
|
|
||||||
0x12f00051: 414, // kkj-CM
|
|
||||||
0x13000000: 415, // kl
|
|
||||||
0x13000080: 416, // kl-GL
|
|
||||||
0x13100000: 417, // kln
|
|
||||||
0x131000a2: 418, // kln-KE
|
|
||||||
0x13200000: 419, // km
|
|
||||||
0x132000a4: 420, // km-KH
|
|
||||||
0x13400000: 421, // kn
|
|
||||||
0x13400097: 422, // kn-IN
|
|
||||||
0x13500000: 423, // ko
|
|
||||||
0x135000a8: 424, // ko-KP
|
|
||||||
0x135000a9: 425, // ko-KR
|
|
||||||
0x13700000: 426, // kok
|
|
||||||
0x13700097: 427, // kok-IN
|
|
||||||
0x14000000: 428, // ks
|
|
||||||
0x14000097: 429, // ks-IN
|
|
||||||
0x14100000: 430, // ksb
|
|
||||||
0x1410012d: 431, // ksb-TZ
|
|
||||||
0x14200000: 432, // ksf
|
|
||||||
0x14200051: 433, // ksf-CM
|
|
||||||
0x14300000: 434, // ksh
|
|
||||||
0x1430005f: 435, // ksh-DE
|
|
||||||
0x14400000: 436, // ku
|
|
||||||
0x14900000: 437, // kw
|
|
||||||
0x14900079: 438, // kw-GB
|
|
||||||
0x14c00000: 439, // ky
|
|
||||||
0x14c000a3: 440, // ky-KG
|
|
||||||
0x15000000: 441, // lag
|
|
||||||
0x1500012d: 442, // lag-TZ
|
|
||||||
0x15300000: 443, // lb
|
|
||||||
0x153000b5: 444, // lb-LU
|
|
||||||
0x15900000: 445, // lg
|
|
||||||
0x1590012f: 446, // lg-UG
|
|
||||||
0x16000000: 447, // lkt
|
|
||||||
0x16000132: 448, // lkt-US
|
|
||||||
0x16300000: 449, // ln
|
|
||||||
0x16300029: 450, // ln-AO
|
|
||||||
0x1630004a: 451, // ln-CD
|
|
||||||
0x1630004b: 452, // ln-CF
|
|
||||||
0x1630004c: 453, // ln-CG
|
|
||||||
0x16400000: 454, // lo
|
|
||||||
0x164000ad: 455, // lo-LA
|
|
||||||
0x16700000: 456, // lrc
|
|
||||||
0x16700099: 457, // lrc-IQ
|
|
||||||
0x1670009a: 458, // lrc-IR
|
|
||||||
0x16800000: 459, // lt
|
|
||||||
0x168000b4: 460, // lt-LT
|
|
||||||
0x16a00000: 461, // lu
|
|
||||||
0x16a0004a: 462, // lu-CD
|
|
||||||
0x16c00000: 463, // luo
|
|
||||||
0x16c000a2: 464, // luo-KE
|
|
||||||
0x16d00000: 465, // luy
|
|
||||||
0x16d000a2: 466, // luy-KE
|
|
||||||
0x16f00000: 467, // lv
|
|
||||||
0x16f000b6: 468, // lv-LV
|
|
||||||
0x17900000: 469, // mas
|
|
||||||
0x179000a2: 470, // mas-KE
|
|
||||||
0x1790012d: 471, // mas-TZ
|
|
||||||
0x17f00000: 472, // mer
|
|
||||||
0x17f000a2: 473, // mer-KE
|
|
||||||
0x18100000: 474, // mfe
|
|
||||||
0x181000ca: 475, // mfe-MU
|
|
||||||
0x18200000: 476, // mg
|
|
||||||
0x182000bd: 477, // mg-MG
|
|
||||||
0x18300000: 478, // mgh
|
|
||||||
0x183000cf: 479, // mgh-MZ
|
|
||||||
0x18400000: 480, // mgo
|
|
||||||
0x18400051: 481, // mgo-CM
|
|
||||||
0x18b00000: 482, // mk
|
|
||||||
0x18b000c0: 483, // mk-MK
|
|
||||||
0x18c00000: 484, // ml
|
|
||||||
0x18c00097: 485, // ml-IN
|
|
||||||
0x18e00000: 486, // mn
|
|
||||||
0x18e000c3: 487, // mn-MN
|
|
||||||
0x19500000: 488, // mr
|
|
||||||
0x19500097: 489, // mr-IN
|
|
||||||
0x19900000: 490, // ms
|
|
||||||
0x1990003d: 491, // ms-BN
|
|
||||||
0x199000ce: 492, // ms-MY
|
|
||||||
0x1990010b: 493, // ms-SG
|
|
||||||
0x19a00000: 494, // mt
|
|
||||||
0x19a000c9: 495, // mt-MT
|
|
||||||
0x19c00000: 496, // mua
|
|
||||||
0x19c00051: 497, // mua-CM
|
|
||||||
0x1a400000: 498, // my
|
|
||||||
0x1a4000c2: 499, // my-MM
|
|
||||||
0x1a800000: 500, // mzn
|
|
||||||
0x1a80009a: 501, // mzn-IR
|
|
||||||
0x1aa00000: 502, // nah
|
|
||||||
0x1ad00000: 503, // naq
|
|
||||||
0x1ad000d0: 504, // naq-NA
|
|
||||||
0x1ae00000: 505, // nb
|
|
||||||
0x1ae000d8: 506, // nb-NO
|
|
||||||
0x1ae0010e: 507, // nb-SJ
|
|
||||||
0x1b000000: 508, // nd
|
|
||||||
0x1b000161: 509, // nd-ZW
|
|
||||||
0x1b300000: 510, // ne
|
|
||||||
0x1b300097: 511, // ne-IN
|
|
||||||
0x1b3000d9: 512, // ne-NP
|
|
||||||
0x1bc00000: 513, // nl
|
|
||||||
0x1bc0002f: 514, // nl-AW
|
|
||||||
0x1bc00035: 515, // nl-BE
|
|
||||||
0x1bc0003f: 516, // nl-BQ
|
|
||||||
0x1bc0005a: 517, // nl-CW
|
|
||||||
0x1bc000d7: 518, // nl-NL
|
|
||||||
0x1bc00114: 519, // nl-SR
|
|
||||||
0x1bc00119: 520, // nl-SX
|
|
||||||
0x1bd00000: 521, // nmg
|
|
||||||
0x1bd00051: 522, // nmg-CM
|
|
||||||
0x1be00000: 523, // nn
|
|
||||||
0x1be000d8: 524, // nn-NO
|
|
||||||
0x1bf00000: 525, // nnh
|
|
||||||
0x1bf00051: 526, // nnh-CM
|
|
||||||
0x1c000000: 527, // no
|
|
||||||
0x1c400000: 528, // nqo
|
|
||||||
0x1c500000: 529, // nr
|
|
||||||
0x1c700000: 530, // nso
|
|
||||||
0x1c800000: 531, // nus
|
|
||||||
0x1c800115: 532, // nus-SS
|
|
||||||
0x1cb00000: 533, // ny
|
|
||||||
0x1cd00000: 534, // nyn
|
|
||||||
0x1cd0012f: 535, // nyn-UG
|
|
||||||
0x1d100000: 536, // om
|
|
||||||
0x1d10006e: 537, // om-ET
|
|
||||||
0x1d1000a2: 538, // om-KE
|
|
||||||
0x1d200000: 539, // or
|
|
||||||
0x1d200097: 540, // or-IN
|
|
||||||
0x1d300000: 541, // os
|
|
||||||
0x1d30007b: 542, // os-GE
|
|
||||||
0x1d300104: 543, // os-RU
|
|
||||||
0x1d500000: 544, // pa
|
|
||||||
0x1d505000: 545, // pa-Arab
|
|
||||||
0x1d5050e6: 546, // pa-Arab-PK
|
|
||||||
0x1d52e000: 547, // pa-Guru
|
|
||||||
0x1d52e097: 548, // pa-Guru-IN
|
|
||||||
0x1d900000: 549, // pap
|
|
||||||
0x1e500000: 550, // pl
|
|
||||||
0x1e5000e7: 551, // pl-PL
|
|
||||||
0x1eb00000: 552, // prg
|
|
||||||
0x1eb00001: 553, // prg-001
|
|
||||||
0x1ec00000: 554, // ps
|
|
||||||
0x1ec00023: 555, // ps-AF
|
|
||||||
0x1ed00000: 556, // pt
|
|
||||||
0x1ed00029: 557, // pt-AO
|
|
||||||
0x1ed00040: 558, // pt-BR
|
|
||||||
0x1ed00059: 559, // pt-CV
|
|
||||||
0x1ed00089: 560, // pt-GW
|
|
||||||
0x1ed000c4: 561, // pt-MO
|
|
||||||
0x1ed000cf: 562, // pt-MZ
|
|
||||||
0x1ed000ec: 563, // pt-PT
|
|
||||||
0x1ed00116: 564, // pt-ST
|
|
||||||
0x1ed00124: 565, // pt-TL
|
|
||||||
0x1ef00000: 566, // qu
|
|
||||||
0x1ef0003e: 567, // qu-BO
|
|
||||||
0x1ef00068: 568, // qu-EC
|
|
||||||
0x1ef000e2: 569, // qu-PE
|
|
||||||
0x1fa00000: 570, // rm
|
|
||||||
0x1fa0004d: 571, // rm-CH
|
|
||||||
0x1ff00000: 572, // rn
|
|
||||||
0x1ff00039: 573, // rn-BI
|
|
||||||
0x20100000: 574, // ro
|
|
||||||
0x201000ba: 575, // ro-MD
|
|
||||||
0x20100102: 576, // ro-RO
|
|
||||||
0x20300000: 577, // rof
|
|
||||||
0x2030012d: 578, // rof-TZ
|
|
||||||
0x20500000: 579, // ru
|
|
||||||
0x20500046: 580, // ru-BY
|
|
||||||
0x205000a3: 581, // ru-KG
|
|
||||||
0x205000ac: 582, // ru-KZ
|
|
||||||
0x205000ba: 583, // ru-MD
|
|
||||||
0x20500104: 584, // ru-RU
|
|
||||||
0x2050012e: 585, // ru-UA
|
|
||||||
0x20800000: 586, // rw
|
|
||||||
0x20800105: 587, // rw-RW
|
|
||||||
0x20900000: 588, // rwk
|
|
||||||
0x2090012d: 589, // rwk-TZ
|
|
||||||
0x20d00000: 590, // sah
|
|
||||||
0x20d00104: 591, // sah-RU
|
|
||||||
0x20e00000: 592, // saq
|
|
||||||
0x20e000a2: 593, // saq-KE
|
|
||||||
0x21200000: 594, // sbp
|
|
||||||
0x2120012d: 595, // sbp-TZ
|
|
||||||
0x21a00000: 596, // sdh
|
|
||||||
0x21b00000: 597, // se
|
|
||||||
0x21b00070: 598, // se-FI
|
|
||||||
0x21b000d8: 599, // se-NO
|
|
||||||
0x21b0010a: 600, // se-SE
|
|
||||||
0x21d00000: 601, // seh
|
|
||||||
0x21d000cf: 602, // seh-MZ
|
|
||||||
0x21f00000: 603, // ses
|
|
||||||
0x21f000c1: 604, // ses-ML
|
|
||||||
0x22000000: 605, // sg
|
|
||||||
0x2200004b: 606, // sg-CF
|
|
||||||
0x22400000: 607, // shi
|
|
||||||
0x2244f000: 608, // shi-Latn
|
|
||||||
0x2244f0b8: 609, // shi-Latn-MA
|
|
||||||
0x224cc000: 610, // shi-Tfng
|
|
||||||
0x224cc0b8: 611, // shi-Tfng-MA
|
|
||||||
0x22600000: 612, // si
|
|
||||||
0x226000b1: 613, // si-LK
|
|
||||||
0x22800000: 614, // sk
|
|
||||||
0x2280010f: 615, // sk-SK
|
|
||||||
0x22a00000: 616, // sl
|
|
||||||
0x22a0010d: 617, // sl-SI
|
|
||||||
0x22e00000: 618, // sma
|
|
||||||
0x22f00000: 619, // smi
|
|
||||||
0x23000000: 620, // smj
|
|
||||||
0x23100000: 621, // smn
|
|
||||||
0x23100070: 622, // smn-FI
|
|
||||||
0x23300000: 623, // sms
|
|
||||||
0x23400000: 624, // sn
|
|
||||||
0x23400161: 625, // sn-ZW
|
|
||||||
0x23600000: 626, // so
|
|
||||||
0x23600061: 627, // so-DJ
|
|
||||||
0x2360006e: 628, // so-ET
|
|
||||||
0x236000a2: 629, // so-KE
|
|
||||||
0x23600113: 630, // so-SO
|
|
||||||
0x23800000: 631, // sq
|
|
||||||
0x23800026: 632, // sq-AL
|
|
||||||
0x238000c0: 633, // sq-MK
|
|
||||||
0x2380014a: 634, // sq-XK
|
|
||||||
0x23900000: 635, // sr
|
|
||||||
0x2391d000: 636, // sr-Cyrl
|
|
||||||
0x2391d032: 637, // sr-Cyrl-BA
|
|
||||||
0x2391d0bb: 638, // sr-Cyrl-ME
|
|
||||||
0x2391d103: 639, // sr-Cyrl-RS
|
|
||||||
0x2391d14a: 640, // sr-Cyrl-XK
|
|
||||||
0x2394f000: 641, // sr-Latn
|
|
||||||
0x2394f032: 642, // sr-Latn-BA
|
|
||||||
0x2394f0bb: 643, // sr-Latn-ME
|
|
||||||
0x2394f103: 644, // sr-Latn-RS
|
|
||||||
0x2394f14a: 645, // sr-Latn-XK
|
|
||||||
0x23e00000: 646, // ss
|
|
||||||
0x23f00000: 647, // ssy
|
|
||||||
0x24000000: 648, // st
|
|
||||||
0x24500000: 649, // sv
|
|
||||||
0x24500030: 650, // sv-AX
|
|
||||||
0x24500070: 651, // sv-FI
|
|
||||||
0x2450010a: 652, // sv-SE
|
|
||||||
0x24600000: 653, // sw
|
|
||||||
0x2460004a: 654, // sw-CD
|
|
||||||
0x246000a2: 655, // sw-KE
|
|
||||||
0x2460012d: 656, // sw-TZ
|
|
||||||
0x2460012f: 657, // sw-UG
|
|
||||||
0x24d00000: 658, // syr
|
|
||||||
0x24f00000: 659, // ta
|
|
||||||
0x24f00097: 660, // ta-IN
|
|
||||||
0x24f000b1: 661, // ta-LK
|
|
||||||
0x24f000ce: 662, // ta-MY
|
|
||||||
0x24f0010b: 663, // ta-SG
|
|
||||||
0x25600000: 664, // te
|
|
||||||
0x25600097: 665, // te-IN
|
|
||||||
0x25800000: 666, // teo
|
|
||||||
0x258000a2: 667, // teo-KE
|
|
||||||
0x2580012f: 668, // teo-UG
|
|
||||||
0x25b00000: 669, // th
|
|
||||||
0x25b00121: 670, // th-TH
|
|
||||||
0x25f00000: 671, // ti
|
|
||||||
0x25f0006c: 672, // ti-ER
|
|
||||||
0x25f0006e: 673, // ti-ET
|
|
||||||
0x26000000: 674, // tig
|
|
||||||
0x26200000: 675, // tk
|
|
||||||
0x26200125: 676, // tk-TM
|
|
||||||
0x26900000: 677, // tn
|
|
||||||
0x26a00000: 678, // to
|
|
||||||
0x26a00127: 679, // to-TO
|
|
||||||
0x26d00000: 680, // tr
|
|
||||||
0x26d0005c: 681, // tr-CY
|
|
||||||
0x26d00129: 682, // tr-TR
|
|
||||||
0x27000000: 683, // ts
|
|
||||||
0x27c00000: 684, // twq
|
|
||||||
0x27c000d2: 685, // twq-NE
|
|
||||||
0x27f00000: 686, // tzm
|
|
||||||
0x27f000b8: 687, // tzm-MA
|
|
||||||
0x28100000: 688, // ug
|
|
||||||
0x28100052: 689, // ug-CN
|
|
||||||
0x28300000: 690, // uk
|
|
||||||
0x2830012e: 691, // uk-UA
|
|
||||||
0x28900000: 692, // ur
|
|
||||||
0x28900097: 693, // ur-IN
|
|
||||||
0x289000e6: 694, // ur-PK
|
|
||||||
0x28a00000: 695, // uz
|
|
||||||
0x28a05000: 696, // uz-Arab
|
|
||||||
0x28a05023: 697, // uz-Arab-AF
|
|
||||||
0x28a1d000: 698, // uz-Cyrl
|
|
||||||
0x28a1d134: 699, // uz-Cyrl-UZ
|
|
||||||
0x28a4f000: 700, // uz-Latn
|
|
||||||
0x28a4f134: 701, // uz-Latn-UZ
|
|
||||||
0x28b00000: 702, // vai
|
|
||||||
0x28b4f000: 703, // vai-Latn
|
|
||||||
0x28b4f0b2: 704, // vai-Latn-LR
|
|
||||||
0x28bd3000: 705, // vai-Vaii
|
|
||||||
0x28bd30b2: 706, // vai-Vaii-LR
|
|
||||||
0x28c00000: 707, // ve
|
|
||||||
0x28f00000: 708, // vi
|
|
||||||
0x28f0013b: 709, // vi-VN
|
|
||||||
0x29400000: 710, // vo
|
|
||||||
0x29400001: 711, // vo-001
|
|
||||||
0x29700000: 712, // vun
|
|
||||||
0x2970012d: 713, // vun-TZ
|
|
||||||
0x29800000: 714, // wa
|
|
||||||
0x29900000: 715, // wae
|
|
||||||
0x2990004d: 716, // wae-CH
|
|
||||||
0x2a100000: 717, // wo
|
|
||||||
0x2a600000: 718, // xh
|
|
||||||
0x2ae00000: 719, // xog
|
|
||||||
0x2ae0012f: 720, // xog-UG
|
|
||||||
0x2b400000: 721, // yav
|
|
||||||
0x2b400051: 722, // yav-CM
|
|
||||||
0x2b600000: 723, // yi
|
|
||||||
0x2b600001: 724, // yi-001
|
|
||||||
0x2b700000: 725, // yo
|
|
||||||
0x2b70003a: 726, // yo-BJ
|
|
||||||
0x2b7000d4: 727, // yo-NG
|
|
||||||
0x2bf00000: 728, // zgh
|
|
||||||
0x2bf000b8: 729, // zgh-MA
|
|
||||||
0x2c000000: 730, // zh
|
|
||||||
0x2c032000: 731, // zh-Hans
|
|
||||||
0x2c032052: 732, // zh-Hans-CN
|
|
||||||
0x2c03208b: 733, // zh-Hans-HK
|
|
||||||
0x2c0320c4: 734, // zh-Hans-MO
|
|
||||||
0x2c03210b: 735, // zh-Hans-SG
|
|
||||||
0x2c033000: 736, // zh-Hant
|
|
||||||
0x2c03308b: 737, // zh-Hant-HK
|
|
||||||
0x2c0330c4: 738, // zh-Hant-MO
|
|
||||||
0x2c03312c: 739, // zh-Hant-TW
|
|
||||||
0x2c200000: 740, // zu
|
|
||||||
0x2c20015e: 741, // zu-ZA
|
|
||||||
}
|
|
||||||
|
|
||||||
// Total table size 4520 bytes (4KiB); checksum: E686101E
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user