version 0.7.2

This commit is contained in:
Andreas Rumpf 2008-12-12 14:02:27 +01:00
commit ddaedab835
158 changed files with 34811 additions and 10001 deletions

180
tools/inno.tmpl Normal file
View file

@ -0,0 +1,180 @@
#proc GenerateInnoSetup(c: TConfigData): string =
# result = ""
; Default Template for NimInst
[Setup]
AppName=$c.name
AppVerName=$c.name $c.version
DefaultDirName={code:GiveMeAPath|nimrod}
DefaultGroupName=$c.name
AllowNoIcons=yes
LicenseFile=${expandFilename(c.license)}
OutputBaseFilename=${c.name}_${c.version}
Compression=lzma
SolidCompression=yes
PrivilegesRequired=none
ChangesEnvironment=yes
[Languages]
Name: english; MessagesFile: compiler:Default.isl
[Files]
#for f in items(c.commonFiles):
Source: ${expandFilename(f)}; DestDir: {app}\${extractDir(f)}; Flags: ignoreversion
#end for
#for f in items(c.windowsFiles):
Source: ${expandFilename(f)}; DestDir: {app}\${extractDir(f)}; Flags: ignoreversion
#end for
[Icons]
#if c.app == appConsole:
Name: {group}\Console for $c.name; Filename: {cmd}
#else:
Name: {group}\$c.name; Filename: {app}
#end if
Name: {group}\Documentation; Filename: {app}\doc\overview.html
Name: {group}\{cm:UninstallProgram,$c.name}; Filename: {uninstallexe}
#if c.binPaths.len > 0:
[Tasks]
Name: modifypath; Description: &Add $c.name to your system path (if not in path already);
#end if
[Code]
function GiveMeAPath(const DefaultPathName: string): string;
begin
if IsAdminLoggedOn then Result := ExpandConstant('{pf}')
else Result := ExpandConstant('{userdocs}');
Result := Result + '\' + DefaultPathName;
end;
#if c.binPaths.len > 0:
// ----------------------------------------------------------------------------
//
// Inno Setup Ver: 5.2.1
// Script Version: 1.3.1
// Author: Jared Breland <jbreland@legroom.net>
// Homepage: http://www.legroom.net/software
//
// Script Function:
// Enable modification of system path directly from Inno Setup installers
function ModPathDir(): TArrayOfString;
begin
setArrayLength(result, $c.binPaths.len);
#var i = 0
#for b in items(c.binPaths):
result[$i] := ExpandConstant('{app}') + '\$b';
#inc(i)
#end for
end;
procedure ModPath();
var
oldpath, newpath, aExecFile: String;
pathArr, aExecArr, pathdir: TArrayOfString;
i, d: Integer;
begin
// Get array of new directories and act on each individually
pathdir := ModPathDir();
for d := 0 to GetArrayLength(pathdir)-1 do begin
// Modify WinNT path
if UsingWinNT() then begin
// Get current path, split into an array
RegQueryStringValue(HKEY_LOCAL_MACHINE,
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
'Path', oldpath);
oldpath := oldpath + ';';
i := 0;
while (Pos(';', oldpath) > 0) do begin
SetArrayLength(pathArr, i+1);
pathArr[i] := Copy(oldpath, 0, Pos(';', oldpath)-1);
oldpath := Copy(oldpath, Pos(';', oldpath)+1, Length(oldpath));
i := i + 1;
// Check if current directory matches app dir
if pathdir[d] = pathArr[i-1] then begin
// if uninstalling, remove dir from path
if IsUninstaller() then continue
// if installing, abort because dir was already in path
else abort;
end;
// Add current directory to new path
if i = 1 then newpath := pathArr[i-1]
else newpath := newpath + ';' + pathArr[i-1];
end;
// Append app dir to path if not already included
if not IsUninstaller() then
newpath := newpath + ';' + pathdir[d];
// Write new path
RegWriteStringValue(HKEY_LOCAL_MACHINE,
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
'Path', newpath);
end
else begin
// Modify Win9x path
// Convert to shortened dirname
pathdir[d] := GetShortName(pathdir[d]);
// If autoexec.bat exists, check if app dir already exists in path
aExecFile := 'C:\AUTOEXEC.BAT';
if FileExists(aExecFile) then begin
LoadStringsFromFile(aExecFile, aExecArr);
for i := 0 to GetArrayLength(aExecArr)-1 do begin
if not IsUninstaller() then begin
// If app dir already exists while installing, abort add
if (Pos(pathdir[d], aExecArr[i]) > 0) then
abort;
end
else begin
// If app dir exists and = what we originally set,
// then delete at uninstall
if aExecArr[i] = 'SET PATH=%PATH%;' + pathdir[d] then
aExecArr[i] := '';
end;
end;
end;
// If app dir not found, or autoexec.bat didn't exist, then
// (create and) append to current path
if not IsUninstaller() then begin
SaveStringToFile(aExecFile, #13#10 + 'SET PATH=%PATH%;' + pathdir[d],
True);
end
else begin
// If uninstalling, write the full autoexec out
SaveStringsToFile(aExecFile, aExecArr, False);
end;
end;
// Write file to flag modifypath was selected
// Workaround since IsTaskSelected() cannot be called at uninstall and
// AppName and AppId cannot be "read" in Code section
if not IsUninstaller() then
SaveStringToFile(ExpandConstant('{app}') + '\uninsTasks.txt',
WizardSelectedTasks(False), False);
end;
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then begin
if IsTaskSelected('modifypath') then
ModPath();
end
end;
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
var
appdir, selectedTasks: String;
begin
appdir := ExpandConstant('{app}');
if CurUninstallStep = usUninstall then begin
if LoadStringFromFile(appdir + '\uninsTasks.txt', selectedTasks) then
if Pos('modifypath', selectedTasks) > 0 then
ModPath();
DeleteFile(appdir + '\uninsTasks.txt')
end;
end;
function NeedRestart(): Boolean;
begin
result := IsTaskSelected('modifypath') and not UsingWinNT()
end;
#end if

97
tools/install.tmpl Normal file
View file

@ -0,0 +1,97 @@
#subsChar ?
#proc GenerateInstallScript(c: TConfigData): string =
# result = "#! /bin/sh\n# Generated by niminst\n"
CC="gcc"
LINKER="gcc"
COMP_FLAGS="-w"
LINK_FLAGS=""
# add(result, "# platform detection\n")
ucpu=`uname -m`
uos=`uname`
# add(result, "# convert to lower case:\n")
upcu=`echo $ucpu | tr "[:upper:]" "[:lower:]"`
uos=`echo $uos | tr "[:upper:]" "[:lower:]"`
case $uos in
*linux* )
myos="linux"
LINK_FLAGS="$LINK_FLAGS -ldl -lm"
;;
*freebsd* )
myos="freebsd"
LINK_FLAGS="$LINK_FLAGS -lm"
;;
*openbsd* )
myos="openbsd"
LINK_FLAGS="$LINK_FLAGS -lm"
;;
*netbsd* )
myos="netbsd"
LINK_FLAGS="$LINK_FLAGS -lm"
;;
*darwin* )
myos="macosx"
LINK_FLAGS="$LINK_FLAGS -ldl -lm"
;;
*aix* )
myos="aix"
LINK_FLAGS="$LINK_FLAGS -ldl -lm"
;;
*solaris* | *sun* )
myos="solaris"
LINK_FLAGS="$LINK_FLAGS -ldl -lm"
;;
*)
echo "Error: unknown operating system: $uos"
exit 1
;;
esac
case $ucpu in
*i386* | *i486* | *i586* | *i686* )
mycpu="i386" ;;
*amd*64* | *x86-64* | *x86_64* )
mycpu="amd64" ;;
*sparc*|*sun* )
mycpu="sparc" ;;
*power* )
mycpu="powerpc" ;;
*mips* )
mycpu="mips" ;;
*)
echo "Error: unknown processor: $ucpu"
exit 1
;;
esac
# add(result, "# write ``build/platdef.c`` file\n")
cat >build/platdef.c <<EOF
char* nimOS(void) { return "$myos"; }
char* nimCPU(void) { return "$mycpu"; }
EOF
# add(result, "# call the compiler:\n")
case $myos in
# for osA in 1..c.oses.len:
?{c.oses[osA-1]})
case $mycpu in
# for cpuA in 1..c.cpus.len:
?{c.cpus[cpuA-1]})
# var linkCmd = "build/platdef.o"
# for f in items(c.cfiles[osA][cpuA]):
echo "$CC $COMP_FLAGS -Ibuild -c ?{f} -o ?{changeFileExt(f, "o")}"
$CC $COMP_FLAGS -Ibuild -c ?{f} -o ?{changeFileExt(f, "o")} || exit 1
# add(linkCmd, " \\\n" & changeFileExt(f, "o"))
# end for
$CC $COMP_FLAGS -Ibuild -c build/platdef.c -o build/platdef.o || exit 1
echo "$LINKER $LINK_FLAGS -o ?{c.binPaths[0]}/?{toLower(c.name)} ?linkCmd"
$LINKER $LINK_FLAGS -o ?{c.binPaths[0]}/?{toLower(c.name)} ?linkCmd || exit 1
;;
# end for
esac
;;
# end for
esac
echo "SUCCESS"

BIN
tools/niminst Normal file

Binary file not shown.

346
tools/niminst.nim Normal file
View file

@ -0,0 +1,346 @@
#
#
# The Nimrod Installation Generator
# (c) Copyright 2008 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
const
haveZipLib = defined(unix)
when haveZipLib:
import zipfiles
import
os, strutils, parseopt, parsecfg, strtabs, streams
const
maxOS = 20 # max number of OSes
maxCPU = 10 # max number of CPUs
buildShFile = "build.sh"
type
TAppType = enum appConsole, appGUI
TAction = enum
actionNone, # action not yet known
actionCSource # action: create C sources
actionInno, # action: create Inno Setup installer
actionZip # action: create zip file
TConfigData = object of TObject
actions: set[TAction]
commonFiles, windowsFiles, unixFiles, binPaths, authors,
oses, cpus: seq[string]
cfiles: array[1..maxOS, array[1..maxCPU, seq[string]]]
ccompiler, innosetup: tuple[path, flags: string]
name, version, description, license, infile, outdir: string
innoSetupFlag, installScript, uninstallScript: bool
vars: PStringTable
app: TAppType
nimrodArgs: string
proc initConfigData(c: var TConfigData) =
c.actions = {}
c.commonFiles = @[]
c.windowsFiles = @[]
c.unixFiles = @[]
c.binPaths = @[]
c.authors = @[]
c.oses = @[]
c.cpus = @[]
c.ccompiler = ("", "")
c.innosetup = ("", "")
c.name = ""
c.version = ""
c.description = ""
c.license = ""
c.infile = ""
c.outdir = ""
c.nimrodArgs = ""
c.innoSetupFlag = false
c.installScript = false
c.uninstallScript = false
c.vars = newStringTable(modeStyleInsensitive)
include "inno.tmpl"
include "install.tmpl"
# ------------------------- configuration file -------------------------------
const
Version = "0.5"
Usage = "niminst - Nimrod Installation Generator Version " & version & """
(c) 2008 Andreas Rumpf
Usage:
niminst [options] command[;command2...] ini-file[.ini] [compile_options]
Command:
csource build C source code for source based installations
zip build the ZIP file
inno build the Inno Setup installer
Options:
-o, --output:dir set the output directory
--var:name=value set the value of a variable
-h, --help shows this help
-v, --version shows the version
Compile_options:
will be passed to the Nimrod compiler
"""
proc parseCmdLine(c: var TConfigData) =
var p = init()
while true:
next(p)
var kind = p.kind
var key = p.key
var val = p.val
case kind
of cmdArgument:
if c.actions == {}:
for a in split(normalize(key), {';', ','}):
case a
of "csource": incl(c.actions, actionCSource)
of "zip": incl(c.actions, actionZip)
of "inno": incl(c.actions, actionInno)
else: quit(Usage)
else:
c.infile = appendFileExt(key, "ini")
c.nimrodArgs = getRestOfCommandLine(p)
break
of cmdLongOption, cmdShortOption:
case normalize(key)
of "help", "h": write(stdout, Usage)
of "version", "v": writeln(stdout, Version)
of "o", "output": c.outdir = val
of "var":
var idx = findSubStr('=', val)
if idx < 0: quit("invalid command line")
c.vars[copy(val, 0, idx-1)] = copy(val, idx+1)
else: quit(Usage)
of cmdEnd: break
if c.infile.len == 0: quit(Usage)
proc walkDirRecursively(s: var seq[string], root: string) =
for k, f in walkDir(root):
case k
of pcFile, pcLinkToFile: add(s, UnixToNativePath(f))
of pcDirectory: walkDirRecursively(s, f)
of pcLinkToDirectory: nil
proc addFiles(s: var seq[string], patterns: seq[string]) =
for p in items(patterns):
if existsDir(p):
walkDirRecursively(s, p)
else:
var i = 0
for f in walkFiles(p):
add(s, UnixToNativePath(f))
inc(i)
if i == 0: echo("[Warning] No file found that matches: " & p)
proc pathFlags(p: var TCfgParser, k, v: string,
t: var tuple[path, flags: string]) =
case normalize(k)
of "path": t.path = v
of "flags": t.flags = v
else: quit(errorStr(p, "unknown variable: " & k))
proc parseIniFile(c: var TConfigData) =
var
p: TCfgParser
section: string # current section
var input = newFileStream(c.infile, fmRead)
if input != nil:
open(p, input, c.infile)
while true:
var k = next(p)
case k.kind
of cfgEof: break
of cfgSectionStart:
section = normalize(k.section)
case section
of "innosetup": c.innoSetupFlag = true
of "installscript": c.installScript = true
of "uninstallscript": c.uninstallScript = true
of "var", "project", "common", "ccompiler", "windows", "unix", "7z": nil
else: nil # quit(errorStr(p, "invalid section: " & section))
of cfgKeyValuePair:
var v = k.value % c.vars
c.vars[k.key] = v
case section
of "project":
case normalize(k.key)
of "name": c.name = v
of "version": c.version = v
of "os": c.oses = splitSeq(v, {';'})
of "cpu": c.cpus = splitSeq(v, {';'})
of "authors": c.authors = splitSeq(v, {';'})
of "description": c.description = v
of "app":
case normalize(v)
of "console": c.app = appConsole
of "gui": c.app = appGUI
else: quit(errorStr(p, "expected: console or gui"))
of "license": c.license = UnixToNativePath(k.value)
else: quit(errorStr(p, "unknown variable: " & k.key))
of "var": nil
of "installscript", "uninstallscript":
quit(errorStr(p, "unknown variable: " & k.key))
of "common":
case normalize(k.key)
of "files": addFiles(c.commonFiles, splitSeq(v, {';'}))
else: quit(errorStr(p, "unknown variable: " & k.key))
of "innosetup": pathFlags(p, k.key, v, c.innoSetup)
of "ccompiler": pathFlags(p, k.key, v, c.ccompiler)
of "windows":
case normalize(k.key)
of "files": addFiles(c.windowsFiles, splitSeq(v, {';'}))
of "binpath": c.binPaths = splitSeq(v, {';'})
else: quit(errorStr(p, "unknown variable: " & k.key))
of "unix":
case normalize(k.key)
of "files": addFiles(c.unixFiles, splitSeq(v, {';'}))
else: quit(errorStr(p, "unknown variable: " & k.key))
else: nil
of cfgOption: quit(errorStr(p, "syntax error"))
of cfgError: quit(errorStr(p, k.msg))
close(p)
if c.name.len == 0: c.name = changeFileExt(extractFilename(c.infile), "")
else:
quit("cannot open: " & c.infile)
# ------------------------- generate source based installation ---------------
proc readCFiles(c: var TConfigData, osA, cpuA: int) =
var cfg: TCfgParser
var cfilesSection = false
var f = extractDir(c.infile) / "mapping.txt"
c.cfiles[osA][cpuA] = @[]
var input = newFileStream(f, fmRead)
if input != nil:
open(cfg, input, f)
while true:
var k = next(cfg)
case k.kind
of cfgEof: break
of cfgSectionStart:
if cfilesSection: break
cfilesSection = cmpIgnoreStyle(k.section, "cfiles") == 0
of cfgKeyValuePair: nil
of cfgOption:
if cfilesSection and cmpIgnoreStyle(k.key, "file") == 0:
add(c.cfiles[osA][cpuA], k.value)
of cfgError: quit(errorStr(cfg, k.msg))
close(cfg)
else:
quit("Cannot open: " & f)
proc buildDir(os, cpu: int): string =
return "build" / ($os & "_" & $cpu)
proc srcdist(c: var TConfigData) =
for x in walkFiles("lib/*.h"): CopyFile("build" / extractFilename(x), x)
for osA in 1..c.oses.len:
for cpuA in 1..c.cpus.len:
var dir = buildDir(osA, cpuA)
createDir(dir)
var cmd = ("nimrod compile -f --symbolfiles:off --compileonly " &
"--gen_mapping $1 " &
" --os:$2 --cpu:$3 $4") %
[c.nimrodArgs, c.oses[osA-1], c.cpus[cpuA-1],
changeFileExt(c.infile, "nim")]
echo("Executing: " & cmd)
if executeShellCommand(cmd) != 0:
quit("Error: call to nimrod compiler failed")
readCFiles(c, osA, cpuA)
for i in 0 .. c.cfiles[osA][cpuA].len-1:
var dest = dir / extractFilename(c.cfiles[osA][cpuA][i])
CopyFile(dest, c.cfiles[osA][cpuA][i])
c.cfiles[osA][cpuA][i] = dest
# second pass: remove duplicate files
for osA in countdown(c.oses.len, 1):
for cpuA in countdown(c.cpus.len, 1):
for i in 0..c.cfiles[osA][cpuA].len-1:
var dup = c.cfiles[osA][cpuA][i]
var f = extractFilename(dup)
for osB in 1..c.oses.len:
for cpuB in 1..c.cpus.len:
if osB != osA or cpuB != cpuA:
var orig = buildDir(osB, cpuB) / f
if ExistsFile(orig) and ExistsFile(dup) and
sameFileContent(orig, dup):
# file is identical, so delete duplicate:
RemoveFile(dup)
c.cfiles[osA][cpuA][i] = orig
var scrpt = GenerateInstallScript(c)
var f: TFile
if openFile(f, buildShFile, fmWrite):
writeln(f, scrpt)
closeFile(f)
else:
quit("Cannot open for writing: " & buildShFile)
# --------------------- generate inno setup -----------------------------------
proc setupDist(c: var TConfigData) =
var scrpt = GenerateInnoSetup(c)
var f: TFile
var n = "build" / "install_$1_$2.iss" % [toLower(c.name), c.version]
if openFile(f, n, fmWrite):
writeln(f, scrpt)
closeFile(f)
when defined(windows):
if c.innoSetup.path.len == 0:
c.innoSetup.path = "iscc.exe"
var outcmd = if c.outdir.len == 0: "build" else: c.outdir
var cmd = "$1 $2 /O$3 $4" % [c.innoSetup.path, c.innoSetup.flags,
outcmd, n]
Echo("Executing: " & cmd)
if executeShellCommand(cmd) == 0:
removeFile(n)
else:
quit("External program failed")
else:
quit("Cannot open for writing: " & n)
# ------------------ generate ZIP file ---------------------------------------
when haveZipLib:
proc zipDist(c: var TConfigData) =
var proj = toLower(c.name)
var n = "$1_$2.zip" % [proj, c.version]
if c.outdir.len == 0: n = "build" / n
else: n = c.outdir / n
var z: TZipArchive
if open(z, n, fmWrite):
addFile(z, proj / buildShFile, buildShFile)
for f in walkFiles("lib/*.h"):
addFile(z, proj / "build" / extractFilename(f), f)
for osA in 1..c.oses.len:
for cpuA in 1..c.cpus.len:
var dir = buildDir(osA, cpuA)
for k, f in walkDir(dir):
if k == pcFile: addFile(z, proj / dir / extractFilename(f), f)
for f in items(c.commonFiles): addFile(z, proj / f, f)
for f in items(c.unixFiles): addFile(z, proj / f, f)
close(z)
else:
quit("Cannot open for writing: " & n)
# ------------------- main ----------------------------------------------------
var c: TConfigData
initConfigData(c)
parseCmdLine(c)
parseIniFile(c)
if actionInno in c.actions:
setupDist(c)
if actionCSource in c.actions:
srcdist(c)
if actionZip in c.actions:
when haveZipLib:
zipdist(c)
else:
quit("libzip is not installed")

203
tools/nimweb.nim Normal file
View file

@ -0,0 +1,203 @@
#
#
# The Nimrod Website Generator
# (c) Copyright 2008 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
import
os, strutils, times, parseopt, parsecfg, streams, strtabs
type
TKeyValPair = tuple[key, val: string]
TConfigData = object of TObject
tabs, links: seq[TKeyValPair]
doc, srcdoc, webdoc: seq[string]
authors, projectName, projectTitle, infile, outdir, ticker: string
vars: PStringTable
nimrodArgs: string
proc initConfigData(c: var TConfigData) =
c.tabs = @[]
c.links = @[]
c.doc = @[]
c.srcdoc = @[]
c.webdoc = @[]
c.infile = ""
c.outdir = ""
c.nimrodArgs = ""
c.authors = ""
c.ticker = ""
c.vars = newStringTable(modeStyleInsensitive)
include "sunset.tmpl"
# ------------------------- configuration file -------------------------------
const
Version = "0.5"
Usage = "nimweb - Nimrod Installation Generator Version " & version & """
(c) 2008 Andreas Rumpf
Usage:
nimweb [options] ini-file[.ini] [compile_options]
Options:
-o, --output:dir set the output directory (default: same as ini-file)
--var:name=value set the value of a variable
-h, --help shows this help
-v, --version shows the version
Compile_options:
will be passed to the Nimrod compiler
"""
proc parseCmdLine(c: var TConfigData) =
var p = init()
while true:
next(p)
var kind = p.kind
var key = p.key
var val = p.val
case kind
of cmdArgument:
c.infile = appendFileExt(key, "ini")
c.nimrodArgs = getRestOfCommandLine(p)
break
of cmdLongOption, cmdShortOption:
case normalize(key)
of "help", "h": write(stdout, Usage)
of "version", "v": writeln(stdout, Version)
of "o", "output": c.outdir = val
of "var":
var idx = findSubStr('=', val)
if idx < 0: quit("invalid command line")
c.vars[copy(val, 0, idx-1)] = copy(val, idx+1)
else: quit(Usage)
of cmdEnd: break
if c.infile.len == 0: quit(Usage)
proc walkDirRecursively(s: var seq[string], root, ext: string) =
for k, f in walkDir(root):
case k
of pcFile, pcLinkToFile:
if cmpIgnoreCase(ext, extractFileExt(f)) == 0:
add(s, f)
of pcDirectory: walkDirRecursively(s, f, ext)
of pcLinkToDirectory: nil
proc addFiles(s: var seq[string], dir, ext: string, patterns: seq[string]) =
for p in items(patterns):
if existsDir(dir / p):
walkDirRecursively(s, dir / p, ext)
else:
add(s, dir / appendFileExt(p, ext))
proc parseIniFile(c: var TConfigData) =
var
p: TCfgParser
section: string # current section
var input = newFileStream(c.infile, fmRead)
if input != nil:
open(p, input, c.infile)
while true:
var k = next(p)
case k.kind
of cfgEof: break
of cfgSectionStart:
section = normalize(k.section)
case section
of "project", "links", "tabs", "ticker", "documentation", "var": nil
else: echo("[Warning] Skipping unknown section: " & section)
of cfgKeyValuePair:
var v = k.value % c.vars
c.vars[k.key] = v
case section
of "project":
case normalize(k.key)
of "name": c.projectName = v
of "title": c.projectTitle = v
of "authors": c.authors = v
else: quit(errorStr(p, "unknown variable: " & k.key))
of "var": nil
of "links": add(c.links, (key: k.key, val: v))
of "tabs": add(c.tabs, (key: k.key, val: v))
of "ticker": c.ticker = v
of "documentation":
case normalize(k.key)
of "doc": addFiles(c.doc, "doc", "txt" splitSeq(v, {';'}))
of "srcdoc": addFiles(c.srcdoc, "lib", "nim", splitSeq(v, {';'}))
of "webdoc": addFiles(c.webdoc, "lib", "nim", splitSeq(v, {';'}))
else: quit(errorStr(p, "unknown variable: " & k.key))
else: nil
of cfgOption: quit(errorStr(p, "syntax error"))
of cfgError: quit(errorStr(p, k.msg))
close(p)
if c.projectName.len == 0:
c.projectName = changeFileExt(extractFilename(c.infile), "")
if c.outdir.len == 0:
c.outdir = extractDir(c.infile)
else:
quit("cannot open: " & c.infile)
# ------------------- main ----------------------------------------------------
proc Exec(cmd: string) =
echo(cmd)
if os.executeShellCommand(cmd) != 0: quit("external program failed")
proc buildDoc(c: var TConfigData, destPath: string) =
# call nim for the documentation:
for d in items(c.doc):
Exec("nimrod rst2html $1 -o:$2 --index=$3/theindex $4" %
[c.nimrodArgs, destPath / changeFileExt(extractFileTrunk(d), "html"),
destpath, d])
for d in items(c.srcdoc):
Exec("nimrod doc $1 -o:$2 --index=$3/theindex $4" %
[c.nimrodArgs, destPath / changeFileExt(extractFileTrunk(d), "html"),
destpath, d])
Exec("nimrod rst2html $1 -o:$2/theindex.html $2/theindex" %
[c.nimrodArgs, destPath])
proc buildAddDoc(c: var TConfigData, destPath: string) =
# build additional documentation (without the index):
for d in items(c.webdoc):
Exec("nimrod doc $1 -o:$2 $3" %
[c.nimrodArgs, destPath / changeFileExt(extractFileTrunk(d), "html"), d])
proc main(c: var TConfigData) =
const
cmd = "nimrod rst2html --compileonly $1 -o:web/$2.temp web/$2.txt"
if c.ticker.len > 0:
Exec(cmd % [c.nimrodArgs, c.ticker])
var temp = "web" / changeFileExt(c.ticker, "temp")
c.ticker = readFile(temp)
if isNil(c.ticker): quit("[Error] cannot open:" & temp)
RemoveFile(temp)
for i in 0..c.tabs.len-1:
var file = c.tabs[i].val
Exec(cmd % [c.nimrodArgs, file])
var temp = "web" / changeFileExt(file, "temp")
var content = readFile(temp)
if isNil(content): quit("[Error] cannot open: " & temp)
var f: TFile
var outfile = "web/upload/$1.html" % file
if openFile(f, outfile, fmWrite):
writeln(f, generateHTMLPage(c, file, content))
closeFile(f)
else:
quit("[Error] cannot write file: " & outfile)
removeFile(temp)
buildAddDoc(c, "web/upload")
buildDoc(c, "web/upload")
buildDoc(c, "doc")
var c: TConfigData
initConfigData(c)
parseCmdLine(c)
parseIniFile(c)
main(c)

72
tools/sunset.tmpl Normal file
View file

@ -0,0 +1,72 @@
#proc generateHTMLPage(c: var TConfigData, currentTab, content: string): string =
# result = ""
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>$c.projectTitle</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" type="text/css" href="style/style.css" />
</head>
<body>
<div id="main">
<div id="links">
<!-- **** INSERT LINKS HERE **** -->
</div>
<div id="logo"><h1>$c.projectTitle</h1></div>
<div id="content">
<div id="menu">
<ul>
#for i in 0.. c.tabs.len-1:
# var name = c.tabs[i].key
# var t = c.tabs[i].val
#if currentTab == t:
<li><a id="selected"
#else:
<li><a
#end if
href="${t}.html" title = "$c.projectName - $name">$name</a></li>
#end for
</ul>
</div>
<div id="column1">
# if len(c.ticker) > 0:
<div class="sidebaritem">
<div class="sbihead">
<h1>latest news</h1>
</div>
<div class="sbicontent">
$c.ticker
</div>
</div>
# end if
# if len(c.links) > 0:
<div class="sidebaritem">
<div class="sbihead">
<h1>additional links</h1>
</div>
<div class="sbilinks">
<!-- **** INSERT ADDITIONAL LINKS HERE **** -->
<ul>
# for i in 0..c.links.len-1:
<li><a class="reference" href="${c.links[i].val}">${c.links[i].key}</a></li>
# end for
</ul>
</div>
</div>
# end if
</div>
<div id="column2">
$content
</div>
</div>
<div id="footer">
copyright &copy; 2008 $c.authors | Last update: ${getDateStr()}
| <a class="reference" href="http://validator.w3.org/check?uri=referer">XHTML 1.1</a>
| <a class="reference" href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a>
| <a class="reference" href="http://www.dcarter.co.uk">design by dcarter</a>
</div>
</div>
</body>
</html>