blob: 39788fccadecacbc2ccf7e3001bff0bddedf6686 [file] [edit]
/*
* GPAC - Multimedia Framework C SDK
*
* Authors: Cyril Concolato
* Copyright (c) Telecom ParisTech 2004-2012
* All rights reserved
*
* This file is part of GPAC / SVG Scene Graph Generator sub-project
*
* GPAC 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 2, or (at your option)
* any later version.
*
* GPAC 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 this library; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <gpac/tools.h>
#include <gpac/list.h>
static void start_ctx(char *ctx_name, FILE **ifce_c, FILE **fun_c)
{
char szFile[GF_MAX_PATH];
sprintf(szFile, "../../../src/jsmods/%s.c", ctx_name);
FILE *res = gf_fopen(szFile, "wt");
*ifce_c = res;
*fun_c = gf_file_temp(NULL);
fprintf(res, "/* !! AUTOGENERATED FILE - DO NOT MODIFY !! \n");
fprintf(res, "\n%s implementation for QJS\n*/\n\n", ctx_name);
}
static void end_ctx(FILE *ifce_c, FILE *func_c, char *ctx_name)
{
fprintf(ifce_c, "static const JSCFunctionListEntry %s_funcs[] =\n\{\n", ctx_name);
gf_fseek(func_c, 0, SEEK_SET);
while (!feof(func_c)) {
char szLine[4001];
szLine[0] = 0;
gf_fgets(szLine, 4000, func_c);
gf_fputs(szLine, ifce_c);
}
gf_fclose(func_c);
fprintf(ifce_c, "};\n");
gf_fclose(ifce_c);
gf_free(ctx_name);
}
static void put_const(FILE *fun_defs, char *c_name, char *c_val)
{
fprintf(fun_defs, "\tJS_PROP_INT32_DEF(\"%s\", %s, JS_PROP_CONFIGURABLE),\n", c_name, c_val);
}
static void put_fun(FILE *fun_defs, char *f_name)
{
fprintf(fun_defs, "\tJS_CFUNC_DEF(\"%s\", 0, wgl_%s),\n", f_name, f_name);
}
static void put_prop(FILE *fun_defs, char *ctx_name, char *pname, Bool is_readonly)
{
if (is_readonly) {
fprintf(fun_defs, "\tJS_CGETSET_MAGIC_DEF(\"%s\", %s_getProperty, NULL, %s_PROP_%s),\n", pname, ctx_name, ctx_name, pname);
} else {
fprintf(fun_defs, "\tJS_CGETSET_MAGIC_DEF(\"%s\", %s_getProperty, %s_setProperty, %s_PROP_%s),\n", pname, ctx_name, ctx_name, ctx_name, pname);
}
}
static const char *get_arg_type(char *arg_type, Bool *is_array)
{
*is_array = GF_FALSE;
if (!strcmp(arg_type, "GLenum")) return "u32";
if (!strcmp(arg_type, "DOMString")) return "const char *";
if (!strcmp(arg_type, "DOMString?")) return "const char *";
if (!strcmp(arg_type, "GLuint")) return "u32";
if (!strcmp(arg_type, "GLint")) return "s32";
if (!strcmp(arg_type, "GLuint")) return "u32";
if (!strcmp(arg_type, "GLclampf")) return "Float";
if (!strcmp(arg_type, "GLfloat")) return "Float";
if (!strcmp(arg_type, "GLboolean")) return "Bool";
if (!strcmp(arg_type, "boolean")) return "Bool";
if (!strcmp(arg_type, "GLsizei")) return "u32";
if (!strcmp(arg_type, "GLbitfield")) return "u32";
if (!strcmp(arg_type, "GLshort")) return "s16";
if (!strcmp(arg_type, "GLushort")) return "u16";
if (!strcmp(arg_type, "GLsizeiptr")) return "u64";
if (!strcmp(arg_type, "GLintptr")) return "u64";
if (!strcmp(arg_type, "GLbyte")) return "s8";
if (!strcmp(arg_type, "GLubyte")) return "u8";
if (!strcmp(arg_type, "WebGLProgram?")) return "WebGLProgram";
if (!strcmp(arg_type, "WebGLShader?")) return "WebGLShader";
if (!strcmp(arg_type, "WebGLBuffer?")) return "WebGLBuffer";
if (!strcmp(arg_type, "WebGLFramebuffer?")) return "WebGLFramebuffer";
if (!strcmp(arg_type, "WebGLRenderbuffer?")) return "WebGLRenderbuffer";
if (!strcmp(arg_type, "WebGLTexture?")) return "WebGLTexture";
if (!strcmp(arg_type, "WebGLUniformLocation?")) return "WebGLUniformLocation";
if (!strcmp(arg_type, "TexImageSource?")) return "TexImageSource";
if (!strcmp(arg_type, "WebGLContextAttributes?")) return "WebGLContextAttributes";
if (!strcmp(arg_type, "boolean?")) return "Bool";
if (!strcmp(arg_type, "WebGLActiveInfo?")) return "JSValue";
if (!strcmp(arg_type, "Float32Array")) {
*is_array = GF_TRUE;
return "Float *";
}
if (!strcmp(arg_type, "Int32Array")) {
*is_array = GF_TRUE;
return "s32 *";
}
if (!strcmp(arg_type, "sequence<DOMString>?")) {
return "JSValue";
}
if (!strcmp(arg_type, "sequence<WebGLShader>?")) {
return "JSValue";
}
if (!strcmp(arg_type, "ArrayBufferView")
|| !strcmp(arg_type, "ArrayBufferView?")
|| !strcmp(arg_type, "BufferDataSource?")
) {
*is_array = GF_TRUE;
return "u8 *";
}
if (!strcmp(arg_type, "object?")
|| !strcmp(arg_type, "WebGLShaderPrecisionFormat?")
|| !strcmp(arg_type, "any")
) {
return NULL;
}
fprintf(stderr, "arg type %s not supported\n", arg_type);
return "JSValue";
}
static void put_arg_get(FILE *ifce_c, char *fname, int idx, char *arg_type, char *arg_name)
{
Bool is_array;
const char *native_type = get_arg_type(arg_type, &is_array);
if (!native_type) return;
if (!strcmp(native_type, "Bool")) {
fprintf(ifce_c, "\tWGL_GET_BOOL(%s, argv[%d]);\n", arg_name, idx);
}
else if (!strcmp(native_type, "s32")) {
fprintf(ifce_c, "\tWGL_GET_S32(%s, argv[%d]);\n", arg_name, idx);
}
else if (!strcmp(native_type, "u32")) {
fprintf(ifce_c, "\tWGL_GET_U32(%s, argv[%d]);\n", arg_name, idx);
}
else if (!strcmp(native_type, "u64")) {
fprintf(ifce_c, "\tWGL_GET_U64(%s, argv[%d]);\n", arg_name, idx);
}
else if (!strcmp(native_type, "s64")) {
fprintf(ifce_c, "\tWGL_GET_S64(%s, argv[%d]);\n", arg_name, idx);
}
else if (!strcmp(native_type, "s16")) {
fprintf(ifce_c, "\tWGL_GET_S16(%s, argv[%d]);\n", arg_name, idx);
}
else if (!strcmp(native_type, "u16")) {
fprintf(ifce_c, "\tWGL_GET_U16(%s, argv[%d]);\n", arg_name, idx);
}
else if (!strcmp(arg_type, "GLclampf")) {
fprintf(ifce_c, "\tWGL_GET_FLOAT_CLAMP(%s, argv[%d]);\n", arg_name, idx);
}
else if (!strcmp(native_type, "Float")) {
fprintf(ifce_c, "\tWGL_GET_FLOAT(%s, argv[%d]);\n", arg_name, idx);
}
else if (!strcmp(native_type, "const char *")) {
fprintf(ifce_c, "\tWGL_GET_STRING(%s, argv[%d]);\n", arg_name, idx);
}
else if (!strcmp(native_type, "WebGLProgram")
|| !strcmp(native_type, "WebGLShader")
|| !strcmp(native_type, "WebGLBuffer")
|| !strcmp(native_type, "WebGLFramebuffer")
|| !strcmp(native_type, "WebGLRenderbuffer")
|| !strcmp(native_type, "WebGLTexture")
|| !strcmp(native_type, "WebGLUniformLocation")
) {
fprintf(ifce_c, "\tWGL_GET_GLID(%s, argv[%d], %s_class_id);\n", arg_name, idx, native_type);
}
else if (!strcmp(arg_type, "BufferDataSource?")) {
fprintf(ifce_c, "\tif(!JS_IsObject(argv[%d])) {\n", idx);
fprintf(ifce_c, "\t\tWGL_GET_U32(%s_size, argv[%d]);\n", arg_name, idx);
fprintf(ifce_c, "\t} else {\n");
fprintf(ifce_c, "\t\t%s = wgl_GetArrayBuffer(ctx, &%s_size, argv[%d]);\n", arg_name, arg_name, idx);
fprintf(ifce_c, "\t}\n");
}
else if (is_array && !strcmp(native_type, "u8 *")) {
fprintf(ifce_c, "\tif(!JS_IsArray(ctx, argv[%d])) return js_throw_err(ctx, WGL_INVALID_VALUE);\n", idx);
fprintf(ifce_c, "\t%s = wgl_GetArrayBuffer(ctx, &%s_size, argv[%d]);\n", arg_name, arg_name, idx);
}
else if (is_array && (!strcmp(native_type, "Float *") || !strcmp(native_type, "s32 *")) ) {
u32 vlen = 1;
if (strstr(fname, "2fv")) vlen = 2;
else if (strstr(fname, "3fv")) vlen = 3;
else if (strstr(fname, "4fv")) vlen = 4;
if (!strcmp(native_type, "s32 *"))
fprintf(ifce_c, "\tif (!WGL_LOAD_INT32_VEC(ctx, argv[%d], (s32 **) &%s, &%s_size, %d)) return js_throw_err(ctx, WGL_INVALID_VALUE);\n", idx, arg_name, arg_name, vlen);
else {
Bool is_matrix = GF_FALSE;
if (strstr(fname, "Matrix")) is_matrix = GF_TRUE;
if (strstr(fname, "vertexAttrib")) {
fprintf(ifce_c, "\tif (!WGL_LOAD_FLOAT_VEC(ctx, argv[%d], (Float **) &%s, NULL, %d, %d)) return js_throw_err(ctx, WGL_INVALID_VALUE);\n", idx, arg_name, vlen, is_matrix);
} else {
fprintf(ifce_c, "\tif (!WGL_LOAD_FLOAT_VEC(ctx, argv[%d], (Float **) &%s, &%s_size, %d, %d)) return js_throw_err(ctx, WGL_INVALID_VALUE);\n", idx, arg_name, arg_name, vlen, is_matrix);
}
}
}
else {
fprintf(stderr, "arg type %s not supported\n", arg_type);
}
}
static void put_arg_decl(FILE *ifce_c, char *fname, char *arg_type, char *arg_name)
{
Bool is_array = GF_FALSE;
const char *native_type = get_arg_type(arg_type, &is_array);
if (!native_type)
return;
if (is_array) {
if (strstr(fname, "vertexAttrib1fv")) {
fprintf(ifce_c, "\tFloat %s[1];\n", arg_name);
} else if (strstr(fname, "vertexAttrib2fv")) {
fprintf(ifce_c, "\tFloat %s[2];\n", arg_name);
} else if (strstr(fname, "vertexAttrib3fv")) {
fprintf(ifce_c, "\tFloat %s[3];\n", arg_name);
} else if (strstr(fname, "vertexAttrib4fv")) {
fprintf(ifce_c, "\tFloat %s[4];\n", arg_name);
} else {
fprintf(ifce_c, "\t%s %s = NULL;\n", native_type, arg_name);
fprintf(ifce_c, "\tu32 %s_size = 0;\n", arg_name);
}
} else {
if (strstr(arg_name, " *"))
fprintf(ifce_c, "\t%s %s = NULL;\n", native_type, arg_name);
else if (!strcmp(native_type, "JSValue"))
fprintf(ifce_c, "\t%s %s = JS_UNDEFINED;\n", native_type, arg_name);
else if (!strncmp(native_type, "WebGL", 5))
fprintf(ifce_c, "\tGLuint %s = 0;\n", arg_name);
else
fprintf(ifce_c, "\t%s %s = 0;\n", native_type, arg_name);
}
}
/*all functions that cannot be mapped directly due to to heavy syntax pacthing or our own hacking*/
static const char *not_autogen_funcs = "getContextAttributes,isContextLost,getSupportedExtensions,getExtension,getBufferParameter,getParameter,getFramebufferAttachmentParameter,getProgramParameter,getRenderbufferParameter,getShaderParameter,getShaderPrecisionFormat,getProgramInfoLog,getShaderParameter,getShaderInfoLog,getShaderSource,getTexParameter,getUniform,getVertexAttrib,getVertexAttribOffset,readPixels,shaderSource,texImage2D,texSubImage2D,useProgram,activeTexture,bindTexture,getUniformLocation,createTexture,bindFramebuffer,pixelStorei";
static void wrap_func(FILE *ifce_c, char *fname, char *fun_def)
{
char *sep, *nsep;
u32 len, i, nb_args;
u32 first_char;
u32 ret_type=0;
Bool is_create=GF_FALSE;
Bool is_delete_fun=GF_FALSE;
char *ret_val=NULL, *exc_value=NULL, *arg_type[50], *arg_name[50];
if (strstr(not_autogen_funcs, fname)) {
fprintf(ifce_c, "\nstatic JSValue wgl_%s(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);\n", fname);
return;
}
fprintf(ifce_c, "\nstatic JSValue wgl_%s(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)\n{\n", fname);
nb_args = 0;
memset(arg_type, 0, sizeof(char *)*50);
memset(arg_name, 0, sizeof(char *)*50);
sep = fun_def;
while (sep[0]==' ') sep++;
/*parse exception*/
if (sep[0]=='[') {
nsep = strchr(sep, ']');
assert(nsep);
nsep[0]=0;
exc_value = gf_strdup(sep);
nsep[0]=']';
sep = nsep+1;
while (sep[0]==' ') sep++;
}
/*parse return value*/
nsep = strchr(sep, ' ');
assert(nsep);
nsep[0] = 0;
ret_val = strdup(sep);
sep = nsep+1;
len = strlen(fname);
assert(!strncmp(sep, fname, len) );
sep += len+1;
while (sep) {
char *next_arg;
nsep = strchr(sep, ',');
if (!nsep) {
nsep = strchr(sep, ')');
if (!nsep) break;
}
nsep[0]=0;
next_arg = nsep+1;
if (nb_args>=50) {
assert(0);
}
nsep = strchr(sep, ' ');
if (!nsep)
break;
assert(nsep);
nsep[0] = 0;
arg_type[nb_args] = gf_strdup(sep);
arg_name[nb_args] = gf_strdup(nsep+1);
nb_args++;
sep = next_arg;
while (sep[0]==' ') sep++;
}
fprintf(ifce_c, "\tJSValue ret_val_js = JS_UNDEFINED;\n");
for (i=0; i<nb_args; i++) {
put_arg_decl(ifce_c, fname, arg_type[i], arg_name[i]);
}
fprintf(ifce_c, "\tWGL_CHECK_CONTEXT\n");
if (nb_args) {
fprintf(ifce_c, "\tif (argc<%d) return js_throw_err(ctx, WGL_INVALID_VALUE);\n", nb_args);
for (i=0; i<nb_args; i++) {
put_arg_get(ifce_c, fname, i, arg_type[i], arg_name[i]);
}
}
/*hack a few funcs with different signatures*/
if (!strcmp(fname, "getActiveAttrib")) {
fprintf(ifce_c, "\tret_val_js = webgl_getActiveAttrib(ctx, program, index);\n\treturn ret_val_js;\n");
goto fun_done;
}
if (!strcmp(fname, "getActiveUniform")) {
fprintf(ifce_c, "\tret_val_js = webgl_getActiveUniform(ctx, program, index);\n\treturn ret_val_js;\n");
goto fun_done;
}
if (!strcmp(fname, "getAttachedShaders")) {
fprintf(ifce_c, "\tret_val_js = webgl_getAttachedShaders(ctx, JS_GetOpaque(this_val, WebGLRenderingContextBase_class_id), program);\n\treturn ret_val_js;\n");
goto fun_done;
}
if (!strcmp(fname, "getBufferParameter")) {
fprintf(ifce_c, "\tret_val_js = webgl_getBufferParameter(ctx, target, pname);\n\treturn ret_val_js;\n");
goto fun_done;
}
if (ret_val && strcmp(ret_val, "void")) {
if (!strcmp(fname, "createBuffer") || !strcmp(fname, "createFramebuffer") || !strcmp(fname, "createTexture") || !strcmp(fname, "createRenderbuffer")) {
fprintf(ifce_c, "\tGF_WebGLObject *wglo;\n");
is_create = GF_TRUE;
ret_type = 2;
} else if (!strcmp(fname, "createProgram") || !strcmp(fname, "createShader")) {
fprintf(ifce_c, "\tGF_WebGLObject *wglo;\n");
ret_type = 2;
} else {
put_arg_decl(ifce_c, fname, ret_val, "ret_val");
ret_type = 1;
}
}
first_char = fname[0];
if ((first_char < 'A') || (first_char > 'Z')) {
first_char += 'A' - 'a';
}
if (is_create) {
fprintf(ifce_c, "\tGF_SAFEALLOC(wglo, GF_WebGLObject);\n");
fprintf(ifce_c, "\tif (!wglo) return js_throw_err(ctx, WGL_OUT_OF_MEMORY);\n");
fprintf(ifce_c, "\twglo->par_ctx = JS_GetOpaque(this_val, WebGLRenderingContextBase_class_id);\n");
fprintf(ifce_c, "\tglGen%ss(1, &wglo->gl_id", fname+6);
} else {
if (!strcmp(fname, "deleteShader") || !strcmp(fname, "deleteProgram")) {
is_delete_fun=GF_TRUE;
}
if (!strcmp(fname, "deleteBuffer") || !strcmp(fname, "deleteTexture") || !strcmp(fname, "deleteFramebuffer") || !strcmp(fname, "deleteRenderbuffer")) {
fprintf(ifce_c, "\tgl%c%ss(1, &", first_char, fname+1);
is_delete_fun=GF_TRUE;
}
else if (!strcmp(fname, "createProgram") || !strcmp(fname, "createShader")) {
fprintf(ifce_c, "\tGF_SAFEALLOC(wglo, GF_WebGLObject);\n");
fprintf(ifce_c, "\tif (!wglo) return js_throw_err(ctx, WGL_OUT_OF_MEMORY);\n");
fprintf(ifce_c, "\twglo->par_ctx = JS_GetOpaque(this_val, WebGLRenderingContextBase_class_id);\n");
fprintf(ifce_c, "\twglo->gl_id = gl%c%s(", first_char, fname+1);
} else if (!strcmp(fname, "clearDepth") || !strcmp(fname, "depthRange")) {
fprintf(ifce_c, "#if defined(GPAC_USE_GLES2)\n");
fprintf(ifce_c, "\tgl%c%sf(\n", first_char, fname+1);
fprintf(ifce_c, "#else\n");
fprintf(ifce_c, "\tgl%c%s(\n", first_char, fname+1);
fprintf(ifce_c, "#endif\n\t\t");
} else {
fprintf(ifce_c, "\t");
if (ret_type==1) {
fprintf(ifce_c, "ret_val = ");
}
if (!strncmp(fname, "uniform", 7)) {
fprintf(ifce_c, "/*hack for GPAC textures, we create uniforms with loc -2 for such textures*/\n\tif ((s32) location>=0)\n\t\t");
}
fprintf(ifce_c, "gl%c%s(", first_char, fname+1);
}
}
Bool prev_is_transpose = GF_FALSE;
for (i=0; i<nb_args; i++) {
Bool is_array;
get_arg_type(arg_type[i], &is_array);
if (!strcmp(arg_name[i], "transpose")) {
fprintf(ifce_c, "%s_size, ", arg_name[i+1]);
prev_is_transpose = GF_TRUE;
}
else if (prev_is_transpose) {
is_array = GF_FALSE;
}
if (is_array && (
!strcmp(fname, "bufferData") || !strcmp(fname, "bufferSubData")
|| !strcmp(fname, "compressedTexImage2D") || !strcmp(fname, "compressedTexSubImage2D")
|| !strncmp(fname, "uniform", 7)
)) {
is_array = GF_FALSE;
fprintf(ifce_c, "%s_size, ", arg_name[i]);
}
if (!strcmp(arg_type[i], "GLintptr") && (!strcmp(fname, "vertexAttribPointer") || !strcmp(fname, "drawElements")) ) {
fprintf(ifce_c, "(void *)");
}
fprintf(ifce_c, "%s", arg_name[i]);
if (is_array) {
if (strstr(fname, "vertexAttrib1fv")) {}
else if (strstr(fname, "vertexAttrib2fv")) {}
else if (strstr(fname, "vertexAttrib3fv")) {}
else if (strstr(fname, "vertexAttrib4fv")) {}
else {
fprintf(ifce_c, ", %s_size", arg_name[i]);
}
}
if (i+1<nb_args)
fprintf(ifce_c, ", ");
}
fprintf(ifce_c, ");\n");
if (is_delete_fun) {
Bool is_array;
const char *nat_type = get_arg_type(arg_type[0], &is_array);
fprintf(ifce_c, "\t{\n\tGF_WebGLObject *glo = JS_GetOpaque(argv[0], %s_class_id);\n\tif (glo) {\n\tglo->gl_id=0;\n", nat_type);
fprintf(ifce_c, "\tJS_FreeValue(ctx, glo->obj);\n\tglo->obj = JS_UNDEFINED;\n\tgf_list_del_item(glo->par_ctx->all_objects, glo);\n\tgf_free(glo);\n\tJS_SetOpaque(argv[0], NULL);\n");
fprintf(ifce_c, "\t}\n\t}\n");
}
if (ret_type==1) {
if (!strcmp(ret_val, "GLenum") || !strcmp(ret_val, "GLint")) {
fprintf(ifce_c, "\tret_val_js = JS_NewInt32(ctx, ret_val);\n");
} else if (!strcmp(ret_val, "GLboolean") ) {
fprintf(ifce_c, "\tret_val_js = JS_NewBool(ctx, ret_val);\n");
} else if (!strcmp(ret_val, "WebGLProgram") ) {
fprintf(ifce_c, "\tret_val_js = JS_NewObjectClass(ctx, WebGLProgram_class_id);\n");
fprintf(ifce_c, "\tJS_SetOpaque(ret_val_js, wglo);\n");
} else {
fprintf(stderr, "retval %s not supported in %s\n", ret_val, fname);
}
} else if (ret_type==2) {
Bool is_array;
const char *native_type = get_arg_type(ret_val, &is_array);
fprintf(ifce_c, "\tret_val_js = JS_NewObjectClass(ctx, %s_class_id);\n", native_type);
fprintf(ifce_c, "\tJS_SetOpaque(ret_val_js, wglo);\n");
fprintf(ifce_c, "\twglo->obj = JS_DupValue(ctx, ret_val_js);\n");
fprintf(ifce_c, "\twglo->class_id = %s_class_id;\n", native_type);
fprintf(ifce_c, "\tgf_list_add(wglo->par_ctx->all_objects, wglo);\n");
}
for (i=0; i<nb_args; i++) {
Bool is_array;
const char *native_type = get_arg_type(arg_type[i], &is_array);
if (!native_type) continue;
if (!strcmp(native_type, "const char *")) {
fprintf(ifce_c, "\tJS_FreeCString(ctx, %s);\n", arg_name[i]);
}
if (is_array && strcmp(native_type, "u8 *")) {
if (strstr(fname, "vertexAttrib1fv")) {
} else if (strstr(fname, "vertexAttrib2fv")) {
} else if (strstr(fname, "vertexAttrib3fv")) {
} else if (strstr(fname, "vertexAttrib4fv")) {
} else {
fprintf(ifce_c, "\tif (%s) gf_free(%s);\n", arg_name[i], arg_name[i]);
}
}
}
fprintf(ifce_c, "\treturn ret_val_js;\n");
fun_done:
while (nb_args>1) {
gf_free(arg_type[nb_args-1]);
gf_free(arg_name[nb_args-1]);
nb_args--;
}
gf_free(ret_val);
fprintf(ifce_c, "}\n");
}
static void load_idl(const char *file)
{
Bool in_ctxbase = GF_FALSE;
char szLine[4001], *sep;
char *curCtx = NULL;
u32 len;
FILE * idl = gf_fopen(file, "rt");
FILE *ifce_c=NULL;
FILE *fun_defs=NULL;
while (!feof(idl)) {
gf_fgets(szLine, 4000, idl);
if (strstr(szLine, "implements"))
continue;
len = strlen(szLine);
while (len && strchr(" \n", szLine[len])) {
szLine[len] = 0;
len--;
}
if (!len) continue;
if (!in_ctxbase) {
if (!strstr(szLine, "RenderingContextBase"))
continue;
in_ctxbase = GF_TRUE;
sep = strchr(szLine, ' ');
assert(sep);
curCtx = gf_strdup(sep+1);
start_ctx(curCtx, &ifce_c, &fun_defs);
continue;
} else {
if (strstr(szLine, "};")){
in_ctxbase = GF_FALSE;
end_ctx(ifce_c, fun_defs, curCtx);
ifce_c = NULL;
continue;
}
}
if (strstr(szLine, "/*")) continue;
sep = strstr(szLine, "const ");
if (sep) {
char *cname, *nsep;
sep = strchr(sep+7, ' ');
assert(sep);
sep++;
nsep = strchr(sep, ' ');
assert(nsep);
nsep[0] = 0;
cname = gf_strdup(sep);
sep = strchr(nsep+1, '=');
assert(sep);
sep++;
while (sep[0]==' ') sep++;
nsep = strchr(sep, ';');
assert(nsep);
nsep[0]=0;
put_const(fun_defs, cname, sep);
gf_free(cname);
continue;
}
sep = strstr(szLine, "typedef");
if (sep) continue;
sep = strstr(szLine, "attribute");
if (sep) {
char *nsep;
Bool is_readonly = GF_FALSE;
sep = szLine;
while (sep[0]==' ') sep++;
if (!strncmp(sep, "readonly", 8)) {
is_readonly = GF_TRUE;
sep+=9;
}
sep += 10;
sep = strchr(sep, ' ');
assert(sep);
sep+=1;
nsep = strchr(sep, ';');
assert(nsep);
nsep[0] = 0;
put_prop(fun_defs, curCtx, sep, is_readonly);
continue;
}
/*double type declaration for glXXXifv*/
if (strstr(szLine, ", sequence<"))
continue;
/*double type declaration for bufferData*/
if (strstr(szLine, ", GLsizeiptr size"))
continue;
/*double type declaration for texImage2D and texSubImage2D*/
if (strstr(szLine, ", TexImageSource"))
continue;
sep = strstr(szLine, "(");
/*this is a function*/
if (sep) {
char *nsep, *fname;
sep = strchr(szLine, ']');
if (sep) sep+=1;
else sep = szLine;
while (sep[0] == ' ') sep++;
sep = strchr(sep, ' ');
assert(sep);
sep++;
nsep = strchr(sep, '(');
assert(nsep);
nsep[0] = 0;
fname = gf_strdup(sep);
put_fun(fun_defs, sep);
nsep[0] = '(';
wrap_func(ifce_c, fname, szLine);
gf_free(fname);
continue;
}
fprintf(stderr, "instruction %s not handled\n", szLine);
}
gf_fclose(idl);
}
int main(int argc, char **argv)
{
u32 i=0;
for (i=1; i<argc; i++) {
load_idl(argv[i]);
}
return 0;
}