Repository: brendanzab/gl-rs (language: rust)

Issue:
crates.io has wrong homepage link for webgl_stdweb
The 'homepage' link on https://crates.io/crates/webgl_stdweb points to a non-existent github project.
Update GLFW example
The readme gives this example for integration with `glfw-rs`:

    gl::Viewport::load_with(|s| window.get_proc_address(s));

It looks like the `glfw-rs` API has changed since the above was written. `gl-rs` expects a `*const std::os::raw::c_void`. But `get_proc_address` now returns a `*const libc::c_void`. I was able to fix it like this:

    gl::load_with(|s| window.get_proc_address(s) as *const std::os::raw::c_void);

I think the readme should be updated accordingly.


Discussion / hints:

Fix patch:
diff --git a/.travis.yml b/.travis.yml
index f1e85dbd..634af35a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,5 +8,5 @@ rust:
 cache: cargo
 
 script:
-  - cargo build --all
-  - cargo test --all
+  - travis_wait cargo build --all
+  - travis_wait cargo test --all
diff --git a/gl/Cargo.toml b/gl/Cargo.toml
index 7c5c2e73..38f3ba50 100644
--- a/gl/Cargo.toml
+++ b/gl/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "gl"
-version = "0.10.0"
+version = "0.11.0"
 authors = [
     "Brendan Zabarauskas <bjzaba@yahoo.com.au>",
     "Corey Richardson",
@@ -10,14 +10,14 @@ description = "OpenGL bindings"
 license = "Apache-2.0"
 build = "build.rs"
 documentation = "https://docs.rs/gl"
-homepage = "https://github.com/brendanzab/gl-rs/gl/"
+homepage = "https://github.com/brendanzab/gl-rs/"
 repository = "https://github.com/brendanzab/gl-rs/"
 readme = "README.md"
 categories = ["api-bindings", "rendering::graphics-api"]
 keywords = ["gl", "egl", "opengl", "khronos"]
 
 [build-dependencies]
-gl_generator = { version = "0.9.0", path = "../gl_generator" }
+gl_generator = { version = "0.10.0", path = "../gl_generator" }
 
 [dev-dependencies]
-glutin = "0.10.0"
+glutin = "0.18.0"
diff --git a/gl/examples/basic.rs b/gl/examples/basic.rs
index 0c3d94a8..b83377e8 100644
--- a/gl/examples/basic.rs
+++ b/gl/examples/basic.rs
@@ -34,7 +34,7 @@ fn main() {
         use glutin::{ControlFlow, Event, WindowEvent};
 
         if let Event::WindowEvent { event, .. } = event {
-            if let WindowEvent::Closed = event {
+            if let WindowEvent::CloseRequested = event {
                 return ControlFlow::Break;
             }
         }
diff --git a/gl/examples/triangle.rs b/gl/examples/triangle.rs
index 44ffd47a..cd0d231b 100644
--- a/gl/examples/triangle.rs
+++ b/gl/examples/triangle.rs
@@ -16,10 +16,10 @@ extern crate gl;
 extern crate glutin;
 
 use gl::types::*;
+use std::ffi::CString;
 use std::mem;
 use std::ptr;
 use std::str;
-use std::ffi::CString;
 
 // Vertex data
 static VERTEX_DATA: [GLfloat; 6] = [0.0, 0.5, 0.5, -0.5, -0.5, -0.5];
@@ -169,7 +169,7 @@ fn main() {
         use glutin::{ControlFlow, Event, WindowEvent};
 
         if let Event::WindowEvent { event, .. } = event {
-            if let WindowEvent::Closed = event {
+            if let WindowEvent::CloseRequested = event {
                 return ControlFlow::Break;
             }
         }
diff --git a/gl_generator/Cargo.toml b/gl_generator/Cargo.toml
index 170024d3..4b09d50a 100644
--- a/gl_generator/Cargo.toml
+++ b/gl_generator/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "gl_generator"
-version = "0.9.0"
+version = "0.10.0"
 authors = [
     "Brendan Zabarauskas <bjzaba@yahoo.com.au>",
     "Corey Richardson",
@@ -9,7 +9,7 @@ authors = [
 description = "Code generators for creating bindings to the Khronos OpenGL APIs."
 license = "Apache-2.0"
 documentation = "https://docs.rs/gl_generator"
-homepage = "https://github.com/brendanzab/gl-rs/gl_generator/"
+homepage = "https://github.com/brendanzab/gl-rs/"
 repository = "https://github.com/brendanzab/gl-rs/"
 readme = "README.md"
 categories = ["api-bindings", "rendering::graphics-api"]
@@ -23,6 +23,6 @@ path = "lib.rs"
 unstable_generator_utils = []
 
 [dependencies]
-khronos_api = { version = "2.1.0", path = "../khronos_api" }
-log = "0.4.1"
-xml-rs = "0.8.0"
+khronos_api = { version = "3.0.0", path = "../khronos_api" }
+log = "0.4"
+xml-rs = "0.8"
diff --git a/gl_generator/README.md b/gl_generator/README.md
index ddafa2ca..36d3e707 100644
--- a/gl_generator/README.md
+++ b/gl_generator/README.md
@@ -59,8 +59,8 @@ mod gl {
 fn main() {
     let window = ...;
 
-    // Assuming `window` is GLFW: initialize, and made current
-    gl::load_with(|s| window.get_proc_address(s));
+    // Assuming `window` is GLFW: initialize, and make current
+    gl::load_with(|s| window.get_proc_address(s) as *const _);
 }
 ```
 
diff --git a/gl_generator/generators/debug_struct_gen.rs b/gl_generator/generators/debug_struct_gen.rs
index 1cd4af5c..c8d32903 100644
--- a/gl_generator/generators/debug_struct_gen.rs
+++ b/gl_generator/generators/debug_struct_gen.rs
@@ -213,7 +213,8 @@ where
             name = cmd.proto.ident,
             symbol = super::gen_symbol_name(registry.api, &cmd.proto.ident),
             fallbacks = match registry.aliases.get(&cmd.proto.ident) {
-                Some(fbs) => fbs.iter()
+                Some(fbs) => fbs
+                    .iter()
                     .map(|name| format!("\"{}\"", super::gen_symbol_name(registry.api, &name)))
                     .collect::<Vec<_>>()
                     .join(", "),
@@ -246,8 +247,7 @@ where
                     format!(", \"<callback>\"")
                 } else {
                     format!(", {}", name)
-                })
-                .collect::<Vec<_>>()
+                }).collect::<Vec<_>>()
                 .concat()
         );
 
diff --git a/gl_generator/generators/global_gen.rs b/gl_generator/generators/global_gen.rs
index 11dffc90..ac737fa6 100644
--- a/gl_generator/generators/global_gen.rs
+++ b/gl_generator/generators/global_gen.rs
@@ -213,11 +213,12 @@ where
     for c in &registry.cmds {
         let fallbacks = match registry.aliases.get(&c.proto.ident) {
             Some(v) => {
-                let names = v.iter()
+                let names = v
+                    .iter()
                     .map(|name| format!("\"{}\"", super::gen_symbol_name(registry.api, &name[..])))
                     .collect::<Vec<_>>();
                 format!("&[{}]", names.join(", "))
-            }
+            },
             None => "&[]".to_string(),
         };
         let fnname = &c.proto.ident[..];
diff --git a/gl_generator/generators/mod.rs b/gl_generator/generators/mod.rs
index 843777b1..659d2eca 100644
--- a/gl_generator/generators/mod.rs
+++ b/gl_generator/generators/mod.rs
@@ -12,15 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-use Api;
 use registry::{Cmd, Enum, Registry};
 use std::io;
+use Api;
 
 pub mod debug_struct_gen;
 pub mod global_gen;
 pub mod static_gen;
-pub mod struct_gen;
 pub mod static_struct_gen;
+pub mod struct_gen;
 
 /// Trait for a bindings generator.
 ///
@@ -81,7 +81,7 @@ where
     match api {
         Api::Glx => try!(writeln!(dest, "{}", include_str!("templates/types/glx.rs"))),
         Api::Wgl => try!(writeln!(dest, "{}", include_str!("templates/types/wgl.rs"))),
-        _ => {}
+        _ => {},
     }
 
     Ok(())
diff --git a/gl_generator/generators/struct_gen.rs b/gl_generator/generators/struct_gen.rs
index c6adfdea..a8c03d06 100644
--- a/gl_generator/generators/struct_gen.rs
+++ b/gl_generator/generators/struct_gen.rs
@@ -213,7 +213,8 @@ where
             name = cmd.proto.ident,
             symbol = super::gen_symbol_name(registry.api, &cmd.proto.ident),
             fallbacks = match registry.aliases.get(&cmd.proto.ident) {
-                Some(fbs) => fbs.iter()
+                Some(fbs) => fbs
+                    .iter()
                     .map(|name| format!("\"{}\"", super::gen_symbol_name(registry.api, &name)))
                     .collect::<Vec<_>>()
                     .join(", "),
diff --git a/gl_generator/lib.rs b/gl_generator/lib.rs
index e4958229..ebeb07be 100644
--- a/gl_generator/lib.rs
+++ b/gl_generator/lib.rs
@@ -71,11 +71,11 @@ mod generators;
 
 mod registry;
 
-pub use generators::Generator;
 pub use generators::debug_struct_gen::DebugStructGenerator;
 pub use generators::global_gen::GlobalGenerator;
 pub use generators::static_gen::StaticGenerator;
 pub use generators::static_struct_gen::StaticStructGenerator;
 pub use generators::struct_gen::StructGenerator;
+pub use generators::Generator;
 
 pub use registry::*;
diff --git a/gl_generator/registry/parse.rs b/gl_generator/registry/parse.rs
index 77c74ce5..ea7d8977 100644
--- a/gl_generator/registry/parse.rs
+++ b/gl_generator/registry/parse.rs
@@ -19,11 +19,11 @@ use std::collections::btree_map::Entry;
 use std::collections::{BTreeMap, BTreeSet};
 use std::io;
 use xml::attribute::OwnedAttribute;
-use xml::EventReader as XmlEventReader;
 use xml::reader::XmlEvent;
+use xml::EventReader as XmlEventReader;
 
-use {Api, Fallbacks, Profile};
 use registry::{Binding, Cmd, Enum, GlxOpcode, Registry};
+use {Api, Fallbacks, Profile};
 
 pub fn from_xml<R: io::Read>(src: R, filter: Filter) -> Registry {
     XmlEventReader::new(src)
@@ -75,7 +75,7 @@ impl ParseEvent {
             } => {
                 let attributes = attributes.into_iter().map(Attribute::from).collect();
                 Some(ParseEvent::Start(name.local_name, attributes))
-            }
+            },
             XmlEvent::EndElement { name } => Some(ParseEvent::End(name.local_name)),
             XmlEvent::Characters(chars) => Some(ParseEvent::Text(chars)),
             XmlEvent::ProcessingInstruction { .. } => None,
@@ -86,16 +86,17 @@ impl ParseEvent {
     }
 }
 
-fn api_from_str(src: &str) -> Result<Api, ()> {
+fn api_from_str(src: &str) -> Result<Option<Api>, ()> {
     match src {
-        "gl" => Ok(Api::Gl),
-        "glx" => Ok(Api::Glx),
-        "wgl" => Ok(Api::Wgl),
-        "egl" => Ok(Api::Egl),
-        "glcore" => Ok(Api::GlCore),
-        "gles1" => Ok(Api::Gles1),
-        "gles2" => Ok(Api::Gles2),
-        "glsc2" => Ok(Api::Glsc2),
+        "gl" => Ok(Some(Api::Gl)),
+        "glx" => Ok(Some(Api::Glx)),
+        "wgl" => Ok(Some(Api::Wgl)),
+        "egl" => Ok(Some(Api::Egl)),
+        "glcore" => Ok(Some(Api::GlCore)),
+        "gles1" => Ok(Some(Api::Gles1)),
+        "gles2" => Ok(Some(Api::Gles2)),
+        "glsc2" => Ok(Some(Api::Glsc2)),
+        "disabled" => Ok(None),
         _ => Err(()),
     }
 }
@@ -234,10 +235,10 @@ fn merge_map(a: &mut BTreeMap<String, Vec<String>>, b: BTreeMap<String, Vec<Stri
         match a.entry(k) {
             Entry::Occupied(mut ent) => {
                 ent.get_mut().extend(v);
-            }
+            },
             Entry::Vacant(ent) => {
                 ent.insert(v);
-            }
+            },
         }
     }
 }
@@ -306,25 +307,25 @@ trait Parse: Sized + Iterator<Item = ParseEvent> {
                 // add enum namespace
                 ParseEvent::Start(ref name, _) if name == "enums" => {
                     enums.extend(self.consume_enums(filter.api));
-                }
+                },
 
                 // add command namespace
                 ParseEvent::Start(ref name, _) if name == "commands" => {
                     let (new_cmds, new_aliases) = self.consume_cmds(filter.api);
                     cmds.extend(new_cmds);
                     merge_map(&mut aliases, new_aliases);
-                }
+                },
 
                 ParseEvent::Start(ref name, ref attributes) if name == "feature" => {
                     debug!("Parsing feature: {:?}", attributes);
                     features.push(Feature::convert(&mut self, &attributes));
-                }
+                },
 
                 ParseEvent::Start(ref name, _) if name == "extensions" => loop {
                     match self.next().unwrap() {
                         ParseEvent::Start(ref name, ref attributes) if name == "extension" => {
                             extensions.push(Extension::convert(&mut self, &attributes));
-                        }
+                        },
                         ParseEvent::End(ref name) if name == "extensions" => break,
                         event => panic!("Unexpected message {:?}", event),
                     }
@@ -429,7 +430,7 @@ trait Parse: Sized + Iterator<Item = ParseEvent> {
                 } else {
                     panic!("Expected <{}>, found: <{}>", expected_name, name)
                 }
-            }
+            },
             event => panic!("Expected <{}>, found: {:?}", expected_name, event),
         }
     }
@@ -445,7 +446,7 @@ trait Parse: Sized + Iterator<Item = ParseEvent> {
         loop {
             match self.next().unwrap() {
                 ParseEvent::End(ref name) if expected_name == name => break,
-                _ => {}
+                _ => {},
             }
         }
     }
@@ -482,7 +483,7 @@ trait Parse: Sized + Iterator<Item = ParseEvent> {
                     } else {
                         panic!("Unexpected element: <{:?} {:?}>", n, &attributes);
                     }
-                }
+                },
                 ParseEvent::End(ref name) => {
                     debug!("Found end element </{:?}>", name);
 
@@ -499,7 +500,7 @@ trait Parse: Sized + Iterator<Item = ParseEvent> {
                     } else {
                         panic!("Unexpected end element {:?}", name);
                     }
-                }
+                },
                 event => panic!("Unexpected message {:?}", event),
             }
         }
@@ -510,13 +511,13 @@ trait Parse: Sized + Iterator<Item = ParseEvent> {
         loop {
             match self.next().unwrap() {
                 // ignores
-                ParseEvent::Text(_) => {}
+                ParseEvent::Text(_) => {},
                 ParseEvent::Start(ref name, _) if name == "unused" => self.skip_to_end("unused"),
 
                 // add enum definition
                 ParseEvent::Start(ref name, ref attributes) if name == "enum" => {
                     enums.push(self.consume_enum(api, attributes));
-                }
+                },
 
                 // finished building the namespace
                 ParseEvent::End(ref name) if name == "enums" => break,
@@ -552,14 +553,14 @@ trait Parse: Sized + Iterator<Item = ParseEvent> {
                         match aliases.entry(v.clone()) {
                             Entry::Occupied(mut ent) => {
                                 ent.get_mut().push(new.proto.ident.clone());
-                            }
+                            },
                             Entry::Vacant(ent) => {
                                 ent.insert(vec![new.proto.ident.clone()]);
-                            }
+                            },
                         }
                     }
                     cmds.push(new);
-                }
+                },
                 // finished building the namespace
                 ParseEvent::End(ref name) if name == "commands" => break,
                 // error handling
@@ -583,23 +584,23 @@ trait Parse: Sized + Iterator<Item = ParseEvent> {
             match self.next().unwrap() {
                 ParseEvent::Start(ref name, _) if name == "param" => {
                     params.push(self.consume_binding("param"));
-                }
+                },
                 ParseEvent::Start(ref name, ref attributes) if name == "alias" => {
                     alias = get_attribute(&attributes, "name");
                     alias = alias.map(|t| trim_cmd_prefix(&t, api).to_string());
                     self.consume_end_element("alias");
-                }
+                },
                 ParseEvent::Start(ref name, ref attributes) if name == "vecequiv" => {
                     vecequiv = get_attribute(&attributes, "vecequiv");
                     self.consume_end_element("vecequiv");
-                }
+                },
                 ParseEvent::Start(ref name, ref attributes) if name == "glx" => {
                     glx = Some(GlxOpcode {
                         opcode: get_attribute(&attributes, "opcode").unwrap(),
                         name: get_attribute(&attributes, "name"),
                     });
                     self.consume_end_element("glx");
-                }
+                },
                 ParseEvent::End(ref name) if name == "command" => break,
                 event => panic!("Expected </command>, found: {:?}", event),
             }
@@ -647,11 +648,7 @@ trait Parse: Sized + Iterator<Item = ParseEvent> {
     }
 }
 
-impl<T> Parse for T
-where
-    T: Sized + Iterator<Item = ParseEvent>,
-{
-}
+impl<T> Parse for T where T: Sized + Iterator<Item = ParseEvent> {}
 
 fn get_attribute(attribs: &[Attribute], key: &str) -> Option<String> {
     attribs
@@ -694,7 +691,7 @@ impl FromXml for Feature {
     fn convert<P: Parse>(parser: &mut P, a: &[Attribute]) -> Feature {
         debug!("Doing a FromXml on Feature");
         let api = get_attribute(a, "api").unwrap();
-        let api = api_from_str(&api).unwrap();
+        let api = api_from_str(&api).unwrap().unwrap();
         let name = get_attribute(a, "name").unwrap();
         let number = get_attribute(a, "number").unwrap();
 
@@ -719,15 +716,16 @@ impl FromXml for Extension {
         let supported = get_attribute(a, "supported")
             .unwrap()
             .split('|')
-            .map(api_from_str)
-            .map(Result::unwrap)
+            .filter_map(|api| {
+                api_from_str(api).unwrap_or_else(|()| panic!("unsupported API `{}`", api))
+            })
             .collect::<Vec<_>>();
         let mut require = Vec::new();
         loop {
             match parser.next().unwrap() {
                 ParseEvent::Start(ref name, ref attributes) if name == "require" => {
                     require.push(FromXml::convert(parser, &attributes));
-                }
+                },
                 ParseEvent::End(ref name) if name == "extension" => break,
                 event => panic!("Unexpected message {:?}", event),
             }
@@ -819,6 +817,7 @@ pub fn to_rust_ty<T: AsRef<str>>(ty: T) -> Cow<'static, str> {
         "const GLfloat *" => "*const types::GLfloat",
         "const GLhalfNV *" => "*const types::GLhalfNV",
         "const GLint *" => "*const types::GLint",
+        "const GLint*" => "*const types::GLint",
         "const GLint64 *" => "*const types::GLint64",
         "const GLint64EXT *" => "*const types::GLint64EXT",
         "const GLintptr *" => "*const types::GLintptr",
@@ -996,7 +995,7 @@ pub fn to_rust_ty<T: AsRef<str>>(ty: T) -> Cow<'static, str> {
         "EGLClientBuffer" => "types::EGLClientBuffer",
         "__eglMustCastToProperFunctionPointerType" => {
             "types::__eglMustCastToProperFunctionPointerType"
-        }
+        },
         "EGLImageKHR" => "types::EGLImageKHR",
         "EGLImage" => "types::EGLImage",
         "EGLOutputLayerEXT" => "types::EGLOutputLayerEXT",
@@ -1027,6 +1026,7 @@ pub fn to_rust_ty<T: AsRef<str>>(ty: T) -> Cow<'static, str> {
         "EGLTimeKHR *" => "*mut types::EGLTimeKHR",
         "EGLOutputPortEXT *" => "*mut types::EGLOutputPortEXT",
         "EGLuint64KHR *" => "*mut types::EGLuint64KHR",
+        "const struct AHardwareBuffer *" => "*const __gl_imports::raw::c_void", // humm
 
         "GLeglClientBufferEXT" => "types::GLeglClientBufferEXT",
         "GLVULKANPROCNV" => "types::GLVULKANPROCNV",
diff --git a/khronos_api/Cargo.toml b/khronos_api/Cargo.toml
index e60120a7..b92eecf1 100644
--- a/khronos_api/Cargo.toml
+++ b/khronos_api/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "khronos_api"
-version = "2.2.0"
+version = "3.0.0"
 authors = [
   "Brendan Zabarauskas <bjzaba@yahoo.com.au>",
   "Corey Richardson",
@@ -10,7 +10,7 @@ authors = [
 description = "The Khronos XML API Registry, exposed as byte string constants."
 license = "Apache-2.0"
 documentation = "https://docs.rs/khronos_api"
-homepage = "https://github.com/brendanzab/gl-rs/khronos_api/"
+homepage = "https://github.com/brendanzab/gl-rs/"
 repository = "https://github.com/brendanzab/gl-rs/"
 readme = "README.md"
 
diff --git a/khronos_api/api b/khronos_api/api
index 73d104ff..85d924a5 160000
--- a/khronos_api/api
+++ b/khronos_api/api
@@ -1,1 +1,1 @@
-Subproject commit 73d104ffe2931585ba24ddc4a943d4daf57deff4
+Subproject commit 85d924a5165e7206f4c73c8c10307658dc2bbe10
diff --git a/khronos_api/api_egl b/khronos_api/api_egl
index d6b5e1e9..b6b558e7 160000
--- a/khronos_api/api_egl
+++ b/khronos_api/api_egl
@@ -1,1 +1,1 @@
-Subproject commit d6b5e1e9ee0c4f3911b31c347e7e66eecb0c46b5
+Subproject commit b6b558e7042d67fc7543383bb0e13a075f21d8ab
diff --git a/khronos_api/api_webgl b/khronos_api/api_webgl
index 4181ad31..c987f075 160000
--- a/khronos_api/api_webgl
+++ b/khronos_api/api_webgl
@@ -1,1 +1,1 @@
-Subproject commit 4181ad31b5ce4f40dee512eb764b61d7bb6131ae
+Subproject commit c987f075bfdca44119175c41f547d849c08983a3
diff --git a/khronos_api/build.rs b/khronos_api/build.rs
index 757bd739..54fbe012 100644
--- a/khronos_api/build.rs
+++ b/khronos_api/build.rs
@@ -17,8 +17,8 @@
 // containing the XML specifications for all of them.
 use std::env;
 use std::fs::File;
-use std::path::*;
 use std::io::Write;
+use std::path::*;
 
 fn main() {
     // Create and open a file in the output directory to contain our generated rust code
diff --git a/rustfmt.toml b/rustfmt.toml
new file mode 100644
index 00000000..cf11cbaa
--- /dev/null
+++ b/rustfmt.toml
@@ -0,0 +1,2 @@
+unstable_features = true
+match_block_trailing_comma = true
diff --git a/webgl_generator/Cargo.toml b/webgl_generator/Cargo.toml
index 34f8de54..39ce797d 100644
--- a/webgl_generator/Cargo.toml
+++ b/webgl_generator/Cargo.toml
@@ -1,13 +1,13 @@
 [package]
 name = "webgl_generator"
-version = "0.1.0"
+version = "0.2.0"
 authors = [
     "Diggory Blake",
 ]
 description = "Code generators for creating bindings to the WebGL APIs."
 license = "Apache-2.0"
 documentation = "https://docs.rs/webgl_generator"
-homepage = "https://github.com/brendanzab/gl-rs/webgl_generator/"
+homepage = "https://github.com/brendanzab/gl-rs/"
 repository = "https://github.com/brendanzab/gl-rs/"
 readme = "README.md"
 categories = ["api-bindings", "rendering::graphics-api"]
@@ -18,9 +18,9 @@ name = "webgl_generator"
 path = "lib.rs"
 
 [dependencies]
-khronos_api = { version = "2.2.0", path = "../khronos_api" }
-webidl = { version = "0.4.1" }
-heck = { version = "0.3.0" }
-RustyXML = "0.1.1"
-html2runes = "1.0.0"
-regex = "1.0.5"
+khronos_api = { version = "3.0.0", path = "../khronos_api" }
+webidl = { version = "0.8" }
+heck = { version = "0.3" }
+RustyXML = "0.1"
+html2runes = "1.0"
+regex = "1.0"
diff --git a/webgl_generator/lib.rs b/webgl_generator/lib.rs
index 17069ea2..e2fc67f7 100644
--- a/webgl_generator/lib.rs
+++ b/webgl_generator/lib.rs
@@ -27,7 +27,7 @@ mod utils;
 mod webgl_generators;
 mod webgl_registry;
 
-pub use webgl_generators::Generator;
 pub use webgl_generators::stdweb_gen::StdwebGenerator;
+pub use webgl_generators::Generator;
 
 pub use webgl_registry::*;
diff --git a/webgl_generator/utils.rs b/webgl_generator/utils.rs
index e7a42f9a..1670510a 100644
--- a/webgl_generator/utils.rs
+++ b/webgl_generator/utils.rs
@@ -26,8 +26,8 @@ pub fn multimap_append<K: Ord + Clone, V: PartialEq>(
 /// Best-effort attempt to render HTML into a doc-comment which can
 /// be placed in the generated code.
 pub fn convert_html_to_doc_comment(html: &str) -> String {
-    use regex::RegexBuilder;
     use html2runes;
+    use regex::RegexBuilder;
 
     // Create doc comments
     let doc_comment_regex = RegexBuilder::new("^").multi_line(true).build().unwrap();
@@ -80,6 +80,5 @@ pub fn camel(name: &str) -> String {
 pub fn parse_defs(src: &[u8]) -> Vec<ast::Definition> {
     let src = str::from_utf8(src).expect("IDL contained invalid UTF-8");
 
-    let parser = webidl::Parser::new();
-    parser.parse_string(src).expect("Failed to parse IDL")
+    webidl::parse_string(src).expect("Failed to parse IDL")
 }
diff --git a/webgl_generator/webgl_generators/stdweb_gen.rs b/webgl_generator/webgl_generators/stdweb_gen.rs
index 773f21ea..c3368985 100644
--- a/webgl_generator/webgl_generators/stdweb_gen.rs
+++ b/webgl_generator/webgl_generators/stdweb_gen.rs
@@ -12,8 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-use std::io;
 use std::collections::BTreeSet;
+use std::io;
 
 use utils::*;
 use webgl_registry::*;
@@ -81,10 +81,12 @@ impl ArgWrapper {
         match self {
             &ArgWrapper::None => arg.into(),
             &ArgWrapper::AsTypedArray => format!("unsafe {{ {}.as_typed_array() }}", arg),
-            &ArgWrapper::AsArrayBufferView => format!("unsafe {{ {}.as_array_buffer_view() }}", arg),
+            &ArgWrapper::AsArrayBufferView => {
+                format!("unsafe {{ {}.as_array_buffer_view() }}", arg)
+            },
             &ArgWrapper::Optional(ref inner) => {
                 format!("{}.map(|inner| {})", arg, inner.wrap("inner"))
-            }
+            },
             &ArgWrapper::Sequence(ref inner) => format!(
                 "{}.iter().map(|inner| {}).collect::<Vec<_>>()",
                 arg,
@@ -167,9 +169,10 @@ fn process_arg_type_kind(
                 },
                 optional: false,
             }
-        }
+        },
         &TypeKind::Union(ref ts) => {
-            let t = ts.iter()
+            let t = ts
+                .iter()
                 .filter_map(|t| match t.kind {
                     TypeKind::TypedArray(_) => Some(t),
                     TypeKind::Sequence(_) => None,
@@ -179,19 +182,19 @@ fn process_arg_type_kind(
                 .expect("Union did not contain a TypedArray");
 
             process_arg_type(t, registry, gc)
-        }
+        },
         &TypeKind::Named(ref actual_name) => {
             match registry.resolve_type(actual_name) {
                 &NamedType::Dictionary(_) | &NamedType::Interface(_) => {
                     ProcessedArg::simple(format!("&{}", name.unwrap()))
-                }
+                },
                 &NamedType::Enum(_) => ProcessedArg::simple(name.unwrap()),
                 &NamedType::Typedef(ref t) => {
                     // We have to "look through" the typedef, as the correct parameter
                     // type is not representable using the alias.
                     assert!(t.optional);
                     process_arg_type(t, registry, gc)
-                }
+                },
                 &NamedType::Callback(_) => {
                     let gp = gc.arg("F");
                     gc.constrain(format!("{}: FnOnce() + 'static", gp));
@@ -200,15 +203,15 @@ fn process_arg_type_kind(
                         wrapper: ArgWrapper::Once,
                         optional: false,
                     }
-                }
+                },
                 &NamedType::Mixin(_) => panic!("Mixins are not usable as types!"),
             }
-        }
+        },
         &TypeKind::Any | &TypeKind::Object => {
             let gp = gc.arg("T");
             gc.constrain(format!("{}: JsSerialize", gp));
             ProcessedArg::simple(gp)
-        }
+        },
     }
 }
 
@@ -263,18 +266,19 @@ fn process_result_type_kind(type_kind: &TypeKind, registry: &Registry) -> Proces
         &TypeKind::String => ProcessedResult::simple("String"),
         &TypeKind::ArrayBuffer | &TypeKind::ArrayBufferView => {
             ProcessedResult::simple("ArrayBuffer")
-        }
+        },
         &TypeKind::BufferSource => unimplemented!("BufferSource not supported in output"),
         &TypeKind::CanvasElement => ProcessedResult::simple("CanvasElement"),
         &TypeKind::TypedArray(ref p) => {
             ProcessedResult::simple(format!("TypedArray<{}>", p.name()))
-        }
+        },
         &TypeKind::Sequence(ref t) => {
             let inner = process_result_type(t, registry);
             ProcessedResult::simple(format!("Vec<{}>", inner.type_))
-        }
+        },
         &TypeKind::Union(ref ts) => {
-            let t = ts.iter()
+            let t = ts
+                .iter()
                 .filter_map(|t| match t.kind {
                     TypeKind::TypedArray(_) => Some(t),
                     TypeKind::Sequence(_) => None,
@@ -284,11 +288,11 @@ fn process_result_type_kind(type_kind: &TypeKind, registry: &Registry) -> Proces
                 .expect("Union did not contain a TypedArray");
 
             process_result_type(t, registry)
-        }
+        },
         &TypeKind::Named(ref name) => match registry.resolve_type(name) {
             &NamedType::Dictionary(_) | &NamedType::Interface(_) | &NamedType::Enum(_) => {
                 ProcessedResult::simple(name.as_str())
-            }
+            },
             &NamedType::Typedef(ref t) => {
                 let inner = process_result_type(t, registry);
                 ProcessedResult {
@@ -296,7 +300,7 @@ fn process_result_type_kind(type_kind: &TypeKind, registry: &Registry) -> Proces
                     wrapper: inner.wrapper.clone(),
                     optional: inner.optional,
                 }
-            }
+            },
             &NamedType::Callback(_) => unimplemented!(),
             &NamedType::Mixin(_) => panic!("Mixins are not usable as types!"),
         },
@@ -324,7 +328,7 @@ where
 // {registry:?}
 extern crate stdweb;
 
-use self::stdweb::{{Reference, Value, UnsafeTypedArray, Once, JsSerialize, InstanceOf}};
+use self::stdweb::{{Reference, Value, UnsafeTypedArray, JsSerialize, InstanceOf}};
 use self::stdweb::unstable::{{TryFrom, TryInto}};
 use self::stdweb::web::{{RenderingContext, TypedArray, ArrayBuffer}};
 use self::stdweb::web::html_element::CanvasElement;
@@ -383,7 +387,7 @@ define_array!(i32);
 define_array!(u32);
 define_array!(f32);
 define_array!(f64);
-    "#,
+"#,
         registry = registry
     )?;
     Ok(())
@@ -581,12 +585,16 @@ where
 
     let mut attrs = String::new();
     let custom_instance_check = if name == "GLContext" {
-        Some("[WebGLRenderingContext, WebGL2RenderingContext].includes( @{{reference}}.constructor )".into())
+        Some((
+            "reference",
+            "[WebGLRenderingContext, WebGL2RenderingContext].includes(@{{reference}}.constructor)"
+                .into(),
+        ))
     } else if interface.has_class {
         attrs += &format!("#[reference(instance_of = {:?})]\n", name);
         None
     } else {
-        Some("true".to_owned())
+        Some(("_reference", "true".to_owned()))
     };
 
     write!(
@@ -596,7 +604,7 @@ where
 {attrs}pub struct {name}(Reference);
 
 impl {name} {{
-    "#,
+"#,
         name = name,
         attrs = attrs,
         doc_comment = interface.doc_comment
@@ -608,14 +616,14 @@ impl {name} {{
                 &Member::Const(ref const_) => {
                     assert!(index == 0);
                     write_const(&name, const_, registry, dest)?;
-                }
+                },
                 &Member::Attribute(ref attribute) => {
                     assert!(index == 0);
                     write_attribute(&name, attribute, registry, dest)?;
-                }
+                },
                 &Member::Operation(ref operation) => {
                     write_operation(&name, index, operation, registry, dest)?;
-                }
+                },
             }
         }
     }
@@ -624,22 +632,23 @@ impl {name} {{
         dest,
         r#"
 }}
-    "#
+"#
     )?;
 
-    if let Some(instance_check) = custom_instance_check {
+    if let Some((param_name, instance_check)) = custom_instance_check {
         write!(
             dest,
             r#"
 impl InstanceOf for {name} {{
     #[inline]
-    fn instance_of( reference: &Reference ) -> bool {{
+    fn instance_of({param_name}: &Reference) -> bool {{
         js!(
             return {instance_check};
         ).try_into().unwrap()
     }}
 }}
-        "#,
+"#,
+            param_name = param_name,
             name = name,
             instance_check = instance_check
         )?;
@@ -656,7 +665,7 @@ impl InstanceOf for {name} {{
         ).try_into()
     }}
 }}
-        "#,
+"#,
             name = name,
             rendering_context = rendering_context
         )?;
@@ -756,7 +765,7 @@ where
 {
     match name {
         "getExtension" => return write_get_extension(dest),
-        _ => {}
+        _ => {},
     }
 
     let mut rust_name = unreserve(snake(name));
@@ -785,11 +794,13 @@ where
         })
         .collect();
 
-    let rust_args = args.iter()
+    let rust_args = args
+        .iter()
         .map(|a| a.arg.clone())
         .collect::<Vec<_>>()
         .join(", ");
-    let js_args = args.iter()
+    let js_args = args
+        .iter()
         .map(|a| a.js_arg.clone())
         .collect::<Vec<_>>()
         .join(", ");
diff --git a/webgl_generator/webgl_registry/mod.rs b/webgl_generator/webgl_registry/mod.rs
index 9884394f..01f0a1b0 100644
--- a/webgl_generator/webgl_registry/mod.rs
+++ b/webgl_generator/webgl_registry/mod.rs
@@ -12,20 +12,20 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-use std::{fmt, str};
 use std::collections::BTreeMap;
+use std::{fmt, str};
 
 use khronos_api;
 
 use utils::convert_html_to_doc_comment;
 
-pub use self::types::*;
 pub use self::named::*;
 pub use self::registry::*;
+pub use self::types::*;
 
-mod types;
 mod named;
 mod registry;
+mod types;
 
 const HIDDEN_NAMES: &'static [&'static str] = &["WebGLObject", "WebGLContextEventInit"];
 const RENDERING_CONTEXTS: &'static [(&'static str, &'static str)] = &[
@@ -95,8 +95,8 @@ impl<'a> Exts<'a> {
                 min_api: match api_dep.get_attribute("version", None).unwrap() {
                     "1.0" => Api::WebGl,
                     "2.0" => Api::WebGl2,
-                    other => panic!("Unknown API version: {}", other)
-                }
+                    other => panic!("Unknown API version: {}", other),
+                },
             };
 
             if match self {
diff --git a/webgl_generator/webgl_registry/named.rs b/webgl_generator/webgl_registry/named.rs
index af116979..2cf42887 100644
--- a/webgl_generator/webgl_registry/named.rs
+++ b/webgl_generator/webgl_registry/named.rs
@@ -14,8 +14,8 @@
 
 use std::collections::{BTreeMap, BTreeSet};
 
-use utils::{multimap_append, multimap_insert};
 use super::{Registry, Type};
+use utils::{multimap_append, multimap_insert};
 
 #[derive(Debug, Clone)]
 pub enum NamedType {
diff --git a/webgl_generator/webgl_registry/registry.rs b/webgl_generator/webgl_registry/registry.rs
index 5fc94c06..3c37782f 100644
--- a/webgl_generator/webgl_registry/registry.rs
+++ b/webgl_generator/webgl_registry/registry.rs
@@ -12,18 +12,20 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-use std::io;
-use std::collections::{BTreeMap, BTreeSet};
 use std::collections::btree_map::{self, Entry};
+use std::collections::{BTreeMap, BTreeSet};
+use std::io;
 
 use webidl::ast;
 
 use utils::{multimap_insert, parse_defs};
 use webgl_generators::Generator;
 
+use super::named::{
+    Argument, Attribute, Callback, Const, Dictionary, Enum, Field, Interface, Member, Mixin,
+    NamedType, Operation,
+};
 use super::types::{Primitive, Type, TypeKind};
-use super::named::{Argument, Attribute, Callback, Const, Dictionary, Enum, Field, Interface,
-                   Member, Mixin, NamedType, Operation};
 use super::{Api, Exts, HIDDEN_NAMES, RENDERING_CONTEXTS};
 
 #[derive(Debug, Default)]
@@ -189,7 +191,8 @@ impl Registry {
                 value: match const_.value {
                     ConstValue::BooleanLiteral(b) => format!("{:?}", b),
                     ConstValue::FloatLiteral(v) => format!("{:?}", v),
-                    ConstValue::IntegerLiteral(v) => format!("{:?}", v),
+                    ConstValue::SignedIntegerLiteral(v) => format!("{:?}", v),
+                    ConstValue::UnsignedIntegerLiteral(v) => format!("{:?}", v),
                     ConstValue::Null => "None".into(),
                 },
             }),
@@ -209,7 +212,7 @@ impl Registry {
                         getter: !a.inherits,
                     }),
                 ))
-            }
+            },
             _ => None,
         }
     }
@@ -228,23 +231,26 @@ impl Registry {
         use self::ast::Operation::*;
         use self::ast::ReturnType;
         match operation {
-            Regular(o) => if let Some(name) = o.name {
-                Some((
-                    name,
-                    Member::Operation(Operation {
-                        args: o.arguments
-                            .into_iter()
-                            .map(|a| self.load_argument(a))
-                            .collect(),
-                        return_type: match o.return_type {
-                            ReturnType::NonVoid(t) => Some(self.load_type(*t)),
-                            ReturnType::Void => None,
-                        },
-                        doc_comment: String::new(),
-                    }),
-                ))
-            } else {
-                None
+            Regular(o) => {
+                if let Some(name) = o.name {
+                    Some((
+                        name,
+                        Member::Operation(Operation {
+                            args: o
+                                .arguments
+                                .into_iter()
+                                .map(|a| self.load_argument(a))
+                                .collect(),
+                            return_type: match o.return_type {
+                                ReturnType::NonVoid(t) => Some(self.load_type(*t)),
+                                ReturnType::Void => None,
+                            },
+                            doc_comment: String::new(),
+                        }),
+                    ))
+                } else {
+                    None
+                }
             },
             _ => None,
         }
@@ -324,19 +330,20 @@ impl Registry {
         match self.types.entry(interface.name) {
             Entry::Vacant(v) => {
                 v.insert(NamedType::Interface(result));
-            }
+            },
             Entry::Occupied(o) => {
                 assert!(
                     result.members.is_empty(),
                     "Duplicate interface: {}",
                     o.key()
                 );
-            }
+            },
         }
     }
 
     fn load_includes(&mut self, includes: ast::Includes) {
-        if let Some(interface) = self.types
+        if let Some(interface) = self
+            .types
             .get_mut(&includes.includer)
             .and_then(NamedType::as_interface_mut)
         {
@@ -408,7 +415,7 @@ impl Registry {
                 } else {
                     TypeKind::Any
                 }
-            }
+            },
 
             // Misc
             ArrayBuffer => TypeKind::ArrayBuffer,
@@ -450,7 +457,7 @@ impl Registry {
                     fields,
                     is_hidden: false,
                 }));
-            }
+            },
             Entry::Occupied(mut o) => {
                 let key = o.key().clone();
                 let d = o.get_mut().as_dictionary_mut().unwrap();
@@ -461,7 +468,7 @@ impl Registry {
                         panic!("Duplicate field: {}.{}", key, k);
                     }
                 }
-            }
+            },
         }
     }
 
@@ -497,7 +504,7 @@ impl Registry {
             Dictionary(ast::Dictionary::NonPartial(d)) => self.load_dictionary(d),
             Enum(e) => self.load_enum(e),
             Callback(c) => self.load_callback(c),
-            _ => {}
+            _ => {},
         }
     }
 }
diff --git a/webgl_generator/webgl_registry/types.rs b/webgl_generator/webgl_registry/types.rs
index e6d1c08e..e73b5e99 100644
--- a/webgl_generator/webgl_registry/types.rs
+++ b/webgl_generator/webgl_registry/types.rs
@@ -120,7 +120,7 @@ impl TypeKind {
                     }
                 }
                 (Some(s.as_str()), self)
-            }
+            },
             _ => (None, self),
         }
     }
diff --git a/webgl_stdweb/Cargo.toml b/webgl_stdweb/Cargo.toml
index 7ed86aed..4ffe4425 100644
--- a/webgl_stdweb/Cargo.toml
+++ b/webgl_stdweb/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "webgl_stdweb"
-version = "0.2.0"
+version = "0.3.0"
 authors = [
     "Diggory Blake",
 ]
@@ -8,17 +8,17 @@ description = "WebGL bindings (stdweb)"
 license = "Apache-2.0"
 build = "build.rs"
 documentation = "https://docs.rs/webgl_stdweb"
-homepage = "https://github.com/brendanzab/gl-rs/webgl/"
+homepage = "https://github.com/brendanzab/gl-rs/"
 repository = "https://github.com/brendanzab/gl-rs/"
 readme = "README.md"
 categories = ["api-bindings", "rendering::graphics-api"]
 keywords = ["webgl", "stdweb"]
 
 [build-dependencies]
-webgl_generator = { version = "0.1.0", path = "../webgl_generator" }
+webgl_generator = { version = "0.2.0", path = "../webgl_generator" }
 
 [dependencies]
-stdweb-derive = "0.5.0"
-stdweb = "0.4.0"
-serde = "1.0.0"
-serde_derive = "1.0.0"
+stdweb-derive = "0.5"
+stdweb = "0.4"
+serde = "1.0"
+serde_derive = "1.0"
diff --git a/webgl_stdweb/build.rs b/webgl_stdweb/build.rs
index 12fd1785..3c877c0e 100644
--- a/webgl_stdweb/build.rs
+++ b/webgl_stdweb/build.rs
@@ -14,10 +14,10 @@
 
 extern crate webgl_generator;
 
-use webgl_generator::*;
 use std::env;
 use std::fs::File;
 use std::path::*;
+use webgl_generator::*;
 
 fn main() {
     let dest = env::var("OUT_DIR").unwrap();


Test patch:
diff --git a/tests/test_gen_symbols/build.rs b/tests/test_gen_symbols/build.rs
index c8cc74cc..26338a1e 100644
--- a/tests/test_gen_symbols/build.rs
+++ b/tests/test_gen_symbols/build.rs
@@ -30,12 +30,24 @@ fn main() {
         .unwrap();
     writeln!(&mut file, "}}").unwrap();
 
-    writeln!(&mut file, "mod gles {{").unwrap();
+    writeln!(&mut file, "mod gles1 {{").unwrap();
+    Registry::new(Api::Gles1, (1, 1), Profile::Core, Fallbacks::All, [])
+        .write_bindings(GlobalGenerator, &mut file)
+        .unwrap();
+    writeln!(&mut file, "}}").unwrap();
+
+    writeln!(&mut file, "mod gles2 {{").unwrap();
     Registry::new(Api::Gles2, (3, 1), Profile::Core, Fallbacks::All, [])
         .write_bindings(GlobalGenerator, &mut file)
         .unwrap();
     writeln!(&mut file, "}}").unwrap();
 
+    writeln!(&mut file, "mod glsc2 {{").unwrap();
+    Registry::new(Api::Glsc2, (3, 1), Profile::Core, Fallbacks::All, [])
+        .write_bindings(GlobalGenerator, &mut file)
+        .unwrap();
+    writeln!(&mut file, "}}").unwrap();
+
     writeln!(&mut file, "mod glx {{").unwrap();
     Registry::new(Api::Glx, (1, 4), Profile::Core, Fallbacks::All, [])
         .write_bindings(GlobalGenerator, &mut file)
diff --git a/tests/test_gen_symbols/lib.rs b/tests/test_gen_symbols/lib.rs
index 34566f86..6e47930d 100644
--- a/tests/test_gen_symbols/lib.rs
+++ b/tests/test_gen_symbols/lib.rs
@@ -32,11 +32,23 @@ pub fn compile_test_gl() {
     }
 }
 
-pub fn compile_test_gles() {
+pub fn compile_test_gles1() {
     unsafe {
-        gles::Clear(gles::COLOR_BUFFER_BIT);
-        let _: raw::c_uint = gles::CreateProgram();
-        gles::CompileShader(5);
+        gles1::Clear(gles1::COLOR_BUFFER_BIT);
+    }
+}
+
+pub fn compile_test_gles2() {
+    unsafe {
+        gles2::Clear(gles2::COLOR_BUFFER_BIT);
+        let _: raw::c_uint = gles2::CreateProgram();
+        gles2::CompileShader(5);
+    }
+}
+
+pub fn compile_test_glsc2() {
+    unsafe {
+        glsc2::Clear(glsc2::COLOR_BUFFER_BIT);
     }
 }
 
diff --git a/tests/test_no_warnings/build.rs b/tests/test_no_warnings/build.rs
index ffe77e10..c8ddd7c8 100644
--- a/tests/test_no_warnings/build.rs
+++ b/tests/test_no_warnings/build.rs
@@ -220,7 +220,8 @@ fn main() {
         &mut file,
         "mod egl_static_struct {{ {}",
         build_egl_symbols()
-    ).unwrap();
+    )
+    .unwrap();
     egl_registry
         .write_bindings(StaticStructGenerator, &mut file)
         .unwrap();
diff --git a/tests/test_webgl_stdweb/build.rs b/tests/test_webgl_stdweb/build.rs
index 714561f0..472ed332 100644
--- a/tests/test_webgl_stdweb/build.rs
+++ b/tests/test_webgl_stdweb/build.rs
@@ -14,10 +14,10 @@
 
 extern crate webgl_generator;
 
-use webgl_generator::*;
 use std::env;
 use std::fs::File;
 use std::path::*;
+use webgl_generator::*;
 
 fn main() {
     let dest = env::var("OUT_DIR").unwrap();