From 44bc5a27d53124ba82becd4181fc381053c56fdb Mon Sep 17 00:00:00 2001 From: "Kjetil S. Matheussen" Date: Thu, 8 Jan 2004 14:55:24 +0000 Subject: First commit of k_vst~, k_guile and k_cext svn path=/trunk/externals/k_cext/; revision=1253 --- k_cext_generatecode.c | 402 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 402 insertions(+) create mode 100644 k_cext_generatecode.c (limited to 'k_cext_generatecode.c') diff --git a/k_cext_generatecode.c b/k_cext_generatecode.c new file mode 100644 index 0000000..d2e493e --- /dev/null +++ b/k_cext_generatecode.c @@ -0,0 +1,402 @@ +/* + * Copyright 2003 Kjetil S. Matheussen. + * + * This 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 2.1 of + * the License, or (at your option) any later version. + * + * This program 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; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +static bool has_intfunc(char *string){ + if(strstr(string,"INT_(")) return false; + if(strstr(string,"INT_")) return true; + return false; +} + +static bool has_floatfunc(char *string){ + if(strstr(string,"FLOAT_(")) return false; + if(strstr(string,"FLOAT_")) return true; + return false; +} + +static void k_cext_fixfuncs(struct k_cext_init *k,char *string){ + char newstring[500]; + + sprintf(newstring,"%s",string); + + if(has_intfunc(newstring)){ + char name[500]={0}; + char *f_intstart=strstr(newstring,"INT_"); + char *f_namestart=f_intstart+4; + char *f_nameend=strstr(f_namestart+1,"("); + int lastarg=false; + + //post("namestart: -%s-",f_namestart); + //post("nameend: -%s-",f_nameend); + + if(f_nameend==NULL){ + post("Error. k_cext needs this syntax: \"%s(\", not \"%s (\"",f_intstart,f_intstart); + return; + } + + if(f_nameend[1]==')') lastarg=true; + + memcpy(&k->intfuncnames[k->num_intfuncs*50],f_namestart,f_nameend-f_namestart); + memcpy(name,f_namestart,f_nameend-f_namestart); + + f_intstart[0]=0; + sprintf(string, + "%s INT_(%s,%d)(I_(%d)%s %s", + newstring, + name, + k->num_intfuncs, + k->num_intfuncs, + lastarg==true?"":",", + f_nameend+1 + ); + k->num_intfuncs++; + }else{ + if(has_floatfunc(newstring)){ + char name[500]={0}; + char *f_floatstart=strstr(newstring,"FLOAT_"); + char *f_namestart=f_floatstart+6; + char *f_nameend=strstr(f_namestart+1,"("); + int lastarg=false; + + //post("namestart: -%s-",f_namestart); + //post("nameend: -%s-",f_nameend); + + + if(f_nameend==NULL){ + post("Error, k_cext needs this syntax: \"%s(\", not \"%s (\"",f_floatstart,f_floatstart); + return; + } + + if(f_nameend[1]==')') lastarg=true; + + memcpy(&k->floatfuncnames[k->num_floatfuncs*50],f_namestart,f_nameend-f_namestart); + memcpy(name,f_namestart,f_nameend-f_namestart); + + f_floatstart[0]=0; + sprintf(string, + "%s FLOAT_(%s,%d)(F_(%d)%s %s", + newstring, + name, + k->num_floatfuncs, + k->num_floatfuncs, + lastarg==true?"":",", + f_nameend+1 + ); + + k->num_floatfuncs++; + }else{ + return; + } + } + + if(has_intfunc(string) || has_floatfunc(string)){ + k_cext_fixfuncs(k,string); + } +} + + +static void k_cext_gen_funcname(struct k_cext_init *k){ + sprintf(k->funcname,"k_cext_process%d",instancenumber++); + + k->doinitpos1=ftell(k->file); + fprintf(k->file," \n"); + // static bool doinit(void); + + fprintf(k->file,"void %s(t_k_cext *x){\n",k->funcname); + k->doinitpos2=ftell(k->file); + fprintf(k->file," \n"); + // if(doinit()){ + +} + + +static int k_cext_gen_cfunc_funcname(t_k_cext *x,int argc, t_atom* argv,int i, struct k_cext_init *k){ + char string[500]; + int lokke; + + k->doinitpos1=ftell(k->file); + fprintf(k->file," \n"); + + sprintf(string,"%s",atom_getsymbolarg(i,argc,argv)->s_name); + if(!strncmp(string,"INT_",4)){ + k->cfuncrettype=0; + sprintf(k->cfuncname,"%s",string+4); + }else{ + if(!strncmp(string,"FLOAT_",6)){ + k->cfuncrettype=1; + sprintf(k->cfuncname,"%s",string+6); + }else{ + post("k_cfunc: Error. Function name must begin with either INT_ or FLOAT_."); + return 1; + } + } + i++; + + for(;is_name); + if(!strcmp(string,";")) goto end; + if(!strcmp(string,"float") || !strcmp(string,"t_float")){ + sprintf(string,"double"); + } + sprintf(&k->cfuncargtypes[k->numargs*50],"%s",string); + sprintf(&k->cfuncargnames[k->numargs*50],"%s",atom_getsymbolarg(i+1,argc,argv)->s_name); + k->numargs++; + } + + end: + + fprintf(k->file,"static %s %s(t_k_cext *x%s",k->cfuncrettype==0?"int":"float",k->cfuncname,k->numargs>0?",":"){\n"); + for(lokke=0;lokkenumargs;lokke++){ + fprintf(k->file,"%s %s%s",&k->cfuncargtypes[lokke*50],&k->cfuncargnames[lokke*50],lokke==k->numargs-1?"){\n":","); + } + + k->doinitpos2=ftell(k->file); + fprintf(k->file," \n"); + + return i; +} + + +static void k_cext_gen_mainfunccode(t_k_cext *x,int argc, t_atom* argv,int i, struct k_cext_init *k){ + int lokke; + int prevwasnewline=1; + + for(;ifile,"%d ",(int)atom_getintarg(i,argc,argv)); + }else{ + fprintf(k->file,"%f ",atom_getfloatarg(i,argc,argv)); + } + prevwasnewline=0; + break; + case A_SYMBOL: + sprintf(string,"%s",atom_getsymbolarg(i,argc,argv)->s_name); + if(!strcmp(".",string)){ + sprintf(string," "); + k->indentation++; + + }else{if(!strcmp("DO",string)){ + k->set_indentation[k->indentation]=1; + sprintf(string,"BEGIN"); + + }else{if(!strcmp(";",string)){ + if(prevwasnewline==1) break; + sprintf(string,";\n"); + prevwasnewline=1; + k->indentation=0; + k->thisisanelifline=0; + + }else{if(!strcmp("ELIF",string)){ + k->thisisanelifline=1; + + }else{ + + if(strstr(string,"INT_") || strstr(string,"FLOAT_")){ + k_cext_fixfuncs(k,string); + } + + prevwasnewline=0; + //post("%d: -%s-",k->indentation,string); + + if( + strcmp("ELSE",string) + && k->thisisanelifline==0 + ) + { + int hasindented=0; + char orgind[500]; + for(lokke=0;lokkeindentation*2;lokke++){ + orgind[lokke]=' '; + } + orgind[lokke]=0; + for(lokke=499;lokke>=k->indentation;lokke--){ + if(k->set_indentation[lokke]==1){ + k->set_indentation[lokke]=0; + fprintf(k->file,"END\n"); + hasindented++; + } + } + if(hasindented>0){ + char temp2[500]; + sprintf(temp2,"%s%s",orgind,string); + sprintf(string,temp2); + } + } + } + } + /* + if(!strcmp("\n",string)){ + sprintf(string," "); + } + */ + } + } + fprintf(k->file,"%s",string); + if(string[strlen(string)-1]!='\n') fprintf(k->file," "); + break; + default: + post("k_cext.c: Unknown argv type: %d",argv[i].a_type); + post("Please send this patch to k->s.matheussen@notam02.no ."); + break; + } + } +} + +static void k_cext_gen_endbrackets(struct k_cext_init *k){ + int lokke; + for(lokke=499;lokke>=0;lokke--){ + if(k->set_indentation[lokke]==1){ + int lokke2; + for(lokke2=0;lokke2file," "); + } + fprintf(k->file,"END\n"); + } + } + fprintf(k->file,"}"); +} + + +static void k_cext_gen_funcs_dasfunc(struct k_cext_init *k){ + sprintf(k->funcname,"k_cext_process%d",instancenumber++); + + fprintf(k->file,"\n%s %s(t_k_cext *x%s){\n",k->cfuncrettype==0?"int":"float",k->funcname,k->numargs>0?",...":""); + + if(k->numargs>0){ + int lokke; + fprintf(k->file," va_list k_cext_a;\n"); + for(lokke=0;lokkenumargs;lokke++){ + fprintf(k->file," %s %s;\n",&k->cfuncargtypes[lokke*50],&k->cfuncargnames[lokke*50]); + } + fprintf(k->file," va_start(k_cext_a,x);\n"); + for(lokke=0;lokkenumargs;lokke++){ + fprintf(k->file," %s=va_arg(k_cext_a,%s);\n",&k->cfuncargnames[lokke*50],&k->cfuncargtypes[lokke*50]); + } + fprintf(k->file," va_end(k_cext_a);\n"); + + fprintf(k->file," return %s(x,",k->cfuncname); + for(lokke=0;lokkenumargs;lokke++){ + fprintf(k->file,"%s%s",&k->cfuncargnames[lokke*50],lokke==k->numargs-1?");\n}\n":","); + } + + }else{ + fprintf(k->file," return %s(x);\n}\n",k->cfuncname); + } +} + + +static void k_cext_gen_doinit(t_k_cext *x,struct k_cext_init *k){ + int lokke; + if(k->num_intfuncs>0 || k->num_floatfuncs>0){ + if(x->iscext==true){ + fprintf(k->file,"}\n"); + } + + fprintf(k->file, + "static bool doinit(void){\n" + " static bool k_cext_inited=false;\n" + " if(k_cext_inited==false){\n" + ); + if(k->num_intfuncs>0){ + fprintf(k->file," if(k_cext_get_int_funcs(&k_cext_int_funcs[0],&k_cext_int_x[0],%d,",k->num_intfuncs); + for(lokke=0;lokkenum_intfuncs;lokke++){ + fprintf(k->file,"\"%s\"%s",k->intfuncnames+(lokke*50),lokkenum_intfuncs-1?",":""); + } + fprintf(k->file,")==false) return false;\n"); + } + + if(k->num_floatfuncs>0){ + fprintf(k->file," if(k_cext_get_float_funcs(&k_cext_float_funcs[0],&k_cext_float_x[0],%d,",k->num_floatfuncs); + for(lokke=0;lokkenum_floatfuncs;lokke++){ + fprintf(k->file,"\"%s\"%s",k->floatfuncnames+(lokke*50),lokkenum_floatfuncs-1?",":""); + } + fprintf(k->file,")==false) return false;\n"); + } + + fprintf(k->file, + " k_cext_inited=true;\n" + " }\n" + " return true;\n" + "}\n" + ); + + if(k->num_intfuncs>0){ + fprintf(k->file, +#ifndef _MSC_VER + "static " +#endif + "k_cext_f_int_callback *k_cext_int_funcs[%d]={0};\n" +#ifndef _MSC_VER + "static " +#endif + "t_k_cext **k_cext_int_x[%d]={0};\n", + k->num_intfuncs,k->num_intfuncs + ); + } + + if(k->num_floatfuncs>0){ + fprintf(k->file, +#ifndef _MSC_VER + "static " +#endif + "k_cext_f_float_callback *k_cext_float_funcs[%d]={0};\n" +#ifndef _MSC_VER + "static " +#endif + "t_k_cext **k_cext_float_x[%d]={0};\n", + k->num_floatfuncs,k->num_floatfuncs + ); + } + + fseek(k->file,k->doinitpos1,SEEK_SET); + fprintf(k->file,"static bool doinit(void);"); + + fseek(k->file,k->doinitpos2,SEEK_SET); + fprintf(k->file,"if(doinit()){"); + }else{ + fprintf(k->file,"\n"); + } + +} + +static void k_cext_generatecode(t_k_cext *x,int argc, t_atom* argv,int i, struct k_cext_init *k){ + + if(x->iscext==true){ + k_cext_gen_funcname(k); + }else{ + i=k_cext_gen_cfunc_funcname(x,argc,argv,i,k); + } + + k_cext_gen_mainfunccode(x,argc,argv,i,k); + k_cext_gen_endbrackets(k); + + if(x->iscext==false){ + if(k->num_intfuncs>0 || k->num_floatfuncs>0){ + fprintf(k->file,"return 0;}\n"); + } + k_cext_gen_funcs_dasfunc(k); + } + + k_cext_gen_doinit(x,k); + + fclose(k->file); +} -- cgit v1.2.1