All pastes #974556 Raw Edit

Untitled

public text v1 · immutable
·published 2008-04-06 21:16 UTC
rendered paste body
enum Types
{
    TYPE_NONE,
    TYPE_CHAR,
    TYPE_UCHAR,
    TYPE_SHORT,
    TYPE_USHORT,
    TYPE_INT,
    TYPE_UINT,
    TYPE_LONG,
    TYPE_ULONG,
    TYPE_UNK_L,
    TYPE_FLOAT,
    TYPE_DOUBLE,
    TYPE_LDOUBLE,
    TYPE_LLONG,
    TYPE_ULLONG,
    TYPE_CHAR_P,
    TYPE_UCHAR_P,
    TYPE_SHORT_P,
    TYPE_USHORT_P,
    TYPE_INT_P,
    TYPE_UINT_P,
    TYPE_LONG_P,
    TYPE_ULONG_P,
    TYPE_UNK_L_P,
    TYPE_FLOAT_P,
    TYPE_DOUBLE_P,
    TYPE_LDOUBLE_P,
    TYPE_LLONG_P,
    TYPE_ULLONG_P
};

template<class T>
int type_to_int()
{
    const char *name = typeid(T).raw_name();
    if(!name[0] || !name[1]) return 0;
    if(name[1] >= 'D' && name[1] <= 'O')
    {
        return name[1]-'D'+1;
    }
    else if(name[1] == '_')
    {
        if(name[2] >= 'J' && name[2] <= 'K') return 'O'-'D'+2 + name[2]-'J';
        else return 0;
    }
    else if(name[1] == 'P' && name[2] == 'A' && name[3] >= 'D' && name[3] <= 'O')
    {
        return 'O'-'D'+2+2 + name[3]-'D';
    }
    else
        return 0;
}

#define MAX_PARAMS 4

enum ParseErrors
{
    PARSE_SUCCESS,
    PARSE_TOOMANY_EXP,
    PARSE_TYPE_MISMATCH
};

int parse_format(char *format, int *given_types, int ng)
{
    int exp_types[MAX_PARAMS], ne = 0;
    bool perc = false;

    for(char *p = format; *p; p++)
    {
        if(perc)
        {
            switch(tolower(*p))
            {
                case 'd':
                    if(ne == ng) return PARSE_TOOMANY_EXP;
                    exp_types[ne] = TYPE_INT;
                    if(given_types[ne] != exp_types[ne]) return PARSE_TYPE_MISMATCH;
                    ne++;
                    break;
                case 's':
                    if(ne == ng) return PARSE_TOOMANY_EXP;
                    exp_types[ne] = TYPE_CHAR_P;
                    if(given_types[ne] != exp_types[ne]) return PARSE_TYPE_MISMATCH;
                    ne++;
                    break;
                default:
                    break;
            }
            perc = false;
        }
        else if(*p == '%')
            perc = true;
    }

    return 0;
}

template<class P1, class P2>
void my_printf(char *format, P1 p1, P2 p2)
{
    int given_types[2] = { type_to_int<P1>(), type_to_int<P2>() };
    if(parse_format(format, given_types, 2) == PARSE_SUCCESS)
        printf(format, p1, p2);
    else
        printf("ERROR: the given parameter list doesn't match the format\n");
}

template<class P1>
void my_printf(char *format, P1 p1)
{
    int given_types[1] = { type_to_int<P1>() };
    if(parse_format(format, given_types, 2) == PARSE_SUCCESS)
        printf(format, p1);
    else
        printf("ERROR: the given parameter list doesn't match the format\n");
}

void my_printf(char *format)
{
    if(parse_format(format, NULL, 0) == PARSE_SUCCESS)
        printf(format);
    else
        printf("ERROR: the given parameter list doesn't match the format\n");
}

void do_printtest()
{
    int p = 1;
    char *q = "-ing";
    my_printf("Test%s %d\n", q, p);
}