Пример #1
0
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);
}
Пример #2
0
/*! @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);
    }
  }
}
Пример #3
0
/*! @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;
  }
}