#!/usr/bin/python

"""
Read a configuration file and save to a database
"""

import re
import sys
from sqlmix import Db

rn=re.compile(r'# CONFIG_(\S+) is not set\s*$')
rm=re.compile(r'CONFIG_(\S+)=m\s*$')
ry=re.compile(r'CONFIG_(\S+)=y\s*$')
ral=re.compile(r'CONFIG_(\S+)=(".*")\s*$')
rnum=re.compile(r'CONFIG_(\S+)=(0x[0-9a-fA-F]+|\d+)\s*$')

db="config"

if __name__ == "__main__":
	try: from optparse import OptionParser
	except ImportError: from optik import OptionParser

	parser = OptionParser(conflict_handler="resolve")
	parser.add_option("-h","--help","-?", action="help", help="gibt diesen Hilfstext aus")
	parser.add_option("-f", "--file", dest="file", action="store", help="file to write")
	parser.add_option("-k", "--key", dest="key", action="store", help="database key")
	parser.add_option("-i", "--init", dest="init", action="store_true", help="initialize the database", default=False)
	parser.add_option("-r", "--replace", dest="replace", action="store_true", help="replace existing values", default=False)
	parser.add_option("-d", "--database", dest="database", action="store", help="database name")

	(opts, args) = parser.parse_args()
	if args:
		raise RuntimeError("No arguments accepted")

	if opts.database: db=opts.database
	db=Db(db)

	if opts.file: f=open(opts.file,"r")
	else: f=sys.stdin

	if opts.init:
		db.Do("""
			create table kernelconfig (
				id int not null auto_increment ,
				conf varchar(100) not null,
				sub varchar(100) not null default '',
				val char(1) null default null,
				primary key(id),
				unique key(sub,conf));
		""", _empty=1)
	
	upd=0

	cf = {}
	for l in f:
		m=None

		if not m:
			m=rn.match(l)
			if m: flag=None
		if not m:
			m=rm.match(l)
			if m: flag="m"
		if not m:
			m=ry.match(l)
			if m: flag="y"
		if not m:
			m=ral.match(l)
			if m: flag=m.group(2)
		if not m:
			m=rnum.match(l)
			if m: flag=m.group(2)
		if not m:
			if l.startswith("CONFIG_"):
				l=l.rstrip()
				print "?",l
			continue
		key=m.group(1)
		cf[key] = flag
	
	sub=opts.key
	if not sub: sub=""
	done = 0
	ocf = cf
	while True:
		for key,val in db.DoSelect("select conf,val from kernelconfig where sub=${sub}", sub=sub, _empty=1):
			if key in cf and cf[key] == val:
				del cf[key]

		i=0
		s="replace into kernelconfig(conf,sub,val) values ";
		args={}
		for k,v in cf.iteritems():
			if i: s += ","
			s += "(${key%d},${sub},${val%d})" % (i,i)
			args["key"+str(i)] = k
			args["val"+str(i)] = v
			i+=1
			upd+=1

			if i >= 100:
				db.Do(s, sub=sub,**args)
				s="replace into kernelconfig(conf,sub,val) values ";
				args={}
				i=0
		if i:
			db.Do(s, sub=sub,**args)
		if not opts.replace or not sub:
			break
		i=sub.rfind("/")
		if i>-1:
			sub=sub[:i]
		else:
			sub=""
		cf = ocf
	
	db.commit()

	print upd

