implementation module PmProject import StdClass,StdBool, StdInt, StdString,StdArray, StdFunc, StdTuple, StdList import StdMaybe import PmPath, UtilStrictLists from UtilDate import NoDate, :: DATE import UtilNewlinesFile import PmTypes import Platform import UtilOptions, PmFiles //-- :: Def_and_Imp :== Bool; DclMod :== True; IclMod :== False; :: WindowOpen_and_Closed :== Bool; WinOpen :== True; WinClosed :== False; :: Modification :== Bool; Modified :== True; Unmodified :== False; // The Project: A list of constituent modules and their mutual dependencies :: Project = { built :: !Bool // Was dependency list generated? , saved :: !Bool , exec :: !Bool // exe linked ok? , inflist :: !InfList // list with constituent modules , codegenopt :: !CodeGenOptions // code generator options , code_gen_options_unchanged :: !Bool , applicationopt :: !ApplicationOptions // application options , linkOptions :: !LinkOptions , prjpaths :: !List String // project paths , staticLibInfo :: !StaticLibInfo , target :: !String // environment , static_info :: !ProjectStaticInfo , dynamic_info :: !ProjectDynamicInfo , execpath :: !String // move to app_opts , prec :: !Maybe String // " (precompile command) , posl :: !Maybe String // " (postlink command) } // First element of InfList (if any) is the root module. :: InfList :== List InfListItem :: InfListItem = { mn :: !Modulename // module name , info :: !ModInfo // module info , src :: !Bool // src up to date? , abc :: !Bool // abc up to date? } :: InfUpdate :== InfListItem -> (!InfListItem, Bool) PR_InitProject :: Project; PR_InitProject = { built = True , saved = True , exec = True , execpath = EmptyPathname , inflist = Nil , codegenopt = DefCodeGenOptions , code_gen_options_unchanged = True , applicationopt = DefApplicationOptions // , projectopt = DefProjectOptions , linkOptions = DefaultLinkOptions , prjpaths = Nil , staticLibInfo = DefStaticLibInfo , target = "" , static_info = EmptyStaticInfo , dynamic_info = EmptyDynamicInfo , prec = Nothing , posl = Nothing } PR_GetExecPath :: !Project -> String PR_GetExecPath {execpath} = execpath PR_SetExecPath :: !String !Project -> Project PR_SetExecPath pth prj = {prj & execpath = pth} DefStaticLibInfo = { sLibs = Nil , sDcls = Nil , sDeps = Nil } PR_ProjectSet :: !Project -> Bool; PR_ProjectSet project=:{inflist=Nil} = False; PR_ProjectSet project=:{inflist} = True; PR_NewProject :: !String !EditWdOptions !CompilerOptions !CodeGenOptions !ApplicationOptions !(List String) !LinkOptions -> Project; PR_NewProject main_module_file_name eo compilerOptions cgo ao prjpaths linkOptions = { PR_InitProject & built = False , saved = False , exec = False , execpath = PlatformDependant //MakeExecPathname main_module_file_name ("{Project}"+++DirSeparatorString+++modname+++".exe") // Win ("{Project}"+++DirSeparatorString+++modname) // Mac , inflist = { mn = modname , info = { dir = "{Project}"//dirname , defeo = eo , impeo = eo , compilerOptions = compilerOptions , defopen = False , impopen = True , abcLinkInfo = {linkObjFileNames = Nil, linkLibraryNames = Nil} } , src = True , abc = True } :! Nil , codegenopt = cgo , code_gen_options_unchanged = True , applicationopt= ao , prjpaths = if (StringOccurs dirname prjpaths) prjpaths (dirname:!prjpaths) , linkOptions = linkOptions , staticLibInfo = DefStaticLibInfo , target = "StdEnv" } where modname = GetModuleName main_module_file_name; dirname = RemoveFilename main_module_file_name; //-- PR_SetBuilt :: !(List Modulename) !.Project -> .Project; PR_SetBuilt used project=:{inflist=Nil} = {Project | project & built = True}; PR_SetBuilt used prj=:{inflist=infl=:(root:!rest),saved} #! len = LLength rest # used = Map GetModuleName used # rest = RemoveUnusedModules used rest # len` = LLength rest # unchanged = len == len` = {prj & built=True,saved=saved && unchanged,inflist= root:!rest} where {mn=rootmn,info} = root RemoveUnusedModules used list = FilterR member list where member {mn} = StringOccurs mn used && rootmn <> mn //-- PR_AddABCInfo :: !String !(List LinkObjFileName) !(List LinkLibraryName) !CompilerOptions !EditWdOptions !EditWdOptions !Project -> Project PR_AddABCInfo mod_path dep_objects dep_libraries compilerOptions defeo impeo project=:{inflist=Nil} // # project = trace_n ("PR_Add: no root...") project = project PR_AddABCInfo mod_path dep_objects dep_libraries compilerOptions defeo impeo project=:{inflist} // # project = trace_n ("PR_Add: adding "+++mod_path) project # inflist = TryInsertInList mod_name mod_dir inflist # (inflist,_) = UpdateList mod_name update inflist; = {project & saved=False,inflist=inflist, built=False} where mod_name = GetModuleName mod_path mod_dir = RemoveFilename mod_path update infListItem=:{InfListItem | info} = ( { InfListItem | infListItem & info.abcLinkInfo.linkObjFileNames = dep_objects , info.abcLinkInfo.linkLibraryNames = dep_libraries , info.dir = mod_dir , info.compilerOptions = compilerOptions }, True) TryInsertInList :: !String !String !InfList -> InfList TryInsertInList importermn importerdir Nil // no root module... = Nil TryInsertInList importermn importerdir ((root=:{mn,info}):!rest) | importermn == mn // updating root module... # root = {InfListItem | root & info = {ModInfo | info & dir = importerdir}} = root :! rest # rest = TryInsertImporter rest rest = root :! rest where TryInsertImporter :: !InfList !InfList -> InfList TryInsertImporter Nil list # item = { mn = importermn, info = { dir = importerdir, compilerOptions = compilerOptions, defeo = defeo, impeo = impeo, defopen = False, impopen = False, abcLinkInfo = {linkObjFileNames = Nil, linkLibraryNames = Nil} }, src = True, abc = True } = item :! list TryInsertImporter (({mn}):!rest) list | importermn<>mn = TryInsertImporter rest list = list //-- PR_ClearDependencies :: !Project -> Project PR_ClearDependencies project=:{inflist=Nil} = {project & saved = False, inflist = Nil, built = False} PR_ClearDependencies project=:{inflist=il=:(root :! rest)} = {project & saved = False, inflist = root` :! Nil, built = False} where root` = {InfListItem | root & info.abcLinkInfo = {linkObjFileNames = Nil, linkLibraryNames = Nil}} PR_SetRoot :: !String !EditWdOptions !CompilerOptions !Project -> Project; PR_SetRoot root eo co project=:{inflist=Nil} = project; PR_SetRoot newroot eo compilerOptions project=:{prjpaths} = {project & saved = False, built = False, exec = False, inflist = { mn = modname, info = { dir = dirname, defeo = eo, impeo = eo, compilerOptions = compilerOptions, defopen = False, /* nonsense, we don't know this! */ impopen = True, abcLinkInfo = {linkObjFileNames = Nil, linkLibraryNames = Nil} }, src = True, abc = True } :! Nil, prjpaths= if (StringOccurs dirname prjpaths) prjpaths (dirname:!prjpaths) /* a bit iffy */ }; where modname = GetModuleName newroot; dirname = RemoveFilename newroot; PR_SetCompiled :: !Modulename !Project -> Project; PR_SetCompiled modname project=:{inflist} = {project & inflist = inf`} where (inf`, _) = UpdateList modname setcompiled inflist; setcompiled :: !InfListItem -> (!InfListItem,!Bool); setcompiled itm=:{src,abc} = ({itm & src = True},True); PR_SetCodeGenerated :: !Modulename !Project -> Project; PR_SetCodeGenerated modname project=:{inflist} = {project & inflist = inf`}; where (inf`,_) = UpdateList modname setcode inflist; setcode :: !InfListItem -> (!InfListItem, !Bool); setcode itm=:{InfListItem | src} = ({InfListItem | itm & abc = True}, True); PR_SetSysCodeGenerated :: !Project -> Project; PR_SetSysCodeGenerated project = {project & code_gen_options_unchanged = True}; PR_SetLinked :: !Project -> Project; PR_SetLinked project=:{inflist} = {project & exec = True}; PR_SetSaved :: !Project -> Project; PR_SetSaved project = {Project | project & saved = True}; PR_SetCodeGenOptions :: !CodeGenOptions !Project -> Project; PR_SetCodeGenOptions options project=:{inflist,saved,codegenopt,code_gen_options_unchanged} = { project & inflist = infl` , saved = saved && unchanged , code_gen_options_unchanged = code_gen_options_unchanged && cg_unchanged , codegenopt = options } where (infl`,_) = infl`_; infl`_ | cg_unchanged = (inflist,True); = P_MapR setcode inflist; unchanged = cg_unchanged; cg_unchanged = options == codegenopt; setcode :: !InfListItem -> (!InfListItem, !Bool); setcode itm=:{InfListItem | src} = ({InfListItem | itm & abc = False}, True); PR_SetApplicationOptions :: !ApplicationOptions !Project -> Project; PR_SetApplicationOptions options project=:{saved,exec,applicationopt} = {project & applicationopt = options, exec = exec && unchanged,saved=saved && unchanged}; where unchanged = eqAppOpts options applicationopt; eqAppOpts :: !ApplicationOptions !ApplicationOptions -> Bool eqAppOpts ao1 ao2 = ao1.hs == ao2.hs && ao1.ss == ao2.ss && ao1.em == ao2.em && ao1.heap_size_multiple == ao2.heap_size_multiple && ao1.initial_heap_size == ao2.initial_heap_size && ao1.set == ao2.set && ao1.sgc == ao2.sgc && ao1.pss == ao2.pss && ao1.marking_collection == ao2.marking_collection && ao1.o == ao2.o && ao1.fn == ao2.fn && ao1.fs == ao2.fs && ao1.write_stderr_to_file == ao2.write_stderr_to_file && ao1.memoryProfiling == ao2.memoryProfiling && ao1.memoryProfilingMinimumHeapSize == ao2.memoryProfilingMinimumHeapSize && ao1.profiling == ao2.profiling && ao1.stack_traces == ao2.stack_traces && ao1.standard_rte == ao2.standard_rte // do we need to check resource linking flags??? eqLinkOpts :: !LinkOptions !LinkOptions -> Bool eqLinkOpts lo1 lo2 = lo1.method == lo2.method && lo1.generate_relocations == lo2.generate_relocations && lo1.generate_link_map == lo2.generate_link_map && lo1.link_resources == lo2.link_resources && (if lo1.link_resources (lo1.resource_source == lo2.resource_source) True) && EQStrings (SortStrings lo1.extraObjectModules) (SortStrings lo2.extraObjectModules) && EQStrings (SortStrings lo1.libraries) (SortStrings lo2.libraries) && lo1.generate_dll == lo2.generate_dll && lo1.dll_export_list_name == lo2.dll_export_list_name PR_SetLinkOptions :: !Project !LinkOptions -> Project; PR_SetLinkOptions project linkOptions | eqLinkOpts linkOptions project.Project.linkOptions = {Project | project & linkOptions = linkOptions, saved = False}; | otherwise = {Project | project & linkOptions = linkOptions, exec = False, saved = False}; PR_GetLinkOptions :: !Project -> LinkOptions; PR_GetLinkOptions project = project.Project.linkOptions; PR_SetPaths :: !Bool !(List String) !(List String) !Project -> Project; PR_SetPaths def defs new project=:{Project | inflist=Nil} = project; PR_SetPaths def defs new project=:{Project | built,inflist=infl=:((root=:{InfListItem | info={dir}}):!rest),prjpaths,saved} | def = {Project | project & built = built && olddirs, saved = saved && olddirs, inflist = inflist1 }; = {Project | project & built = built && olddirs, saved = saved && unchanged && olddirs, inflist = inflist1, prjpaths = prjpaths1 }; where (inflist1,olddirs) = P_MapR SetDcl_and_Icl_and_ABCModified infl; unchanged = EQStrings (SortStrings prjpaths) (SortStrings prjpaths1); prjpaths1 | def = prjpaths; | StringOccurs dir new = new; = dir:!new; SetDcl_and_Icl_and_ABCModified :: !InfListItem -> (!InfListItem,!Bool); SetDcl_and_Icl_and_ABCModified itm=:{InfListItem | info=minfo=:{dir}} | unchanged = ({itm & src=False}, True); = ({itm & info = {minfo & dir=""}, src=False},False); where unchanged = StringOccurs dir defs || StringOccurs dir prjpaths1; PR_GetCodeGenOptions :: !Project -> CodeGenOptions; PR_GetCodeGenOptions project=:{codegenopt} = codegenopt; //PR_GetProcessor :: !Project -> Processor; //PR_GetProcessor project=:{codegenopt={tp}} = tp; PR_GetApplicationOptions :: !Project -> ApplicationOptions; PR_GetApplicationOptions project=:{applicationopt} = applicationopt; PR_GetPaths :: !Project -> List String; PR_GetPaths project=:{Project | prjpaths} = prjpaths; PR_GetRootModuleName :: !Project -> String PR_GetRootModuleName p=:{inflist=Nil} = EmptyPathname PR_GetRootModuleName p=:{inflist={mn}:!rest} = mn PR_GetRootPathName :: !Project -> (String,Project) PR_GetRootPathName p=:{inflist=Nil} = (EmptyPathname,p) PR_GetRootPathName p=:{inflist={mn,info={dir}}:!rest} | size dir==0 = (EmptyPathname,p) = (MakeFullPathname dir (MakeImpPathname mn),p) PR_GetRootPath :: !Project -> String PR_GetRootPath {inflist=Nil} = EmptyPathname; PR_GetRootPath {inflist={mn,info={dir}}:!rest} | size dir==0 = EmptyPathname; = dir; PR_GetModulenames :: !Bool !Def_and_Imp !Project -> (List String,Project) PR_GetModulenames full def project=:{inflist} = (modnames,project) where (modnames,_) = P_MapR GetModulenames inflist GetModulenames :: !InfListItem -> (!String ,!Bool) GetModulenames {mn,info={dir}} | full && def = (MakeFullPathname dir (MakeDefPathname mn),True) | full = (MakeFullPathname dir (MakeImpPathname mn),True) = (mn,True) PR_GetOpenModulenames :: !Project -> List String PR_GetOpenModulenames project=:{inflist} = FlattenList modnames where (modnames,_) = P_MapR GetModulenames inflist GetModulenames :: !InfListItem -> (List String,!Bool) GetModulenames {mn,info={dir,defopen,impopen}} | defopen && impopen = ((defname :! impname :! Nil),True) | defopen = ((defname :! Nil),True) | impopen = ((impname :! Nil),True) = (Nil,True) where defname = MakeFullPathname dir (MakeDefPathname mn) impname = MakeFullPathname dir (MakeImpPathname mn) PR_GetModuleStuff :: !Project -> List (Modulename,String,Modulename,String) PR_GetModuleStuff project=:{inflist} = stuff where (stuff,_) = P_MapR GetModulenames inflist GetModulenames :: !InfListItem -> ((!Modulename,!String,!Modulename,!String),!Bool) GetModulenames {mn,info={dir}} = ((MakeDefPathname mn,dir,MakeImpPathname mn,dir),True) PR_Built :: !Project -> Bool; PR_Built project=:{Project | built} = built; PR_SrcUpToDate :: !Modulename !Project -> Bool; PR_SrcUpToDate modname project=:{inflist} # item = FindInList modname inflist | isNothing item = False # item = fromJust item = item.src PR_ABCUpToDate :: !Modulename !Project -> Bool; PR_ABCUpToDate modname project=:{inflist} # item = FindInList modname inflist | isNothing item = False # item = fromJust item = item.abc PR_SysUptoDate :: !Project -> Bool; PR_SysUptoDate project=:{code_gen_options_unchanged} = code_gen_options_unchanged; PR_ExecUpToDate :: !Project -> Bool; PR_ExecUpToDate project=:{exec} = exec; PR_Saved :: !Project -> Bool; PR_Saved {Project | saved} = saved; PR_AddRootModule :: !Bool !CodeGenOptions !ApplicationOptions !(List String) !LinkOptions !Modulename !ModInfo -> Project; PR_AddRootModule built cg ao prjs linkOptions mn info=:{dir} = { PR_InitProject & built = built && dir <> "" , saved = False // ??? , exec = True , execpath = ""//MakeExecPathname (MakeFullPathname dir mn) , code_gen_options_unchanged = True , inflist = root:!Nil , codegenopt = cg , applicationopt = ao , prjpaths = prjs , linkOptions = linkOptions , staticLibInfo = DefStaticLibInfo , target = "" }; where root = { mn = mn,info = info,src = True,abc = True }; PR_AddModule :: !Modulename !ModInfo !Project -> Project; PR_AddModule mn info=:{dir} project=:{built,inflist=root:!rest} = {project & built = built && dir<>"", inflist = root:!new:!rest}; where new = { mn = mn, info = info, src = True, abc = True }; PR_AddModule mn info=:{dir} project=:{built,inflist=Nil} = {project & built = built && dir<>"", inflist = new:!Nil}; where new = { mn = mn, info = info, src = True, abc = True }; PR_GetModuleInfo :: !Modulename !Project -> Maybe ModInfo PR_GetModuleInfo mn {Project | inflist} # item = FindInList mn inflist | isNothing item = Nothing = Just (fromJust item).InfListItem.info PR_UpdateModule :: !Modulename !(ModInfo -> ModInfo) !Project -> Project; PR_UpdateModule mn update project=:{inflist,saved} = {project & inflist = infl`,saved = saved && unchanged}; where (infl`,unchanged) = UpdateList mn update` inflist; update` itm=:{InfListItem | info} = ({InfListItem | itm & info = info`}, unchanged); where info` = update info; unchanged = eqInfo info info`; eqInfo :: !ModInfo !ModInfo -> Bool eqInfo info1 info2 = info1.defeo.eo == info2.defeo.eo && info1.impeo.eo == info2.impeo.eo && eqCO info1.compilerOptions info2.compilerOptions && info1.defeo.pos_size == info2.defeo.pos_size && info1.impeo.pos_size == info2.impeo.pos_size && info1.defopen == info2.defopen && info1.impopen == info2.impopen eqCO :: !CompilerOptions !CompilerOptions -> Bool eqCO co1 co2 = co1.neverTimeProfile == co2.neverTimeProfile && co1.neverMemoryProfile == co2.neverMemoryProfile && co1.sa == co2.sa && co1.CompilerOptions.listTypes == co2.CompilerOptions.listTypes && co1.gw == co2.gw && co1.bv == co2.bv && co1.gc == co2.gc PR_UpdateModules :: ![Modulename] !(ModInfo -> ModInfo) !Project -> Project PR_UpdateModules mn update project = seq [(PR_UpdateModule m update) \\ m <- mn] project // DvA quick hack, not very efficient! // // Operations on tables // UpdateList :: !String InfUpdate !InfList -> (!InfList,!Bool) UpdateList key update list = UpdateList2 key update list Nil where UpdateList2 :: !String InfUpdate !InfList !InfList -> (!InfList,!Bool) UpdateList2 key update Nil acc = (Reverse2 acc Nil,True) UpdateList2 key update ((first=:{mn,info}):!rest) acc | mn <> key = UpdateList2 key update rest (first:!acc) # (first,changed) = update first = (Reverse2 acc (first :! rest), changed) FindInList :: !String !InfList -> Maybe InfListItem FindInList key Nil = Nothing FindInList key ((itm=:{mn,info}):!rest) | mn <> key = FindInList key rest = Just itm //-- SetProject :: !{#Char} !{#Char} !ProjectGlobalOptions -> Project SetProject applicationDir projectDir { pg_built , pg_codegen , pg_application , pg_projectPaths, pg_link, pg_mainModuleInfo={name, info},pg_otherModules , pg_target , pg_staticLibInfo , pg_execpath , pg_static , pg_dynamic // , pg_generateDLL // , pg_exportedDLL , pg_precompile , pg_postlink } # paths = ExpandPaths applicationDir projectDir pg_projectPaths # linkOptions = ExpandLinkOptionsPaths applicationDir projectDir pg_link # project = PR_AddRootModule pg_built pg_codegen pg_application paths linkOptions name (ExpandModuleInfoPaths applicationDir projectDir info) # project = addModules pg_otherModules project # staticLibInfo = ExpandStaticLibPaths applicationDir projectDir pg_staticLibInfo # project = PR_SetStaticLibsInfo staticLibInfo project # project = PR_SetTarget pg_target project # exepath = ExpandPath applicationDir projectDir pg_execpath # project = PR_SetExecPath exepath project // # project = PR_SetGenDLL pg_generateDLL project // # project = PR_SetExpDLL pg_exportedDLL project // default of used appopts in exe are ok isn't right :-( # pg_static = FixStatic applicationDir projectDir pg_static # pg_postlink = case pg_postlink of Just post_link -> Just (ExpandPath applicationDir projectDir post_link) Nothing -> Nothing # project = {project & static_info = pg_static, dynamic_info = pg_dynamic} # project = {project & prec = pg_precompile, posl = pg_postlink} = project where addModules Nil project = project addModules ({name, info} :! t) project = addModules t (PR_AddModule name (ExpandModuleInfoPaths applicationDir projectDir info) project) FixStatic ap pp si=:{stat_mods,stat_objs,stat_slibs,stat_dlibs,stat_paths} = { si & stat_mods = ExpandPaths ap pp stat_mods , stat_objs = ExpandPaths ap pp stat_objs , stat_slibs = ExpandPaths ap pp stat_slibs , stat_dlibs = ExpandPaths ap pp stat_dlibs , stat_paths = ExpandPaths ap pp stat_paths } GetProject :: !{#Char} !{#Char} !Project -> ProjectGlobalOptions GetProject applicationDir projectDir project # post_link = case project.posl of Just post_link -> Just (SubstitutePath applicationDir projectDir post_link) Nothing -> Nothing = { pg_built = PR_Built project , pg_codegen = PR_GetCodeGenOptions project , pg_application = PR_GetApplicationOptions project , pg_projectPaths = projectPaths , pg_link = linkOptions , pg_mainModuleInfo = mainModuleInfo , pg_otherModules = otherModules , pg_staticLibInfo = staticLibInfo , pg_target = target , pg_execpath = exepath , pg_static = substitite_paths_in_static applicationDir projectDir project.static_info , pg_dynamic = project.dynamic_info , pg_precompile = project.prec , pg_postlink = post_link } where exepath # xp = PR_GetExecPath project # xp = symPath applicationDir projectDir xp = xp mainModuleInfo = getModule mainModuleName mainModuleName = PR_GetRootModuleName project (otherModuleNames,project`) = PR_GetModulenames False IclMod project otherModules = Map getModule (Filter ((<>) mainModuleName) otherModuleNames) getModule name # info = PR_GetModuleInfo name project # info = if (isJust info) (fromJust info) defaultModInfo # info = SubstituteModuleInfoPaths applicationDir projectDir info = {name = name, info = info} linkOptions = SubstituteLinkOptionsPaths applicationDir projectDir (PR_GetLinkOptions project) projectPaths = SubstitutePaths applicationDir projectDir (PR_GetPaths project) staticLibInfo = SubstituteStaticLibPaths applicationDir projectDir (PR_GetStaticLibsInfo project) target = PR_GetTarget project substitite_paths_in_static ap pp si=:{stat_mods,stat_objs,stat_slibs,stat_dlibs,stat_paths} = { si & stat_mods = SubstitutePaths ap pp stat_mods , stat_objs = SubstitutePaths ap pp stat_objs , stat_slibs = SubstitutePaths ap pp stat_slibs , stat_dlibs = SubstitutePaths ap pp stat_dlibs , stat_paths = SubstitutePaths ap pp stat_paths } defaultModInfo :: ModInfo defaultModInfo = { dir = EmptyPathname , compilerOptions = DefaultCompilerOptions , defeo = {eo=DefaultEditOptions,pos_size=NoWindowPosAndSize} , impeo = {eo=DefaultEditOptions,pos_size=NoWindowPosAndSize} , defopen = False , impopen = False , abcLinkInfo = {linkObjFileNames = Nil, linkLibraryNames = Nil} } where DefaultEditOptions = { newlines = HostNativeNewlineConvention} /* { tabs = 4 , fontname = "Courier New" //NonProportionalFontDef.fName , fontsize = 10 //NonProportionalFontDef.fSize , autoi = True , newlines = HostNativeNewlineConvention , showtabs = False , showlins = False , showsync = True } */ //-- ExpandModuleInfoPaths :: {#Char} {#Char} ModInfo -> ModInfo ExpandModuleInfoPaths applicationDir projectDir moduleInfo=:{dir} = {moduleInfo & dir = ExpandPath applicationDir projectDir dir} ExpandLinkOptionsPaths :: {#Char} {#Char} LinkOptions -> LinkOptions ExpandLinkOptionsPaths applicationDir projectDir linkOptions=:{extraObjectModules, libraries} = { linkOptions & extraObjectModules = ExpandPaths applicationDir projectDir extraObjectModules , libraries = ExpandPaths applicationDir projectDir libraries } ExpandStaticLibPaths :: {#Char} {#Char} StaticLibInfo -> StaticLibInfo ExpandStaticLibPaths applicationDir projectDir staticLibs=:{sLibs} = { staticLibs & sLibs = ExpandPaths applicationDir projectDir sLibs } //ExpandPaths :: {#Char} {#Char} (List {#Char}) -> List {#Char} ExpandPaths applicationDir projectDir list :== fulPaths applicationDir projectDir list ExpandPath applicationDir projectDir path :== fulPath applicationDir projectDir path SubstituteModuleInfoPaths :: {#Char} {#Char} ModInfo -> ModInfo SubstituteModuleInfoPaths applicationDir projectDir info = {info & dir = SubstitutePath applicationDir projectDir info.dir} SubstituteLinkOptionsPaths :: {#Char} {#Char} LinkOptions -> LinkOptions SubstituteLinkOptionsPaths applicationDir projectDir linkOptions=:{extraObjectModules, libraries} = {linkOptions & extraObjectModules = SubstitutePaths applicationDir projectDir extraObjectModules , libraries = SubstitutePaths applicationDir projectDir libraries } SubstituteStaticLibPaths :: {#Char} {#Char} StaticLibInfo -> StaticLibInfo SubstituteStaticLibPaths applicationDir projectDir staticLibs=:{sLibs} = { staticLibs & sLibs = SubstitutePaths applicationDir projectDir sLibs } //SubstitutePaths :: {#Char} {#Char} (List {#Char}) -> List {#Char} SubstitutePaths applicationDir projectDir list :== symPaths applicationDir projectDir list SubstitutePath applicationDir projectDir path :== symPath applicationDir projectDir path //--- PR_GetABCLinkInfo :: !Project -> ABCLinkInfo; PR_GetABCLinkInfo project=:{inflist} # allLinkInfoRecords = map (\{InfListItem | info={abcLinkInfo}} -> abcLinkInfo) (StrictListToList inflist); oneLinkInfoRecord = foldl mergeTwoRecords emptyRecord allLinkInfoRecords; = oneLinkInfoRecord; where mergeTwoRecords { linkObjFileNames=linkObjFileNames1, linkLibraryNames=linkLibraryNames1} { linkObjFileNames=linkObjFileNames2, linkLibraryNames=linkLibraryNames2} = { linkObjFileNames = UnionStringList linkObjFileNames2 linkObjFileNames1, linkLibraryNames = UnionStringList linkLibraryNames2 linkLibraryNames1}; emptyRecord = { linkObjFileNames = Nil, linkLibraryNames = Nil}; //--- PR_GetStaticLibsInfo :: !Project -> StaticLibInfo PR_GetStaticLibsInfo {Project | staticLibInfo} = staticLibInfo PR_SetStaticLibsInfo :: !StaticLibInfo !Project -> Project PR_SetStaticLibsInfo staticLibInfo project = {Project | project & staticLibInfo = staticLibInfo} PR_GetTarget :: !Project -> String PR_GetTarget {Project | target} = target PR_SetTarget :: !String !Project -> Project PR_SetTarget target project | target == project.Project.target = project = {Project | project & target = target, exec = False, saved = False} //-- SL_Add :: !String !StaticLibInfo -> StaticLibInfo SL_Add pathname sl // load sDcls and sDeps info... // read some kind of libdef file... = {sl & sLibs = Append sl.sLibs pathname} SL_Rem :: ![String] !String !String !StaticLibInfo -> StaticLibInfo SL_Rem pathsel ap pp sl // remove sDcls and sDeps... = {sl & sLibs = seq [ RemoveStringFromList (fulPath ap pp s) \\ s <- pathsel ] sl.sLibs} SL_Libs :: !StaticLibInfo -> List String SL_Libs sl=:{sLibs} = sLibs SL_Dcls :: !StaticLibInfo -> List String SL_Dcls sl=:{sDcls} = sDcls SL_Deps :: !StaticLibInfo -> List String SL_Deps sl=:{sDeps} = sDeps SL_SetLibs :: !(List String) !StaticLibInfo -> StaticLibInfo SL_SetLibs lp sl = {sl & sLibs = lp} SL_SetDcls :: !(List String) !StaticLibInfo -> StaticLibInfo SL_SetDcls lp sl = {sl & sDcls = lp} SL_SetDeps :: !(List String) !StaticLibInfo -> StaticLibInfo SL_SetDeps lp sl = {sl & sDeps = lp} //-- SaveProjectFile :: !String !Project !String !*Files -> (!Bool, !*Files); SaveProjectFile projectPath project applicationDir files #! (opened, file, files) = fopen projectPath FWriteText files | not opened = (False, files) #! projectDir = RemoveFilename projectPath #! projectGO = GetProject applicationDir projectDir project #! options = PutOptions ProjectTable projectGO #! file = WriteOptionsFile ProjectFileVersion options file = fclose file files ReadProjectFile :: !String !String !*Files -> ((!Project, !Bool, !{#Char}),!*Files) ReadProjectFile projectPath applicationDir ps # (opened, file, ps) = fopen projectPath FReadData ps emptyProject = PR_InitProject projectName = RemovePath projectPath projectDir = RemoveFilename projectPath | not opened = ((emptyProject,False,"The file \"" +++ projectName +++ "\" could not be opened."),ps) # (version, file) = ReadVersion file | version == "" # (_, ps) = fclose file ps = ((emptyProject,False,"The file \"" +++ projectName +++ "\" is an old project and could not be opened."),ps) #! (options, file) = ReadOptionsFile file projectGO = GetProject applicationDir projectDir emptyProject projectGO = GetOptions ProjectTable options projectGO projectGO = (if (version == "1.3") (\p->{p&pg_target="StdEnv"}) (id) ) projectGO // DvA: need to set needs save flag for project; /* It's better to replace above with a dialog with popup of available environments. */ unexpanded_exec_path = projectGO.pg_execpath project = SetProject applicationDir projectDir projectGO execpath = PR_GetExecPath project (rootpath,project) = PR_GetRootPathName project project = PR_SetExecPath (if (size unexpanded_exec_path==0) (MakeExecPathname rootpath) execpath) project (closed, ps) = fclose file ps | not closed // generate warning? = ((project, True,"The file \"" +++ projectName +++ "\" could not be closed."), ps) = ((project, True,""), ps) getStaticInfo :: !Project -> (ProjectStaticInfo,Project) getStaticInfo prj=:{static_info} = (static_info,prj) setStaticInfo :: !.ProjectStaticInfo !.Project -> .Project setStaticInfo inf prj = {prj & static_info = inf} getDynamicInfo :: !Project -> (ProjectDynamicInfo,Project) getDynamicInfo prj=:{dynamic_info} = (dynamic_info,prj) setDynamicInfo :: !.ProjectDynamicInfo !.Project -> .Project setDynamicInfo inf prj = {prj & dynamic_info = inf} PR_SetPrecompile :: !(Maybe String) !Project -> Project PR_SetPrecompile prec prj = {prj & prec = prec} PR_GetPrecompile :: !Project -> (!Maybe String, !Project) PR_GetPrecompile prj=:{prec} = (prec,prj) PR_SetPostlink :: !(Maybe String) !Project -> Project PR_SetPostlink posl prj = {prj & posl = posl} PR_GetPostlink :: !Project -> (!Maybe String, !Project) PR_GetPostlink prj=:{posl} = (posl,prj)