home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / c2local / c2local.dok < prev    next >
Text File  |  1977-12-31  |  19KB  |  483 lines

  1.  
  2.  
  3.  
  4.                              C2Local V1.0
  5.                              ============
  6.  
  7.                      © 1994-95 by Matthias Meixner
  8.  
  9.  
  10.  
  11.                               Copyright
  12.                               ---------
  13.  
  14. C2Local, CComp, CTMerge, StrMerge (C) Copyright 1994-95 by Matthias Meixner.
  15. Alle Rechte vorbehalten.
  16.  
  17. Für die rechtlichen Aspekte, lesen Sie bitte auch die Liesmich Datei.
  18.  
  19.  
  20.  
  21.  
  22.                             Hintergrund
  23.                             -----------
  24. Seit der Version 2.1 des Amiga-Betriebssystems ist es möglich Programme
  25. mehrsprachig auszulegen. Dies wird über sogenannte Kataloge realisiert.
  26. Dabei wird eine Sprache in das Programm eincompiliert und die anderen
  27. Übersetzungen in Katalogen abgelegt. Zur Laufzeit des Programms wird nun
  28. die passende Sprache bestimmt und über den zugehörigen Katalog in das
  29. Programm eingebunden. Nun erfordert dies aber, daß in den Sourcecodes die
  30. Strings nicht mehr direkt als Strings dargestellt werden können, da sie
  31. ja von der eingestellten Sprache abhängen. Ziel von C2Local war es zu
  32. ermöglichen, daß der Sourcecode weiterhin auf die vertraute Art geschrieben
  33. werden kann und man danach vollautomatisch eine lokalisierte Version
  34. generieren kann. Dieses Ziel wird mit C2Local für C und C++ Sourcecodes
  35. fast vollständig erreicht. Programme wie CatComp generieren zwar Code zum
  36. ansprechen von lokalisierten Strings, doch der Programmierer muß den
  37. Sourcecode selbst daraufhin anpassen. "Localize" geht zwar einen Schritt
  38. weiter und kann den Sourcecode selbständig patchen, ist aber auf Strings
  39. innerhalb von Funktionen beschränkt, so daß z.B. Strukturen von Menüs
  40. manuell lokalisiert werden müssen. C2Local kann dagegen die meisten dieser
  41. Strings lokalisieren. Die einzige Ausnahme ist, daß char-Arrays nicht
  42. statisch mit diesen Strings initialisiert werden können.
  43. z.B. ist
  44.  
  45.    char a[]="test"
  46.  
  47. nicht automatisch lokalisierbar. Aber der viel häufiger benötigte Fall
  48.  
  49.    char *a="test"
  50.  
  51. kann automatisch lokalisiert werden. Dieser Fall tritt unter anderem bei
  52. der Initialisierung von Systemstrukturen auf, so daß z.B. Menüs oder Gadgets
  53. ohne Probleme automatisch lokaliert werden können.
  54.  
  55.  
  56.  
  57.  
  58.                         Systemanforderungen
  59.                         -------------------
  60. Die Programme benötigen mindestens OS2.0 (V37). Die mit c2local lokalisierten
  61. Programme benötigen keine andere Betriebssystemversion als das Original,
  62. allerdings wird die Lokalisierung nur ab OS2.1 wirksam.
  63.  
  64.  
  65.  
  66.  
  67.                               Programme
  68.                               ---------
  69. Dieses Programmpaket enthält folgende Programme:
  70.  
  71.    C2Local:    Programm zum Generieren von lokalisierten Sourcecodes
  72.    CComp:      Programm zum Übersetzen von Katalogen
  73.    CTMerge:    Programm zum Mischen von Übersetzungsdateien
  74.    StrMerge:   Programm zum Mischen von Stringdateien
  75.  
  76. Diese Programme befinden sich im Bin-Directory.
  77.  
  78.  
  79.  
  80.                              Installation
  81.                              ------------
  82. Es reicht zur Installation aus das C2Local Verzeichnis an die gewünschte
  83. Stelle zu kopieren und das Bin-Verzeichnis in den Suchpfad aufzunehmen.
  84. Falls man die Programme in ein anderes Verzeichnis kopieren möchte, muß man
  85. nur darauf achten, daß man das zugehörige Catalogs-Verzeichnis mitkopiert.
  86. Es muß sich im gleichen Verzeichnis wie die Programme befinden, damit die
  87. deutschen Strings der Lokalisierung gefunden werden können. Ansonsten ist
  88. nur die eingebaute englische Version verfügbar. Dies gilt auch für den Fall,
  89. daß Sie mit einer Version des Betriebssystems arbeiten, die die Lokalisierung
  90. noch nicht unterstützt.
  91.  
  92.  
  93.  
  94.                               Bedienung
  95.                               ---------
  96.  
  97. C2Local Scan/S,Patch/S,Compile/S,Pattern/M,Ign=Ignore/K,Lab=Labels/K,
  98.         Cat=Catalog/K,Lang=Language/K,Ver=Version/N,Name/A/K
  99.  
  100. NAME dient als Basisname, aus dem alle Namen der zu erzeugenden Dateien
  101. abgeleitet werden.
  102.  
  103.  
  104. C2Local kennt drei verschiedene Betriebsarten: Scan, Patch und Compile.
  105.  
  106. 'Scan' durchsucht alle Dateien, die dem Pattern entsprechen, nach Strings und
  107. erzeugt eine Stringdatei <Name>_locale.str, die alle Strings enthält. Die
  108. Zeilen dieser Datei sind folgendermaßen aufgebaut:
  109.  
  110. <Label> <String> [<Größe>]
  111.  
  112.                    ^^^^^^^ Dieses Feld wird hier nicht erzeugt, kann jedoch
  113.                            für die Verwendung mit 'Compile' mit einem Editor
  114.                            angehängt werden.
  115.  
  116. Ein '+' am Ende eines Strings zeigt an, daß sich der String auch noch über
  117. die nächste Zeile erstreckt. Mit IGNORE kann man bestimmte Strings aus
  118. dieser Liste ausschließen, mit LABEL den Labels bestimmte Werte zuweisen.
  119. Diese Dateien sind genauso aufgebaut, wie die von Scan erzeugte Datei, wobei
  120. in der Datei für IGNORE das Feld <Label> weggelassen werden kann.
  121. Typischerweise wird man also zuerst einmal mit 'Scan' alle Dateien
  122. durchsuchen lassen und dann in der erzeugten Datei alle Strings, die nicht
  123. lokalisiert werden sollen, herraussuchen und abspeichern. Ist dies nicht
  124. genau genug, so kann man Strings auch dadurch ausschließen, daß man im
  125. Sourcecode direkt hinter den String ohne Leerzeichen '/*-' schreibt, also
  126. z.B.
  127.        char *a="wird nicht lokalisiert"/*-*/;
  128.  
  129. Kommentare beginnen wie in C++ mit // und markieren den Rest der Zeile als
  130. Kommentar.
  131.  
  132.  
  133. 'Patch' macht zunächst einmal genau das gleiche wie 'Scan', erzeugt jedoch
  134. ein neues Directory 'Localized', kopiert alle Dateien, die im Pattern
  135. angegeben waren in dieses Directory und ersetzt die Strings durch die Label
  136. aus der neu erzeugten Stringdatei. ACHTUNG: will man die automatisch
  137. generierten Labels durch eigene ersetzen, so kann man dies nicht dadurch tun,
  138. daß man die Stringdatei <Name>_locale.str einfach editiert und danach
  139. C2Local mit 'Patch' startet, da 'Patch' diese Datei neu erzeugt und dadurch
  140. überschreibt. Stattdessen muß man die editierte Datei umbenennen und mit
  141. 'Label' als Parameter beim Aufruf von C2Local angeben.
  142. Hat man bereits eine Datei mit den Strings, die nicht lokalisiert werden
  143. sollen, und möchte den Labels keine eigenen Namen geben, bzw. hat bereits
  144. eine Datei mit diesen Namen, so kann man auf 'Scan' ersatzlos verzichten.
  145.  
  146.  
  147. 'Compile' erzeugt aus <Name>_locale.str, die Dateien:
  148.  
  149.    Localized/<Name>_locale.cd   Katalogbeschreibung
  150.    Localized/<Name>_locale.ct   leere Katalogübersetzung
  151.    Localized/<Name>_locale.h    Headerdatei, diese Datei wird per #include in
  152.                                 jede gepatchte Sourcecodedatei eingebunden
  153.    Localized/<Name>_locale.c    C-Sourcecode mit allen verwendeten Strings
  154.                                 und der Routine InitStrings();
  155.  
  156. 'Compile' benötigt folgende Optionen:
  157.    Catalog: Gibt den Katalognamen an, der später verwendet werden soll.
  158.    Version: Versionsnummer des Katalogs (ACHTUNG im Unterschied zu
  159.             OpenLibrary muß bei OpenCatalog, das in InitStrings() verwendet
  160.             wird die Versionsnummer exakt übereinstimmen, wenn sie ungleich
  161.             0 ist !!) (default: 0)
  162.    Language: Dies gibt die eigebaute Sprache an. (default: english)
  163.  
  164. Diese Werte werden in InitStrings() einkodiert !
  165. Die Routine InitStrings() muß vom eigenen Programm aus aufgerufen werden.
  166. Am besten ist es, wenn man sie als erste Routine in main() aufruft. Damit
  167. man dies bereits im Original-Sourcecode machen kann, dies gleichzeitig aber
  168. nicht beim compilieren der Originalversion stört macht man dies am besten
  169. so:
  170.  
  171. #ifdef __LOCALIZED
  172.    InitStrings();
  173. #endif
  174.  
  175.  
  176. __LOCALIZED wird in Localized/<Name>_locale.h definiert. Da diese Datei per
  177. #include in die gepatchten Sourcen eingebunden wird, wird InitStrings()
  178. in der lokalisierten Version dann automatisch verwendet.
  179.  
  180.  
  181.  
  182.                            Lokalisieren
  183.                            ------------
  184. Voraussetzung für eine erfolgreiche Lokalisierung mit C2Lokal ist, daß
  185. Strings grundsätzlich nur gelesen werden, da mehrfache Vorkommen von Strings
  186. auf den gleichen String abgebildet werden. Wird dieser String geändert, so
  187. ändern sich alle Strings mit gleichem Inhalt im ganzen Programm. Genau dies
  188. wird nämlich ausgenutzt um die Strings durch ihre lokalisierten Versionen
  189. zu ersetzen.
  190.  
  191. Typischerweise wird man bei der Lokalisierung eines Programms
  192. folgendermaßen vorgehen:
  193.  
  194. Zuerst wird man sich einmal alle Strings heraussuchen lassen, z.B.:
  195.  
  196. C2Local SCAN #?.c #?.h NAME test
  197.  
  198. Aus test_locale.str löscht man alle Strings, die lokalisiert werden sollen
  199. und speichert sie als ignore.str. Da normalerweise später niemand die
  200. lokalisierten Sourcecodes lesen wird, braucht man auf die Namen der Labels
  201. keine Rücksicht zu nehmen.
  202.  
  203. Nun kann man den lokalisierten Sourcecode erzeugen:
  204.  
  205. C2Local PATCH #?.c #?.h NAME test IGNORE ignore.str
  206.  
  207. Sollte dabei die Meldung auftreten, daß die Catalog-Translation-Datei nicht
  208. neu angelegt wurde, da sie bereits existiert, so muß man diese Datei
  209. umbenennen oder löschen und nocheinmal 'Patch' aufrufen. Dies hat den Sinn,
  210. daß nicht mühsam erstellte Übersetzungen aus Versehen überschrieben werden.
  211.  
  212. C2Local COMPILE NAME test VERSION 1 CATALOG test.catalog
  213.  
  214. erzeugt die restlichen noch fehlenden Dateien und danach kann alles bereits
  215. compiliert werden:
  216.  
  217. cd Localized
  218. sc #?.c link  // z.B. Für SAS-C
  219.  
  220. Sollten dabei Fehler auftreten, während vorher keine Fehler aufgetreten sind,
  221. dann handelt es sich vermutlich um eine der oben erwähnten Ausnahmen.
  222.  
  223. Jetzt kommt der aufwendigste Teil, das Übersetzen der Strings :)
  224. Zuerst sollte man sich die leere Catalog-Translation-Datei <Name>_locale.ct
  225. kopieren, damit sie noch für weitere Übersetzungen zur Verfügung steht. In
  226. diese Datei trägt man die übersetzen Strings ein. Dabei enthalten die
  227. Kommentarzeilen, die mit ';' beginnen den Originalstring. Ein Eintrag sieht
  228. ungefähr folgendermaßen aus:
  229.  
  230. Label
  231. deutscher String
  232. ; english String
  233. ;
  234.  
  235. WICHTIG: Die Kommentarzeilen dürfen nicht verändert werden, wenn man CTMerge
  236. verwenden will !!!!!
  237.  
  238. Innerhalb der Übersetzung können C-Escape-Sequenzen verwendet werden
  239. inclusive ein paar Erweiterungen (siehe Tabelle)
  240.  
  241. Ein Backslash ('\') am Ende der Zeile zeigt an, daß dieser String in der
  242. nächsten Zeile fortgesetzt wird.
  243. Tip: Da manche Texteditoren Leerzeichen am Zeilenende abschneiden, kann man
  244.      \ hinter die Leerzeichen setzen und in der folgenden Zeile eine
  245.      Leerzeile einfügen.
  246.  
  247. Kommentarzeilen beginnen mit ';' in der ersten Spalte.
  248.  
  249. Beim Ausfüllen sollte man nicht vergessen hinter '## language' die Sprache
  250. des Katalogs einzutragen und hinter '## version' die Version des Katalogs.
  251. Diese wird als Standart-Versionsstring angegeben.
  252.  
  253.  
  254. Aus dieser Übersetzung kann man nun mit CComp einen Katalog bauen:
  255.  
  256. CComp <name>_locale.cd übersetzung.ct Catalogs/deutsch/test.catalog
  257.  
  258. Sollte dabei die Fehlermeldung auftreten, daß ein übersetzter String zu lang
  259. ist, so kann man die für einen String reservierte Länge ändern, indem man
  260. in der Stringdatei hinter dem String die maximal vorkommende Länge aller
  261. Übersetzungen angibt, z.B.:
  262.  
  263. msg_0 "Teststring" 20
  264.  
  265. Als default wird die doppelte Länge des Strings angenommen, wenn kein Wert
  266. angegeben wird. Diesen Wert kann man auch dazu benutzen, um den Speicherbe-
  267. darf von langen Strings einzuschränken, allerdings sollte man dabei bedenken,
  268. daß Strings in anderen Sprachen deutlich länger sein können. Wenn man auf
  269. diese Art eine Stringdatei (hier test_locale.str) geändert hat, so ist es
  270. notwendig C2Local noch einmal mit 'Compile' aufzurufen und das Programm neu
  271. zu compilieren, damit die neu erzeugten Sourcecodes wieder eingebunden
  272. werden.
  273.  
  274. Wichtig: Der Name der Katalogs muß mit dem Namen übereinstimmen, der bei
  275. 'Compile' verwendet wurde !
  276.  
  277. Anstelle von CComp kann man natürlich auch CatComp, FlexCat, KitCat, MakeCat
  278. oder eines der anderen Katalogtools verwenden.
  279.  
  280. Das wars!
  281.  
  282. Falls andere Sprachen trotz einer entsprechenden Einstellung in den
  283. Preferences nicht verwendet werden:
  284.  
  285. - befindet sich der Katalog im richtigen Verzeichnis ?
  286. - stimmt der Name des Katalogs ?
  287. - stimmt die Version des Katalogs ?
  288. - ist im .ct-file die Sprache eingetragen, Tippfehler ?
  289. - ist noch ein alter Katalog im Speicher (evtl. "avail flush") ?
  290. - wurde InitStrings() aufgerufen ?
  291.  
  292.  
  293.  
  294.                           Funktionsweise
  295.                           --------------
  296. C2Local sucht alle Strings und ersetzt sie durch ein Label. Dieses Label ist
  297. eine Referenz auf den String, der in eine Struktur eingebettet wurde, um es
  298. zu ermöglichen die Strings zu verketten. Die Strings sind dabei als Array
  299. angegeben. Dies bedingt allerdings die Einschränkung, daß sie eine bestimmte
  300. Länge nicht überschreiten dürfen, bietet allerdings den Vorteil, daß man sie
  301. überschreiben kann,ohne daß sich dabei ihre Adresse ändert. Ihre Adresse
  302. ist also bereits beim Compilieren/Linken bekannt und kann in statischen
  303. Initialisierungen verwendet werden. Beim Aufruf von InitStrings wird
  304. nun versucht der Katalog zu öffnen. Falls dies möglich ist, wird jeder
  305. String durch seine Übersetzung Überschrieben.
  306.  
  307. Da Strings nun in Arrays stehen, kann man allerdings keine weiteren Arrays
  308. damit initialisieren, wodurch es zu den oben genannten Ausnahmen bei der
  309. automatischen Lokalisierung kommt. Man kann den Sourcecode jedoch etwas
  310. anpassen, um dies trotzdem zu ermöglichen. Falls dieses Array nur gelesen
  311. wird, so kann man es Grundsätzlich durch einen Zeiger auf den String ersetzt
  312. werden:
  313.  
  314.    char a[]="test";                -> char *a="test";
  315.  
  316. Lokale Arrays kann man recht einfach ersetzen:
  317.  
  318.    test() {                        ->  test() {
  319.       char a[10]="String";         ->     char a[10];
  320.    }                               ->     strcpy(a,"String");
  321.                                    ->  }
  322.  
  323. Globale Arrays muß man leider per Hand inititalisieren:
  324.  
  325.    char a[10]="String";            ->  char a[10];
  326.                                    ->
  327.    main() {                        ->  main() {
  328.    }                               ->     strcpy(a,"String");
  329.                                    ->  }
  330.  
  331. Für statische lokale Arrays gibt es zwei Möglichkeiten:
  332. 1) Man macht daraus eine globale Variable und inititalisiert sie beim
  333.    Programmstart
  334.  
  335. 2)
  336.    test() {                        ->  test() {
  337.       static char a[10]="String";  ->     char a[10];
  338.    }                               ->     static int init=0;
  339.                                    ->     if(!init) {
  340.                                    ->        strcpy(a,"String");
  341.                                    ->        init=1;
  342.                                    ->     }
  343.                                    ->  }
  344.  
  345.  
  346.  
  347.                     Die anderen Programme im Paket
  348.                     ------------------------------
  349.  
  350. CComp Catalogdescription/A,Translation/A,Catalog/A
  351.  
  352. CComp dient zum Erzeugen von Katalogdateien. Es benötigt drei Parameter.
  353. Eine Katalogbeschreibungsdatei (Endung .cd), eine Katalogübersetzungsdatei
  354. (Endung .ct) und den Namen des zu erzeugenden Katalogs.
  355.  
  356.  
  357. CTMerge From/A,Merge/A/M,To/K/A
  358.  
  359. CTMerge mischt zu der Katalogübersetzung 'From' alle Katalogübersetzungen
  360. 'Merge' und schreibt das Ergebnis nach 'To'. 'From' und 'To' müssen
  361. verschiedene Dateien sein !! CTMerge verwendet dabei die Kommentarzeilen,
  362. um bereits bekannte Übersetzungen aus den 'Merge'-Dateien zu erkennen und in
  363. die Ausgabedatei einzukopieren. Die Labelnamen werden dabei nicht verändert.
  364. Auf diese Weise kann man recht schnell neue Übersetzungen erstellen, wenn
  365. ein Programm erweitert wurde und neue Strings hinzugekommen sind. Man kann
  366. nicht einfach die alte Übersetzungsdatei direkt verwenden solange man
  367. automatisch generierte Labelnamen verwendet hat, da sich die Labelnamen
  368. vermutlich seit der letzen Version verändert haben. In diesem Fall kann man
  369. deshalb CTMerge verwenden, um sich eine komplette Neuübersetzung zu sparen.
  370.  
  371.  
  372. StrMerge From/A,Merge/A/M,To/K/A
  373.  
  374. StrMerge mischt Längenangaben in Stringfiles. Manchmal ist es notwendig,
  375. Strings explizit eine Maximallänge zuzuweisen. Dies kann man durch editieren
  376. der Stringdatei <name>_locale.str vor dem 'Compile' Aufruf von C2Local
  377. machen; da diese Datei bei jedem 'Scan' oder 'Patch' überschrieben wird,
  378. wäre es wünschenswert dies automatisch vornehmen zu lassen. StrMerge macht
  379. genau dies. Es extrahiert die Längenangaben aus den 'Merge'-Dateien und
  380. kombiniert sie mit der vorgegebenen Stringdatei. 'From' und 'To' darf die
  381. gleiche Datei sein. Damit wird es möglich Batch-Dateien für die
  382. Lokalisierung eines Programms zu schreiben.
  383.  
  384.  
  385.                Zusätzliche Informationen zu den Dateiformaten
  386.                ----------------------------------------------
  387. Endung:  Beschreibung:
  388.  
  389. .cd      eine 'Catalog Description'-Datei
  390.  
  391.          Sie enthält die Nummern, Kennungen und Originaltexte, sowie die
  392.          Längenbegrenzungen für die Übersetzungen.
  393.  
  394.          Bsp:         Text1_STR (22/7/80)
  395.                       Hallo Leute, ein deutscher String !
  396.  
  397.          Das Beispiel weist dem String Nr. 22 die Kennung Text1_STR und den
  398.          Text in der zweiten Zeile zu. Die minimale Länge der Übersetzungen
  399.          muß 7, die maximale Länge 80 betragen. Diese Angaben sind optional,
  400.          (//) ist also genauso gültig.
  401.          Kommentarzeilen beginnen mit ';'.
  402.          '\' in einer Stringzeile bedeutet, daß die Zeile in der nächsten
  403.          Zeile weitergeht.
  404.          Escape-Codes: siehe Tabelle.
  405.          Nähere Informationen siehe Doc-File zu CatComp !
  406.  
  407. .ct:     eine 'Catalog Translation'-Datei
  408.  
  409.          Sie enthält die Übersetzungen in einer bestimmten Sprache.
  410.  
  411.          Bsp:     Text1_STR
  412.                   C'est français !
  413.                   ; Hallo Leute, ein deutscher String !
  414.  
  415.          Der sog. Header enthät außerdem weitere Informationen:
  416.  
  417.          ## version $VER: name.catalog ver.rev (10.09.92)
  418.          ## language français
  419.  
  420.          Kommentarzeilen beginnen mit ';'.
  421.          Kommentare sollten nicht gelöscht oder verändert werden,
  422.          da sie von CTMerge benötigt werden (also für CTMerge eigentlich
  423.          gar keine sind)!
  424.          '\' in einer Stringzeile bedeutet, daß die Zeile in der nächsten
  425.          Zeile weitergeht.
  426.          Escape-Codes siehe Tabelle.
  427.          Nähere Informationen siehe Doc-File zu CatComp !
  428.  
  429. .str     Stringdatei
  430.  
  431.          Sie enthält die Strings:
  432.  
  433.          <Label> <String> [<Größe>]
  434.  
  435.          Bsp:     msg_0 "String" 10
  436.  
  437.          Strings können über mehrere Zeilen gehen:
  438.  
  439.          Bsp:     msg_0 "Str"+
  440.                         "ing"
  441.  
  442.          <Label> ist für Ignore-Dateien und Dateien, die mit StrMerge
  443.          dazugemischt werden, optional. <Größe> ist immer optional
  444.          (default: 2*Länge des Strings).
  445.  
  446.  
  447.  
  448.                       Tabelle der Escape-Codes
  449.                       --------------------------
  450.  
  451.   \a    Beep            (ASCII 7)
  452.   \b    Backspace       (ASCII 8)
  453.   \c    Control Sequence Introducer CSI (ASCII 155)
  454.   \e    ESC             (ASCII 27)
  455.   \f    Formfeed        (ASCII 12)
  456.   \n    Newline         (ASCII 10)
  457.   \r    Carriage Return (ASCII 13)
  458.   \t    Tab             (ASCII 9)
  459.   \v    Vertical Tab    (ASCII 11)
  460.   \xNN  ASCII-Code NN (Hexadezimal)
  461.   \NNN  ASCII-Code NNN (Oktal)
  462.   \\    Backslash (\)
  463.  
  464. Ein Backslash ('\') am Ende der Zeile zeigt an, daß dieser String in der
  465. nächsten Zeile fortgesetzt wird.
  466.  
  467.  
  468.  
  469.                               Der Autor
  470.                               ---------
  471. Fragen, Bug-Reports oder sonstiges schicken Sie bitte an:
  472.  
  473.    Matthias Meixner
  474.    Sandberg 13
  475.    36145 Schwarzbach
  476.    Deutschland
  477.  
  478. oder EMail:
  479.    meixner@rbg.informatik.th-darmstadt.de
  480.  
  481.  
  482.  
  483.