From 77fe6091096d7bf1a73f600cbe8f90c702583ef3 Mon Sep 17 00:00:00 2001
From: Artur Artamonov <freeartman@wechall.net>
Date: Thu, 13 Mar 2014 13:19:24 +0200
Subject: Initial commit

---
 Makefile             |  20 ++++
 config_test1         |  13 ++
 kconf2h.c            |  50 ++++++++
 kconf2h.h            |  10 ++
 kconf2h_parser.c     | 327 +++++++++++++++++++++++++++++++++++++++++++++++++++
 kconf2h_parser.ragel | 124 +++++++++++++++++++
 6 files changed, 544 insertions(+)
 create mode 100644 Makefile
 create mode 100644 config_test1
 create mode 100644 kconf2h.c
 create mode 100644 kconf2h.h
 create mode 100644 kconf2h_parser.c
 create mode 100644 kconf2h_parser.ragel

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;
+}
+
+
+
-- 
cgit v1.2.3