+static void read_int(const char **line, int *ptr)
I think "ptr" is a bit of an awkward name for this. Likewise for read_uint().
+static void read_int4(const char **line, int (*v)[4])
The "natural" type for "v" would seem struct ivec4. I imagine the choice of passing an array was largely dictated by the set_uniforms() interface, but perhaps it shouldn't be? Likewise for read_uint4().