aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtur Artamonov <freeartman@wechall.net>2014-03-13 13:19:24 +0200
committerArtur Artamonov <freeartman@wechall.net>2014-03-13 13:19:24 +0200
commit77fe6091096d7bf1a73f600cbe8f90c702583ef3 (patch)
tree70a4e1918cb99874a614454ae6d2cd60c96dfffa
downloadkconfig2h-77fe6091096d7bf1a73f600cbe8f90c702583ef3.tar.gz
kconfig2h-77fe6091096d7bf1a73f600cbe8f90c702583ef3.zip
Initial commit
-rw-r--r--Makefile20
-rw-r--r--config_test113
-rw-r--r--kconf2h.c50
-rw-r--r--kconf2h.h10
-rw-r--r--kconf2h_parser.c327
-rw-r--r--kconf2h_parser.ragel124
6 files changed, 544 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..b5a42c3
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,20 @@
+PROJECT=kconf2h
+CC=gcc
+CFLAGS=
+SOURCES=$(PROJECT)_parser.c
+OBJECTS=$(SOURCES:.c=.o)
+
+all: clean ragel $(OBJECTS) $(PROJECT)
+
+$(PROJECT):
+ $(CC) $(CFLAGS) $(OBJECTS) $(PROJECT).c -o $(PROJECT)
+
+ragel:
+ ragel $(PROJECT)_parser.ragel
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c $<
+
+clean:
+ rm -f $(PROJECT)
+ rm -f *.o
diff --git a/config_test1 b/config_test1
new file mode 100644
index 0000000..e2daaa1
--- /dev/null
+++ b/config_test1
@@ -0,0 +1,13 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux Kernel Configuration
+#
+CONFIG_DEBUG=y
+CONFIG_DEBUG_PRINT=y
+CONFIG_DEBUG_COLORIZE=y
+CONFIG_DEBUG_PRINT_LINE_NUM=y
+CONFIG_DEBUG_PRINT_FILE_NAME=y
+CONFIG_MEMLEAK=y
+# CONFIG_MEMLEAK_PLAIN is not set
+CONFIG_MEMLEAK_PLAIN_SAFE=y
+# CONFIG_MEMLEAK_RECORD is not set
diff --git a/kconf2h.c b/kconf2h.c
new file mode 100644
index 0000000..91ef6c7
--- /dev/null
+++ b/kconf2h.c
@@ -0,0 +1,50 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/stat.h>
+
+#include "kconf2h.h"
+
+int main( int argc, char **argv )
+{
+ FILE *fin = NULL;
+ FILE *fout = NULL;
+ struct stat st;
+
+ char *buf=NULL;
+ if ( argc == 3 )
+ {
+ fin = fopen( argv[1], "r+" );
+ fout = fopen( argv[2], "w+" );
+ fseek( fin, 0, SEEK_SET );
+ if ( fin && fout )
+ {
+ if ( stat( argv[1], &st ) )
+ {
+ goto error_exit;
+ }
+ buf = malloc( st.st_size ); memset( buf, 0, st.st_size );
+ size_t r_size = fread( buf, 1, st.st_size, fin );
+ if ( r_size > 0 )
+ {
+ int ret = parse_kconf2h( buf, fout );
+ printf("Kconfig file parsed %d %d bytes\n", ret, r_size );
+ } else
+ {
+ printf("ERR: while reading file %s [%d]\n", argv[1], r_size);
+ }
+error_exit:
+ if ( buf ) free( buf );
+ fclose( fin );
+ fclose( fout );
+ } else
+ {
+ printf("ERR: Cannot open file\n");
+ }
+ } else
+ {
+ printf("ERR: usage ./kconf2h [conffile] [outputheader]\n");
+ return -1;
+ }
+ return 0;
+}
diff --git a/kconf2h.h b/kconf2h.h
new file mode 100644
index 0000000..165d4cc
--- /dev/null
+++ b/kconf2h.h
@@ -0,0 +1,10 @@
+#ifndef __KCONF2H_H
+#define __KCONF2H_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int parse_kconf2h( const char*, FILE* );
+
+#endif
diff --git a/kconf2h_parser.c b/kconf2h_parser.c
new file mode 100644
index 0000000..6a25dbc
--- /dev/null
+++ b/kconf2h_parser.c
@@ -0,0 +1,327 @@
+
+#line 1 "kconf2h_parser.ragel"
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "kconf2h.h"
+
+#define TYPE_YM 1
+#define TYPE_HEX 2
+#define TYPE_STR 3
+#define TYPE_DEC 4
+
+char *new_string( const char *start, const char *end )
+{
+ int str_s = end-start+1;
+ char *new_str=malloc( str_s+1 );
+ memcpy( new_str, start, str_s );
+ if ( new_str != NULL )
+ new_str[str_s]=0x0;
+ return new_str;
+}
+
+int o_head_def( FILE *f, int type, const char *s_define, const char *e_define,
+ const char *s_value, const char *e_value )
+{
+ if ( f != NULL )
+ {
+ if ( (s_define != NULL) && (e_define != NULL) && (s_define <= e_define) &&
+ (s_value != NULL) && ( e_value != NULL ) && ( s_value <= e_value ))
+ {
+ char *def = new_string( s_define, e_define );
+ char *val = NULL;
+ //printf( "%s\n", def );
+ fprintf( f, "#define %s", def );
+ free( def );
+
+ if ( type != TYPE_YM )
+ {
+ val = new_string( s_value, e_value );
+ fprintf( f, " %s", val );
+ free( val );
+ }
+ /*
+ switch ( type )
+ {
+ case TYPE_HEX:
+ fprintf( f, " %s", val );
+ break;
+ case TYPE_STR:
+ fprintf( f, " %s", val );
+ break;
+ case TYPE_DEC:
+ fprintf( f, " %s", val );
+ break;
+ default:
+ printf("Unknown Kconfig type %d\n", type);
+ }
+ */
+
+ fprintf( f, "\n" );
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+#line 71 "kconf2h_parser.c"
+static const char _k2h_actions[] = {
+ 0, 1, 0, 1, 2, 1, 7, 1,
+ 11, 2, 9, 1, 4, 3, 8, 10,
+ 11, 4, 4, 8, 10, 11, 4, 5,
+ 8, 10, 11, 4, 6, 8, 10, 11
+
+};
+
+static const char _k2h_key_offsets[] = {
+ 0, 0, 3, 6, 7, 8, 9, 10,
+ 11, 12, 17, 23, 30, 33, 37, 39,
+ 42, 46, 52, 59, 60
+};
+
+static const char _k2h_trans_keys[] = {
+ 10, 35, 67, 10, 32, 126, 79, 78,
+ 70, 73, 71, 95, 95, 48, 57, 65,
+ 90, 61, 95, 48, 57, 65, 90, 34,
+ 45, 48, 109, 121, 49, 57, 34, 32,
+ 126, 10, 34, 32, 126, 48, 57, 10,
+ 48, 57, 10, 120, 48, 57, 48, 57,
+ 65, 70, 97, 102, 10, 48, 57, 65,
+ 70, 97, 102, 10, 10, 35, 67, 0
+};
+
+static const char _k2h_single_lengths[] = {
+ 0, 3, 1, 1, 1, 1, 1, 1,
+ 1, 1, 2, 5, 1, 2, 0, 1,
+ 2, 0, 1, 1, 3
+};
+
+static const char _k2h_range_lengths[] = {
+ 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 2, 2, 1, 1, 1, 1, 1,
+ 1, 3, 3, 0, 0
+};
+
+static const char _k2h_index_offsets[] = {
+ 0, 0, 4, 7, 9, 11, 13, 15,
+ 17, 19, 23, 28, 35, 38, 42, 44,
+ 47, 51, 55, 60, 62
+};
+
+static const char _k2h_indicies[] = {
+ 0, 2, 3, 1, 0, 4, 1, 5,
+ 1, 6, 1, 7, 1, 8, 1, 9,
+ 1, 10, 1, 11, 11, 11, 1, 12,
+ 11, 11, 11, 1, 13, 14, 15, 17,
+ 17, 16, 1, 19, 18, 1, 20, 19,
+ 18, 1, 21, 1, 22, 21, 1, 22,
+ 23, 21, 1, 24, 24, 24, 1, 25,
+ 24, 24, 24, 1, 26, 1, 0, 2,
+ 3, 1, 0
+};
+
+static const char _k2h_trans_targs[] = {
+ 20, 0, 2, 3, 2, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 14, 16,
+ 15, 19, 12, 13, 20, 15, 20, 17,
+ 18, 20, 20
+};
+
+static const char _k2h_trans_actions[] = {
+ 7, 0, 1, 9, 0, 0, 0, 0,
+ 0, 0, 0, 0, 3, 5, 5, 5,
+ 5, 5, 0, 0, 22, 0, 17, 0,
+ 0, 27, 12
+};
+
+static const int k2h_start = 1;
+static const int k2h_first_final = 20;
+static const int k2h_error = 0;
+
+static const int k2h_en_main = 1;
+
+
+#line 87 "kconf2h_parser.ragel"
+
+
+int parse_kconf2h( const char *str, FILE *outf )
+{
+
+
+
+ static uint8_t cs;
+ const int stacksize = 10;
+ int res=0, *top=0, *stack=NULL;
+ stack = malloc( sizeof(stack)*stacksize );
+ char *p=(char *)str, *pe = (char *)str + strlen( str ), *eof=NULL;
+
+ /*
+ variables used in state machine
+ */
+ char *token_s=NULL, *token_e=NULL;
+ char *value_s=NULL, *value_e=NULL;
+ int token_type=0;
+ fprintf( outf, "#ifndef __CONFIG_H\n" );
+ fprintf( outf, "#define __CONFIG_H\n" );
+
+
+#line 172 "kconf2h_parser.c"
+ {
+ cs = k2h_start;
+ }
+
+#line 110 "kconf2h_parser.ragel"
+
+#line 179 "kconf2h_parser.c"
+ {
+ int _klen;
+ unsigned int _trans;
+ const char *_acts;
+ unsigned int _nacts;
+ const char *_keys;
+
+ if ( p == pe )
+ goto _test_eof;
+ if ( cs == 0 )
+ goto _out;
+_resume:
+ _keys = _k2h_trans_keys + _k2h_key_offsets[cs];
+ _trans = _k2h_index_offsets[cs];
+
+ _klen = _k2h_single_lengths[cs];
+ if ( _klen > 0 ) {
+ const char *_lower = _keys;
+ const char *_mid;
+ const char *_upper = _keys + _klen - 1;
+ while (1) {
+ if ( _upper < _lower )
+ break;
+
+ _mid = _lower + ((_upper-_lower) >> 1);
+ if ( (*p) < *_mid )
+ _upper = _mid - 1;
+ else if ( (*p) > *_mid )
+ _lower = _mid + 1;
+ else {
+ _trans += (unsigned int)(_mid - _keys);
+ goto _match;
+ }
+ }
+ _keys += _klen;
+ _trans += _klen;
+ }
+
+ _klen = _k2h_range_lengths[cs];
+ if ( _klen > 0 ) {
+ const char *_lower = _keys;
+ const char *_mid;
+ const char *_upper = _keys + (_klen<<1) - 2;
+ while (1) {
+ if ( _upper < _lower )
+ break;
+
+ _mid = _lower + (((_upper-_lower) >> 1) & ~1);
+ if ( (*p) < _mid[0] )
+ _upper = _mid - 2;
+ else if ( (*p) > _mid[1] )
+ _lower = _mid + 2;
+ else {
+ _trans += (unsigned int)((_mid - _keys)>>1);
+ goto _match;
+ }
+ }
+ _trans += _klen;
+ }
+
+_match:
+ _trans = _k2h_indicies[_trans];
+ cs = _k2h_trans_targs[_trans];
+
+ if ( _k2h_trans_actions[_trans] == 0 )
+ goto _again;
+
+ _acts = _k2h_actions + _k2h_trans_actions[_trans];
+ _nacts = (unsigned int) *_acts++;
+ while ( _nacts-- > 0 )
+ {
+ switch ( *_acts++ )
+ {
+ case 0:
+#line 72 "kconf2h_parser.ragel"
+ {}
+ break;
+ case 1:
+#line 73 "kconf2h_parser.ragel"
+ {token_s = p;}
+ break;
+ case 2:
+#line 73 "kconf2h_parser.ragel"
+ {token_e = p-1;}
+ break;
+ case 3:
+#line 76 "kconf2h_parser.ragel"
+ {token_type=TYPE_YM;}
+ break;
+ case 4:
+#line 77 "kconf2h_parser.ragel"
+ {token_type=TYPE_DEC;}
+ break;
+ case 5:
+#line 78 "kconf2h_parser.ragel"
+ {token_type=TYPE_STR;}
+ break;
+ case 6:
+#line 79 "kconf2h_parser.ragel"
+ {token_type=TYPE_HEX;}
+ break;
+ case 7:
+#line 79 "kconf2h_parser.ragel"
+ {value_s = p;}
+ break;
+ case 8:
+#line 79 "kconf2h_parser.ragel"
+ {value_e = p-1;}
+ break;
+ case 9:
+#line 80 "kconf2h_parser.ragel"
+ {}
+ break;
+ case 10:
+#line 80 "kconf2h_parser.ragel"
+ { o_head_def( outf, token_type, token_s, token_e, value_s, value_e ); }
+ break;
+ case 11:
+#line 82 "kconf2h_parser.ragel"
+ {}
+ break;
+#line 301 "kconf2h_parser.c"
+ }
+ }
+
+_again:
+ if ( cs == 0 )
+ goto _out;
+ if ( ++p != pe )
+ goto _resume;
+ _test_eof: {}
+ _out: {}
+ }
+
+#line 111 "kconf2h_parser.ragel"
+
+ if ( cs == k2h_error )
+ {
+ printf("ERR state [%d] pos[%d]:[%s]\n", res, p-str, p);
+ res = -1;
+ }
+
+ fprintf( outf, "#endif\n" );
+
+ return res;
+}
+
+
+
diff --git a/kconf2h_parser.ragel b/kconf2h_parser.ragel
new file mode 100644
index 0000000..c45dc9d
--- /dev/null
+++ b/kconf2h_parser.ragel
@@ -0,0 +1,124 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "kconf2h.h"
+
+#define TYPE_YM 1
+#define TYPE_HEX 2
+#define TYPE_STR 3
+#define TYPE_DEC 4
+
+char *new_string( const char *start, const char *end )
+{
+ int str_s = end-start+1;
+ char *new_str=malloc( str_s+1 );
+ memcpy( new_str, start, str_s );
+ if ( new_str != NULL )
+ new_str[str_s]=0x0;
+ return new_str;
+}
+
+int o_head_def( FILE *f, int type, const char *s_define, const char *e_define,
+ const char *s_value, const char *e_value )
+{
+ if ( f != NULL )
+ {
+ if ( (s_define != NULL) && (e_define != NULL) && (s_define <= e_define) &&
+ (s_value != NULL) && ( e_value != NULL ) && ( s_value <= e_value ))
+ {
+ char *def = new_string( s_define, e_define );
+ char *val = NULL;
+ //printf( "%s\n", def );
+ fprintf( f, "#define %s", def );
+ free( def );
+
+ if ( type != TYPE_YM )
+ {
+ val = new_string( s_value, e_value );
+ fprintf( f, " %s", val );
+ free( val );
+ }
+ /*
+ switch ( type )
+ {
+ case TYPE_HEX:
+ fprintf( f, " %s", val );
+ break;
+ case TYPE_STR:
+ fprintf( f, " %s", val );
+ break;
+ case TYPE_DEC:
+ fprintf( f, " %s", val );
+ break;
+ default:
+ printf("Unknown Kconfig type %d\n", type);
+ }
+ */
+
+ fprintf( f, "\n" );
+ return 1;
+ }
+ }
+ return 0;
+}
+
+%%{
+ machine k2h;
+
+ strings = ( '"' (print+)? '"' );
+ hex = ( '0x' ([a-fA-F0-9])+ );
+ comments = ( ('#' (print+)? )>{} );
+ command_name = (( 'CONFIG_' ([A-Z0-9_])+ )>{token_s = p;}%{token_e = p-1;});
+
+ command = (( command_name '=' (
+ ('y'|'m')%{token_type=TYPE_YM;} |
+ ('-'? digit+)%{token_type=TYPE_DEC;} |
+ strings%{token_type=TYPE_STR;} |
+ hex%{token_type=TYPE_HEX;} )>{value_s = p;}%{value_e = p-1;}
+ )>{}%{ o_head_def( outf, token_type, token_s, token_e, value_s, value_e ); } );
+
+ eol = ( ( '\n' )>{} );
+
+ expr = ((command | comments )? eol)+;
+ main := expr;
+ write data;
+}%%
+
+int parse_kconf2h( const char *str, FILE *outf )
+{
+
+
+
+ static uint8_t cs;
+ const int stacksize = 10;
+ int res=0, *top=0, *stack=NULL;
+ stack = malloc( sizeof(stack)*stacksize );
+ char *p=(char *)str, *pe = (char *)str + strlen( str ), *eof=NULL;
+
+ /*
+ variables used in state machine
+ */
+ char *token_s=NULL, *token_e=NULL;
+ char *value_s=NULL, *value_e=NULL;
+ int token_type=0;
+ fprintf( outf, "#ifndef __CONFIG_H\n" );
+ fprintf( outf, "#define __CONFIG_H\n" );
+
+ %%write init;
+ %%write exec;
+
+ if ( cs == k2h_error )
+ {
+ printf("ERR state [%d] pos[%d]:[%s]\n", res, p-str, p);
+ res = -1;
+ }
+
+ fprintf( outf, "#endif\n" );
+
+ return res;
+}
+
+
+