コード例 #1
0
ファイル: big_num.c プロジェクト: gnuvse/c_git
int main() {
	char *buf1 = malloc(sizeof(char) * SIZE);
	char *buf2 = malloc(sizeof(char) * SIZE);

	int count1;
	int count2;


	count1 = input_number(SIZE, buf1);
	printf("count = %i\n", count1);
	count2 = input_number(SIZE, buf2);
	printf("count = %i\n", count2);


	output_number(count1, buf1);
	output_number(count2, buf2);

	char *buf1_reversed = reverse_number(count1, buf1);
	char *buf2_reversed = reverse_number(count2, buf2);
	char *res_diff = diff_number(count1, buf1_reversed, buf2_reversed);
	char *res = reverse_number(count1, res_diff);

	output_number(count1, res);

	free(buf1);
	free(buf2);
	free(buf1_reversed);
	free(buf2_reversed);
	free(res);
	free(res_diff);

	return 0;
}
コード例 #2
0
ファイル: main.c プロジェクト: JamesLinus/FUZIX
/**
 * dump all static variables
 */
void dumpglbs(void) {
    int dim, i, list_size, line_count, value;
    if (!glbflag)
        return;
    current_symbol_table_idx = rglobal_table_index;
    while (current_symbol_table_idx < global_table_index) {
        SYMBOL *symbol = &symbol_table[current_symbol_table_idx];
        if (symbol->identity != FUNCTION) {
            ppubext(symbol);
            if (symbol->storage != EXTERN) {
                output_string(symbol->name);
                output_label_terminator();
                dim = symbol->offset;
                list_size = 0;
                line_count = 0;
                if (find_symbol_initials(symbol->name)) { // has initials
                    list_size = get_size(symbol->name);
                    if (dim == -1) {
                        dim = list_size;
                    }
                }
                for (i=0; i<dim; i++) {
                    if (symbol->type == STRUCT) {
                        dump_struct(symbol, i);
                    } else {
                        if (line_count % 10 == 0) {
                            newline();
                            if ((symbol->type & CINT) || (symbol->identity == POINTER)) {
                                gen_def_word();
                            } else {
                                gen_def_byte();
                            }
                        }
                        if (i < list_size) {
                            // dump data
                            value = get_item_at(symbol->name, i, &tag_table[symbol->tagidx]);
                            output_number(value);
                        } else {
                            // dump zero, no more data available
                            output_number(0);
                        }
                        line_count++;
                        if (line_count % 10 == 0) {
                            line_count = 0;
                        } else {
                            if (i < dim-1) {
                                output_byte( ',' );
                            }
                        }
                    }
                }
                newline();
            }
        } else {
            fpubext(symbol);
        }
        current_symbol_table_idx++;
    }
}
コード例 #3
0
ファイル: code8080.c プロジェクト: beretta42/FUZIX
/**
 * divide the primary register by INTSIZE, never used
 */
void gen_divide_by_two(void) {
    gen_push(HL_REG);        /* push primary in prep for gasr */
    gen_immediate ();
    output_number (1);
    newline ();
    gen_arithm_shift_right ();  /* divide by two */
}
コード例 #4
0
ファイル: code8080.c プロジェクト: beretta42/FUZIX
/**
 * decrement the primary register by one if char, INTSIZE if int
 */
void gen_decrement_primary_reg(LVALUE *lval) {
    output_line("dcx \th");
    switch (lval->ptr_type) {
        case CINT:
        case UINT:
            output_line("dcx \th");
            break;
        case STRUCT:
            gen_immediate2();
            output_number(lval->tagsym->size - 1);
            newline();
            // two's complement
            output_line("mov  \ta,d");
            output_line("cma");
            output_line("mov  \td,a");
            output_line("mov  \ta,e");
            output_line("cma");
            output_line("mov \te,a");
            output_line("inx \td");
            // substract
            output_line("dad \td");
            break ;
        default:
            break;
    }
}
コード例 #5
0
ファイル: stmt.c プロジェクト: AtomSoftTech/retrobsd
/**
 * dump switch table
 */
dumpsw(loop_t *loop) {
        int     i,j;

        data_segment_gdata ();
        generate_label (loop->body_label);
        if (loop->test_label != swstp) {
                j = loop->test_label;
                while (j < swstp) {
                        gen_def_word ();
                        i = 4;
                        while (i--) {
                                output_number (swstcase[j]);
                                output_byte (',');
                                print_label (swstlab[j++]);
                                if ((i == 0) | (j >= swstp)) {
                                        newline ();
                                        break;
                                }
                                output_byte (',');
                        }
                }
        }
        gen_def_word ();
        print_label (loop->cont_label);
        output_string (",0");
        newline ();
        code_segment_gtext ();
}
コード例 #6
0
ファイル: sym.c プロジェクト: EtchedPixels/FUZIX
/**
 * add new symbol to local table
 * @param sname
 * @param identity
 * @param type
 * @param offset size in bytes
 * @param storage_class
 * @return 
 */
int add_local (char *sname, int identity, int type, int offset, int storage_class) {
    int k;
    SYMBOL *symbol;
    char *buffer_ptr;

    if ((current_symbol_table_idx = find_locale (sname)) > -1) {
        return (current_symbol_table_idx);
    }
    if (local_table_index >= NUMBER_OF_GLOBALS + NUMBER_OF_LOCALS) {
        error ("local symbol table overflow");
        return (0);
    }
    current_symbol_table_idx = local_table_index;
    symbol = &symbol_table[current_symbol_table_idx];
    buffer_ptr = symbol->name;
    /* FIXME: only copy so many bytes */
    while (alphanumeric(*buffer_ptr++ = *sname++));
    symbol->identity = identity;
    symbol->type = type;
    symbol->storage = storage_class;
    if (storage_class == LSTATIC) {
        data_segment_gdata();
        print_label(k = getlabel());
        output_label_terminator();
        gen_def_storage();
        output_number(offset);
        newline();
        code_segment_gtext();
        offset = k;
    }
    symbol->offset = offset;
    local_table_index++;
    return (current_symbol_table_idx);
}
コード例 #7
0
ファイル: sym.c プロジェクト: EtchedPixels/FUZIX
/**
 * evaluate one initializer, add data to table
 * @param symbol_name
 * @param type
 * @param identity
 * @param dim
 * @param tag
 * @return
 *	returns size of initializer, or 0 for none (a null string is size 1)
 *
 */
int init(char *symbol_name, int type, int identity, int *dim, TAG_SYMBOL *tag) {
    int value, n;

    /* A pointer is initialized as a word holding the address of the struct
       or string etc that directly follows */
    if(identity == POINTER) {
        int x = getlabel();
        gen_def_word();
        print_label(x);
        newline();
        print_label(x);
        output_label_terminator();
        newline();
    }
    /* FIXME: may need to distinguish const string v data in future */
    if(quoted_string(&n, NULL)) {
        if((identity == VARIABLE) || !(type & CCHAR))
            error("found string: must assign to char pointer or array");
        *dim = *dim - n; /* ??? FIXME arrays of char only */
        return n;
    }

    if (type & CCHAR)
        gen_def_byte();
    else
        gen_def_word();
    if (!number(&value) && !quoted_char(&value))
        return 0;
    *dim = *dim - 1;
    output_number(value);
    newline();
    return (type & CCHAR) ? 1 : 2;
}
コード例 #8
0
ファイル: stmt.c プロジェクト: beretta42/FUZIX
/**
 * dump switch table
 */
void dumpsw(WHILE *ws) {
        int     i,j;

        data_segment_gdata ();
        generate_label (ws->body_tab);
        if (ws->case_test != swstp) {
                j = ws->case_test;
                while (j < swstp) {
                        gen_def_word ();
                        i = 4;
                        while (i--) {
                                output_number (swstcase[j]);
                                output_byte (',');
                                print_label (swstlab[j++]);
                                if ((i == 0) | (j >= swstp)) {
                                        newline ();
                                        break;
                                }
                                output_byte (',');
                        }
                }
        }
        gen_def_word ();
        print_label (ws->incr_def);
        output_string (",0");
        newline ();
        code_segment_gtext ();
}
コード例 #9
0
ファイル: codegeneric.c プロジェクト: EtchedPixels/FUZIX
/**
 * call the specified subroutine name
 * @param sname subroutine name
 */
void gen_call(char *sname) {
    output_with_tab ("call ");
    output_string (sname);
    output_byte(',');
    output_number(args);
    newline ();
}
コード例 #10
0
/* Output the given array to the output file. */
static void output_from_array(FILE * outfile, unsigned long ary[],
			      unsigned long n)
{
    unsigned long i;

    for (i = 0; i < n; i += 1)
	output_number(outfile, ary[i]);
}
コード例 #11
0
ファイル: codegeneric.c プロジェクト: EtchedPixels/FUZIX
static void describe_access(SYMBOL *sym)
{
    if (sym->storage == REGISTER) {
        output_string("r");
        output_number(sym->offset);
        newline();
        return;
    }
    output_byte('(');
    if (sym->storage == LSTATIC) {
        print_label(sym->offset);
    } else if (sym->storage == AUTO || sym->storage == DEFAUTO) {
        output_number(sym->offset);
        output_string("+fp");
    } else
        output_label_name(sym->name);
    output_byte(')');
    newline();
}
コード例 #12
0
ファイル: codegeneric.c プロジェクト: EtchedPixels/FUZIX
void gen_epilogue(void)
{
    int i;
    /* FIXME: usual case we can pop these in this order need to spot the
       sp position and optimize accordingly */
    for (i = nextreg - 1; i >= 3; i--) {
        if (stkp == regv[i]) {
            stkp += 2;
            output_with_tab("pop r");
            output_number(i);
        } else {
            output_with_tab("load r");
            output_number(i);
            output_string(" (");
            output_number(regv[i]);
            output_string("+fp)");
        }
        newline();
    }
}
コード例 #13
0
ファイル: code8080.c プロジェクト: beretta42/FUZIX
/**
 * asm - fetch the address of the specified symbol into the primary register
 * @param sym the symbol name
 * @return which register pair contains result
 */
int gen_get_locale(SYMBOL *sym) {
    if (sym->storage == LSTATIC) {
        gen_immediate();
        print_label(sym->offset);
        newline();
        return HL_REG;
    } else {
        if (uflag && !(sym->identity == ARRAY)) {// ||
                //(sym->identity == VARIABLE && sym->type == STRUCT))) {
            output_with_tab("ldsi\t");
            output_number(sym->offset - stkp);
            newline ();
            return DE_REG;
        } else {
            gen_immediate();
            output_number(sym->offset - stkp);
            newline ();
            output_line ("dad \tsp");
            return HL_REG;
        }
    }
}
コード例 #14
0
ファイル: codegeneric.c プロジェクト: EtchedPixels/FUZIX
int gen_register(int vp, int size, int typ)
{
    if (size != 2)
        return -1;
    if (nextreg > 6)
        return -1;
    stkp = stkp - 2;
    regv[nextreg] = stkp;
    output_with_tab("push r");
    output_number(nextreg);
    newline();
    return nextreg++;
}
コード例 #15
0
ファイル: main.c プロジェクト: JamesLinus/FUZIX
/**
 * dump struct data
 * @param symbol struct variable
 * @param position position of the struct in the array, or zero
 */
void dump_struct(SYMBOL *symbol, int position) {
    int i, number_of_members, value;
    number_of_members = tag_table[symbol->tagidx].number_of_members;
    newline();
    for (i=0; i<number_of_members; i++) {
        // i is the index of current member, get type
        int member_type = member_table[tag_table[symbol->tagidx].member_idx + i].type;
        if (member_type & CINT) {
            gen_def_word();
        } else {
            gen_def_byte();
        }
        if (position < get_size(symbol->name)) {
            // dump data
            value = get_item_at(symbol->name, position*number_of_members+i, &tag_table[symbol->tagidx]);
            output_number(value);
        } else {
            // dump zero, no more data available
            output_number(0);
        }
        newline();
    }
}
コード例 #16
0
ファイル: codegeneric.c プロジェクト: EtchedPixels/FUZIX
/**
 * asm - fetch the address of the specified symbol into the primary register
 * @param sym the symbol name
 * @return which register pair contains result
 */
int gen_get_locale(SYMBOL *sym) {
    if (sym->storage == LSTATIC) {
        gen_immediate();
        print_label(sym->offset);
        newline();
        return HL_REG;
    } else {
        gen_immediate();
        output_number(sym->offset);
        output_string("+fp");
        newline();
        return HL_REG;
    }
}
コード例 #17
0
ファイル: primary.c プロジェクト: beretta42/FUZIX
int constant(int val[]) {
    if (number (val))
        gen_immediate ();
    else if (quoted_char (val))
        gen_immediate ();
    else if (quoted_string (val)) {
        gen_immediate ();
        print_label (litlab);
        output_byte ('+');
    } else
        return (0);
    output_number (val[0]);
    newline ();
    return (1);
}
コード例 #18
0
ファイル: codegeneric.c プロジェクト: EtchedPixels/FUZIX
/**
 * multiply the primary register by the length of some variable
 * @param type
 * @param size
 */
void gen_multiply(int type, int size) {
	switch (type) {
        case CINT:
        case UINT:
            output_line("mul r1 2");
            break;
        case STRUCT:
            output_with_tab("mul r1 ");
            output_number(size);
            newline();
            break;
        default:
            break;
    }
}
コード例 #19
0
ファイル: codegeneric.c プロジェクト: EtchedPixels/FUZIX
/**
 * decrement the primary register by one if char, INTSIZE if int
 */
void gen_decrement_primary_reg(LVALUE *lval) {
    switch (lval->ptr_type) {
        case CINT:
        case UINT:
            output_line("sub r1 2");
            break;
        case STRUCT:
            output_with_tab("sub r1 ");
            output_number(lval->tagsym->size - 1);
            newline();
            break ;
        default:
            output_line("sub r1 1");
            break;
    }
}
コード例 #20
0
ファイル: code8080.c プロジェクト: beretta42/FUZIX
/**
 * multiply the primary register by the length of some variable
 * @param type
 * @param size
 */
void gen_multiply(int type, int size) {
	switch (type) {
        case CINT:
        case UINT:
            gen_multiply_by_two();
            break;
        case STRUCT:
            gen_immediate2();
            output_number(size);
            newline();
            gen_call("ccmul");
            break ;
        default:
            break;
    }
}
コード例 #21
0
ファイル: code8080.c プロジェクト: beretta42/FUZIX
/**
 * increment the primary register by 1 if char, INTSIZE if int
 */
void gen_increment_primary_reg(LVALUE *lval) {
    switch (lval->ptr_type) {
        case STRUCT:
            gen_immediate2();
            output_number(lval->tagsym->size);
            newline();
            output_line("dad \td");
            break ;
        case CINT:
        case UINT:
            output_line("inx \th");
        default:
            output_line("inx \th");
            break;
    }
}
コード例 #22
0
ファイル: sym.c プロジェクト: EtchedPixels/FUZIX
/**
 * initialise structure
 * @param tag
 */
void struct_init(TAG_SYMBOL *tag, char *symbol_name) {
	int dim ;
	int member_idx;
	int size = tag->size;

	member_idx = tag->member_idx;
	while (member_idx < tag->member_idx + tag->number_of_members) {
		size -= init(symbol_name, member_table[tag->member_idx + member_idx].type,
                        member_table[tag->member_idx + member_idx].identity, &dim, tag);
		++member_idx;
		/* FIXME:  not an error - zero rest */
		if ((match(",") == 0) && (member_idx != (tag->member_idx + tag->number_of_members))) {
		    gen_def_storage();
		    output_number(size);
		    newline();
		    break;
		}
	}
}
コード例 #23
0
ファイル: userinterface.c プロジェクト: metakevin/tds1
u8 mode_select_display_func(ui_mode_t mode, ui_display_event_t event)
{
    if (event == CONFIG_SHORT_PRESS)
    {
        u16 m = 1;
        u8 i;
        for(i=0; i<3-mode_select_digit; i++)
        {
            m *= 10;
        }
        u8 p = (mode_select_current/m)%10;
        mode_select_current -= p*m;
        p = (p+1)%10;
        mode_select_current += p*m;
    }
    else if (event == CONFIG_LONG_PRESS)
    {
        ++mode_select_digit;
        if (mode_select_digit >= 4)
        {
            /* Save the new config word */
            save_persist_data_16(PDATA_CONFIG_WORD_1L + mode_select_word*2, ~mode_select_current);
            
            ++mode_select_word;
            do_config_word(mode_select_word);
        }        
        if (mode_select_word >= NUM_CONFIG_WORDS)
        {
            /* wait for button release */
            while (!(LED_PIN & (1<<LED_BIT)));
            
            radio_disable();
            
            /* reset */
            void (*rstvec)() = (void (*)())0;
            (*rstvec)();
        }
    }
    output_number(MODE_MODE_SELECT + mode_select_word + 1, 
            mode_select_current, CENTER_NONE, DFLAGS_FLASH_PLACE_0<<mode_select_digit);
    return 1;
}
コード例 #24
0
ファイル: oilpressure.c プロジェクト: metakevin/ms2cluster
void oilpres_display_func(ui_mode_t mode, u8 mode_changed)
{
    const u16 r1 = 390; // value of resistor to +5
    const u16 r2_fixed = 90; // value of fixed resistor added to sensor resistance
    // actually measured 96.5, but ADC reports 90.

    u16 adc_10q6 = oilpres_ctx.current_oilpres_accum;

#if 1
    u16 Vratio_10q6 = adc_10q6 / 1023;

    u16 r2 = (Vratio_10q6 * r1)/(64 - Vratio_10q6);
#else
    // underflow ?
    u16 r2 = (adc_10q6 * r1)/(64*1023 - adc_10q6);
#endif


//    r2_10q6 -= r2_fixed_10q6;

    if (r2 > r2_fixed)
    {
        r2 -= r2_fixed;
    }
    else
    {
        r2 = 0;
    }

    if (r2 > 999)
    {
        /* output_number uses signed int, so limit this */
        r2 = 999;
    }
    else
    {
        r2 = r2 * 10;
    }

    output_number(mode, r2, CENTER_D, 0);
}
コード例 #25
0
ファイル: main.c プロジェクト: JamesLinus/FUZIX
/**
 * dump the literal pool
 */
void dumplits(void) {
    int j, k;

    if (litptr == 0)
        return;
    print_label(litlab);
    output_label_terminator();
    k = 0;
    while (k < litptr) {
        gen_def_byte();
        j = 8;
        while (j--) {
            output_number(litq[k++] & 127);
            if ((j == 0) | (k >= litptr)) {
                newline();
                break;
            }
            output_byte(',');
        }
    }
}
コード例 #26
0
ファイル: code8080.c プロジェクト: beretta42/FUZIX
/**
 * modify the stack pointer to the new value indicated
 * @param newstkp new value
 */
int gen_modify_stack(int newstkp) {
    int k;

    k = newstkp - stkp;
    if (k == 0)
        return (newstkp);
    if (k > 0) {
        if (k < 7) {
            if (k & 1) {
                output_line ("inx \tsp");
                k--;
            }
            while (k) {
                output_line ("pop \tb");
                k = k - INTSIZE;
            }
            return (newstkp);
        }
    } else {
        if (k > -7) {
            if (k & 1) {
                output_line ("dcx \tsp");
                k++;
            }
            while (k) {
                output_line ("push\tb");
                k = k + INTSIZE;
            }
            return (newstkp);
        }
    }
    gen_swap ();
    gen_immediate ();
    output_number (k);
    newline ();
    output_line ("dad \tsp");
    output_line ("sphl");
    gen_swap ();
    return (newstkp);
}
コード例 #27
0
ファイル: code8080.c プロジェクト: beretta42/FUZIX
/**
 * add offset to primary register
 * @param val the value
 */
void add_offset(int val) {
    gen_immediate2();
    output_number(val);
    newline();
    output_line ("dad \td");
}
コード例 #28
0
ファイル: code8080.c プロジェクト: beretta42/FUZIX
/**
 * Squirrel away argument count in a register that modstk doesn't touch.
 * @param d
 */
void gnargs(int d)
{
    output_with_tab ("mvi \ta,");
    output_number(d);
    newline ();
}
コード例 #29
0
ファイル: sym.c プロジェクト: EtchedPixels/FUZIX
/**
 * initialize global objects
 * @param symbol_name
 * @param type char or integer or struct
 * @param identity
 * @param dim
 * @return 1 if variable is initialized
 */
int initials(char *symbol_name, int type, int identity, int dim, int otag) {
    int dim_unknown = 0;
    int n;

    if(dim == 0) { // allow for xx[] = {..}; declaration
        dim_unknown = 1;
    }
    if (!(type & CCHAR) && !(type & CINT) && !(type == STRUCT)) {
        error("unsupported storage size");
    }
    data_segment_gdata();
    glabel(symbol_name);
    if(match("=")) {
        // an array or struct
        if(match("{")) {
            // aggregate initialiser
            if ((identity == POINTER || identity == VARIABLE) && type == STRUCT) {
                // aggregate is structure or pointer to structure
                dim = 0;
                struct_init(&tag_table[otag], symbol_name);
            }
            else {
                while((dim > 0) || (dim_unknown)) {
                    if (identity == ARRAY && type == STRUCT) {
                        // array of struct
                        needbrack("{");
                        struct_init(&tag_table[otag], symbol_name);
                        --dim;
                        needbrack("}");
                    }
                    else {
                        if (init(symbol_name, type, identity, &dim, 0)) {
                            dim_unknown++;
                        }
                    }
                    if(match(",") == 0) {
                        break;
                    }
                }
                if(--dim_unknown == 0)
                    identity = POINTER;
                else {
                    /* Pad any missing objects */
                    n = dim;
                    gen_def_storage();
                    if (identity != ARRAY && type != STRUCT) {
                        if (!(type & CCHAR))
                           n *= 2;
                    } else
                        n = tag_table[otag].size;

                    output_number(n);
                    newline();
                }
            }
            needbrack("}");
        // single constant
        } else {
            init(symbol_name, type, identity, &dim, 0);
        }
    }
    code_segment_gtext();
    return identity;
}
コード例 #30
0
int main(int argc, char **argv)
{
	char *descriptor;
	char *curpos; /* current position in input string */
	struct keyval *parser_id; /* the parser we are creating output for */
	FILE *outputf;
	struct keyval *rkv; /* current read key:val */
	struct keyval_list *curlist;
	bool do_token_check = true; /* if the check for valid tokens is done */
	bool only_ident = true; /* if the only token type is ident */
	bool is_generic = false;

	struct keyval_list base;
	struct keyval_list IDENT;
	struct keyval_list IDENT_LIST;
	struct keyval_list LENGTH_UNIT;
	struct keyval_list URI;
	struct keyval_list WRAP;
	struct keyval_list NUMBER;
	struct keyval_list COLOR;


	if (argc < 2) {
		fprintf(stderr,"Usage: %s [-o <filename>] <descriptor>\n", argv[0]);
		return 1;
	}

	if ((argv[1][0] == '-') && (argv[1][1] == 'o')) {
		if (argc != 4) {
			fprintf(stderr,"Usage: %s [-o <filename>] <descriptor>\n", argv[0]);
			return 1;
		}
		outputf = fopen(argv[2], "w");
		if (outputf == NULL) {
			perror("unable to open file");
		}
		descriptor = strdup(argv[3]);
	} else {
		outputf = stdout;
		descriptor = strdup(argv[1]);
	}
	curpos = descriptor;

	base.count = 0;
	IDENT.count = 0;
	URI.count = 0;
	WRAP.count = 0;
	NUMBER.count = 0;
	COLOR.count = 0;
	LENGTH_UNIT.count = 0;
	IDENT_LIST.count = 0;

	curlist = &base;

	while (*curpos != 0) {
		rkv = get_keyval(&curpos);
		if (rkv == NULL) {
			fprintf(stderr,"Token error at offset %ld\n", curpos - descriptor);
			fclose(outputf);
			return 2;
		}

		if (strcmp(rkv->key, "WRAP") == 0) {
			WRAP.item[WRAP.count++] = rkv;
			only_ident = false;
		} else if (strcmp(rkv->key, "NUMBER") == 0) {
			if (rkv->val[0] == '(') {
				curlist = &NUMBER;
			} else if (rkv->val[0] == ')') {
				curlist = &base;
			} else {
				NUMBER.item[NUMBER.count++] = rkv;
			}
			only_ident = false;
		} else if (strcmp(rkv->key, "IDENT") == 0) {
			if (rkv->val[0] == '(') {
				curlist = &IDENT;
			} else if (rkv->val[0] == ')') {
				curlist = &base;
			} else if (strcmp(rkv->val, str_INHERIT) == 0) {
				IDENT.item[IDENT.count++] = &ident_inherit;
			}
		} else if (strcmp(rkv->key, "IDENT_LIST") == 0) {
			if (rkv->val[0] == '(') {
				curlist = &IDENT_LIST;
			} else if (rkv->val[0] == ')') {
				curlist = &base;
			} 
		} else if (strcmp(rkv->key, "LENGTH_UNIT") == 0) {
			if (rkv->val[0] == '(') {
				curlist = &LENGTH_UNIT;
			} else if (rkv->val[0] == ')') {
				curlist = &base;
			} 
			only_ident = false;
			do_token_check = false;
		} else if (strcmp(rkv->key, "COLOR") == 0) {
			COLOR.item[COLOR.count++] = rkv;
			do_token_check = false;
			only_ident = false;
		} else if (strcmp(rkv->key, "URI") == 0) {
			URI.item[URI.count++] = rkv;
			only_ident = false;
		} else if (strcmp(rkv->key, "GENERIC") == 0) {
			is_generic = true;
		} else {
			/* just append to current list */
			curlist->item[curlist->count++] = rkv;
		}
	}

	if (base.count != 1) {
		fprintf(stderr,"Incorrect base element count (got %d expected 1)\n", base.count);
		fclose(outputf);
		return 3;
	}


	/* header */
output_header(outputf, descriptor, base.item[0], is_generic);

	if (WRAP.count > 0) {
		output_wrap(outputf, base.item[0], &WRAP);
	} else {
		/* check token type is correct */
		output_token_type_check(outputf, do_token_check,  &IDENT, &URI, &NUMBER);

		if (IDENT.count > 0)
			output_ident(outputf, only_ident, base.item[0], &IDENT);

		if (URI.count > 0)
			output_uri(outputf, base.item[0], &URI);

		if (NUMBER.count > 0)
			output_number(outputf, base.item[0], &NUMBER);

		/* terminal blocks, these end the ladder ie no trailing else */
		if (COLOR.count > 0) {
			output_color(outputf, base.item[0], &COLOR);
		} else if (LENGTH_UNIT.count > 0) {
			output_length_unit(outputf, base.item[0], &LENGTH_UNIT);
		} else if (IDENT_LIST.count > 0) {
			output_ident_list(outputf, base.item[0], &IDENT_LIST);
		} else {
			output_invalidcss(outputf);
		}

		output_footer(outputf);

	}

	fclose(outputf);

	return 0;
}