static void make_colors(void) { static struct color { int r,g,b; char *name; struct pike_string *pname; } c[]={ #define COLOR(name,R,G,B) \ {R,G,B,name,NULL}, #include "colors.h" #undef COLOR }; int i; const int n=sizeof(c)/sizeof(c[0]); for (i=0; (size_t)i<sizeof(html_color)/sizeof(html_color[0]); i++) html_color[i].pname=make_shared_string(html_color[i].name); for (i=0;i<n;i++) { struct color_struct *cs; push_text(c[i].name); copy_shared_string(c[i].pname,sp[-1].u.string); push_object(clone_object(image_color_program,0)); cs=get_storage(sp[-1].u.object,image_color_program); cs->rgb.r=(COLORTYPE)c[i].r; cs->rgb.g=(COLORTYPE)c[i].g; cs->rgb.b=(COLORTYPE)c[i].b; RGB_TO_RGBL(cs->rgbl,cs->rgb); copy_shared_string(cs->name,c[i].pname); } f_aggregate_mapping(n*2); colors=sp[-1].u.mapping; sp--; dmalloc_touch_svalue(sp); for (i=0;i<n;i++) { push_int(c[i].r); push_int(c[i].g); push_int(c[i].b); f_aggregate(3); } f_aggregate(n); colortable=clone_object(image_colortable_program,1); if (!colortable) Pike_fatal("couldn't create colortable\n"); push_int(12); push_int(12); push_int(12); push_int(1); safe_apply(colortable,"cubicles",4); pop_stack(); for (i=0;i<n;i++) push_string(c[i].pname); f_aggregate(n); colornames=sp[-1].u.array; sp--; dmalloc_touch_svalue(sp); }
/*! @decl program load_module(string module_name) *! *! Load a binary module. *! *! This function loads a module written in C or some other language *! into Pike. The module is initialized and any programs or constants *! defined will immediately be available. *! *! When a module is loaded the C function @tt{pike_module_init()@} will *! be called to initialize it. When Pike exits @tt{pike_module_exit()@} *! will be called. These two functions @b{must@} be available in the module. *! *! @note *! The current working directory is normally not searched for *! dynamic modules. Please use @expr{"./name.so"@} instead of just *! @expr{"name.so"@} to load modules from the current directory. */ void f_load_module(INT32 args) { extern int global_callable_flags; void *module; modfun init, exit; struct module_list *new_module; struct pike_string *module_name; ONERROR err; module_name = Pike_sp[-args].u.string; if((Pike_sp[-args].type != T_STRING) || (module_name->size_shift) || string_has_null(module_name)) { Pike_error("Bad argument 1 to load_module()\n"); } { struct module_list *mp; for (mp = dynamic_module_list; mp; mp = mp->next) if (mp->name == module_name && mp->module_prog) { pop_n_elems(args); ref_push_program(mp->module_prog); return; } } /* Removing RTLD_GLOBAL breaks some PiGTK themes - Hubbe */ /* Using RTLD_LAZY is faster, but makes it impossible to * detect linking problems at runtime.. */ module=dlopen(module_name->str, RTLD_NOW /*|RTLD_GLOBAL*/ ); if(!module) { struct object *err_obj = low_clone (module_load_error_program); #define LOADERR_STRUCT(OBJ) \ ((struct module_load_error_struct *) (err_obj->storage + module_load_error_offset)) const char *err = dlerror(); if (err) { if (err[strlen (err) - 1] == '\n') push_string (make_shared_binary_string (err, strlen (err) - 1)); else push_text (err); } else push_constant_text ("Unknown reason"); add_ref (LOADERR_STRUCT (err_obj)->path = Pike_sp[-args - 1].u.string); add_ref (LOADERR_STRUCT (err_obj)->reason = Pike_sp[-1].u.string); if (Pike_sp[-args].u.string->len < 1024) { throw_error_object (err_obj, "load_module", Pike_sp - args - 1, args, "load_module(\"%s\") failed: %s\n", module_name->str, Pike_sp[-1].u.string->str); } else { throw_error_object (err_obj, "load_module", Pike_sp - args - 1, args, "load_module() failed: %s\n", Pike_sp[-1].u.string->str); } } #ifdef PIKE_DEBUG { struct module_list *mp; for (mp = dynamic_module_list; mp; mp = mp->next) if (mp->module == module && mp->module_prog) { fprintf(stderr, "load_module(): Module loaded twice:\n" "Old name: %s\n" "New name: %s\n", mp->name->str, module_name->str); pop_n_elems(args); ref_push_program(mp->module_prog); return; } } #endif /* PIKE_DEBUG */ init = CAST_TO_FUN(dlsym(module, "pike_module_init")); if (!init) { init = CAST_TO_FUN(dlsym(module, "_pike_module_init")); if (!init) { dlclose(module); Pike_error("pike_module_init missing in dynamic module \"%S\".\n", module_name); } } exit = CAST_TO_FUN(dlsym(module, "pike_module_exit")); if (!exit) { exit = CAST_TO_FUN(dlsym(module, "_pike_module_exit")); if (!exit) { dlclose(module); Pike_error("pike_module_exit missing in dynamic module \"%S\".\n", module_name); } } #if defined(__NT__) && defined(_M_IA64) { fprintf(stderr, "pike_module_init: 0x%p\n" " func: 0x%p\n" " gp: 0x%p\n", init, ((void **)init)[0], ((void **)init)[1]); fprintf(stderr, "pike_module_exit: 0x%p\n" " func: 0x%p\n" " gp: 0x%p\n", exit, ((void **)exit)[0], ((void **)exit)[1]); } #endif /* __NT__ && _M_IA64 */ new_module=ALLOC_STRUCT(module_list); new_module->next=dynamic_module_list; dynamic_module_list=new_module; new_module->module=module; copy_shared_string(new_module->name, Pike_sp[-args].u.string); new_module->module_prog = NULL; new_module->init=init; new_module->exit=exit; enter_compiler(new_module->name, 1); start_new_program(); global_callable_flags|=CALLABLE_DYNAMIC; #ifdef PIKE_DEBUG { struct svalue *save_sp=Pike_sp; #endif SET_ONERROR(err, cleanup_compilation, NULL); #if defined(__NT__) && defined(_M_IA64) fprintf(stderr, "Calling pike_module_init()...\n"); #endif /* __NT__ && _M_IA64 */ (*(modfun)init)(); #if defined(__NT__) && defined(_M_IA64) fprintf(stderr, "pike_module_init() done.\n"); #endif /* __NT__ && _M_IA64 */ UNSET_ONERROR(err); #ifdef PIKE_DEBUG if(Pike_sp != save_sp) Pike_fatal("load_module(%s) left %ld droppings on stack!\n", module_name->str, PTRDIFF_T_TO_LONG(Pike_sp - save_sp)); } #endif pop_n_elems(args); { struct program *p = end_program(); exit_compiler(); if (p) { if ( #if 0 p->num_identifier_references #else /* !0 */ 1 #endif /* 0 */ ) { push_program(p); add_ref(new_module->module_prog = Pike_sp[-1].u.program); } else { /* No identifier references -- Disabled module. */ free_program(p); push_undefined(); } } else { /* Initialization failed. */ new_module->exit(); dlclose(module); dynamic_module_list = new_module->next; free_string(new_module->name); free(new_module); Pike_error("Failed to initialize dynamic module \"%S\".\n", module_name); } } }
/*! @decl void create(string|object input, object callbacks, mapping|void entities, mixed|void user_data, int|void input_is_data) */ static void f_create(INT32 args) { struct object *file_obj = NULL, *callbacks = NULL; char *file_name = NULL; struct mapping *entities = NULL; int input_is_data = 0; struct pike_string *input_data = NULL; struct svalue *user_data = NULL; char *missing_method = NULL; switch(args) { case 5: if (ARG(5).type != T_INT) Pike_error("Incorrect type for argument 4: expected an integer\n"); input_is_data = ARG(5).u.integer != 0; /* fall through */ case 4: user_data = &ARG(4); /* fall_through */ case 3: if (ARG(3).type != T_MAPPING) Pike_error("Incorrect type for argument 3: expected a mapping\n"); entities = ARG(3).u.mapping; /* fall through */ case 2: if (ARG(2).type != T_OBJECT) Pike_error("Incorrect type for argument 2: expected an object\n"); callbacks = ARG(2).u.object; add_ref(callbacks); /* fall through */ case 1: if (ARG(1).type != T_OBJECT && ARG(1).type != T_STRING) Pike_error("Incorrect type for argument 1: expected a string or an object\n"); if (ARG(1).type == T_OBJECT) { file_obj = ARG(1).u.object; add_ref(file_obj); } else input_data = ARG(1).u.string; break; default: Pike_error("Incorrect number of arguments: expected between 2 and 4\n"); } /* check whether file_obj is Stdio.File or derived */ if (file_obj && find_identifier("read", file_obj->prog) < 0) Pike_error("Passed file object is not Stdio.File or derived from it\n"); /* The parser state is initialized so that no time is wasted for * callbacks that aren't used by the calling Pike code. */ THIS->sax = (xmlSAXHandler*)calloc(1, sizeof(xmlSAXHandler)); if (!THIS->sax) SIMPLE_OUT_OF_MEMORY_ERROR("create", sizeof(xmlSAXHandler)); /* check whether the callbacks object contains all the required methods * */ if (!is_callback_ok(callbacks, &missing_method)) Pike_error("Passed callbacks object is not valid. The %s method is missing.\n", missing_method); /* choose the parsing method */ if (file_obj) THIS->parsing_method = PARSE_PUSH_PARSER; else if (input_data && input_is_data) THIS->parsing_method = PARSE_MEMORY_PARSER; else if (input_data) THIS->parsing_method = PARSE_FILE_PARSER; else Pike_error("Cannot determine the parser type to use\n"); pop_n_elems(args); /* initialize the parser and state */ switch (THIS->parsing_method) { case PARSE_PUSH_PARSER: THIS->file_obj = file_obj; /* the context creation is delayed in this case */ break; case PARSE_MEMORY_PARSER: case PARSE_FILE_PARSER: copy_shared_string(THIS->input_data, input_data); break; } THIS->callbacks = callbacks; if (user_data) assign_svalue_no_free(&THIS->user_data, user_data); else { THIS->user_data.type = PIKE_T_INT; THIS->user_data.u.integer = 0; THIS->user_data.subtype = 1; } }