Beispiel #1
0
static void push_sprintf_state (void) {
    sprintf_state_t *state;

    state = ALLOCATE(sprintf_state_t, TAG_TEMPORARY, "push_sprintf_state");
    outbuf_zero(&(state->obuff));
    state->csts = NULL;
    state->cur_arg = -1;
    state->clean.type = T_NUMBER;
    state->clean.u.number = 0;
    state->next = sprintf_state;
    sprintf_state = state;
}
Beispiel #2
0
void f_db_status (void)
{
	int i;
	outbuffer_t out;

	outbuf_zero(&out);

	for (i = 0;  i < dbConnAlloc;  i++) {
		if (dbConnList[i].flags & DB_FLAG_EMPTY) {
			continue;
		}

		outbuf_addv(&out, "Handle: %d (%s)\n", i + 1, dbConnList[i].type->name);
		if (dbConnList[i].type->status != NULL) {
			dbConnList[i].type->status(&(dbConnList[i].c), &out);
		}
	}

	outbuf_push(&out);
}
Beispiel #3
0
void
f_debug_info (void)
{
    svalue_t *arg;
    outbuffer_t out;

    outbuf_zero(&out);
    arg = sp - 1;
    switch (arg[0].u.number) {
    case 0:
        {
            int i, flags;
            object_t *obj2;

            ob = arg[1].u.ob;
            flags = ob->flags;
           outbuf_addv(&out, "O_HEART_BEAT      : %s\n",
                        flags & O_HEART_BEAT ? "TRUE" : "FALSE");
#ifndef NO_WIZARDS
           outbuf_addv(&out, "O_IS_WIZARD       : %s\n",
                        flags & O_IS_WIZARD ? "TRUE" : "FALSE");
#endif
#ifdef NO_ADD_ACTION
           outbuf_addv(&out, "O_LISTENER        : %s\n",
                        flags & O_LISTENER ? "TRUE" : "FALSE");
#else
           outbuf_addv(&out, "O_ENABLE_COMMANDS : %s\n",
                        flags & O_ENABLE_COMMANDS ? "TRUE" : "FALSE");
#endif
           outbuf_addv(&out, "O_CLONE           : %s\n",
                        flags & O_CLONE ? "TRUE" : "FALSE");
           outbuf_addv(&out, "O_VIRTUAL         : %s\n",
                        flags & O_VIRTUAL ? "TRUE" : "FALSE");
           outbuf_addv(&out, "O_DESTRUCTED      : %s\n",
                        flags & O_DESTRUCTED ? "TRUE" : "FALSE");
           outbuf_addv(&out, "O_ONCE_INTERACTIVE: %s\n",
                        flags & O_ONCE_INTERACTIVE ? "TRUE" : "FALSE");
           outbuf_addv(&out, "O_RESET_STATE     : %s\n",
                        flags & O_RESET_STATE ? "TRUE" : "FALSE");
           outbuf_addv(&out, "O_WILL_CLEAN_UP   : %s\n",
                        flags & O_WILL_CLEAN_UP ? "TRUE" : "FALSE");
           outbuf_addv(&out, "O_WILL_RESET      : %s\n",
                        flags & O_WILL_RESET ? "TRUE" : "FALSE");
#ifdef HAVE_ZLIB
           if (ob->interactive) {
             outbuf_addv(&out, "O_COMPRESSED      : %s\n",
                         ob->interactive->compressed_stream ? "TRUE" :
                         "FALSE");
             outbuf_addv(&out, "O_ZMP             : %s\n",
                                      ob->interactive->iflags & USING_ZMP ? "TRUE" :
                                      "FALSE");
             outbuf_addv(&out, "O_GMCP            : %s\n",
                                      ob->interactive->iflags & USING_GMCP ? "TRUE" :
                                      "FALSE");
             outbuf_addv(&out, "O_MXP             : %s\n",
                                      ob->interactive->iflags & USING_MXP ? "TRUE" :
                                      "FALSE");
           }
#endif
           
#ifndef NO_LIGHT
           outbuf_addv(&out, "total light : %d\n", ob->total_light);
#endif
#ifndef NO_RESETS
           outbuf_addv(&out, "next_reset  : %d\n", ob->next_reset);
#endif
           outbuf_addv(&out, "time_of_ref : %d\n", ob->time_of_ref);
           outbuf_addv(&out, "ref         : %d\n", ob->ref);
#ifdef DEBUG
           outbuf_addv(&out, "extra_ref   : %d\n", ob->extra_ref);
#endif
           outbuf_addv(&out, "name        : '/%s'\n", ob->obname);
           outbuf_addv(&out, "next_all    : OBJ(/%s)\n",
                        ob->next_all ? ob->next_all->obname : "NULL");
            if (obj_list == ob)
                outbuf_add(&out, "This object is the head of the object list.\n");
            for (obj2 = obj_list, i = 1; obj2; obj2 = obj2->next_all, i++)
                if (obj2->next_all == ob) {
                   outbuf_addv(&out, "Previous object in object list: OBJ(/%s)\n",
                                obj2->obname);
                   outbuf_addv(&out, "position in object list:%d\n", i);
                }
            break;
        }
    case 1:
        ob = arg[1].u.ob;

        outbuf_addv(&out, "program ref's %d\n", ob->prog->ref);
        outbuf_addv(&out, "Name /%s\n", ob->prog->filename);
        outbuf_addv(&out, "program size %d\n",
                    ob->prog->program_size);
        outbuf_addv(&out, "function flags table %d (%d) \n", 
                    ob->prog->last_inherited + ob->prog->num_functions_defined,
                    (ob->prog->last_inherited + ob->prog->num_functions_defined)* sizeof(unsigned short));
        outbuf_addv(&out, "compiler function table %d (%d) \n", 
                    ob->prog->num_functions_defined,
                    ob->prog->num_functions_defined * sizeof(function_t));
        outbuf_addv(&out, "num strings %d\n", ob->prog->num_strings);
        outbuf_addv(&out, "num vars %d (%d)\n", ob->prog->num_variables_defined,
                    ob->prog->num_variables_defined * (sizeof(char *) + sizeof(short)));
        outbuf_addv(&out, "num inherits %d (%d)\n", ob->prog->num_inherited,
                    ob->prog->num_inherited * sizeof(inherit_t));
        outbuf_addv(&out, "total size %d\n", ob->prog->total_size);
        break;
    case 2:
        {
            int i;
            ob = arg[1].u.ob;
            for (i=0; i<ob->prog->num_variables_total; i++) {
                /* inefficient, but: */
                outbuf_addv(&out, "%s: ", variable_name(ob->prog, i));
                svalue_to_string(&ob->variables[i], &out, 2, 0, 0);
                outbuf_add(&out, "\n");
            }
            break;
        }       
    default:
        bad_arg(1, F_DEBUG_INFO);
    }
    pop_stack();
    pop_stack();
    outbuf_push(&out);
}
Beispiel #4
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() */