static Link addChild(Link self,Link value,Link keys){ Link * args = array_getArray(keys); size_t argn = array_getLength(keys); if (argn != 1) return NULL; string_t key = object_getString(args[0]); if ( ! key ) return NULL; Dict dict = self->value.vptr; if ( ! dict){ dict = self->value.vptr = malloc( sizeof( *dict) ); dict->dictionary = dictionary_new(); dict->mutex = mutex_new(); } mutex_lock(dict->mutex); Link old = dictionary_insert(dict->dictionary, key, value ); mutex_unlock(dict->mutex); if (old) link_free(old); return value; // return original not duplicate child }
static NATIVECALL(exec_stream){ Link * args = array_getArray(Arg); string_t command = object_getString( args[0] ); Link link = object_create(stream_type); link->value.vptr = stream_open_exec(command->data); return link; }
static NATIVECALL(read_stream){ Link * args = array_getArray(Arg); size_t argn = array_getLength(Arg); string_t ret = NULL; size_t amount = 0; Link obj = NULL; switch(argn){ /* no arguments */ case 0: ret = stream_read(This->value.vptr, 4096); break; case 1: obj = args[0]; if (obj->type == Global->number_type){ amount =(size_t) obj->value.number; ret = stream_read(This->value.vptr, amount); }else if ( object_getString( obj ) ){ ret = stream_readbreak(This->value.vptr, object_getString(obj) ); }else{ return exception("InvalidTypeForArgument",NULL,NULL); } break; } if (! ret) return exception("StreamFinished", NULL, NULL); return create_string_str( ret ); }
static void showBacktrace(Link ret){ if (! is_critical(ret)) return; string_t retstring = object_asString(ret); printf("%s\n", retstring->data); free(retstring); Link bt = getAttr(ret, Global->backtrace_key); if ( ! bt ) return; Link * args = array_getArray(bt); size_t argn = array_getLength(bt); Link a; int c; for (c=0; c< argn; c++){ a = args[c]; if (! a ) break; retstring = object_asString(a); printf(" %s\n", retstring->data); free(retstring); } link_free(bt); }
static NATIVECALL(bwindow_onKeyUp){ BWindow self = This->value.vptr; if ( self->onKeyUp ) link_free( self->onKeyUp); Link * args = array_getArray(Arg); self->onKeyUp = link_dup(args[0]); return link_dup(This); }
static NATIVECALL(sql_exec){ Link * args = array_getArray(Arg); //size_t argn = array_getLength(Arg); Link array = array_new(0); Sqlite sql = This->value.vptr; int err = sqlite3_exec(sql->db, object_getString(args[0])->data, callback_convert, (void *) array, NULL); if (err) return exception("SQLExecError",NULL,NULL); return array; };
static NATIVECALL(socket_stream){ Link * args = array_getArray(Arg); string_t location = object_getString( args[0] ); Link link = object_create(stream_type); link->value.vptr = stream_open_socket(location->data); return link; }
static NATIVECALL(view_cameraPosition){ View self = This->value.vptr; Link * args = array_getArray(Arg); if (! self->camera_pos) self->camera_pos = malloc( sizeof(GLdouble) *3); self->camera_pos[0] = object_asNumber(args[0]); self->camera_pos[1] = object_asNumber(args[1]); self->camera_pos[2] = object_asNumber(args[2]); return object_create(Global->null_type); }
static NATIVECALL(streamserver_create){ Link * args = array_getArray(Arg); int port = object_asNumber(args[0]); StreamServer ss = stream_server(port); if (! ss) return exception("StreamListenError", NULL, NULL); Link link = object_create(streamserver_type); link->value.vptr = ss; return link; }
static NATIVECALL(sql_open){ Link * args = array_getArray(Arg); //size_t argn = array_getLength(Arg); Link sql_link = object_create(sqlite_type); Sqlite sql = sql_link->value.vptr; int err = sqlite3_open(object_getString(args[0])->data, &(sql->db)); if (err) return exception("SQLOpenError",NULL,NULL); return sql_link; };
static NATIVECALL(bwindow_setColor){ BWindow win = This->value.vptr; Link * args = array_getArray(Arg); size_t argn = array_getLength(Arg); size_t count; if (argn > 3) argn=3; for ( count = 0; count < argn; count++){ win->clear_color[count] = object_asNumber(args[count]); } win->clear_color[3] = 1.0; return link_dup(This); }
static NATIVECALL(view_setBounds){ fflush(stdout); View self = This->value.vptr; Link * args = array_getArray(Arg); //size_t argn = array_getLength(Arg); self->bounds[0] = object_asNumber(args[0]); self->bounds[1] = object_asNumber(args[1]); self->bounds[2] = object_asNumber(args[2]); self->bounds[3] = object_asNumber(args[3]); self->bounds[4] = object_asNumber(args[4]); self->bounds[5] = object_asNumber(args[5]); return link_dup(This); }
static Link delChild(Link self,Link keys){ Dict dict = self->value.vptr; if ( ! dict ) return NULL; Link * args = array_getArray(keys); size_t argn = array_getLength(keys); if (argn != 1) return NULL; mutex_lock(dict->mutex); Link ret = dictionary_delete(dict->dictionary, object_getString(args[0])); mutex_unlock(dict->mutex); if ( ! ret) return NULL; return ret; }
static NATIVECALL(view_setOrigin){ View self = This->value.vptr; Link * args = array_getArray(Arg); //size_t argn = array_getLength(Arg); string_t s = object_getString(args[0]); unsigned char origin = 0; switch( s->data[0] ){ case 'n': case 'N': origin |= 1; break; case 'c': case 'C': origin |= 2; break; case 's': case 'S': origin |= 3; break; } switch( s->data[1] ){ case 'e': case 'E': origin |= 1<<2; break; case 'c': case 'C': origin |= 2<<2; break; case 'w': case 'W': origin |= 3<<2; break; } self->origin = origin; return link_dup(This); }
static NATIVECALL(file_stream){ Link * args = array_getArray(Arg); size_t argn = array_getLength(Arg); string_t type = file_stream_def_type; string_t name = NULL; mode_t mode = 0666; switch (argn){ case 3: mode = object_asNumber( args[2] ); case 2: type = object_getString( args[1] ); case 1: name = object_getString( args[0] ); break; default: return exception("FileNameRequired", NULL, NULL); } Link link = object_create(stream_type); link->value.vptr = stream_open_file(name->data , type->data, mode); return link; }
static NATIVECALL(write_stream){ Link * args = array_getArray(Arg); string_t content = object_getString(args[0]); stream_write(This->value.vptr , content); return link_dup(This); }
static NATIVECALL(png_new){ Link * args = array_getArray(Arg); unsigned char pngheader[HEADERSIZE]; png_structp png; png_infop info; png_bytep * row_pointers; png_byte* row ; FILE *fp; int y, width, height; /* open the file args[0] is the filename */ string_t filename_string = object_getString(args[0]); fp = fopen(filename_string->data , "rb"); if (! fp){ return exception("CouldNotOpenFile", NULL, NULL); } /* read the png header and ensure it is a png */ fread(pngheader, 1, HEADERSIZE, fp); if (png_sig_cmp(pngheader, 0, HEADERSIZE)){ return exception("NotPNG", NULL, NULL); } png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_set_sig_bytes(png, HEADERSIZE); info = png_create_info_struct(png); png_init_io(png, fp); png_read_info(png, info); Link obj = object_create(image_type); Image self = obj->value.vptr; self->width = info->width; self->height = info->height; width = info->width; height = info->height; //info->bit_depth; //info->channels; //info->color_type; //printf(" bit depth:%i channels:%i color type:%i rowbytes:%i\n", info->bit_depth, info->channels, info->color_type , info->rowbytes); /* read png information */ png_read_update_info(png, info); /* allocate memory for rows */ row_pointers = malloc(sizeof(png_bytep) * height); for (y=0; y<height; y++) row_pointers[y] = malloc(info->rowbytes); /* read image into allocated memory */ png_read_image(png, row_pointers); fclose(fp); png_byte * pdata; self->format = info->channels; self->data = pdata = malloc(self->width * self->height * self->format); for (y=0; y<height; y++) { row = row_pointers[height-y-1]; memcpy(pdata,row, self->width * self->format); pdata+=self->width * self->format; free(row); } free(row_pointers); png_destroy_read_struct(&png, &info, NULL); return obj; }
static NATIVECALL(make_async){ Link * args = array_getArray(Arg); Link self = object_create(asyncfunc_type); self->value.vptr = link_dup(args[0]); return self; }
void process_execute(PROCESS *self, const char *command) { assert(self); #ifdef SYSTEM_OS_TYPE_WINDOWS /* security settings */ SECURITY_ATTRIBUTES sa; ZeroMemory( &sa, sizeof(sa) ); sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; /* stdin */ self->hi = GetStdHandle(STD_INPUT_HANDLE); if (file_exists(self->file_input)) { self->hi = CreateFile(self->file_input, GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (self->hi == INVALID_HANDLE_VALUE) { self->hi = GetStdHandle(STD_INPUT_HANDLE); } } /* stdout */ self->ho = CreateFile(self->file_output, GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (self->ho == INVALID_HANDLE_VALUE) { self->ho = GetStdHandle(STD_OUTPUT_HANDLE); } /* stderr */ self->he = CreateFile(self->file_error, GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (self->he == INVALID_HANDLE_VALUE) { self->he = GetStdHandle(STD_ERROR_HANDLE); } /* set process information*/ DWORD flags = CREATE_NO_WINDOW | CREATE_BREAKAWAY_FROM_JOB; ZeroMemory(&self->pi, sizeof(PROCESS_INFORMATION)); ZeroMemory(&self->si, sizeof(STARTUPINFO)); self->si.cb = sizeof(STARTUPINFO); self->si.dwFlags |= STARTF_USESTDHANDLES; self->si.hStdInput = self->hi; self->si.hStdOutput = self->ho; self->si.hStdError = self->he; /* call process */ BOOL ok; char *cmdstr = strdup(command); ok = CreateProcess( NULL, cmdstr, NULL, NULL, TRUE, flags, NULL, self->dir_work, &self->si, &self->pi ); free(cmdstr); if (ok) { self->status = PROCESS_STATUS_RUNNING; self->id = self->pi.dwProcessId; if (self->wait) { WaitForSingleObject(self->pi.hProcess, INFINITE); GetExitCodeProcess(self->pi.hProcess, &self->exit); self->status = PROCESS_STATUS_FINISHED; CloseHandle(self->pi.hProcess); CloseHandle(self->pi.hThread); CloseHandle(self->he); CloseHandle(self->ho); CloseHandle(self->hi); } } else { self->exit = ok; self->status = PROCESS_STATUS_ERROR; } #else int status; self->id = fork(); if (self->id < 0) { /* error */ message_error("unable to fork process"); return; } if (self->id > 0) { /* parent */ self->status = PROCESS_STATUS_RUNNING; if (self->wait) { waitpid(self->id, &status, 0); self->exit = status; self->status = PROCESS_STATUS_FINISHED; } else { /* wait for child */ int dummy; waitpid(self->id, &dummy, WNOHANG); } } else { /* child */ if (file_exists(self->file_input)) { int fd_i = open(self->file_input, O_RDONLY); dup2(fd_i, 0); close(fd_i); } int fd_o = open(self->file_output, O_WRONLY | O_CREAT | S_IRUSR | S_IWUSR, 0666); dup2(fd_o, 1); close(fd_o); int fd_e = open(self->file_error, O_WRONLY | O_CREAT | S_IRUSR | S_IWUSR, 0666); dup2(fd_e, 2); close(fd_e); /* change working directory */ if (self->dir_work) { chdir(self->dir_work); } /* format command */ // execl("./test", "process","arg1", "arg2", NULL); char *cmdarg; char *cmdstr; const char *sep = strchr(command, ' '); if (sep) { int seplen = (sep - command) + 1; cmdstr = (char *)malloc(seplen - 1 + 1); memcpy(cmdstr, command, seplen - 1); cmdstr[seplen - 1] = '\0'; cmdarg = strdup(command); } else { cmdstr = strdup(command); cmdarg = strdup(command); } ARRAY *cmdary = array_new(); array_loadFromString(cmdary, cmdarg, ' '); char **args = array_getArray(cmdary); array_free(cmdary); // char *args[3] = {"proc", "NULL", NULL}; int rc = execv(cmdstr, args); /* in the case of an error */ array_freeArray(args); free(cmdarg); free(cmdstr); close(0); close(1); close(2); exit(rc); } #endif }
int blue_main(int argc, char **argv){ int arg_index; int mode=0; char * filename = NULL; char * output_filename = NULL; /* Not enough arguments */ if (argc < 2 ) usage(); Global = malloc(sizeof(struct Global)); if ( ! Global){ printf("Out of Memory\n"); exit(1); } Global->dbg_status = 0; /* handle arguments to blue */ for (arg_index=1; arg_index<argc ; arg_index++){ if (argv[arg_index][0] == '-'){ /* disassemble and quit*/ if ( strcmp(argv[arg_index], "-d")==0 ) mode = 1; else if ( strcmp(argv[arg_index], "-c")==0 ) mode = 2; else if ( strcmp(argv[arg_index], "-g")==0 ) Global->dbg_status = 1; else if ( strcmp(argv[arg_index], "-o")==0 ){ arg_index++; output_filename = argv[arg_index]; } else if ( strcmp(argv[arg_index], "-s")==0 ){ mode = 3 ; } else if ( strcmp(argv[arg_index], "-a")==0 ){ mode = 4 ; } if (argc <3) return 0; }else{ filename = argv[arg_index]; break; } } /* Initialization routines */ global_init(); link_setThreadState(0); // turn multi-threading off until needed if (mode==1){ /* DISASSEMBLE */ Link module = create_module_filename(filename); string_t code = disassemble(module->value.module->bytecode); string_fprint(code , stdout); exit(0); } else if (mode == 2){ /* COMPILE */ Link module = create_module_filename(filename); module_save( module, output_filename ? output_filename : "blue.blx"); exit(0); }else if (mode == 3){ /* COMPILE TO ASSEMBLY CODE */ char * acode = compile_file( filename); if ( memcmp( acode, "ERR:",4) ==0 ){ printf( acode+4); exit(0); } if (output_filename){ FILE * fp = fopen( output_filename,"wb"); fprintf(fp,acode); fclose(fp); }else{ printf(acode); } free(acode); exit(0); }else if (mode == 4){ /* ASSEMBLE THS ASSEMBLY CODE TO BYTECODE */ char * acode = file_load(filename); if ( memcmp( acode, "ERR:",4) ==0 ){ printf( acode+4); exit(0); } Bytes bytes = assemble( acode ); if (output_filename){ bytes_save(bytes, output_filename); }else{ bytes_save(bytes, "out.blx"); } free(acode); exit(0); } /* Add arguments from call to this application */ Link Arg = array_new(argc-arg_index); Link * Argv = array_getArray(Arg); Link a = NULL; int c = 0; for(c=0; c <argc-arg_index; c++){ a = create_string_str( string_new((argv+arg_index)[c]) ); Argv[c] =a; } /* creates and runs the module */ Link main_ret = module_new(filename, Arg); link_free(Arg); if (main_ret){ showBacktrace(main_ret); link_free(main_ret); } fflush(stdout); fflush(stderr); exit(0); return 0; }
static NATIVECALL(shape_sphere){ Link * args = array_getArray(Arg); size_t argn = array_getLength(Arg); Link link = object_create(shape_type); Shape self = link->value.vptr; int n = 20; if (argn == 1){ n = (int)object_asNumber(args[0]); } float radius = 1.0; float center[] = {0.0, 0.0, 0.0}; float twopi = M_PI * 2; List normals = self->normals; List vertices = self->vtx; List texcoords = self->texcoords; struct Xyz vertex; struct Xyz normal; struct Xy texcoord; float j, i; float theta1, theta2, theta3; for ( j = -n/4.0 ; j < n/4.0 ; j++){ theta1 = j * twopi/n; theta2 = (j+1) * twopi/n; for( i=0 ; i < n+1 ; i++){ theta3 = i * twopi/n; if (i == n) theta3 = 0; normal.x = cos(theta2)*cos(theta3); normal.y = sin(theta2); normal.z = cos(theta2)*sin(theta3); vertex.x = center[0] + radius*normal.x; vertex.y = center[1] + radius*normal.y; vertex.z = center[2] + radius*normal.z; texcoord.x = 1.0 - (i/(float)n); texcoord.y = 0.5 + (2*(j+1)/(float)n); list_append(normals, &normal); list_append(vertices, &vertex); list_append(texcoords, &texcoord); normal.x = cos(theta1)*cos(theta3); normal.y = sin(theta1); normal.z = cos(theta1)*sin(theta3); vertex.x = center[0] + radius*normal.x; vertex.y = center[1] + radius*normal.y; vertex.z = center[2] + radius*normal.z; texcoord.x = 1.0 - (i/(float)n); texcoord.y = 0.5 + (2*j/(float)n); list_append(normals,&normal); list_append(vertices, &vertex); list_append(texcoords, &texcoord); } } return link; }