#!/bin/bash

OptionToggle () {
    type=$1
    feature=$2
    file=.config

    grep -q $feature $file || { echo "no $feature feature" && return 1 ;}
    
    cp -f $file config.tmp
    if [ $type = "disable" ]; then
	echo "Disabling option $feature"
	OPT="CONFIG_$feature" perl -e 'my $a = $ENV{'OPT'}; while (<>) {if (/^$a=/) {print "# $a is not defined\n"; next;} print;}' \
	    < config.tmp > $file
    elif [ $type = "enable" ]; then
	echo "Enabling option $feature"
	OPT="CONFIG_$feature" perl -e 'my $a = $ENV{'OPT'}; while (<>) {if (/^#\s+$a is not set/ || /^$a=m/) {print "$a=y\n"; next;} print;}' \
	    < config.tmp > $file
    elif [ $type = "module" ]; then
	echo "Modularize option $feature"
	OPT="CONFIG_$feature" perl -e 'my $a = $ENV{'OPT'}; while (<>) {if (/^#\s+$a is not set/ || /^$a=y/) {print "$a=m\n"; next;} print;}' \
	    < config.tmp > $file
    fi
    rm -f config.tmp
}

OptionEnable() {
	feature=$1
	OptionToggle enable $feature
}

OptionDisable() {
	feature=$1
	OptionToggle disable $feature
}

OptionModule() {
	feature=$1
	OptionToggle module $feature
}

OptionChange () {
	value=$1
	new_value=$2
	file=.config
	perl -p -i -e "s/$value$/$new_value/" $file
}


# Default kernel is a kernel with everything, then we are removing things
# that we don't need


ConfigPPC () {
	flavour=$1

	case $flavour in
	up)
		OptionDisable SMP
		OptionDisable HIGHMEM
		;;
	smp)
		OptionDisable HIGHMEM
		;;
	enterprise)
		;;
	esac
}

ConfigALPHA () {
	flavour=$1

	case $flavour in
	up)
		OptionDisable SMP
		;;
	smp)
		;;
	esac
}

EnableUPAPIC () {
	OptionChange "CONFIG_HAVE_DEC_LOCK=y" "CONFIG_X86_UP_APIC=y\nCONFIG_X86_UP_IOAPIC=y"
}

ConfigX86 () {
	flavour=$1

	if [ "$KDB" != "1" ]; then
		OptionDisable DEBUG_HIGHMEM
		OptionDisable DEBUG_SLAB
		OptionDisable KDB
		OptionDisable KDB_MODULES
		OptionDisable KALLSYMS
	fi

	# For the cases that we don't have controlated, default behaviour

	case $TARGET_CPU in
	i686)
		# do nothing, that is the default
		;;
	i486)
			OptionDisable M686
			OptionEnable  M486
		;;

	i386)
			OptionDisable M686
			OptionEnable  M386
		;;

	athlon)
			OptionDisable M686
			OptionEnable  MK7
		;;

	k6)
			OptionDisable M686
			OptionEnable  MK6
		;;
	*)
		case $flavour in
		up|smp)
			OptionDisable M686
			OptionEnable  M586
			;;
		enterprise|secure)
			OptionDisable M686
			OptionEnable  MPENTIUMIII
			;;
		BOOT)
			OptionDisable M686
			OptionEnable  M386
			;;
		esac
		;;
	esac

	case $flavour in
	up)
		OptionModule I8K
		OptionModule TOSHIBA
		OptionDisable SMP
		OptionEnable NOHIGHMEM
		OptionDisable HIGHMEM4G
		EnableUPAPIC 
		OptionEnable APM_DO_ENABLE
		OptionEnable APM_CPU_IDLE
		OptionChange "SR_EXTRA_DEVS=4" "SR_EXTRA_DEVS=2"
		OptionModule SONYPI
		OptionDisable GRKERNSEC
		;;
	smp)
		OptionEnable NOHIGHMEM
		OptionDisable HIGHMEM4G
		OptionEnable APM_DO_ENABLE
		OptionEnable APM_CPU_IDLE
		OptionChange "SR_EXTRA_DEVS=4" "SR_EXTRA_DEVS=2"
		OptionDisable GRKERNSEC
		;;
	enterprise)
		OptionDisable MTD
		OptionDisable IDE_CHIPSETS
		OptionDisable ARCNET
		OptionDisable HAMRADIO
		OptionDisable PARPORT_OTHER
		OptionDisable SMC9194
		OptionDisable EWRK3
		OptionDisable QIC02_TAPE
		OptionDisable ADFS_FS
		OptionDisable EFS_FS
		OptionDisable JFFS_FS
		OptionDisable JFFS2_FS
		OptionDisable PARTITION_ADVANCED
		OptionDisable GRKERNSEC
		;;
	secure)
		OptionDisable MTD
		OptionDisable IDE_CHIPSETS
		OptionDisable ARCNET
		OptionDisable HAMRADIO
		OptionDisable PARPORT_OTHER
		OptionDisable SMC9194
		OptionDisable EWRK3
		OptionDisable QIC02_TAPE
		OptionDisable ADFS_FS
		OptionDisable EFS_FS
		OptionDisable JFFS_FS
		OptionDisable JFFS2_FS
		OptionDisable DEVFS_FS
		OptionDisable PARTITION_ADVANCED
		;;
	BOOT)
		OptionDisable MODVERSIONS
		OptionDisable KMOD
		OptionDisable E820_PROC
		OptionDisable SMP
		OptionDisable MICROCODE
		OptionDisable X86_MSR
		OptionDisable X86_CPUID
		OptionDisable MTRR
		OptionDisable HIGHMEM4G
		OptionEnable NOHIGHMEM
		EnableUPAPIC 
		OptionDisable PCI_NAMES
		OptionDisable EISA
		OptionDisable HOTPLUG_PCI
		OptionDisable BSD_PROCESS_ACCT
		OptionDisable BINFMT_AOUT
		OptionDisable BINFMT_MISC
		OptionDisable PM
		OptionDisable MTD
		OptionDisable PARPORT_SERIAL
		OptionEnable PARPORT_PC_SUPERIO
		OptionDisable PARPORT_OTHER
		OptionDisable PNP
		OptionDisable BLK_DEV_XD
		OptionDisable PARIDE
		OptionModule BLK_DEV_MD
		OptionDisable PACKET_MMAP
		OptionDisable NETLINK_DEV
		OptionDisable NETFILTER
		OptionDisable FILTER
		OptionDisable IP_MULTICAST
		OptionDisable IP_ADVANCED_ROUTER
		OptionDisable NET_IPIP
		OptionDisable NET_IPGRE
		OptionDisable INET_ECN
		OptionDisable SYN_COOKIES
		OptionDisable IPV6
		OptionDisable KHTTPD
		OptionDisable ATM
		OptionDisable VLAN_8021Q
		OptionDisable IPX
		OptionDisable ATALK
		OptionDisable DECNET
		OptionDisable BRIDGE
		OptionDisable X25
		OptionDisable LAPB
		OptionDisable IPSEC
		OptionDisable ECONET
		OptionDisable WAN_ROUTER
		OptionDisable NET_SCHED
		OptionDisable PHONE
		OptionModule BLK_DEV_IDECD
		OptionModule BLK_DEV_IDEFLOPPY
		OptionDisable BLK_DEV_ISAPNP
		OptionDisable IDEDMA_PCI_WIP
		OptionDisable IDEDMA_NEW_DRIVE_LISTINGS
		OptionDisable AEC62XX_TUNING
		OptionDisable PIIX_TUNING
		OptionDisable BLK_DEV_PDC_ADMA
		OptionDisable BLK_DEV_QD65XX
		OptionDisable IDEDMA_IVB
		OptionDisable SCSI_CONSTANTS
		OptionDisable SCSI_LOGGING
		OptionDisable AIC7XXX_OLD_TCQ_ON_BY_DEFAULT
		OptionDisable AIC7XXX_OLD_PROC_STATS
		OptionChange "SR_EXTRA_DEVS=4" "SR_EXTRA_DEVS=2"
		OptionDisable SCSI_GENERIC_NCR53C400
		OptionDisable SCSI_U14_34F_LINKED_COMMANDS
		OptionDisable SCSI_DEBUG
		OptionDisable FUSION
		OptionDisable IEEE1394
		OptionDisable I2O
		OptionDisable ARCNET
		OptionDisable BONDING
		OptionDisable TUN
		OptionDisable ETHERTAP
		OptionDisable ULTRA32
		OptionDisable LNE390
		OptionDisable NE3210
		OptionDisable ES3210
		OptionDisable FDDI
		OptionDisable PPP_FILTER
		OptionDisable SLIP_COMPRESSED
		OptionDisable SLIP_SMART
		OptionDisable SLIP_MODE_SLIP6
		OptionDisable CIPE
		OptionDisable SHAPER
		OptionDisable WAN
		OptionDisable HAMRADIO
		OptionDisable IRDA
		OptionDisable ISDN_PPP
		OptionDisable ISDN_AUDIO
		OptionDisable ISDN_DRV_LOOP
		OptionDisable ISDN_DIVERSION
		OptionDisable ISDN_DRV_HISAX
		OptionDisable ISDN_DRV_ICN
		OptionDisable ISDN_DRV_PCBIT
		OptionDisable ISDN_DRV_SC
		OptionDisable ISDN_DRV_ACT2000
		OptionDisable ISDN_DRV_EICON
		OptionDisable ISDN_CAPI
		OptionDisable HYSDN
		OptionDisable HYSDN_CAPI
		OptionDisable CD_NO_IDESCSI
		OptionDisable INPUT_JOYDEV
		OptionDisable ECC
		OptionModule SERIAL
		OptionDisable SERIAL_NONSTANDARD
		OptionDisable UNIX98_PTYS
		OptionDisable I2C
		OptionDisable INPUT_GAMEPORT
		OptionDisable INPUT_NS558
		OptionDisable INPUT_LIGHTNING
		OptionDisable INPUT_PCIGAME
		OptionDisable INPUT_CS461X
		OptionDisable INPUT_EMU10K1
		OptionDisable INPUT_SERIO
		OptionDisable INPUT_SERPORT
		OptionDisable INPUT_ANALOG
		OptionDisable INPUT_A3D
		OptionDisable INPUT_ADI
		OptionDisable INPUT_COBRA
		OptionDisable INPUT_GF2K
		OptionDisable INPUT_GRIP
		OptionDisable INPUT_INTERACT
		OptionDisable INPUT_TMDC
		OptionDisable INPUT_SIDEWINDER
		OptionDisable INPUT_IFORCE_USB
		OptionDisable INPUT_IFORCE_232
		OptionDisable INPUT_WARRIOR
		OptionDisable INPUT_MAGELLAN
		OptionDisable INPUT_SPACEORB
		OptionDisable INPUT_SPACEBALL
		OptionDisable INPUT_STINGER
		OptionDisable INPUT_DB9
		OptionDisable INPUT_GAMECON
		OptionDisable INPUT_TURBOGRAFX
		OptionDisable QIC02_TAPE
		OptionDisable WATCHDOG
		OptionDisable RTC
		OptionDisable DTLK
		OptionDisable FTAPE
		OptionDisable DRM
		OptionDisable VIDEO_DEV
		OptionDisable CRYPTO
		OptionDisable QUOTA
		OptionDisable FS_POSIX_ACL
		OptionDisable AUTOFS_FS
		OptionDisable AUTOFS4_FS
		OptionDisable SUPERMOUNT
		OptionDisable ADFS_FS
		OptionDisable AFFS_FS
		OptionDisable HFS_FS
		OptionDisable BFS_FS
		OptionDisable MSDOS_FS
		OptionDisable UMSDOS_FS
		OptionDisable EFS_FS
		OptionDisable CRAMFS
		OptionDisable TMPFS
		OptionDisable RAMFS
		OptionDisable JOLIET
		OptionDisable ZISOFS
		OptionDisable MINIX_FS
		OptionDisable VXFS_FS
		OptionDisable NTFS_FS
		OptionDisable HPFS_FS
		OptionDisable DEVFS_FS
		OptionDisable DEVPTS_FS
		OptionDisable ROMFS_FS
		OptionDisable SYSV_FS
		OptionDisable UDF_FS
		OptionDisable UFS_FS
		OptionDisable XFS_RT
		OptionDisable XFS_QUOTA
		OptionDisable XFS_DMAPI
		OptionDisable CODA_FS
		OptionDisable INTERMEZZO_FS
		OptionDisable NFSD
		OptionDisable SMB_FS
		OptionDisable NCP_FS
		OptionDisable PARTITION_ADVANCED
		OptionDisable NLS_CODEPAGE_437
		OptionDisable NLS_CODEPAGE_737
		OptionDisable NLS_CODEPAGE_775
		OptionDisable NLS_CODEPAGE_850
		OptionDisable NLS_CODEPAGE_852
		OptionDisable NLS_CODEPAGE_855
		OptionDisable NLS_CODEPAGE_857
		OptionDisable NLS_CODEPAGE_860
		OptionDisable NLS_CODEPAGE_861
		OptionDisable NLS_CODEPAGE_862
		OptionDisable NLS_CODEPAGE_863
		OptionDisable NLS_CODEPAGE_864
		OptionDisable NLS_CODEPAGE_865
		OptionDisable NLS_CODEPAGE_866
		OptionDisable NLS_CODEPAGE_869
		OptionDisable NLS_CODEPAGE_936
		OptionDisable NLS_CODEPAGE_950
		OptionDisable NLS_CODEPAGE_932
		OptionDisable NLS_CODEPAGE_949
		OptionDisable NLS_CODEPAGE_874
		OptionDisable NLS_ISO8859_8
		OptionDisable NLS_CODEPAGE_1250
		OptionDisable NLS_CODEPAGE_1251
		OptionDisable NLS_ISO8859_2
		OptionDisable NLS_ISO8859_3
		OptionDisable NLS_ISO8859_4
		OptionDisable NLS_ISO8859_5
		OptionDisable NLS_ISO8859_6
		OptionDisable NLS_ISO8859_7
		OptionDisable NLS_ISO8859_9
		OptionDisable NLS_ISO8859_13
		OptionDisable NLS_ISO8859_14
		OptionDisable NLS_ISO8859_15
		OptionDisable NLS_KOI8_R
		OptionDisable NLS_KOI8_U
		OptionDisable NLS_UTF8
		OptionDisable MDA_CONSOLE
		OptionDisable FB_RIVA
		OptionDisable FB_CLGEN
		OptionDisable FB_PM2
		OptionDisable FB_CYBER2000
		OptionDisable FB_VGA16
		OptionDisable FB_HGA
		OptionDisable FB_MATROX
		OptionDisable FB_ATY
		OptionDisable FB_RADEON
		OptionDisable FB_ATY128
		OptionDisable FB_SIS
		OptionDisable FB_3DFX
		OptionDisable FB_VOODOO1
		OptionDisable FBCON_SPLASHSCREEN
		OptionDisable SOUND
		OptionDisable USB_AUDIO
		OptionDisable USB_BLUETOOTH
		OptionDisable USB_STORAGE_DPCM
		OptionDisable USB_STORAGE_HP8200e
		OptionDisable USB_STORAGE_SDDR09
		OptionDisable USB_HIDDEV
		OptionDisable USB_DC2XX
		OptionDisable USB_MDC800
		OptionDisable USB_SERIAL_GENERIC
		OptionDisable USB_SERIAL_BELKIN
		OptionDisable USB_SERIAL_WHITEHEAT
		OptionDisable USB_SERIAL_DIGI_ACCELEPORT
		OptionDisable USB_SERIAL_EMPEG
		OptionDisable USB_SERIAL_FTDI_SIO
		OptionDisable USB_SERIAL_VISOR
		OptionDisable USB_SERIAL_IPAQ
		OptionDisable USB_SERIAL_IR
		OptionDisable USB_SERIAL_EDGEPORT
		OptionDisable USB_SERIAL_KEYSPAN_PDA
		OptionDisable USB_SERIAL_KEYSPAN
		OptionDisable USB_SERIAL_MCT_U232
		OptionDisable USB_SERIAL_KLSI
		OptionDisable USB_SERIAL_PL2303
		OptionDisable USB_SERIAL_XIRCOM
		OptionDisable USB_SERIAL_OMNINET
		OptionDisable USB_RIO500
		OptionDisable BLUEZ
		OptionEnable BOOT_KERNEL
		OptionDisable MAGIC_SYSRQ
		OptionDisable DEBUG_BUGVERBOSE
		OptionDisable MOD_QUICKCAM
		OptionDisable PAEP
		OptionDisable SAM9407
		OptionDisable GRKERNSEC
		;;
	esac
}

CreateConfig () {
	arch=$1
	flavour=$2

	# Notice that here we don't need make mrproper, because we are not
	# going to compile (yet).
	install -m 644 arch/$arch/defconfig-maximum .config

	case $arch in
	alpha)
		ConfigALPHA $flavour
		;;
	ppc)
		ConfigPPC $flavour
		;;
	i386)
		ConfigX86 $flavour
		;;
	esac
	make ARCH=$arch oldconfig

	if [ "$flavour" = "up" ]; then
		install -m 644 .config arch/$arch/defconfig
	else
		install -m 644 .config arch/$arch/defconfig-$flavour
	fi
}

CreateConfigs() {
	CreateConfig i386 up
	CreateConfig i386 smp
	CreateConfig i386 enterprise
	CreateConfig i386 secure
	CreateConfig i386 BOOT

	CreateConfig alpha up
	CreateConfig alpha smp

	CreateConfig ppc up
	CreateConfig ppc smp
	CreateConfig ppc enterprise
}

CreateConfigs
