# Process this file with http://www.scons.org to build FSPlib.

import os
# init Scons
EnsureSConsVersion(0,96)
PACKAGE='fsplib'
VERSION='0.11'

#Defaults
PREFIX='/usr/local'
SHARED=0

env = Environment()
# Turn CPPFLAGS to list
env.Append( CPPFLAGS = [])

################### Functions ######################
def importEnv(list=None, prefix=None):
   if list:
       for i in list:
	   if os.environ.get(i):
	       kw={}
	       kw[i]=os.environ.get(i)
	       kw={ 'ENV': kw }
	       env.Append(**kw)
   if prefix:
       for i in os.environ.keys():
	   if i.startswith(prefix):
	       kw={}
	       kw[i]=os.environ.get(i)
	       kw={ 'ENV': kw }
	       env.Append(**kw)

#import environment
importEnv(['HOME','CC'])
importEnv(prefix='DISTCC_')
importEnv(prefix='CCACHE_')
if env['ENV'].get('CC'):
    env.Replace( CC = env['ENV'].get('CC'))
# Get CC from commandline
if ARGUMENTS.get('CC', 0):
    env.Replace(CC =  ARGUMENTS.get('CC'))

############# Custom configure tests ###################

def checkForDirentMember(conf,member,symbol):
    """Checks if dirent structure has specified field member.
 
    Keyword arguments:
    member -- what member we are checking
    symbol -- symbol to be defined by preprocessor if member exists

    """
    conf.Message("checking whether dirent structure has member "+member+"... ")
    rc=conf.TryCompile("""
    #include <sys/types.h>
    #include <dirent.h>

    void dummy(void);
    void dummy()
    {
	struct dirent d;
	d."""+member+"""=0;
    }
    """,".c")
    if rc:
        conf.env.Append(CPPFLAGS = '-D'+symbol)
    conf.Result(rc)
    return rc

def checkForGCCOption(conf,option):
    """Check if compiler supports specified option"""
    conf.Message("checking whether CC supports "+option+" ")
    lastCFLAGS=conf.env['CCFLAGS']
    conf.env.Append(CCFLAGS = option)
    rc = conf.TryCompile("""
    void dummy(void);
    void dummy(void) {}
    """,'.c')
    if not rc:
       conf.env.Replace(CCFLAGS = lastCFLAGS)
    conf.Result(rc)
    return rc

def checkForMaintainerMode(conf):
    """Check if maintainer mode is enabled by command line"""
    conf.Message("checking whether to enable maintainer mode... ")
    if ARGUMENTS.get('maintainer-mode', 0) or \
       ARGUMENTS.get('enable-maintainer-mode', 0):
			  conf.Result(1)
			  conf.env.Append(CCFLAGS = '-O0')
			  conf.env.Append(CPPFLAGS = '-DMAINTAINER_MODE')
    else:
			  conf.env.Append(CCFLAGS = '-O')
			  conf.Result(0)

def checkForLockPrefix(conf):
    """check for user-supplied lock prefix on command line"""
    conf.Message("checking for user supplied lockprefix... ")
    lp = ARGUMENTS.get('lockprefix', 0) or ARGUMENTS.get("with-lockprefix",0)

    if lp:
			  conf.Result(1)
			  conf.env.Append(CPPFLAGS = '-DFSP_KEY_PREFIX=\\"'+lp+'\\"')
    else:
			  conf.Result(0)

def checkForUserPrefix(conf):
    """check for user-supplied installation prefix"""
    global PREFIX
    conf.Message("checking for user supplied prefix... ")
    lp = ARGUMENTS.get('prefix', 0)
    if lp:
			  conf.Result(1)
			  PREFIX=lp
    else:
			  conf.Result(0)

def checkForBuildingSharedLibrary(conf):
    """check if building shared library was requested"""
    global SHARED
    conf.Message("checking whether to build shared library... ")
    makeshared=ARGUMENTS.get('enable-shared', 0)
    if makeshared == 0 or makeshared == 'no':
			  conf.Result(0)
			  SHARED=0
    else:
			  conf.Result(1)
			  SHARED=1

#Start configuration
conf = Configure(env,{'checkForGCCOption':checkForGCCOption,
                      'MAINTAINER_MODE':checkForMaintainerMode,
		      'checkForLockPrefix':checkForLockPrefix,
		      'checkPrefix':checkForUserPrefix,
		      'checkDirentFor':checkForDirentMember,
		      'ENABLE_SHARED':checkForBuildingSharedLibrary}
		      )
for option in Split("""
      -Wall -W -Wstrict-prototypes -Wmissing-prototypes -Wshadow
      -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings
      -Waggregate-return -Wmissing-declarations
      -Wmissing-format-attribute -Wnested-externs
      -ggdb -fno-common -Wchar-subscripts -Wcomment
      -Wimplicit -Wsequence-point -Wreturn-type
      -Wfloat-equal -Wno-system-headers -Wredundant-decls
      -Wmissing-noreturn -pedantic
      -Wlong-long -Wundef -Winline
      -Wpointer-arith -Wno-unused-parameter
"""):
       conf.checkForGCCOption(option)
#portability checks       
if not conf.CheckType("union semun", "#include <sys/types.h>\n#include <sys/ipc.h>\n#include <sys/sem.h>",'c'):
       conf.env.Append(CPPFLAGS = "-D_SEM_SEMUN_UNDEFINED=1")
conf.checkDirentFor('d_namlen','HAVE_DIRENT_NAMLEN')
conf.checkDirentFor('d_fileno','HAVE_DIRENT_FILENO')
conf.checkDirentFor('d_type','HAVE_DIRENT_TYPE')
if conf.CheckCHeader('stdint.h'):
       conf.env.Append(CPPFLAGS = "-DHAVE_STDINT_H")
#locking type checks
fun_lockf=conf.CheckFunc("lockf")
fun_semop=conf.CheckFunc("semop")
fun_shmget=conf.CheckFunc("shmget")
#select locking type
lt=ARGUMENTS.get('locking', 0) or ARGUMENTS.get("with-locking",0) or ARGUMENTS.get("lock",0) or ARGUMENTS.get("with-lock",0)
if lt == "none":
    conf.env.Append(CPPFLAGS = '-DFSP_NOLOCKING')
elif lt == "lockf" and fun_lockf:
    conf.env.Append(CPPFLAGS = '-DFSP_USE_LOCKF')
elif lt == "semop" and fun_semop and fun_shmget:
    conf.env.Append(CPPFLAGS = '-DFSP_USE_SHAREMEM_AND_SEMOP')
elif fun_semop and fun_shmget:
    conf.env.Append(CPPFLAGS = '-DFSP_USE_SHAREMEM_AND_SEMOP')
elif fun_lockf:
    conf.env.Append(CPPFLAGS = '-DFSP_USE_LOCKF')
else:
    conf.env.Append(CPPFLAGS = '-DFSP_NOLOCKING')
conf.checkForLockPrefix()
conf.checkPrefix()
conf.ENABLE_SHARED()
conf.MAINTAINER_MODE()
conf.Finish()

# process build rules
Export( Split("env PREFIX PACKAGE VERSION SHARED"))
env.SConscript(dirs=['.'])
