Exemplo n.º 1
0
char *implode_string P3(array_t *, arr, char *, del, int, del_len)
{
    int size, i, num;
    char *p, *q;
    svalue_t *sv = arr->item;

    for (i = arr->size, size = 0, num = 0; i--;) {
	if (sv[i].type == T_STRING) {
	    size += SVALUE_STRLEN(&sv[i]);
	    num++;
	}
    }
    if (num == 0)
	return string_copy("", "implode_string");

    p = new_string(size + (num - 1) * del_len, "implode_string: p");
    q = p;
    for (i = 0, num = 0; i < arr->size; i++) {
	if (sv[i].type == T_STRING) {
	    if (num) {
		strncpy(p, del, del_len);
		p += del_len;
	    }
	    size = SVALUE_STRLEN(&sv[i]);
	    strncpy(p, sv[i].u.string, size);
	    p += size;
	    num++;
	}
    }
    *p = 0;
    return q;
}
Exemplo n.º 2
0
void f_query_temp () {
    int idx;
    object_t *ob;
    unsigned short type;
    svalue_t *value;
    char *src, *dst;
    mapping_t *map;
    char *tmpstr;

    if( st_num_arg==2 ) {
        ob=sp->u.ob;
        pop_stack();
    } else
        ob = current_object;

    idx = find_global_variable(ob->prog, "tmp_dbase", &type, 0);
    if (idx == -1)
    {
        free_string_svalue(sp--);
        push_undefined();
        return;
    }
    value = &ob->variables[idx];

    if( value->type != T_MAPPING )
    {
    	free_string_svalue(sp--);
    	error("(query_temp) %s 物件的资料库变数型态错误。\n", ob->obname);
    }

    map = value->u.map;
    src = (char *)sp->u.string;
    dst = tmpstr = (char *)DMALLOC(SVALUE_STRLEN(sp) + 1, TAG_STRING, "query_temp");

    while (*src)
    {
	while (*src != '/' && *src)
	    *dst++ = *src++;
	if (*src == '/')
	{
	    while (*++src == '/');
	    if( dst == tmpstr ) continue;
	}
	*dst = '\0';
	value = find_string_in_mapping(map, tmpstr);

	if( value == &const0u ) break;
	if( value->type != T_MAPPING )
	{
	    if(*src) value = &const0u;
	    break;
	}
	map = value->u.map;
	dst = tmpstr;
    }

    FREE(tmpstr);
    free_string_svalue(sp--);
    push_svalue(value);
}
Exemplo n.º 3
0
/*
 * Execute a command for an object. Copy the command into a
 * new buffer, because 'parse_command()' can modify the command.
 * If the object is not current object, static functions will not
 * be executed. This will prevent forcing users to do illegal things.
 *
 * Return cost of the command executed if success (> 0).
 * When failure, return 0.
 */
void f_command (void)
{
    long rc = 0;

    if (current_object && !(current_object->flags & O_DESTRUCTED))
    {
	char buff[1000];
	int save_eval_cost = get_eval();

	if (SVALUE_STRLEN(sp) > sizeof(buff) - 1)
	    error("Too long command.\n");

	strncpy(buff, sp->u.string, sizeof(buff));
	buff[sizeof(buff) - 1] = 0;

	if (parse_command(buff, current_object))
#ifndef WIN32
             rc = save_eval_cost - get_eval();
#else
             rc = 1;
#endif
    }

    free_string_svalue(sp);
    put_number(rc);
}
Exemplo n.º 4
0
static void notify_no_command (void)
{
    union string_or_func p;
    svalue_t *v;

    if (!command_giver || !command_giver->interactive)
	return;
    p = command_giver->interactive->default_err_message;
    if (command_giver->interactive->iflags & NOTIFY_FAIL_FUNC) {
	save_command_giver(command_giver);
	v = call_function_pointer(p.f, 0);
	restore_command_giver();
	free_funp(p.f);
	if (command_giver && command_giver->interactive) {
	    if (v && v->type == T_STRING) {
		tell_object(command_giver, v->u.string, SVALUE_STRLEN(v));
	    }
	    command_giver->interactive->iflags &= ~NOTIFY_FAIL_FUNC;
	    command_giver->interactive->default_err_message.s = 0;
	}
    } else {
	if (p.s) {
	    tell_object(command_giver, p.s, strlen(p.s));
	    free_string(p.s);
	    command_giver->interactive->default_err_message.s = 0;
	} else {
	    tell_object(command_giver, default_fail_message, strlen(default_fail_message));
	}
    }
}
Exemplo n.º 5
0
void c_foreach P3(int, flags, int, idx1, int, idx2) {
    IF_DEBUG(stack_in_use_as_temporary++);
    
    if (flags & 4) {
	CHECK_TYPES(sp, T_MAPPING, 2, F_FOREACH);
	
	push_refed_array(mapping_indices(sp->u.map));
	(++sp)->type = T_NUMBER;
	sp->u.lvalue = (sp-1)->u.arr->item;
	sp->subtype = (sp-1)->u.arr->size;
		    
	(++sp)->type = T_LVALUE;
	if (flags & 2)
	    sp->u.lvalue = &current_object->variables[idx1 + variable_index_offset];
	else
	    sp->u.lvalue = fp + idx1;
    } else 
    if (sp->type == T_STRING) {
	(++sp)->type = T_NUMBER;
	sp->u.lvalue_byte = (unsigned char *)((sp-1)->u.string);
	sp->subtype = SVALUE_STRLEN(sp - 1);
    } else {
	CHECK_TYPES(sp, T_ARRAY, 2, F_FOREACH);

	(++sp)->type = T_NUMBER;
	sp->u.lvalue = (sp-1)->u.arr->item;
	sp->subtype = (sp-1)->u.arr->size;
    }

    (++sp)->type = T_LVALUE;
    if (flags & 1)
	sp->u.lvalue = &current_object->variables[idx2 + variable_index_offset];
    else
	sp->u.lvalue = fp + idx2;
}
Exemplo n.º 6
0
void c_rindex() {
    int i;

    switch (sp->type) {
#ifndef NO_BUFFER_TYPE
    case T_BUFFER:
	{
	    if ((sp-1)->type != T_NUMBER)
		error("Indexing a buffer with an illegal type.\n");
	    
	    i = sp->u.buf->size - (sp - 1)->u.number;
	    if ((i > sp->u.buf->size) || (i < 0))
		error("Buffer index out of bounds.\n");

	    i = sp->u.buf->item[i];
	    free_buffer(sp->u.buf);
	    (--sp)->u.number = i;
	    break;
	}
#endif
    case T_STRING:
	{
	    int len = SVALUE_STRLEN(sp);
	    if ((sp-1)->type != T_NUMBER) {
		error("Indexing a string with an illegal type.\n");
	    }
	    i = len - (sp - 1)->u.number;
	    if ((i > len) || (i < 0))
		error("String index out of bounds.\n");
	    i = (unsigned char) sp->u.string[i];
	    free_string_svalue(sp);
	    (--sp)->u.number = i;
	    break;
	}
    case T_ARRAY:
	{
	    array_t *vec = sp->u.arr;
	    
	    if ((sp-1)->type != T_NUMBER)
		error("Indexing an array with an illegal type\n");
	    i = vec->size - (sp - 1)->u.number;
	    if (i < 0 || i >= vec->size) error("Array index out of bounds.\n");
	    assign_svalue_no_free(--sp, &vec->item[i]);
	    free_array(vec);
	    break;
	}
    default:
	error("Indexing from the right on illegal type.\n");
    }
    
    /*
     * Fetch value of a variable. It is possible that it is a
     * variable that points to a destructed object. In that case,
     * it has to be replaced by 0.
     */
    if (sp->type == T_OBJECT && (sp->u.ob->flags & O_DESTRUCTED)) {
	free_object(sp->u.ob, "F_RINDEX");
	*sp = const0u;
    }
}
Exemplo n.º 7
0
static int pcre_match_single(svalue_t *str, svalue_t *pattern)
{
	pcre_t *run;
	int ret;

	run = CALLOCATE(1, pcre_t, TAG_TEMPORARY, "pcre_match_single : run");
	run->ovector = NULL;
	run->ovecsize = 0;
	assign_svalue_no_free(&run->pattern, pattern);
	run->subject  = str->u.string;
	run->s_length = SVALUE_STRLEN(str);


	if(pcre_magic(run) < 0)
	{
		error("PCRE compilation failed at offset %d: %s\n", run->erroffset,
				run->error);
		pcre_free_memory(run);
		return 0;
	}

	ret = pcre_query_match(run);

	/* Free memory */
	pcre_free_memory(run);
	return ret;
}
Exemplo n.º 8
0
void f_compress (void)
{
   unsigned char* buffer;
   unsigned char* input;
   int size;
   buffer_t* real_buffer;
   uLongf new_size;

   if (sp->type == T_STRING) {
      size = SVALUE_STRLEN(sp);
      input = (unsigned char*)sp->u.string;
   } else if (sp->type == T_BUFFER) {
      size = sp->u.buf->size;
      input = sp->u.buf->item;
   } else {
      pop_n_elems(st_num_arg);
      push_undefined();
      return ;
   }

   new_size = size;
   // Make it a little larger as specified in the docs.
   buffer = (unsigned char*)DXALLOC(size * 101 / 100 + 12, TAG_TEMPORARY, "compress");
   compress(buffer, &new_size, input, size);

   // Shrink it down.
   pop_n_elems(st_num_arg);
   real_buffer = allocate_buffer(new_size);
   write_buffer(real_buffer, 0, (char *)buffer, new_size);
   FREE(buffer);
   push_buffer(real_buffer);
}
Exemplo n.º 9
0
void
f_crypt (void)
{
    const char *res, *p;
    char salt[SALT_LEN + 1];
    const char *choice =
    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ./";

    if (sp->type == T_STRING && SVALUE_STRLEN(sp) >= 2) {
        p = sp->u.string;
    } else {
        int i;
        
        for (i = 0; i < SALT_LEN; i++)
            salt[i] = choice[random_number(strlen(choice))];

        salt[SALT_LEN] = 0;
        p = salt;
    }
    
    res = string_copy(CRYPT((sp-1)->u.string, p), "f_crypt");
    pop_stack();
    free_string_svalue(sp);
    sp->subtype = STRING_MALLOC;
    sp->u.string = res;
}
Exemplo n.º 10
0
void c_foreach(int  flags, int  idx1, int  idx2) {
    IF_DEBUG(stack_in_use_as_temporary++);
    
    if (flags & FOREACH_MAPPING) {
	CHECK_TYPES(sp, T_MAPPING, 2, F_FOREACH);
	
	push_refed_array(mapping_indices(sp->u.map));

	STACK_INC;
	sp->type = T_NUMBER;
	sp->u.lvalue = (sp-1)->u.arr->item;
	sp->subtype = (sp-1)->u.arr->size;
		    
	STACK_INC;
	sp->type = T_LVALUE;
	if (flags & FOREACH_LEFT_GLOBAL) {
	    sp->u.lvalue = &current_object->variables[idx1 + variable_index_offset];
	} else {
	    sp->u.lvalue = fp + idx1;
	}
    } else 
    if (sp->type == T_STRING) {
	STACK_INC;
	sp->type = T_NUMBER;
	sp->u.lvalue_byte = (unsigned char *)((sp-1)->u.string);
	sp->subtype = SVALUE_STRLEN(sp - 1);
    } else {
	CHECK_TYPES(sp, T_ARRAY, 2, F_FOREACH);

	STACK_INC;
	sp->type = T_NUMBER;
	sp->u.lvalue = (sp-1)->u.arr->item;
	sp->subtype = (sp-1)->u.arr->size;
    }

    if (flags & FOREACH_RIGHT_GLOBAL) {
	STACK_INC;
	sp->type = T_LVALUE;
	sp->u.lvalue = &current_object->variables[idx2 + variable_index_offset];
    } else if (flags & FOREACH_REF) {
	ref_t *ref = make_ref();
	svalue_t *loc = fp + idx2;

	/* foreach guarantees our target remains valid */
	ref->lvalue = 0;
	ref->sv.type = T_NUMBER;
	STACK_INC;
	sp->type = T_REF;
	sp->u.ref = ref;
	DEBUG_CHECK(loc->type != T_NUMBER && loc->type != T_REF, "Somehow a reference in foreach acquired a value before coming into scope");
	loc->type = T_REF;
	loc->u.ref = ref;
	ref->ref++;
    } else {
	STACK_INC;
	sp->type = T_LVALUE;
	sp->u.lvalue = fp + idx2;
    }
}
Exemplo n.º 11
0
void f_strwidth(){
  int len = SVALUE_STRLEN(sp);
  int width = 0;
  int i;
  for(i=0; i<len; i++)
    width += !(((sp->u.string[i]) & 0xc0) == 0x80);
  pop_stack();
  push_number(width);
}
Exemplo n.º 12
0
void f_str_to_arr(){
  static struct translation *newt = 0;
  if(!newt){
    newt = get_translator("UTF-32");
    translate_easy(newt->outgoing, " ");
  }
  int len;
  int *trans = (int *)translate(newt->outgoing, sp->u.string, SVALUE_STRLEN(sp)+1, &len);
  len/=4;
  array_t *arr = allocate_array(len);
  while(len--)
    arr->item[len].u.number = trans[len];
  free_svalue(sp, "str_to_arr");
  put_array(arr);
}
Exemplo n.º 13
0
void
f_replace_program (void)
{
    replace_ob_t *tmp;
    int name_len;
    char *name, *xname;
    program_t *new_prog;
    int var_offset;

    if (sp->type != T_STRING)
	bad_arg(1, F_REPLACE_PROGRAM);
    debug(d_flag, ("replace_program called"));

    if (!current_object)
	error("replace_program called with no current object\n");
    if (current_object == simul_efun_ob)
	error("replace_program on simul_efun object\n");

    if (current_object->prog->func_ref)
	error("cannot replace a program with function references.\n");

    name_len = SVALUE_STRLEN(sp);
    name = (char *) DMALLOC(name_len + 3, TAG_TEMPORARY, "replace_program");
    xname = name;
    strcpy(name, sp->u.string);
    if (name[name_len - 2] != '.' || name[name_len - 1] != 'c')
	strcat(name, ".c");
    if (*name == '/')
	name++;
    new_prog = search_inherited(name, current_object->prog, &var_offset);
    FREE(xname);
    if (!new_prog) {
	error("program to replace the current with has to be inherited\n");
    }
    if (!(tmp = retrieve_replace_program_entry())) {
	tmp = ALLOCATE(replace_ob_t, TAG_TEMPORARY, "replace_program");
	tmp->ob = current_object;
	tmp->next = obj_list_replace;
	obj_list_replace = tmp;
    }
    tmp->new_prog = new_prog;
    tmp->var_offset = var_offset;

    debug(d_flag, ("replace_program finished"));

    free_string_svalue(sp--);
}
Exemplo n.º 14
0
void f_pcre_extract(void)
{
	pcre_t *run;
	array_t *ret;

	run = CALLOCATE(1, pcre_t, TAG_TEMPORARY, "f_pcre_extract : run");
	assign_svalue_no_free(&run->pattern, sp);
	run->subject  = (sp - 1)->u.string;
	run->s_length = SVALUE_STRLEN(sp - 1);
	run->ovector = NULL;
	run->ovecsize = 0;

	if(pcre_magic(run) < 0)
	{
		error("PCRE compilation failed at offset %d: %s\n", run->erroffset,
				run->error);
		pop_2_elems();
		pcre_free_memory(run);
		return;
	}

	/* Pop the 2 arguments from the stack */

	if (run->rc < 0) /* No match. could do handling of matching errors if wanted */
	{
		pop_2_elems();
		pcre_free_memory(run);
		push_refed_array(&the_null_array);
		return;
	}
	else if (run->rc > (run->ovecsize/3 - 1))
	{
		pop_2_elems();
		pcre_free_memory(run);
		error("Too many substrings.\n");
		return;
	}


	ret = pcre_get_substrings(run);
	pop_2_elems();

	push_refed_array(ret);

	pcre_free_memory(run);
	return;
}
Exemplo n.º 15
0
void
f_oldcrypt (void) {
    char *res, salt[3];
    const char *choice =
    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ./";

    if (sp->type == T_STRING && SVALUE_STRLEN(sp) >= 2) {
        salt[0] = sp->u.string[0];
        salt[1] = sp->u.string[1];
        free_string_svalue(sp--);
    } else {
        salt[0] = choice[random_number(strlen(choice))];
        salt[1] = choice[random_number(strlen(choice))];
        pop_stack();
    }
    salt[2] = 0;
    res = string_copy(OLDCRYPT(sp->u.string, salt), "f_crypt");
    free_string_svalue(sp);
    sp->subtype = STRING_MALLOC;
    sp->u.string = res;
}
Exemplo n.º 16
0
void f_B2G ()
{
  int i;
  char *istr, *ostr;

  istr = (char *)sp->u.string;
  i = SVALUE_STRLEN(sp);

  if(i == 0)
  {
    push_number(0);
    free_string_svalue(sp);
    return;
  }
  
  ostr = new_string(i, "f_B2G");
  Big2GB(istr, ostr, i);

  free_string_svalue(sp);
  put_malloced_string(ostr);
}
Exemplo n.º 17
0
void f_bg5cc ()
{
  char *istr, *ostr, *ret;
  unsigned char s;

  istr = (char *)sp->u.string;

  if(SVALUE_STRLEN(sp) == 0)
    push_number(0);

  if(!strchr(istr, '\\'))
  {
    ret = string_copy(istr, "f_bg5cc");
  }
  else
  {
    ostr = ret = new_string(max_string_length, "f_bg5cc");

    while(*istr)
    {
      *ostr++ = s = *istr++;

      if(is_B51(s))
      {
        *ostr++ = s = *istr++;

        if(s == '\\' && *istr != '\\')
          *ostr++ = s;
      }
    }

    *ostr = '\0';
  }

  free_string_svalue(sp);
  put_malloced_string(ret);
}
Exemplo n.º 18
0
/* Hideous mangling of C code by Taffyd. */ 
void query_multiple_short(svalue_t * arg, const char * type, int no_dollars, int quiet, int dark, int num_arg) { 
    char m[] = "$M$";
    char s[] = "_short";
    char default_function[] = "a_short";
    char separator[] = ", ";
    char andsep[] = " and ";
    int mlen = strlen(m);
    int slen = strlen(s);
    int seplen = strlen( separator );
    int andlen = strlen( andsep );

    array_t *arr = arg->u.arr;
    svalue_t *sv;
    svalue_t *v;
    int size = arr->size;
    int i;
    int len;
    int total_len;
    char *str, *res;
    object_t *ob;
    char *fun; 

    if (!size) {
        str = new_string(0, "f_query_multiple_short");
        str[0] = '\0';
        pop_n_elems(num_arg);
        push_malloced_string(str);
        return; 
    }
    
    /* 
    if (no_dollars && sizeof(args) && objectp(args[0]) && undefinedp(dark) && 
        this_player() && environment(this_player())) {
        dark = this_player()->check_dark(environment(this_player())->query_light());
        if (dark) {
        return "some objects you cannot make out";
        }
    } */ 

    if (no_dollars && arr->item->type == T_OBJECT && !dark && command_giver &&
        command_giver->super) { 
        call_origin = ORIGIN_EFUN;
        if(!apply_low("query_light", command_giver->super, 0))
            push_number(0);
        v = apply("check_dark", command_giver, 1, ORIGIN_EFUN);
        
        if (v && v->type == T_NUMBER && v->u.number) {
            pop_n_elems(num_arg);
            copy_and_push_string("some objects you cannot make out"); 
            return;
        }
    }

    /* If we don't have a type parameter, then use default_function */ 
    /* We need to free this value with FREE_MSTR() */ 

    if ( !type ) { 
        len = strlen( default_function );
        fun = new_string( len, "f_query_multiple_short");
        fun[len] = '\0';
        strncpy( fun, default_function, len );
    }
    else { 
        len = strlen( type ) + slen;
        fun = new_string( len, "f_query_multiple_short");
        fun[len] = '\0';
        strncpy( fun, type, len );
        strncpy( fun + strlen( type ), s, slen);
    }
   
    /* Check to see if there are any non-objects in the array. */ 
    for (i = 0; i < size; i++) {
        if ((arr->item + i)->type != T_OBJECT) {
            break;
        }
    }

    /* The array consists only of objects, and will use the $M$ 
       expansion code. */ 
    if (i == size && !no_dollars) {
        str = new_string(max_string_length, "f_query_multiple_short");
        str[max_string_length]= '\0';
        strncpy(str, m, mlen);
        total_len = mlen;

        for ( i = 0; i < size; i++ ) {
            sv = (arr->item + i);
            push_number(quiet);
            v = apply(fun, sv->u.ob, 1, ORIGIN_EFUN);

            if (!v || v->type != T_STRING) {
                continue;                
            }
            if(total_len + SVALUE_STRLEN(v) > max_string_length - mlen)
                continue;
            strncpy(str + total_len, v->u.string, (len = SVALUE_STRLEN(v)));
            total_len += len;
        }

        strncpy(str + total_len, m, mlen);
        total_len += mlen;

        res = new_string( total_len, "f_query_multiple_short" );
        res[ total_len ] = '\0';
        memcpy(res, str, total_len);

        /* Clean up our temporary buffer. */ 

        FREE_MSTR(str);
        FREE_MSTR(fun);

        pop_n_elems(num_arg);
        push_malloced_string(res);
        return;
    }

    /* This is a mixed array, so we don't use $M$ format.  Instead, we 
       do as much $a_short$ conversion as we can etc.  */ 

    str = new_string(max_string_length, "f_query_multiple_short");
    str[max_string_length]= '\0';
    total_len = 0;

    for ( i = 0; i < size; i++ ) {
        sv = (arr->item + i);
    
        switch(sv->type) {
            case T_STRING:
                len = SVALUE_STRLEN(sv);
                if(total_len + len < max_string_length){
                    strncpy(str + total_len, sv->u.string, len);
                    total_len += len;
                }
                break;
            case T_OBJECT:
                push_number(quiet);
                v = apply(fun, sv->u.ob, 1, ORIGIN_EFUN);

                if (!v || v->type != T_STRING) {
                    continue;                
                }

                if(total_len + SVALUE_STRLEN(v) < max_string_length){
                    strncpy(str + total_len, v->u.string, 
                            (len = SVALUE_STRLEN(v)));
                    total_len += len;
                }

                break;
            case T_ARRAY:
              /* Does anyone use this? */ 
              /* args[ i ] = "$"+ type +"_short:"+ file_name( args[ i ][ 1 ] ) +"$"; */ 
            default:    
                /* Get the next element. */ 
                continue;            
                break;
        }
        
        if ( len && size > 1 ) {
            if ( i < size - 2 ) {
                if(total_len+seplen < max_string_length){
                    strncpy( str + total_len, separator, seplen );
                    total_len += seplen;
                }
            }
            else { 
                if ( i < size - 1 ) {    
                    if(total_len+andlen < max_string_length){
                        strncpy( str + total_len, andsep, andlen );
                        total_len += andlen;
                    }
                }
            }
        }
    }

    FREE_MSTR(fun);

    res = new_string(total_len, "f_query_multiple_short");
    res[total_len] = '\0';
    memcpy(res, str, total_len);

    FREE_MSTR(str);

    /* Ok, now that we have cleaned up here we have to decide what to do
       with it. If nodollars is 0, then we need to pass it to an object
       for conversion. */ 

    if (no_dollars) { 
        if (command_giver) { 
            /* We need to call on this_player(). */ 
            push_malloced_string(res);
            v = apply("convert_message", command_giver, 1, ORIGIN_EFUN);
            
            if (v && v->type == T_STRING) { 
                pop_n_elems(num_arg);
                share_and_push_string(v->u.string);
            }
            else { 
                pop_n_elems(num_arg);
                push_undefined();
            }
            
        }
        else {
            /* We need to find /global/player. */ 
            /* Does this work? Seems not to. */ 
            ob = find_object("/global/player");
            
            if (ob) {
                push_malloced_string(res);
                v = apply("convert_message", ob, 1, ORIGIN_EFUN);
                
                /* Return the result! */ 
                if (v && v->type == T_STRING) { 
                    pop_n_elems(num_arg);
                    share_and_push_string(v->u.string);
                }
                else { 
                    pop_n_elems(num_arg);
                    push_undefined();
                }
            }
            else { 
                pop_n_elems(num_arg);
                push_undefined();
            }
        }

    }
    else { 
        pop_n_elems(num_arg);
        push_malloced_string(res);
    }
} /* query_multiple_short() */
Exemplo n.º 19
0
void f_cwrap ()
{
	register int i, j;
	int width, slen, blanks;
	register char *istr, *ostr, *ret;

	if(st_num_arg >= 2)
	{
		if(st_num_arg == 3)
		{
			blanks = sp->u.number;
			pop_stack();
	
			if(blanks < 0)
				blanks = 0;
		}
		else
			blanks = 4;
	
		width = sp->u.number;
		pop_stack();
	
		if(width < 2)
			width = 64;
	
		if(width - blanks < 2)
		{
			width = 64;
			blanks = 4;
		}
	}
	else
	{
		blanks = 4;
		width = 64;
	}

	istr = (char *)sp->u.string;
	slen = SVALUE_STRLEN(sp);
	
	if(slen < blanks)
		blanks = 0;
	
	i = blanks;
	
	ostr = ret = new_string(slen+slen/width+blanks, "f_cwrap");
	
	while(blanks--)
		*ostr++ = ' ';
	
	while(*istr)
	{
		if(*istr == '\n')
		{
			istr++;
			continue;
		}
	
		if(istr[0] == 27 && istr[1] == '[')
		{
			j=2;
	
			while(istr[j] && (isdigit(istr[j]) || istr[j]==';'))
				j++;
	
			if(istr[j++] == 'm')
			{
				while(j--)
					*ostr++ = *istr++;
	
				continue;
			}
		}
	
		i++;
		*ostr++ = *istr++;
	
		if(is_B51((unsigned char)*(istr-1)))
		{
			i++;
			*ostr++ = *istr++;
		}
		else if((unsigned char)*(istr-1) == '\t')
			i += 4;
	
		if(i >= width)
		{
			*ostr++ = '\n';
			i = 0;
		}
	}
	
	*ostr = '\0';
	
	ostr = string_copy(ret, "f_cwrap");
	FREE_MSTR(ret);
	
	free_string_svalue(sp);
	put_malloced_string(ostr);
}
Exemplo n.º 20
0
//string pcre_replace_callback(string, string, function)
void f_pcre_replace_callback(void)
{
	int num_arg = st_num_arg, i;
	char *ret;
	pcre_t *run;
	svalue_t *arg;
	array_t *arr, *r;
	function_to_call_t ftc;

	arg = sp - num_arg + 1;

	run = CALLOCATE(1, pcre_t, TAG_TEMPORARY, "f_pcre_replace: run");
	run->ovector = NULL;
	run->ovecsize = 0;
	run->subject = arg->u.string;
	assign_svalue_no_free(&run->pattern, (arg + 1));

	run->s_length = SVALUE_STRLEN(arg);

	if(pcre_magic(run) < 0)
	{
		pcre_free_memory(run);
		error("PCRE compilation failed at offset %d: %s\n", run->erroffset,
				run->error);
	}


	if (run->rc < 0) /* No match. could do handling of matching errors if wanted */
	{
		pop_n_elems(num_arg-1);
		pcre_free_memory(run);
		return;
	}


	if (run->rc > (run->ovecsize/3-1))
	{
		pcre_free_memory(run);
		error("Too many substrings.\n");
	}

	arr = pcre_get_substrings(run);

	if(arg[2].type == T_FUNCTION || arg[2].type == T_STRING)
		process_efun_callback(2, &ftc, F_PCRE_REPLACE_CALLBACK);
	else {// 0
		pcre_free_memory(run);
		error("Illegal third argument (0) to pcre_replace_callback");
	}


	r = allocate_array(run->rc - 1); //can't use the empty variant in case we error below

	push_refed_array(r);
	push_refed_array(arr);
	error_context_t econ;

	if (!save_context(&econ)){
		pcre_free_memory(run);
		error("context stack full!\n");
	}
	if (SETJMP(econ.context)) {
		restore_context(&econ);
		/* condition was restored to where it was when we came in */
		pcre_free_memory(run);
		pop_context(&econ);
		error("error in callback!\n");
	}

	for (i = 0; i < run->rc - 1; i++)
	{
		svalue_t *v;
		push_svalue(arr->item + i);
		push_number(i);
		v = call_efun_callback(&ftc, 2);


		/* Mimic behaviour of map(string, function) when function pointer returns null,
         ie return the input.  */ 
		if (v && v->type == T_STRING && v->u.string != NULL)
			assign_svalue_no_free(&r->item[i], v);
		else
			assign_svalue_no_free(&r->item[i], &arr->item[i]);
	}
	pop_context(&econ);
	ret = pcre_get_replace(run, r);

	pop_n_elems(num_arg+2); //refed arrays
	push_malloced_string(ret);
	pcre_free_memory(run);
	return;
}
Exemplo n.º 21
0
static array_t *pcre_match(array_t *v, svalue_t *pattern, int flag)
{
	pcre_t *run;
	array_t *ret;
	svalue_t *sv1, *sv2;
	char *res;
	int num_match, size, match = !(flag & 2);

	if (!(size = v->size))
		return &the_null_array;

	run = CALLOCATE(1, pcre_t, TAG_TEMPORARY, "pcre_match : run");
	run->ovector = NULL;
	run->ovecsize = 0;
	assign_svalue_no_free(&run->pattern, pattern);

	run->re = pcre_get_cached_pattern(&pcre_cache, &run->pattern);

	if (run->re == NULL)
	{
		if (pcre_local_compile(run) == NULL)
		{
			const char *rerror = run->error;
			int offset = run->erroffset;

			pcre_free_memory(run);
			error("PCRE compilation failed at offset %d: %s\n", offset, rerror);
		}
		else
			pcre_cache_pattern(&pcre_cache, run->re, &run->pattern);
	}

	res       = (char*)DMALLOC(size, TAG_TEMPORARY, "prcre_match: res");
	sv1       = v->item + size;
	num_match = 0;

	while (size--)
	{
		if ((--sv1)->type != T_STRING)
		{
			res[size] = 0;
			continue;
		}

		run->subject  = sv1->u.string;
		run->s_length = SVALUE_STRLEN(sv1);

		pcre_local_exec(run);

		if (pcre_query_match(run) != match) //was not checking for match! (woom)
		{
			res[size] = 0;
			continue;
		}

		res[size] = 1;
		num_match++;
	}

	flag &= 1;
	ret  = allocate_empty_array(num_match << flag);
	sv2  = ret->item + (num_match << flag);
	size = v->size;

	while (size--)
	{
		if (res[size])
		{
			if (flag)
			{
				(--sv2)->type = T_NUMBER;
				sv2->u.number = size + 1;
			}

			(--sv2)->type = T_STRING;

			sv1  = v->item + size;
			*sv2 = *sv1;

			if (sv1->subtype & STRING_COUNTED)
			{
				INC_COUNTED_REF(sv1->u.string);
				ADD_STRING(MSTR_SIZE(sv1->u.string));
			}

			if (!--num_match)
				break;
		}
	}
	FREE(res);
	pcre_free_memory(run);

	return ret;
}
Exemplo n.º 22
0
void c_index() {
    int i;
    
    switch (sp->type) {
    case T_MAPPING:
	{
	    svalue_t *v;
	    mapping_t *m;
	    
	    v = find_in_mapping(m = sp->u.map, sp - 1);
	    assign_svalue(--sp, v);    /* v will always have a
					* value */
	    free_mapping(m);
	    break;
	}
#ifndef NO_BUFFER_TYPE
    case T_BUFFER:
	{
	    if ((sp-1)->type != T_NUMBER)
		error("Indexing a buffer with an illegal type.\n");
	    
	    i = (sp - 1)->u.number;
	    if ((i > sp->u.buf->size) || (i < 0))
		error("Buffer index out of bounds.\n");
	    i = sp->u.buf->item[i];
	    free_buffer(sp->u.buf);
	    (--sp)->u.number = i;
	    break;
	}
#endif
    case T_STRING:
	{
	    if ((sp-1)->type != T_NUMBER) {
		error("Indexing a string with an illegal type.\n");
	    }
	    i = (sp - 1)->u.number;
	    if ((i > SVALUE_STRLEN(sp)) || (i < 0))
		error("String index out of bounds.\n");
	    i = (unsigned char) sp->u.string[i];
	    free_string_svalue(sp);
	    (--sp)->u.number = i;
	    break;
	}
    case T_ARRAY:
	{
	    array_t *arr;
	    
	    if ((sp-1)->type != T_NUMBER)
		error("Indexing an array with an illegal type\n");
	    i = (sp - 1)->u.number;
	    if (i<0) error("Negative index passed to array.\n");
	    arr = sp->u.arr;
	    if (i >= arr->size) error("Array index out of bounds.\n");
	    assign_svalue_no_free(--sp, &arr->item[i]);
	    free_array(arr);
	    break;
	}
    default:
	error("Indexing on illegal type.\n");
    }
    
    /*
     * Fetch value of a variable. It is possible that it is a
     * variable that points to a destructed object. In that case,
     * it has to be replaced by 0.
     */
    if (sp->type == T_OBJECT && (sp->u.ob->flags & O_DESTRUCTED)) {
	free_object(sp->u.ob, "F_INDEX");
	*sp = const0u;
    }
}
Exemplo n.º 23
0
/* This is mostly copy/paste from reg_assoc, some parts are changed
 * TODO: rewrite with new logic
 */
static array_t *pcre_assoc(svalue_t *str, array_t *pat, array_t *tok, svalue_t *def)
{
	int i, size;
	const char *tmp;
	array_t *ret;

	if ((size = pat->size) != tok->size)
		error("Pattern and token array size must be identical.\n");

	for (i = 0; i < size; i++)
		if (pat->item[i].type != T_STRING)
			error("Non-string found in pattern array.\n");

	ret = allocate_empty_array(2);

	if (size)
	{
		pcre_t **rgpp;
		struct reg_match {
			int tok_i;
			const char *begin, *end;
			struct reg_match *next;
		} *rmp = (struct reg_match *) 0, *rmph = (struct reg_match *) 0;
		int num_match = 0, length;
		svalue_t *sv1, *sv2, *sv;
		int regindex;
		pcre_t *tmpreg;
		int laststart;

		rgpp = CALLOCATE(size, pcre_t *, TAG_TEMPORARY, "pcre_assoc : rgpp");

		for (i = 0; i < size; i++)
		{
			rgpp[i] = CALLOCATE(1, pcre_t, TAG_TEMPORARY, "pcre_assoc : rgpp[i]");
			rgpp[i]->ovector = NULL;
			rgpp[i]->ovecsize = 0;
			assign_svalue_no_free(&rgpp[i]->pattern, &pat->item[i]);
			rgpp[i]->re = pcre_get_cached_pattern(&pcre_cache, &rgpp[i]->pattern);

			if (rgpp[i]->re == NULL)
			{
				if (pcre_local_compile(rgpp[i]) == NULL)
				{
					const char *rerror = rgpp[i]->error;
					int offset = rgpp[i]->erroffset;

					while (i--)
						pcre_free_memory(rgpp[i]);

					FREE(rgpp);
					free_empty_array(ret);
					error("PCRE compilation failed at offset %d: %s\n", offset, rerror);
				}
				else
					pcre_cache_pattern(&pcre_cache, rgpp[i]->re, &rgpp[i]->pattern);
			}
		}


		tmp = str->u.string;
		int totalsize = SVALUE_STRLEN(str);
		int used = 0;
		while (*tmp)
		{
			laststart =  0;
			regindex  = -1;

			for (i = 0; i < size; i++)
			{

				rgpp[i]->subject = tmp;
				rgpp[i]->s_length = totalsize-used;

				pcre_local_exec(tmpreg = rgpp[i]);

				if (pcre_query_match(tmpreg))
				{
					char *curr_temp;
					size_t curr_temp_sz;

					curr_temp_sz = totalsize - used - tmpreg->ovector[0];
					if(!tmpreg->ovector[0]){
					  regindex = i;
					  break;
					}
					if (laststart < curr_temp_sz)
					{
						laststart = curr_temp_sz;
						regindex = i;
					}
				}
			}

			if (regindex >= 0)
			{
				const char *rmpb_tmp, *rmpe_tmp;
				size_t rmpb_tmp_sz, rmpe_tmp_sz;
				num_match++;

				if (rmp)
				{
					rmp->next = ALLOCATE(struct reg_match,
							TAG_TEMPORARY, "pcre_assoc : rmp->next");
					rmp = rmp->next;
				}
				else
					rmph = rmp = ALLOCATE(struct reg_match,
							TAG_TEMPORARY, "pcre_assoc : rmp");

				tmpreg = rgpp[regindex];

				rmpb_tmp = tmp + tmpreg->ovector[0];
				rmpe_tmp = tmp + tmpreg->ovector[1];

				rmp->begin = rmpb_tmp;
				rmp->end = tmp = rmpe_tmp;
				used+=tmpreg->ovector[1];
				rmp->tok_i = regindex;
				rmp->next = (struct reg_match *) 0;
			}
			else
				break;

			if (rmp->begin == tmp && (!*++tmp))
				break;
		}
Exemplo n.º 24
0
void f_sha1(void)
{
   unsigned long int h0,h1,h2,h3,h4,a,b,c,d,e,f,k,temp;
   int i, j, m;

   h0 = 0x67452301;
   h1 = 0xEFCDAB89;
   h2 = 0x98BADCFE;
   h3 = 0x10325476;
   h4 = 0xC3D2E1F0;

   unsigned char *str;
   str = (unsigned char *)malloc(SVALUE_STRLEN(sp)+100);
   
   strcpy((char *)str, (const char *)sp->u.string);
   
   int current_length = strlen((const char *)str);
   int original_length = current_length;
   str[current_length] = 0x80;
   str[current_length + 1] = '\0';
   
   char ic = str[current_length];
   current_length++;
   
   int ib = current_length % 64;
   if (ib < 56)
      ib = 56 - ib;
   else
      ib = 120 - ib;
      
   for (i=0; i<ib; i++)
   {
      str[current_length] = 0x00;
      current_length++;
   }
   
   str[current_length + 1] = '\0';
   
   for (i=0; i<6; i++)
   {
      str[current_length] = 0x0;
      current_length++;
   }
   
   str[current_length] = (original_length * 8) / 0x100;
   current_length++;
   str[current_length] = (original_length * 8) % 0x100;
   current_length++;
   str[current_length + i] = '\0';
   
   int number_of_chunks = current_length / 64;
   unsigned long int word[80];
   
   for (i=0; i<number_of_chunks; i++)
   {
      for (j=0; j<16; j++)
      {
         word[j] = str[i*64+j*4+0] * 0x1000000 + str[i*64+j*4+1] * 0x10000 + str[i*64+j*4+2] * 0x100 + str[i*64+j*4+3];
      }
      
      for (j=16; j<80; j++)
      {
         word[j] = rotateleft((word[j-3] ^ word[j-8] ^ word[j-14] ^ word[j-16]),1);
      }
      
      a = h0;
      b = h1;
      c = h2;
      d = h3;
      e = h4;
      
      for (m=0; m<80; m++)
      {
         if (m <= 19)
         {
            f = (b & c) | ((~b) & d);
            k = 0x5A827999;
         }
         else if (m <= 39)
         {
            f = b ^ c ^ d;
            k = 0x6ED9EBA1;
         }
         else if (m <= 59)
         {
            f = (b & c) | (b & d) | (c & d);
            k = 0x8F1BBCDC;
         }
         else
         {
            f = b ^ c ^ d;
            k = 0xCA62C1D6;
         }
         
         temp = (rotateleft(a, 5) + f + e + k + word[m]) & 0xFFFFFFFF;
         e = d;
         d = c;
         c = rotateleft(b, 30);
         b = a;
         a = temp;
      }
      
      h0 = h0 + a;
      h1 = h1 + b;
      h2 = h2 + c;
      h3 = h3 + d;
      h4 = h4 + e;
   }
   
   sprintf((char *)str, "%x%x%x%x%x", h0, h1, h2, h3, h4);
   pop_stack();
   push_malloced_string(string_copy((char *)str, "f_sha1"));
   free(str);
}
Exemplo n.º 25
0
void f_delete_temp () {
    int i;
    object_t *ob;
    svalue_t *value, lv;
    mapping_t *map;
    unsigned short type;
    char *src, *dst;

    if( st_num_arg == 2 )
    {
    	ob = sp->u.ob;
    	pop_stack();
    }
    else
    	ob = current_object;

    i = find_global_variable(ob->prog, "tmp_dbase", &type, 0);
    if (i == -1)
    {
        free_string_svalue(sp--);
        error("(delete_temp) %s 物件未宣告全域映射资料库变数。\n", ob->obname);
    }

    value = &ob->variables[i];

    if( value->type != T_MAPPING )
    {
        free_string_svalue(sp--);
    	error("(delete_temp) %s 物件的资料库变数型态错误。\n", ob->obname);
    }

    map = value->u.map;
    src = (char *)sp->u.string;
    dst = (char *)DMALLOC(SVALUE_STRLEN(sp)+1, TAG_STRING, "delete_temp");

    while(*src)
    {
    	i = 0;

	while(*src != '/' && *src)
	    *(dst+(i++)) = *src++;

	if(*src == '/')
	{
	    while (*++src == '/');
	    if(!i) continue;
	}

	*(dst+i) = '\0';

	value = find_string_in_mapping(map, dst);

	if( value == &const0u ) break;

	if(!*src)
	{
   	    	lv.type = T_STRING;
   	    	lv.subtype = STRING_CONSTANT;
    		lv.u.string = dst;
	    	mapping_delete(map, &lv);
	    	FREE(dst);
	    	free_string_svalue(sp--);
	    	return;
	}
	if( value->type != T_MAPPING ) break;

	map = value->u.map;
    }

    FREE(dst);
    free_string_svalue(sp--);
}
Exemplo n.º 26
0
void f_addn_temp () {
    int i, j;
    object_t *ob;
    unsigned short type;
    mapping_t *map;
    svalue_t *value;
    char *src, *dst;
    char *tmpstr;

    if( st_num_arg == 3 )
    {
        ob = sp->u.ob;
        pop_stack();
    }
    else
        ob = current_object;

    i = find_global_variable(ob->prog, "tmp_dbase", &type, 0);
    if (i == -1)
    {
        pop_2_elems();
        error("(addn_temp) %s 物件未宣告全域映射资料库变数。\n", ob->obname);
    }

    value = &ob->variables[i];

    if( value->type != T_MAPPING )
    {
    	pop_2_elems();
    	error("(addn_temp) %s 物件的资料库变数型态错误。\n", ob->obname);
    }

    map = value->u.map;
    src = (char *)(sp-1)->u.string;
    dst = tmpstr = (char *)DMALLOC(SVALUE_STRLEN(sp-1) + 1, TAG_STRING, "addn_temp");
    j=0;

    while (*src)
    {
    	i=0;
    	if( ++j > 20 )
	{
    		pop_2_elems();
    		error("(addn_temp) %s too deep mapping(20)。\n", ob->obname);
    	}

	while (*src != '/' && *src)
	{
	    *(dst+i) = *src++;
	    i++;
	}

	if (*src == '/')
	{
	    while (*++src == '/');
	    if(!i) continue;
	}
	*(dst+i) = '\0';

	value = find_string_in_mapping(map, tmpstr);

	if(!*src)
	{
    		if( value == &const0u || value->type != T_NUMBER )
    		{
    			value = insert_in_mapping(map, dst);
			*value = *sp--;
    		}
    		else
    			value->u.number += (sp--)->u.number;
    		break;
    	}

	if(value == &const0u || value->type != T_MAPPING)
	{
    		value = insert_in_mapping(map, dst);
		value->type = T_MAPPING;
		value->u.map = allocate_mapping(0);
	}

	map = value->u.map;
	dst = tmpstr;
    }

    FREE(tmpstr);
    free_string_svalue(sp--);
    push_svalue(value);
}
Exemplo n.º 27
0
/*
 * THE (s)printf() function.
 * It returns a pointer to it's internal buffer (or a string in the text
 * segment) thus, the string must be copied if it has to survive after
 * this function is called again, or if it's going to be modified (esp.
 * if it risks being free()ed).
 */
char *string_print_formatted (const char * format_str, int argc, svalue_t * argv)
{
    format_info finfo;
    svalue_t *carg;     /* current arg */
    unsigned int nelemno = 0;   /* next offset into array */
    unsigned int fpos;          /* position in format_str */
    int fs;                     /* field size */
    int pres;                   /* precision */
    pad_info_t pad;             /* fs pad string */
    unsigned int i;
    char *retvalue;
    int last;

    push_sprintf_state();
    STACK_INC;
    sp->type = T_ERROR_HANDLER;
    sp->u.error_handler = pop_sprintf_state;

    last = 0;
    for (fpos = 0; 1; fpos++) {
        char c = format_str[fpos];

        if (c == '\n' || !c) {
            int column_stat = 0;

            if (last != fpos) {
                add_nstr(format_str + last, fpos - last);
                last = fpos + 1;
            } else last++;

            if (!sprintf_state->csts) {
                if (!c)
                    break;
                ADD_CHAR('\n');
                continue;
            }
            ADD_CHAR('\n');
            while (sprintf_state->csts) {
                cst **temp;

                temp = &(sprintf_state->csts);
                while (*temp) {
                    if ((*temp)->info & INFO_COLS) {
                        if (*((*temp)->d.col - 1) != '\n')
                            while (*((*temp)->d.col) == ' ')
                                (*temp)->d.col++;
                        add_pad(0, (*temp)->start - get_curpos());
                        column_stat = add_column(temp, 0);
                        if (!column_stat)
                            temp = &((*temp)->next);
                    } else {
                        add_pad(0, (*temp)->start - get_curpos());
                        if (!add_table(temp))
                            temp = &((*temp)->next);
                    }
                }               /* of while (*temp) */
                if (sprintf_state->csts || c == '\n')
                    ADD_CHAR('\n');
            }                   /* of while (sprintf_state->csts) */
            if (column_stat == 2)
                ADD_CHAR('\n');
            if (!c)
                break;
        } else
            if (c == '%') {
                if (last != fpos) {
                    add_nstr(format_str + last, fpos - last);
                    last = fpos + 1;
                } else last++;
                if (format_str[fpos + 1] == '%') {
                    ADD_CHAR('%');
                    fpos++;
                    last++;
                    continue;
                }
                GET_NEXT_ARG;
                fs = 0;
                pres = 0;
                pad.len = 0;
                finfo = 0;
                for (fpos++; !(finfo & INFO_T); fpos++) {
                    if (!format_str[fpos]) {
                        finfo |= INFO_T_ERROR;
                        break;
                    }
                    if (((format_str[fpos] >= '0') && (format_str[fpos] <= '9'))
                            || (format_str[fpos] == '*')) {
                        if (pres == -1) {   /* then looking for pres */
                            if (format_str[fpos] == '*') {
                                if (carg->type != T_NUMBER)
                                    ERROR(ERR_INVALID_STAR);
                                pres = carg->u.number;
                                GET_NEXT_ARG;
                                continue;
                            }
                            pres = format_str[fpos] - '0';
                            for (fpos++;
                                    (format_str[fpos] >= '0') && (format_str[fpos] <= '9'); fpos++) {
                                pres = pres * 10 + format_str[fpos] - '0';
                            }
                            if (pres < 0) pres = 0;
                        } else {    /* then is fs (and maybe pres) */
                            if ((format_str[fpos] == '0') && (((format_str[fpos + 1] >= '1')
                                            && (format_str[fpos + 1] <= '9')) || (format_str[fpos + 1] == '*'))) {
                                pad.what = "0";
                                pad.len = 1;
                            } else {
                                if (format_str[fpos] == '*') {
                                    if (carg->type != T_NUMBER)
                                        ERROR(ERR_INVALID_STAR);
                                    fs = carg->u.number;
                                    if (fs < 0) fs = 0;
                                    if (pres == -2)
                                        pres = fs;  /* colon */
                                    GET_NEXT_ARG;
                                    continue;
                                }
                                fs = format_str[fpos] - '0';
                            }
                            for (fpos++;
                                    (format_str[fpos] >= '0') && (format_str[fpos] <= '9'); fpos++) {
                                fs = fs * 10 + format_str[fpos] - '0';
                            }
                            if (fs < 0) fs = 0;
                            if (pres == -2) {       /* colon */
                                pres = fs;
                            }
                        }
                        fpos--; /* about to get incremented */
                        continue;
                    }
                    switch (format_str[fpos]) {
                        case ' ':
                            finfo |= INFO_PP_SPACE;
                            break;
                        case '+':
                            finfo |= INFO_PP_PLUS;
                            break;
                        case '-':
                            finfo |= INFO_J_LEFT;
                            break;
                        case '|':
                            finfo |= INFO_J_CENTRE;
                            break;
                        case '@':
                            finfo |= INFO_ARRAY;
                            break;
                        case '=':
                            finfo |= INFO_COLS;
                            break;
                        case '#':
                            finfo |= INFO_TABLE;
                            break;
                        case '.':
                            pres = -1;
                            break;
                        case ':':
                            pres = -2;
                            break;
#ifdef DEBUG
                        case '%':
                            finfo |= INFO_T_NULL;
                            break;      /* never reached */
#endif
                        case 'O':
                            finfo |= INFO_T_LPC;
                            break;
                        case 's':
                            finfo |= INFO_T_STRING;
                            break;
                        case 'd':
                        case 'i':
                            finfo |= INFO_T_INT;
                            break;
                        case 'f':
                            finfo |= INFO_T_FLOAT;
                            break;
                        case 'c':
                            finfo |= INFO_T_CHAR;
                            break;
                        case 'o':
                            finfo |= INFO_T_OCT;
                            break;
                        case 'x':
                            finfo |= INFO_T_HEX;
                            break;
                        case 'X':
                            finfo |= INFO_T_C_HEX;
                            break;
                        case '\'':
                            fpos++;
                            pad.what = format_str + fpos;
                            while (1) {
                                if (!format_str[fpos])
                                    ERROR(ERR_UNEXPECTED_EOS);
                                if (format_str[fpos] == '\\') {
                                    if (!format_str[++fpos])
                                        ERROR(ERR_UNEXPECTED_EOS);
                                } else
                                    if (format_str[fpos] == '\'') {
                                        pad.len = format_str + fpos - pad.what;
                                        if (!pad.len)
                                            ERROR(ERR_NULL_PS);
                                        break;
                                    }
                                fpos++;
                            }
                            break;
                        default:
                            finfo |= INFO_T_ERROR;
                    }
                }                   /* end of for () */
                if (pres < 0)
                    ERROR(ERR_PRES_EXPECTED);
                /*
                 * now handle the different arg types...
                 */
                if (finfo & INFO_ARRAY) {
                    if (carg->type != T_ARRAY)
                        ERROR(ERR_ARRAY_EXPECTED);
                    if (carg->u.arr->size == 0) {
                        last = fpos;
                        fpos--;     /* 'bout to get incremented */
                        continue;
                    }
                    carg = (argv + sprintf_state->cur_arg)->u.arr->item;
                    nelemno = 1;    /* next element number */
                }
                while (1) {
                    if ((finfo & INFO_T) == INFO_T_LPC) {
                        outbuffer_t outbuf;

                        outbuf_zero(&outbuf);
                        svalue_to_string(carg, &outbuf, 0, 0, 0);
                        outbuf_fix(&outbuf);

                        sprintf_state->clean.type = T_STRING;
                        sprintf_state->clean.subtype = STRING_MALLOC;
                        sprintf_state->clean.u.string = outbuf.buffer;
                        carg = &(sprintf_state->clean);
                        finfo ^= INFO_T_LPC;
                        finfo |= INFO_T_STRING;
                    }
                    if ((finfo & INFO_T) == INFO_T_ERROR) {
                        ERROR(ERR_INVALID_FORMAT_STR);
#ifdef DEBUG
                    } else if ((finfo & INFO_T) == INFO_T_NULL) {
                        /* never reached... */
                        fprintf(stderr, "/%s: (s)printf: INFO_T_NULL.... found.\n",
                                current_object->obname);
                        ADD_CHAR('%');
#endif
                    } else if ((finfo & INFO_T) == INFO_T_STRING) {
                        int slen;
                        /*
                         * %s null handling added 930709 by Luke Mewburn
                         * <*****@*****.**>
                         */
                        if (carg->type == T_NUMBER && carg->u.number == 0) {
                            sprintf_state->clean.type = T_STRING;
                            sprintf_state->clean.subtype = STRING_MALLOC;
                            sprintf_state->clean.u.string = string_copy(NULL_MSG, "sprintf NULL");
                            carg = &(sprintf_state->clean);
                        } else
                            if (carg->type != T_STRING) {
                                ERROR(ERR_INCORRECT_ARG_S);
                            }
                        slen = SVALUE_STRLEN(carg);
                        if ((finfo & INFO_COLS) || (finfo & INFO_TABLE)) {
                            cst **temp;

                            if (!fs) {
                                ERROR(ERR_CST_REQUIRES_FS);
                            }

                            temp = &(sprintf_state->csts);
                            while (*temp)
                                temp = &((*temp)->next);
                            if (finfo & INFO_COLS) {
                                int tmp;
                                if (pres > fs) pres = fs;
                                *temp = ALLOCATE(cst, TAG_TEMPORARY, "string_print: 3");
                                (*temp)->next = 0;
                                (*temp)->d.col = carg->u.string;
                                (*temp)->pad = make_pad(&pad);
                                (*temp)->size = fs;
                                (*temp)->pres = (pres) ? pres : fs;
                                (*temp)->info = finfo;
                                (*temp)->start = get_curpos();
#ifdef TCC
                                puts("tcc has some bugs");
#endif
                                tmp = ((format_str[fpos] != '\n')
                                        && (format_str[fpos] != '\0'))
                                    || ((finfo & INFO_ARRAY)
                                            && (nelemno < (argv + sprintf_state->cur_arg)->u.arr->size));
                                tmp = add_column(temp, tmp);
                                if (tmp == 2 && !format_str[fpos]) {
                                    ADD_CHAR('\n');
                                }
                            } else {/* (finfo & INFO_TABLE) */
                                unsigned int n, len, max_len;
                                const char *p1, *p2;

#define TABLE carg->u.string
                                (*temp) = ALLOCATE(cst, TAG_TEMPORARY, "string_print: 4");
                                (*temp)->d.tab = 0;
                                (*temp)->pad = make_pad(&pad);
                                (*temp)->info = finfo;
                                (*temp)->start = get_curpos();
                                (*temp)->next = 0;
                                max_len = 0;
                                n = 1;

                                p2 = p1 = TABLE;
                                while (*p1) {
                                    if (*p1 == '\n') {
                                        if (p1 - p2 > max_len)
                                            max_len = p1 - p2;
                                        p1++;
                                        if (*(p2 = p1))
                                            n++;
                                    } else
                                        p1++;
                                }
                                if (!pres) {
                                    /* the null terminated word */
                                    if (p1 - p2 > max_len)
                                        max_len = p1 - p2;
                                    pres = fs / (max_len + 2); /* at least two
                                                                * separating spaces */
                                    if (!pres)
                                        pres = 1;

                                    /* This moves some entries from the right side
                                     * of the table to fill out the last line,
                                     * which makes the table look a bit nicer.
                                     * E.g.
                                     * (n=13,p=6)      (l=3,p=5)
                                     * X X X X X X     X X X X X
                                     * X X X X X X  -> X X X X X
                                     * X               X X X X
                                     *
                                     */
                                    len = (n-1)/pres + 1;
                                    if (n > pres && n % pres)
                                        pres -= (pres - n % pres) / len;
                                } else {
                                    len = (n-1)/pres + 1;
                                }
                                (*temp)->size = fs / pres;
                                (*temp)->remainder = fs % pres;
                                if (n < pres) {
                                    /* If we have fewer elements than columns,
                                     * pretend we are dealing with a smaller
                                     * table.
                                     */
                                    (*temp)->remainder += (pres - n)*((*temp)->size);
                                    pres = n;
                                }

                                (*temp)->d.tab = CALLOCATE(pres + 1, tab_data_t,
                                        TAG_TEMPORARY, "string_print: 5");
                                (*temp)->nocols = pres;     /* heavy sigh */
                                (*temp)->d.tab[0].start = TABLE;
                                if (pres == 1) {
                                    (*temp)->d.tab[1].start = TABLE + SVALUE_STRLEN(carg) + 1;
                                } else {
                                    i = 1;  /* the next column number */
                                    n = 0;  /* the current "word" number in this
                                             * column */

                                    p1 = TABLE;
                                    while (*p1) {
                                        if (*p1++ == '\n' && ++n >= len) {
                                            (*temp)->d.tab[i++].start = p1;
                                            n = 0;
                                        }
                                    }
                                    for ( ; i <= pres; i++)
                                        (*temp)->d.tab[i].start = ++p1;
                                }
                                for (i = 0; i < pres; i++)
                                    (*temp)->d.tab[i].cur = (*temp)->d.tab[i].start;

                                add_table(temp);
                            }
                        } else {    /* not column or table */
                            const char *tmp = carg->u.string; //work around tcc bug;
                            if (pres && pres < slen)
                                slen = pres;
                            add_justified(tmp, slen, &pad, fs, finfo,
                                    (((format_str[fpos] != '\n') && (format_str[fpos] != '\0'))
                                     || ((finfo & INFO_ARRAY) && (nelemno < (argv + sprintf_state->cur_arg)->u.arr->size)))
                                    || carg->u.string[slen - 1] != '\n');
                        }
                    } else if (finfo & INFO_T_INT) {        /* one of the integer
                                                             * types */
                        char cheat[20];
                        char temp[100];

                        *cheat = '%';
                        i = 1;
                        switch (finfo & INFO_PP) {
                            case INFO_PP_SPACE:
                                cheat[i++] = ' ';
                                break;
                            case INFO_PP_PLUS:
                                cheat[i++] = '+';
                                break;
                        }
                        if (pres) {
                            cheat[i++] = '.';
                            if(pres >= sizeof(temp))
                                sprintf(cheat + i, "%ld", sizeof(temp) - 1);
                            else
                                sprintf(cheat + i, "%d", pres);

                            i += strlen(cheat + i);
                        }
                        switch (finfo & INFO_T) {
                            case INFO_T_INT:
                                cheat[i++] = 'l';
                                cheat[i++] = 'd';
                                break;
                            case INFO_T_FLOAT:
                                cheat[i++] = 'f';
                                break;
                            case INFO_T_CHAR:
                                cheat[i++] = 'c';
                                break;
                            case INFO_T_OCT:
                                cheat[i++] = 'l';
                                cheat[i++] = 'o';
                                break;
                            case INFO_T_HEX:
                                cheat[i++] = 'l';
                                cheat[i++] = 'x';
                                break;
                            case INFO_T_C_HEX:
                                cheat[i++] = 'l';
                                cheat[i++] = 'X';
                                break;
                            default:
                                ERROR(ERR_BAD_INT_TYPE);
                        }
                        if ((cheat[i - 1] == 'f' && carg->type != T_REAL) || (cheat[i - 1] != 'f' && carg->type != T_NUMBER)) {
#ifdef RETURN_ERROR_MESSAGES
                            sprintf(buff,
                                    "ERROR: (s)printf(): Incorrect argument type to %%%c. (arg: %u)\n",
                                    cheat[i - 1], sprintf_state->cur_arg);
                            fprintf(stderr, "Program /%s File: %s: %s", current_prog->name,
                                    get_line_number_if_any(), buff);
                            debug_message("%s", buff);
                            if (current_object) {
                                debug_message("program: /%s, object: %s, file: %s\n",
                                        current_prog ? current_prog->name : "",
                                        current_object->name,
                                        get_line_number_if_any());
                            }
                            ERROR(ERR_RECOVERY_ONLY);
#else
                            error("ERROR: (s)printf(): Incorrect argument type to %%%c.\n",
                                    cheat[i - 1]);
#endif                          /* RETURN_ERROR_MESSAGES */
                        }
                        cheat[i] = '\0';

                        if (carg->type == T_REAL) {
                            sprintf(temp, cheat, carg->u.real);
                        } else
                            sprintf(temp, cheat, carg->u.number);
                        {
                            int tmpl = strlen(temp);

                            add_justified(temp, tmpl, &pad, fs, finfo,
                                    (((format_str[fpos] != '\n') && (format_str[fpos] != '\0'))
                                     || ((finfo & INFO_ARRAY) && (nelemno < (argv + sprintf_state->cur_arg)->u.arr->size))));
                        }
                    } else          /* type not found */
                        ERROR(ERR_UNDEFINED_TYPE);
                    if (sprintf_state->clean.type != T_NUMBER) {
                        free_svalue(&(sprintf_state->clean), "string_print_formatted");
                        sprintf_state->clean.type = T_NUMBER;
                    }

                    if (!(finfo & INFO_ARRAY))
                        break;
                    if (nelemno >= (argv + sprintf_state->cur_arg)->u.arr->size)
                        break;
                    carg = (argv + sprintf_state->cur_arg)->u.arr->item + nelemno++;
                }                   /* end of while (1) */
                last = fpos;
                fpos--;             /* bout to get incremented */
            }
    }                           /* end of for (fpos=0; 1; fpos++) */

    outbuf_fix(&sprintf_state->obuff);
    retvalue = sprintf_state->obuff.buffer;
    sprintf_state->obuff.buffer = 0;
    pop_stack();                /* pop off our error handler, will call pop_sprintf_state */
    return retvalue;
}                               /* end of string_print_formatted() */
Exemplo n.º 28
0
void f_pcre_replace(void)
{
	pcre_t *run;
	array_t *replacements;

	unsigned int i;
	char *ret;

	run = CALLOCATE(1, pcre_t, TAG_TEMPORARY, "f_pcre_replace: run");

	run->ovector = NULL;
	run->ovecsize = 0;
	assign_svalue_no_free(&run->pattern, (sp - 1));
	run->subject = (sp - 2)->u.string;
	replacements = sp->u.arr;

	run->s_length = SVALUE_STRLEN(sp - 2);


	if(pcre_magic(run) < 0)
	{
		pcre_free_memory(run);
		error("PCRE compilation failed at offset %d: %s\n", run->erroffset,
				run->error);
	}


	if (run->rc < 0) /* No match. could do handling of matching errors if wanted */
	{
		pcre_free_memory(run);
		pop_2_elems();
		return;
	}


	if (run->rc > (run->ovecsize/3-1))
	{
		pcre_free_memory(run);
		error("Too many substrings.\n");
	}
	if ( (run->rc - 1) != replacements->size )
	{
		int tmp = run->rc-1;
		pcre_free_memory(run);
		error("Number of captured substrings and replacements do not match, "
				"%d vs %d.\n", tmp, replacements->size);
	}



	if (run->rc == 1)
	{
		/* No captured substrings, return subject */
		pcre_free_memory(run);
		pop_2_elems();
		return;
		//push_malloced_string(run->subject);
	}

	ret = pcre_get_replace(run, replacements);


	pop_3_elems();
	push_malloced_string(ret);
	pcre_free_memory(run);
	return;
}