mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 01:13:30 +00:00
extras/gator/gator:
Update programming style. Fix indentation. Add a vim modeline.
extras/gator/genotype.m:
extras/gator/phenotype.m:
Fix indentation.
extras/lex/regex.m:
Replace if-then-else chain with a switch.
extras/base64/base64.m:
extras/cgi/cgi.m:
extras/cgi/form_test.m:
extras/cgi/html.m:
extras/cgi/mercury_www.m:
extras/complex_numbers/complex_numbers.complex.m:
extras/complex_numbers/complex_numbers.complex_float.m:
extras/complex_numbers/complex_numbers.complex_imag.m:
extras/complex_numbers/complex_numbers.float_complex.m:
extras/complex_numbers/complex_numbers.float_imag.m:
extras/complex_numbers/complex_numbers.imag.m:
extras/complex_numbers/complex_numbers.imag_complex.m:
extras/complex_numbers/complex_numbers.imag_float.m:
extras/complex_numbers/complex_numbers.m:
extras/curs/curs.m:
extras/dynamic_linking/dl_test.m:
extras/dynamic_linking/dl_test2.m:
extras/dynamic_linking/hello.m:
extras/error/error.m:
extras/fixed/fixed.m:
extras/fixed/mercury_fixed.m:
extras/java_extras/make_temp.m:
extras/lex/lex.automata.m:
extras/lex/lex.buf.m:
extras/lex/lex.convert_NFA_to_DFA.m:
extras/lex/lex.lexeme.m:
extras/lex/lex.m:
extras/lex/lex.regexp.m:
extras/logged_output/logged_output.m:
extras/logged_output/main.m:
extras/monte/doit.m:
extras/monte/dots.m:
extras/monte/geom.m:
extras/monte/hg.m:
extras/monte/monte.m:
extras/monte/rnd.m:
extras/mopenssl/mopenssl.m:
extras/odbc/mercury_odbc.m:
extras/odbc/odbc.m:
extras/odbc/odbc_test.m:
extras/posix/posix.chdir.m:
extras/posix/posix.closedir.m:
extras/posix/posix.dup.m:
extras/posix/posix.exec.m:
extras/posix/posix.fork.m:
extras/posix/posix.getpid.m:
extras/posix/posix.kill.m:
extras/posix/posix.lseek.m:
extras/posix/posix.m:
extras/posix/posix.mkdir.m:
extras/posix/posix.open.m:
extras/posix/posix.opendir.m:
extras/posix/posix.pipe.m:
extras/posix/posix.read.m:
extras/posix/posix.readdir.m:
extras/posix/posix.realpath.m:
extras/posix/posix.rmdir.m:
extras/posix/posix.select.m:
extras/posix/posix.sleep.m:
extras/posix/posix.socket.m:
extras/posix/posix.stat.m:
extras/posix/posix.strerror.m:
extras/posix/posix.wait.m:
extras/posix/posix.write.m:
extras/quickcheck/qcheck.m:
extras/quickcheck/rnd.m:
extras/quickcheck/test_qcheck.m:
extras/show_ops/show_ops.m:
extras/split_file/split_file.m:
extras/windows_installer_generator/wix.m:
extras/windows_installer_generator/wix_files.m:
extras/windows_installer_generator/wix_gui.m:
extras/windows_installer_generator/wix_installer.m:
extras/windows_installer_generator/wix_util.m:
Apply tools/stdlines to all these files.
345 lines
13 KiB
Mathematica
345 lines
13 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 2005-2006 The University of Melbourne.
|
|
% Copyright (C) 2018, 2025 The Mercury team.
|
|
% This file is distributed under the terms specified in COPYING.LIB.
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Main author: Ian MacLarty (maclarty@cs.mu.oz.au).
|
|
%
|
|
% This module is responsible for generating the Wix source code for the
|
|
% installer.
|
|
% The installer is first converted to an annotated installer and then
|
|
% to XML. The annotated installer contains extra information, like Ids
|
|
% for all the elements.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module wix_installer.
|
|
:- interface.
|
|
|
|
:- import_module io.
|
|
:- import_module term_to_xml.
|
|
|
|
:- import_module wix.
|
|
|
|
:- type annotated_installer.
|
|
|
|
% gen_annotated_installer(Installer, GUIDStream, AnnotatedInstaller, !IO).
|
|
%
|
|
|
|
:- pred gen_annotated_installer(installer(L)::in, io.input_stream::in,
|
|
annotated_installer::out, io::di, io::uo) is det
|
|
<= language_independent_tokens(L).
|
|
|
|
:- instance xmlable(annotated_installer).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module bool.
|
|
:- import_module exception.
|
|
:- import_module int.
|
|
:- import_module list.
|
|
:- import_module map.
|
|
:- import_module maybe.
|
|
:- import_module string.
|
|
|
|
:- import_module wix_files.
|
|
:- import_module wix_gui.
|
|
:- import_module wix_language.
|
|
:- import_module wix_util.
|
|
|
|
:- type annotated_installer
|
|
---> annotated_installer(
|
|
ann_installer_product_info :: annotated_product,
|
|
ann_installer_language :: language,
|
|
ann_installer_env_vars_guid :: guid,
|
|
ann_installer_set_env_vars :: list(ann_set_env_var),
|
|
ann_installer_wizard_steps :: list(annotated_dialog),
|
|
ann_installer_bitmaps :: map(string, id),
|
|
ann_installer_removedlg_id :: id,
|
|
ann_installer_finish_id :: id,
|
|
ann_installer_checkifadmin :: maybe(string),
|
|
ann_insatller_all_users :: bool
|
|
).
|
|
|
|
:- type ann_set_env_var
|
|
---> ann_set_env_var(
|
|
ann_env_var :: string,
|
|
ann_env_var_value :: string,
|
|
ann_env_var_how_set :: env_var_how_set,
|
|
ann_env_var_system_or_user :: env_var_system_or_user,
|
|
ann_env_var_id :: id
|
|
).
|
|
|
|
:- type annotated_product
|
|
---> annotated_product(
|
|
ann_prod_guid :: guid,
|
|
% XXX Upgrade installers are not yet supported,
|
|
% however the upgrade code is required so that
|
|
% deployed packages can be upgraded when
|
|
% upgrade installers are supported.
|
|
ann_prod_upgrade_guid :: guid,
|
|
ann_prod_manufacturer :: string,
|
|
ann_prod_name :: string,
|
|
ann_prod_version :: version_no,
|
|
ann_prod_description :: string,
|
|
ann_prod_comments :: string,
|
|
ann_prod_contents :: list(annotated_file),
|
|
ann_prod_default_install_loc :: string
|
|
).
|
|
|
|
:- instance xmlable(annotated_installer) where [
|
|
func(to_xml/1) is annotated_installer_to_xml
|
|
].
|
|
|
|
:- func annotated_installer_to_xml(annotated_installer::in) =
|
|
(xml::out(xml_doc)) is det.
|
|
|
|
annotated_installer_to_xml(Installer) = XML :-
|
|
Installer = annotated_installer(Product, LanguageId, EnvVarsGUID, EnvVars,
|
|
WizardSteps, BitMaps, RemoveDlgId, FinishDlgId, CheckIfAdmin,
|
|
AllUsers),
|
|
language_to_lcid(LanguageId, LCID),
|
|
Product = annotated_product(
|
|
GUID,
|
|
UpgradeGUID,
|
|
Manufacturer,
|
|
Name,
|
|
Version,
|
|
Description,
|
|
Comments,
|
|
Contents,
|
|
DefInstallLoc),
|
|
(
|
|
AllUsers = yes,
|
|
AllUsersPropertyList = [elem("Property", [id_attr("ALLUSERS")],
|
|
[data("2")])]
|
|
;
|
|
AllUsers = no,
|
|
AllUsersPropertyList = []
|
|
),
|
|
XML = elem("Wix", [
|
|
attr("xmlns","http://schemas.microsoft.com/wix/2003/01/wix")],
|
|
[
|
|
elem("Product", [
|
|
id_attr(GUID),
|
|
attr("UpgradeCode", UpgradeGUID),
|
|
attr("Name", Name),
|
|
attr("Version", version_no_to_string(Version)),
|
|
attr("Language", int_to_string(LCID)),
|
|
attr("Manufacturer", Manufacturer)
|
|
],
|
|
[elem("Package",
|
|
% The following causes wix to generate a fresh guid each time
|
|
% it compiles the XML file.
|
|
[id_attr("????????-????-????-????-????????????")] ++
|
|
attr_if_not_blank(attr("Description", Description)) ++
|
|
[attr("Manufacturer", Manufacturer)] ++
|
|
attr_if_not_blank(attr("Comments", Comments)) ++
|
|
[attr("InstallerVersion", "150")] ++
|
|
[attr("Compressed", "yes")]
|
|
, [])] ++
|
|
( if CheckIfAdmin = yes(MustBeAdminMessage) then
|
|
[elem("Condition", [attr("Message", MustBeAdminMessage)],
|
|
[data("Privileged")])]
|
|
else
|
|
[]
|
|
) ++
|
|
AllUsersPropertyList ++
|
|
[elem("Media", [
|
|
id_attr("1"),
|
|
attr("Cabinet", "contents.cab"),
|
|
attr("EmbedCab", "yes"),
|
|
attr("CompressionLevel", "high")], [])] ++
|
|
[elem("Directory", [
|
|
id_attr("TARGETDIR"),
|
|
attr("Name", "SourceDir")
|
|
], [
|
|
elem("Component", [
|
|
id_attr(env_vars_component_id),
|
|
guid_attr(EnvVarsGUID)
|
|
], list.map(ann_set_env_var_to_xml, EnvVars)),
|
|
elem("Directory", [
|
|
id_attr("ProgramFilesFolder"),
|
|
attr("Name", "PFiles")
|
|
], [
|
|
elem("Directory",
|
|
[id_attr("INSTALLDIR")] ++
|
|
name_attrs(DefInstallLoc, "INSDIR"),
|
|
list.map(annotated_file_to_xml, Contents))
|
|
]),
|
|
elem("Directory", [
|
|
id_attr(desktop_id),
|
|
attr("Name", "Desktop")],
|
|
[])
|
|
] ++
|
|
programs_menu_directory_if_required(Name, Contents)
|
|
)] ++
|
|
generate_feature_elements(Contents) ++
|
|
maybe_ui_elements(WizardSteps, RemoveDlgId, FinishDlgId) ++
|
|
bitmaps_to_xml(map.keys(BitMaps), map.values(BitMaps))
|
|
)
|
|
]).
|
|
|
|
:- func ann_set_env_var_to_xml(ann_set_env_var) = xml.
|
|
|
|
ann_set_env_var_to_xml(ann_set_env_var(Name, Value, HowSet, SysOrUser, EnvId))
|
|
= elem("Environment", [
|
|
id_attr(EnvId),
|
|
attr("Name", Name),
|
|
attr("Part", how_set_to_string(HowSet)),
|
|
attr("Action", "set"),
|
|
attr("System", system_or_user_to_string(SysOrUser)),
|
|
attr("Value", Value)], []).
|
|
|
|
gen_annotated_installer(Installer, GUIDStream, AnnotatedInstaller, !IO) :-
|
|
some [!IdSupply, !DialogIdMap, !BitMaps] (
|
|
!:IdSupply = init_id_supply,
|
|
!:DialogIdMap = map.init,
|
|
!:BitMaps = map.init,
|
|
Installer = installer(
|
|
Product,
|
|
Language,
|
|
EnvVars,
|
|
ShortCuts, AllUsers,
|
|
Title, InstallHeading, InstallDescr,
|
|
Next, Back, Cancel, Install, CancelMessage,
|
|
RemoveHeading, RemoveConfirm, Remove,
|
|
RemoveProgressHeading, RemoveProgressDescr,
|
|
FinishHeading, FinishMessage, Finish,
|
|
FilesInUseHeading, FilesInUseMessage, Ignore, Retry,
|
|
Yes, No, MustBeAdminMessage, BannerSrc, BackgroundSrc,
|
|
WizardSteps),
|
|
Product = product(
|
|
ManufacturerToken,
|
|
NameToken,
|
|
Version,
|
|
DescriptionToken,
|
|
CommentsToken,
|
|
FilesPath,
|
|
DefaultInstallToken),
|
|
generate_wizard_dialogs(Title, Next, Back, Cancel, Install,
|
|
BannerSrc, BackgroundSrc, WizardSteps, WizDialogs),
|
|
CancelDlg = cancel_dialog(Title, CancelMessage, Yes, No),
|
|
FinishDlg = finish_dialog(Title, FinishHeading, FinishMessage,
|
|
Finish, BackgroundSrc),
|
|
InstallProgressDlg =
|
|
install_progress_dialog(Title, InstallHeading, InstallDescr,
|
|
Cancel, BannerSrc),
|
|
RemoveProgressDlg =
|
|
remove_progress_dialog(Title, RemoveProgressHeading,
|
|
RemoveProgressDescr, Cancel, BannerSrc),
|
|
RemoveDlg = remove_dialog(Title, RemoveHeading, RemoveConfirm,
|
|
Remove, Cancel, BannerSrc),
|
|
annotate_dialogs(Language, WizDialogs ++
|
|
[CancelDlg, InstallProgressDlg,
|
|
RemoveDlg, RemoveProgressDlg, FinishDlg],
|
|
AnnDialogs0, !IdSupply, !DialogIdMap, !BitMaps),
|
|
%
|
|
% Generate the default files-in-use dialog which asks the user
|
|
% to close applications that are using installed files.
|
|
% The dialog must be handled separately because it has the
|
|
% reserved id `FilesInUse'.
|
|
%
|
|
FilesInUseDlg = files_in_use_dialog(Title, FilesInUseHeading,
|
|
FilesInUseMessage, Retry, Ignore, Cancel, BannerSrc),
|
|
annotate_dialog(Language, FilesInUseDlg, AnnFilesInUseDlg0, !IdSupply,
|
|
!DialogIdMap, !BitMaps),
|
|
set_ann_dialog_id("FilesInUse", AnnFilesInUseDlg0, AnnFilesInUseDlg),
|
|
list.append(AnnDialogs0, [AnnFilesInUseDlg], AnnDialogs),
|
|
|
|
% Look up the ID assigned to the remove dialog which will be
|
|
% shown if the product is already installed.
|
|
map.lookup(!.DialogIdMap, remove_dlg, RemoveDlgId),
|
|
|
|
% Look up the ID assigned to the finish dialog so we can call it
|
|
% after installation has finished.
|
|
map.lookup(!.DialogIdMap, finish_dlg, FinishDlgId),
|
|
|
|
annotate_env_vars(Language, EnvVars, AnnEnvVars, !IdSupply,
|
|
RequiredPrivilege),
|
|
( if ( RequiredPrivilege = admin ; AllUsers = yes ) then
|
|
det_translate(MustBeAdminMessage, Language, MustBeAdminMsgStr),
|
|
CheckForAdmin = yes(MustBeAdminMsgStr)
|
|
else
|
|
CheckForAdmin = no
|
|
),
|
|
det_translate(ManufacturerToken, Language, Manufacturer),
|
|
det_translate(NameToken, Language, Name),
|
|
det_translate(DescriptionToken, Language, Description),
|
|
det_translate(CommentsToken, Language, Comments),
|
|
det_translate(DefaultInstallToken, Language, DefInsLoc),
|
|
gen_files(FilesPath, ShortCuts, Files, !IO),
|
|
annotate_files(Language, Files, !.IdSupply, _, GUIDStream, FilesPath,
|
|
AnnotatedFiles, !IO),
|
|
gen_guid(GUIDStream, ProductGUID, !IO),
|
|
gen_guid(GUIDStream, UpgradeGUID, !IO),
|
|
gen_guid(GUIDStream, EnvVarsGUID, !IO),
|
|
AnnotatedInstaller =
|
|
annotated_installer(
|
|
annotated_product(
|
|
ProductGUID,
|
|
UpgradeGUID,
|
|
Manufacturer,
|
|
Name,
|
|
Version,
|
|
Description,
|
|
Comments,
|
|
AnnotatedFiles,
|
|
DefInsLoc
|
|
),
|
|
Language,
|
|
EnvVarsGUID,
|
|
AnnEnvVars,
|
|
AnnDialogs,
|
|
!.BitMaps,
|
|
RemoveDlgId,
|
|
FinishDlgId,
|
|
CheckForAdmin,
|
|
AllUsers
|
|
)
|
|
).
|
|
|
|
:- pred annotate_env_vars(language::in,
|
|
list(set_env_var(L))::in, list(ann_set_env_var)::out,
|
|
id_supply::in, id_supply::out, privilege::out)
|
|
is det <= language_independent_tokens(L).
|
|
|
|
annotate_env_vars(_, [], [], !IdSupply, normal).
|
|
annotate_env_vars(Language, [Var | Vars], [AnnVar | AnnVars], !IdSupply, Priv)
|
|
:-
|
|
Var = set_env_var(VarName, ValueToken, HowSet, SysOrUser),
|
|
det_translate(ValueToken, Language, Value),
|
|
allocate_id(EnvId, !IdSupply),
|
|
AnnVar = ann_set_env_var(VarName, Value, HowSet, SysOrUser, EnvId),
|
|
annotate_env_vars(Language, Vars, AnnVars, !IdSupply, Priv0),
|
|
(
|
|
SysOrUser = system,
|
|
Priv = admin
|
|
;
|
|
SysOrUser = user,
|
|
Priv = Priv0
|
|
).
|
|
|
|
:- func programs_menu_directory_if_required(string, list(annotated_file)) =
|
|
list(xml).
|
|
|
|
programs_menu_directory_if_required(Name, Contents) = XML :-
|
|
( if is_shortcut_from_programs_menu(Contents) then
|
|
XML = [elem("Directory", [
|
|
id_attr("ProgramMenuFolder"),
|
|
attr("Name", "PMENU"),
|
|
attr("LongName", "Programs")
|
|
], [
|
|
elem("Directory",
|
|
[id_attr(programs_menu_id)] ++
|
|
name_attrs(Name, "PROGMENU"), [])
|
|
])]
|
|
else
|
|
XML = []
|
|
).
|