Why learn Another Language?
The first answer is: because it's fun. Just as a botanist is excited to find a new plant, programming language nerds like trying out new languages. Secondly, any new language uses new strategies for dealing with the basic problems of communicating algorithms to computers and intents to other programmers. So it is the most sincere form of criticism: a working implementation to constrast with the approaches taken by other languages. There's far too much armchairing and bikeshedding involved in discussions about languages, and you have to admire a guy who has spent a sizeable chunk of his life trying something new like Nimrod's author, Andreas Rumpf.
If you're not a language nerd, a new language might provide a solution to an actual computing problem you are facing. (Who would have guessed?)
# IupTabs: Creates a IupTabs control.
import iup
discard iup.Open(nil, nil)
var vbox1 = Iup.Vbox(Iup.Label("Inside Tab A"), Iup.Button("Button A", ""), nil)
var vbox2 = Iup.Vbox(Iup.Label("Inside Tab B"), Iup.Button("Button B", ""), nil)
Iup.SetAttribute(vbox1, "TABTITLE", "Tab A")
Iup.SetAttribute(vbox2, "TABTITLE", "Tab B")
var tabs1 = Iup.Tabs(vbox1, vbox2, nil)
vbox1 = Iup.Vbox(Iup.Label("Inside Tab C"), Iup.Button("Button C", ""), nil)
vbox2 = Iup.Vbox(Iup.Label("Inside Tab D"), Iup.Button("Button D", ""), nil)
Iup.SetAttribute(vbox1, "TABTITLE", "Tab C")
Iup.SetAttribute(vbox2, "TABTITLE", "Tab D")
var tabs2 = Iup.Tabs(vbox1, vbox2, nil)
Iup.SetAttribute(tabs2, "TABTYPE", "LEFT")
var box = Iup.Hbox(tabs1, tabs2, nil)
Iup.SetAttribute(box, "MARGIN", "10x10")
Iup.SetAttribute(box, "GAP", "10")
var dlg = Iup.Dialog(box)
Iup.SetAttribute(dlg, "TITLE", "IupTabs")
Iup.SetAttribute(dlg, "SIZE", "200x100")
discard Iup.ShowXY(dlg, IUP_CENTER, IUP_CENTER)
discard Iup.MainLoop()
Iup.Close()
' Creates a Iup::Tabs control.
IMPORT iup.bas
GLOBAL CONST IUP_CENTER = 0xFFFF
Iup::Open()
vbox1 = Iup::Vbox(Iup::Label("Inside Tab A"), Iup::Button("Button A", ""))
vbox2 = Iup::Vbox(Iup::Label("Inside Tab B"), Iup::Button("Button B", ""))
Iup::SetAttribute(vbox1, "TABTITLE", "Tab A")
Iup::SetAttribute(vbox2, "TABTITLE", "Tab B")
tabs1 = Iup::Tabs(vbox1, vbox2)
vbox1 = Iup::Vbox(Iup::Label("Inside Tab C"), Iup::Button("Button C", ""))
vbox2 = Iup::Vbox(Iup::Label("Inside Tab D"), Iup::Button("Button D", ""))
Iup::SetAttribute(vbox1, "TABTITLE", "Tab C")
Iup::SetAttribute(vbox2, "TABTITLE", "Tab D")
tabs2 = Iup::Tabs(vbox1, vbox2)
Iup::SetAttribute(tabs2, "TABTYPE", "LEFT")
box = Iup::Hbox(tabs1, tabs2)
Iup::SetAttribute(box, "MARGIN", "10x10")
Iup::SetAttribute(box, "GAP", "10")
dlg = Iup::Dialog(box)
Iup::SetAttribute(dlg, "TITLE", "IupTabs")
Iup::SetAttribute(dlg, "SIZE", "200x80")
Iup::ShowXY (dlg, IUP_CENTER, IUP_CENTER)
Iup::MainLoop ()
Iup::Close ()
END
# test a Windows GUI application
import
windows, shellapi, nb30, mmsystem, shfolder
#proc MessageBox(hWnd: int, lpText, lpCaption: CString, uType: uint): int
# {stdcall, import: "MessageBox", header: "<windows.h>"}
discard MessageBox(0, "Hello World!", "Nimrod GUI Application", 0)
From statement
We have already seen the simple import statement that just imports all exported symbols. An alternative that only imports listed symbols is the from import statement:
from mymodule import x, y, z
import
glib2, gtk2
proc destroy(widget: pWidget, data: pgpointer){.cdecl.} =
main_quit()
proc widgetDestroy(w: PWidget) {.cdecl.} =
destroy(w)
nimrod_init()
var window = window_new(WINDOW_TOPLEVEL)
var button = button_new("Click me")
set_border_width(Window, 5)
add(window, button)
discard signal_connect(window, "destroy",
SIGNAL_FUNC(ex5.destroy), nil)
discard signal_connect_object(button, "clicked",
SIGNAL_FUNC(widgetDestroy),
window)
show(button)
show(window)
main()
type
TPerson = tuple [name: string, age:int]
proc result(): TPerson = ("Bob",42)
var r = result()
echo(r) # default stringification
echo (r.name) # access by field name
var (name,age) = r # tuple unpacking
echo (name,"|",age)
import parseopt
from strutils import parseInt
from os import existsFile
const usage = """
head [flags] filename
-n: number of lines (default 10)
-h,--help: this help
-v,--version: version
"""
proc showUsage(msg: string) =
if msg != nil: echo("head: ",msg)
quit(usage,1)
proc head(file: string, n: int) =
if not existsFile(file): quit("file " & file & " does not exist")
var
f = open(file)
i = 0
for line in f.lines:
echo(line)
i += 1
if i == n: break
proc parseCommands() =
var
files: seq[string]
n = 10
newSeq(files,0)
for kind, key, val in getopt():
case kind
of cmdArgument:
files.add(key)
of cmdLongOption, cmdShortOption:
case key
of "help", "h": showUsage(nil)
of "n":
n = parseInt(val)
of "version", "v":
echo("1.0")
return
of cmdEnd: assert(false) # cannot happen
if len(files) == 0:
# no filename has been given, so we show the help:
showUsage("please supply filename")
if len(files) == 1:
head(files[0],n)
else:
for f in files:
echo("----- ",f)
head(f,n)
parseCommands()
Here we are making objects which are references (by default they are value types, like tuples, unlike java), initialized with the standard procedure new. Note the Pascal-like special variable result in procedures!
As expected, you may pass Germans to sayit, because a German is a person, but greeting has to be declared as a method for this to work; if it were a proc, we would get a warning about the second greeting being unused, and Germans are then addressed in English.
The cool thing about multi-methods is that they restore symmetry; a traditional polymorphic call a.foo(b) is only polymorphic in a. This makes sense in a language where dot method notation is just sugar for procedure calls where the first argument matches the type.
type
TPerson = object of TObject
name: string
age: int
proc setPerson(p: ref TPerson, name: string, age:int) =
p.name = name
p.age = age
proc newPerson(name: string, age:int): ref TPerson =
new(result)
result.setPerson(name,age)
method greeting(p: ref TPerson):string = "Hello " & p.name & ", age " & $p.age
type
TGerman = object of TPerson
proc newGerman(name: string, age:int): ref TGerman =
new(result)
result.setPerson(name,age)
method greeting(p: ref TGerman):string = "Hallo " & p.name & ", " & $p.age & " Jahre alt"
var john = newPerson("John",60)
var rene = newGerman("Rene",43)
proc sayit(p: ref TPerson) = echo p.greeting
sayit(john)
sayit(rene)
class person
string name
int age
'default methods:
method sayit() as string
return "Hi " & name & ", age " & age
end method
'
end class
class EnglishSpeaker
person
method sayit() as string
return "Hello " & name & ", age " & age
end method
end class
class GermanSpeaker
person
method sayit() as string
return "Hallo " & name & ", " & age & " Jahre alt"
end method
end class
let anon=Person : anon = {"Anonymous",42}
let john=EnglishSpeaker : john = {"John",60}
let rene=GermanSpeaker : rene = {"Rene",43}
def sayit %1.sayit
print sayit john
print sayit rene
print sayit anon
jrs@laptop:~/nimrod/Aporia-master$ nimrod c -d:release aporia.nim
config/nimrod.cfg(36, 11) Hint: added path: '/home/jrs/.babel/libs/' [Path]
Hint: used config file '/home/jrs/nimrod/config/nimrod.cfg' [Conf]
Hint: used config file '/home/jrs/nimrod/Aporia-master/aporia.nimrod.cfg' [Conf]
Hint: system [Processing]
Hint: aporia [Processing]
Hint: glib2 [Processing]
Hint: gtk2 [Processing]
Hint: atk [Processing]
Hint: pango [Processing]
Hint: gdk2pixbuf [Processing]
Hint: gdk2 [Processing]
Hint: gtksourceview [Processing]
Hint: dialogs [Processing]
Hint: os [Processing]
Hint: strutils [Processing]
Hint: parseutils [Processing]
Hint: times [Processing]
Hint: posix [Processing]
Hint: osproc [Processing]
Hint: strtabs [Processing]
Hint: hashes [Processing]
Hint: streams [Processing]
Hint: pegs [Processing]
Hint: unicode [Processing]
Hint: parseopt [Processing]
Hint: asyncio [Processing]
Hint: sockets [Processing]
Hint: encodings [Processing]
Hint: tables [Processing]
Hint: math [Processing]
Hint: algorithm [Processing]
Hint: settings [Processing]
Hint: utils [Processing]
Hint: AboutDialog [Processing]
Hint: CustomStatusBar [Processing]
Aporia-master/CustomStatusBar.nim(92, 11) Hint: 'tid' is declared but not used [XDeclaredButNotUsed]
Aporia-master/utils.nim(494, 11) Info: instantiation from here
lib/pure/pegs.nim(873, 14) Warning: injected 'matches' might be affected by new scoping rules in 0.9.4 [User]
Hint: cfg [Processing]
Hint: parsecfg [Processing]
Hint: lexbase [Processing]
Hint: search [Processing]
Hint: re [Processing]
Hint: pcre [Processing]
Aporia-master/search.nim(60, 14) Hint: 'brackets' is declared but not used [XDeclaredButNotUsed]
Aporia-master/search.nim(120, 13) Hint: 'matches' is declared but not used [XDeclaredButNotUsed]
Hint: suggest [Processing]
Hint: processes [Processing]
Aporia-master/processes.nim(145, 14) Info: instantiation from here
lib/pure/pegs.nim(873, 14) Warning: injected 'matches' might be affected by new scoping rules in 0.9.4 [User]
Aporia-master/processes.nim(162, 19) Info: instantiation from here
lib/pure/pegs.nim(873, 14) Warning: injected 'matches' might be affected by new scoping rules in 0.9.4 [User]
Aporia-master/processes.nim(334, 18) Warning: thread analysis incomplete due to unknown call 'echod(["[Thread] Process already running"])' [AnalysisLoophole]
Aporia-master/processes.nim(339, 12) Info: instantiation from here
lib/pure/streams.nim(42, 41) Warning: thread analysis incomplete due to unknown call 's.closeImpl(s)' [AnalysisLoophole]
Aporia-master/processes.nim(349, 17) Info: instantiation from here
lib/pure/streams.nim(51, 23) Warning: thread analysis incomplete due to unknown call 's.atEndImpl(s)' [AnalysisLoophole]
Aporia-master/processes.nim(352, 21) Info: instantiation from here
lib/pure/streams.nim(185, 21) Info: instantiation from here
lib/pure/streams.nim(123, 14) Info: instantiation from here
lib/pure/streams.nim(76, 26) Warning: thread analysis incomplete due to unknown call 's.readDataImpl(s, buffer, bufLen)' [AnalysisLoophole]
Hint: rst [Processing]
Hint: rstast [Processing]
lib/packages/docutils/rst.nim(853, 20) Hint: 'dkAuthor' is declared but not used [XDeclaredButNotUsed]
lib/packages/docutils/rst.nim(1362, 6) Hint: 'rst.$(t: TToken): string' is declared but not used [XDeclaredButNotUsed]
lib/packages/docutils/rst.nim(853, 31) Hint: 'dkAuthors' is declared but not used [XDeclaredButNotUsed]
Aporia-master/suggest.nim(66, 12) Warning: get_size is deprecated, get_width should be used [User]
Aporia-master/suggest.nim(277, 13) Hint: 'f' is declared but not used [XDeclaredButNotUsed]
Aporia-master/suggest.nim(412, 12) Hint: 'lang' is declared but not used [XDeclaredButNotUsed]
Aporia-master/aporia.nim(1066, 26) Hint: 'startOldLineOffset' is declared but not used [XDeclaredButNotUsed]
Aporia-master/aporia.nim(1204, 27) Hint: 'cfgFile' is declared but not used [XDeclaredButNotUsed]
Aporia-master/aporia.nim(1610, 10) Hint: 'cmpB' is declared but not used [XDeclaredButNotUsed]
Aporia-master/aporia.nim(1832, 14) Hint: 'OpenItem' is declared but not used [XDeclaredButNotUsed]
Aporia-master/aporia.nim(1842, 16) Hint: 'SearchItem' is declared but not used [XDeclaredButNotUsed]
Aporia-master/aporia.nim(1839, 14) Hint: 'RedoItem' is declared but not used [XDeclaredButNotUsed]
Aporia-master/aporia.nim(1829, 17) Hint: 'NewFileItem' is declared but not used [XDeclaredButNotUsed]
Aporia-master/aporia.nim(1834, 14) Hint: 'SaveItem' is declared but not used [XDeclaredButNotUsed]
Aporia-master/aporia.nim(1837, 14) Hint: 'UndoItem' is declared but not used [XDeclaredButNotUsed]
Aporia-master/aporia.nim(179, 16) Hint: 'aporia.saveAllTabs()' is declared but not used [XDeclaredButNotUsed]
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/aporia.o Aporia-master/nimcache/aporia.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/system.o Aporia-master/nimcache/system.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/glib2.o Aporia-master/nimcache/glib2.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/gtk2.o Aporia-master/nimcache/gtk2.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/atk.o Aporia-master/nimcache/atk.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/pango.o Aporia-master/nimcache/pango.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/gdk2pixbuf.o Aporia-master/nimcache/gdk2pixbuf.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/gdk2.o Aporia-master/nimcache/gdk2.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/gtksourceview.o Aporia-master/nimcache/gtksourceview.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/dialogs.o Aporia-master/nimcache/dialogs.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/os.o Aporia-master/nimcache/os.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/strutils.o Aporia-master/nimcache/strutils.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/parseutils.o Aporia-master/nimcache/parseutils.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/times.o Aporia-master/nimcache/times.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/posix.o Aporia-master/nimcache/posix.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/osproc.o Aporia-master/nimcache/osproc.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/strtabs.o Aporia-master/nimcache/strtabs.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/hashes.o Aporia-master/nimcache/hashes.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/streams.o Aporia-master/nimcache/streams.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/pegs.o Aporia-master/nimcache/pegs.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/unicode.o Aporia-master/nimcache/unicode.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/parseopt.o Aporia-master/nimcache/parseopt.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/asyncio.o Aporia-master/nimcache/asyncio.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/sockets.o Aporia-master/nimcache/sockets.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/encodings.o Aporia-master/nimcache/encodings.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/tables.o Aporia-master/nimcache/tables.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/math.o Aporia-master/nimcache/math.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/algorithm.o Aporia-master/nimcache/algorithm.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/settings.o Aporia-master/nimcache/settings.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/utils.o Aporia-master/nimcache/utils.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/AboutDialog.o Aporia-master/nimcache/AboutDialog.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/CustomStatusBar.o Aporia-master/nimcache/CustomStatusBar.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/cfg.o Aporia-master/nimcache/cfg.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/parsecfg.o Aporia-master/nimcache/parsecfg.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/lexbase.o Aporia-master/nimcache/lexbase.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/search.o Aporia-master/nimcache/search.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/re.o Aporia-master/nimcache/re.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/pcre.o Aporia-master/nimcache/pcre.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/suggest.o Aporia-master/nimcache/suggest.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/processes.o Aporia-master/nimcache/processes.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/rst.o Aporia-master/nimcache/rst.c
gcc -c -w -pthread -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o Aporia-master/nimcache/rstast.o Aporia-master/nimcache/rstast.c
gcc -o /home/jrs/nimrod/Aporia-master/aporia Aporia-master/nimcache/rstast.o Aporia-master/nimcache/rst.o Aporia-master/nimcache/processes.o Aporia-master/nimcache/suggest.o Aporia-master/nimcache/pcre.o Aporia-master/nimcache/re.o Aporia-master/nimcache/search.o Aporia-master/nimcache/lexbase.o Aporia-master/nimcache/parsecfg.o Aporia-master/nimcache/cfg.o Aporia-master/nimcache/CustomStatusBar.o Aporia-master/nimcache/AboutDialog.o Aporia-master/nimcache/utils.o Aporia-master/nimcache/settings.o Aporia-master/nimcache/algorithm.o Aporia-master/nimcache/math.o Aporia-master/nimcache/tables.o Aporia-master/nimcache/encodings.o Aporia-master/nimcache/sockets.o Aporia-master/nimcache/asyncio.o Aporia-master/nimcache/parseopt.o Aporia-master/nimcache/unicode.o Aporia-master/nimcache/pegs.o Aporia-master/nimcache/streams.o Aporia-master/nimcache/hashes.o Aporia-master/nimcache/strtabs.o Aporia-master/nimcache/osproc.o Aporia-master/nimcache/posix.o Aporia-master/nimcache/times.o Aporia-master/nimcache/parseutils.o Aporia-master/nimcache/strutils.o Aporia-master/nimcache/os.o Aporia-master/nimcache/dialogs.o Aporia-master/nimcache/gtksourceview.o Aporia-master/nimcache/gdk2.o Aporia-master/nimcache/gdk2pixbuf.o Aporia-master/nimcache/pango.o Aporia-master/nimcache/atk.o Aporia-master/nimcache/gtk2.o Aporia-master/nimcache/glib2.o Aporia-master/nimcache/system.o Aporia-master/nimcache/aporia.o -ldl -pthread -lm
Hint: operation successful (60707 lines compiled; 14.303 sec total; 90.926MB) [SuccessX]
jrs@laptop:~/nimrod/Aporia-master$
I'm forking this thread to the All BASIC forum (translator board) so the project isn't a distraction to the O2 forum.
FYI Nimrod has a C header conversion tool that might be useful for the O2 project.
@Kent - It would be great if you would join us on All BASIC. (Charles is a member) Just send me an e-mail and I'll set you up.
export PATH=$PATH:/home/kent/scriptbasic/bin
Hmmm
I see this but i don't know why not work on windows version,probably because of some
problems with GTK.
minimal installer for Windows XP/Vista/7 (i386, 32bit): download/nimrod_gamera_0.9.2.exe ("Gamera edition": includes only a minimal GCC)
installer for Windows XP/Vista/7 (i386, 32bit): download/nimrod_0.9.2.exe (includes GCC and everything else you need)
...Lets assume you unzipped you SB archive in /home/kent/scriptbasic. All you need to do to get scriba to run from anywhere is point your search path to the SB bin directory.Code: [Select]export PATH=$PATH:/home/kent/scriptbasic/bin
...You can add these startup commands to your login shell profile once you get settled in.
John
export PATH=/home/jrs/sb/sb22/bin:$PATH
export SCRIBACONF=/home/jrs/sb/sb22/bin/basic.conf
export UBUNTU_MENUPROXY=0