Autor Nachricht
hydemarie

(Threadstarter)
BeitragVerfasst: Mo 31.10.16 18:45

Nota bene: COBOL-in-JavaScript-Compiler. 8)
Antworten mit Zitat
hydemarie

(Threadstarter)
BeitragVerfasst: Fr 29.07.16 21:47

FastCGI-Fallstrick:

Ist mir hinterher erst aufgefallen, vielleicht aber auch in anderem Kontext (etwa für FastCGI mit Delphi) interessant: Unter Umständen sucht FastCGI am Anfang der Ausgabe eines Programms nach den HTTP-Headern. Es funktioniert auch ohne, dann wird aber möglicherweise die erste Ausgabezeile nicht geparst.

Richtig wäre also (gemäß RFC 2616):

anzeigen Quelltext
   


Solltet ihr dieses Problem auch haben: Hier ist eine (vielleicht nicht die kürzeste) der möglichen Lösungen.

anzeigen Quelltext
   


Das Literal '0D' steht hierbei für den "Carriage Return", '0A' für "Line Feed".
Antworten mit Zitat
hydemarie

(Threadstarter)
BeitragVerfasst: Fr 29.07.16 11:17

Heute machen wir mal etwas lustiges, heute programmieren wir eine Website in COBOL.

So genannte Single Serving Sites habt ihr bestimmt schon mal gesehen, das sind im Wesentlichen Ein-Seiten-Websites, die nur einen einzigen bestimmten Zweck erfüllen, zum Beispiel purple.com, das euch zeigt, was Lila ist, und hasthelargehadroncol...royedtheworldyet.com. Ihr seht: Das ist unter Umständen durchaus sinnvoll. Es muss nicht immer ein CMS sein.

COBOL (Common Business Oriented Language) ist eine 1960 erstmals standardisierte Programmiersprache, die seit ihrer ersten Version zusammen mit Fortran (früher: FORTRAN, Formula Translator) die Weltwirtschaft beherrscht und bis heute aktiv weiterentwickelt wird. Wer schon mal eine Bank von innen gesehen hat, der ahnt, dass eine Menge Logik nötig ist, um ein Konto zu verwalten. Es wäre Irrsinn, diese Logik, wenn sie einmal funktioniert, in einer anderen Sprache neu zu programmieren, nur weil die alte Sprache nicht mehr im Trend liegt. Das bedeutet, dass Unternehmen mit viel Geld dringend Leute suchen, die Software pflegen sollen, die mitunter älter ist als diejenigen, die sie derzeit entwickeln. Ihr ahnt, warum es interessant sein kann, mal was mit COBOL gemacht zu haben. Und was liegt näher als eine Webanwendung in einer solch rustikalen Sprache zu schreiben?

Eben.

Um ein praxistaugliches Beispiel zu haben: Nehmen wir an, ihr wollt eine Website namens "HalloWelt.coffee" (ist tatsächlich noch frei) erstellen, die deutschsprachige Benutzer mit "Hallo Welt!", anderssprachige Benutzer aber mit "Hello World!" begrüßt. Ein alltägliches Problem, nicht wahr?

Damit ihr anfangen könnt, braucht ihr zunächst einmal ein wenig Software:

  • Einen FastCGI-tauglichen Webspace oder Webserver. (Wenn ihr das nicht so genau wisst, fragt euren Hoster. Wenn euer Hoster kein FastCGI anbietet, habt ihr einen schlechten Hoster. Wenn ihr einen schlechten Hoster habt, besorgt euch bitte einen besseren und lest dann hier weiter.) Ich empfehle Uberspace.
  • GnuCOBOL oder einen anderen COBOL-Compiler. Es gibt höchstwahrscheinlich auch einen für euer Betriebssystem (wenn ihr nicht gerade RISC OS oder TempleOS einsetzt). Das Kompilat muss später auf eurem Webspace oder Webserver lauffähig sein, wenn ihr also zum Beispiel einen Linux-Webserver habt, müsst ihr auch ein GnuCOBOL unter Linux benutzen. Unter den meisten GNU/Linux-Distributionen und den "großen" BSDs ist GnuCOBOL auch über euren Paketmanager verfügbar.
  • Einen Texteditor, am besten einen, der COBOL-Highlighting beherrscht. Notepad funktioniert aber auch. Ihr werdet sehen, dass Highlighting für COBOL nicht so wichtig ist. Unter welchem System ihr den Code schreibt, ist egal, so lange ihr ihn später unter dem "richtigen" System kompiliert.


Erstellt nun mit besagtem Texteditor eine neue Datei namens hallowelt.cob (oder hallowelt.cbl, da gibt es keine einheitliche Norm). Wir fangen klein an, wir geben erst mal nur den HTML-Code für die Website aus. Wie ihr den dann in eurem Browser anzeigen könnt, erkläre ich euch weiter unten.

anzeigen Quelltext
   


Ihr seht: COBOL ist eine hübsche Sprache, man versteht sie eigentlich sofort. COBOL-Befehle könnt ihr inzwischen auch in normaler Schreibweise benutzen, also zum Beispiel "Display" statt "DISPLAY", ihr müsst den Code also nicht so "brüllen" wie im Beispiel. Ich finde es so aber übersichtlicher, damit man auch in Editoren, die kein COBOL-Highlighting können, Variablennamen und Strings optisch besser von Anweisungen unterscheiden kann.

Allerdings fängt das Programm absichtlich "eingerückt" an. Die Aufteilung in Spalten hat historische Gründe: COBOL stammt aus einer Zeit, in der man noch "zweidimensional" auf Lochkarten programmiert hat, die ersten sieben Spalten waren dort etwa für die Zeilennummer reserviert. Zwar ist auch die "Freiform" - also das Abweichen von der Lochkartenformatierung, in der das Programm in Spalte 8 anfangen muss, Kommentare mit einem "*" in Spalte 7 eingeleitet werden müssen und so weiter - inzwischen Teil des Standards, aber viele Texteditoren, die COBOL-Highlighting beherrschen, legen Wert darauf, dass ihr ebenfalls wenigstens ein bisschen konservativ programmiert, sonst funktioniert das Highlighting nicht richtig. Wenn ihr euch das von Anfang an angewöhnt, werdet ihr es später auch leichter mit fremdem Code haben, der sich in der Regel an die Konventionen hält. Übrigens: Ein Zeilenumbruch am Ende (den dieses Forum anscheinend verschluckt?) ist zwar nicht zwingend notwendig, wird aber gern gesehen. GnuCOBOL beschwert sich auch, wenn ihr ihn weglasst.

Wenn ihr diesen Code jetzt kompiliert ...

anzeigen Quelltext
   


..., bekommt ihr nach einer kurzen Wartezeit ein Programm namens "hallowelt.exe" (oder, wenn ihr auf einem unixoiden Computer arbeitet, "hallowelt") heraus, das nach dem Ausführen den gewünschten HTML-Code ausgibt:

Erstes_Kompilat

(Wenn sich cobc beim Kompilierversuch beschwert, dass es cl.exe nicht finden kann, benutzt ihr offenbar die Windowsversion. Die Windowsversion sucht Microsofts C-Compiler, zum Beispiel aus der Visual-Studio-Community-Edition, in eurem %PATH%. GnuCOBOL wandelt COBOL-Code als Zwischenschritt in C-Code um, wenn ihr also bereits C könnt, kann euch GnuCOBOL auf Wunsch auch nur den erzeugten C-Code ausgeben, den ihr dann weiterbearbeiten und selbst kompilieren könnt. Wenn ihr stattdessen einen anderen C-Compiler nutzen möchtet, müsst ihr GnuCOBOLs defaults.h.tmpl anpassen und GnuCOBOL neu kompilieren. Nehmt also lieber cl.exe.)

Nun ist das natürlich noch recht langweilig, denn dafür hättet ihr kein COBOL gebraucht. Wie kriegt ihr denn überhaupt das Programm ins Web und wie kriegt ihr das mit der Mehrsprachigkeit hinein?

Die Lösung heißt FastCGI.

FastCGI ist heute so was wie "ein Standard", es ist nicht unwahrscheinlich, dass auch eure PHP-basierte Website (ihr habt doch sicher eine PHP-basierte Website? Jeder hat eine PHP-basierte Website! ;)) unter FastCGI läuft. Stark vereinfacht heißt das, dass euer Webserver bei der Abfrage nach "*.php" das zugeordnete Programm, eben den PHP-Interpreter, aufruft und das Ergebnis, also eure "generierte" Website, zurückschickt. Der Trick: Statt eines PHP-Interpreters könnt ihr auch ein beliebiges anderes Programm starten, etwa ein Perlscript, ein C-Programm oder eben euer "hallowelt".

Ab hier müsst ihr also auf eurem Server/Webspace weitermachen.

  • Wenn ihr bei Uberspace seid, erklärt euch deren Wiki, wie ihr FastCGI einrichtet und nutzt. Das FastCGI-Programm ist in diesem Fall euer kompiliertes "hallowelt".
  • Auf einem OpenBSD-Server sind folgende zwei Einträge unter server "hallowelt.coffee" nötig:

    Zitat:
    root "/irgendein/pfad/hallowelt"
    fastcgi

  • Unter Apache braucht ihr mod_fcgid, dann könnt ihr in eurer httpd.conf das "hallowelt"-Programm einfach als Handler festlegen. (Wenn ihr Hilfe braucht: Entschuldigt - Apache habe ich schon zu lange nicht mehr so wirklich benutzt.)
  • Unter nginx müsst ihr nur die location ändern, indem ihr mindestens die "root"-Direktive sowie die beiden FastCGI-Parameter "SCRIPT_FILENAME" und "SCRIPT_NAME" (beide müssen auf euer "hallowelt" zeigen) einfügt.


Keine Sorge - das sieht nur so kompliziert aus. Wenn alles so weit funktioniert hat, solltet ihr beim Aufruf eurer Website ein großes "Hallo Welt!" sehen. Wenn nicht, habt ihr etwas falsch eingestellt. ;)

FastCGI gibt also die Ausgabe des zugeteilten Scripts/Programms zurück. Es macht aber noch mehr: Beim Aufruf übergibt es ein paar Umgebungsvariablen (PHP-Programmierern vielleicht als $_SERVER[] bekannt) an das aufgerufene Script, darunter HTTP_ACCEPT_LANGUAGE, in das euer Browser ungefähr so was reinschreibt:

Zitat:
de,de-DE,de-AT;q=0.8,fr;q=0.6,en-US;q=0.4


Das ist die Liste eurer "bevorzugten" Sprachen mit ihren Prioritäten, in den meisten Browsern könnt ihr die einfach einstellen. Fest steht: Die ersten 2 Zeichen dieses Wertes sind höchstwahrscheinlich die Muttersprache desjenigen, der gerade den Browser bedient. Und damit genau das, was wir brauchen!

So, wie kriegen wir das jetzt in unser COBOL-Programm hinein? Um das zu verstehen, müsst ihr Variablen verstehen. Variablen werden in COBOL traditionell (ähnlich wie z.B. unter Delphi) oberhalb des eigentlichen Programmcodes (PROCEDURE DIVISION) definiert, nämlich in der DATA DIVISION. Unterschieden werden hier der "local storage" (Variablen, die für jede Programminstanz definiert werden) und der "working storage" (jede Instanz greift auf dieselben Variablen zurück). Da so eine Website ja durchaus für mehrere Benutzer gleichzeitig funktionieren sollte, greifen wir hier auf den "local storage" zurück.

Der COBOL-Datentyp für Zeichenketten - denn damit wollen wir hier arbeiten - ist das PICTURE, kurz "PIC". Unterschieden wird im Wesentlichen zwischen alphabetischen Zeichenketten (A), alphanummerischen Zeichenketten (X), "nationalen" Zeichenketten mit erweitertem Zeichensatz (N), nummerischen Zeichenketten (9) und booleschen Werten (1). Da COBOL nicht nur die Datenlogik, sondern auch die Datenbank selbst enthalten kann, besteht auch die Möglichkeit, Zeichenketten zu gruppieren, etwa "Vorname und Nachname" als "Vollständiger Name" zusammenzufassen; aber dies würde hier den Rahmen sprengen.

Wir brauchen höchstens drei Variablen auf der ersten Ebene:

  1. Liste aller Sprachen: Eine Zeichenkette von, sagen wir, höchstens 75 Zeichen Länge, in der wir das Ergebnis von HTTP_ACCEPT_LANGUAGE zwischenspeichern können.
  2. Hauptsprache: Eine Zeichenkette von zwei Zeichen Länge, in der dann entweder "de" oder eben etwas völlig anderes steht.
  3. Ausgabetext: Der Ausgabetext (also "Hallo Welt!", "Hello World!" oder etwas völlig anderes). Warum wir diese Variable berücksichtigen sollten, werdet ihr noch sehen.


Über der "PROCEDURE DIVISION" ist nun also folgender Code einzufügen:

anzeigen Quelltext
   


Der erste Teil des Programmcodes ist bis zum <h1> identisch, aber wir wollen ja nach dem <h1> einen Text einfügen, der von einer anderen Variable abhängt. Ändert also folgende Zeile

anzeigen Quelltext
   


wie folgt:

anzeigen Quelltext
   


"WITH NO ADVANCING" sorgt dafür, dass am Ende kein Zeilenumbruch eingefügt wird. Das ist technisch gesehen zwar egal, sieht hinterher im generierten Code aber schöner aus.

Jetzt können wir die Umgebungsvariable HTTP_ACCEPT_LANGUAGE, die wir von FastCGI "bekommen" haben, auslesen und in unsere Variable "alle-sprachen" schreiben:

anzeigen Quelltext
   


Was passiert hier? Es wird per ACCEPT (unter C++ wäre das ungefähr cin) in die Variable "alle-sprachen" das Ergebnis der Umgebungsvariable "HTTP_ACCEPT_LANGUAGE" geschrieben. Deren erste zwei Zeichen (2 Zeichen ab Zeichen 1) werden anschließend in "hauptsprache" gespeichert.

Jetzt hat die Variable "hauptsprache" drei mögliche Werte: "Leer" beziehungsweise "nicht definiert" (FastCGI hat keine HTTP_ACCEPT_LANGUAGE gesendet), "de" oder etwas völlig anderes. Das ist genau das, was wir brauchen. Mit einem einfachen Vergleich dieser Variablen können wir jetzt den richtigen Text herausfinden:

anzeigen Quelltext
   


Natürlich könnt ihr den Text auch einfach ändern. :)

Nun, warum "MOVE" und nicht gleich "DISPLAY"? Das hat kosmetische Gründe: COBOL füllt ein PICTURE immer bis zur maximalen Länge auf, im HTML-Code stünde also ungefähr so etwas:

anzeigen Quelltext
   


Das ist nun nicht schlimm, aber wir sind ja bekanntlich allesamt Perfektionisten hier. Zum Glück beherrscht GnuCOBOL wie auch andere COBOL-Compiler die intrinsische Funktion trim(), die wir einfach nutzen können, um Leerzeichen am Ende "abzuschneiden". Das sieht zwar im COBOL-Umfeld etwas merkwürdig aus (es werden Klammern benutzt!), aber es spart uns eine Menge Bastelei. (Natürlich würde das auch mit etwas Bastelei hinzukriegen sein, aber warum das Rad neu erfinden?)

anzeigen Quelltext
   


Hinter dem <h1> steht nun also eine zurechtgekürzte Version eures Ausgabetextes - wiederum ohne weiteren Zeilenumbruch. Alles Weitere bleibt wie bisher: </h1> schließen, Rest auch schließen. Hier einmal die vollständige Version mit ein paar Kommentaren:

anzeigen reduzierte Höhe Quelltext
   


Wenn ihr das Programm jetzt noch einmal kompiliert und lokal ausführt, ist das Ergebnis natürlich merkwürdig:

H4CK0RZ

Klar: Ohne Webserver kein HTTP_ACCEPT_LANGUAGE. Versuchen wir es doch mal hinter unserem FastCGI:

HalloWelt

Tatah!

Alles Weitere überlasse ich euch. Ihr wollt eine "richtige" Website mit Routing und allem? Das ist gar kein Problem.

Diese Anleitung ist übrigens das Ergebnis von einem Tag mit COBOL. Wenn hier jemand mit mehr Erfahrung reinguckt: Entschuldigung! Ergänzungen sind gern gesehen. Sicherlich werde ich auch noch besser.
Antworten mit Zitat

Entwickler-Ecke.de rev.276b99aea638 based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2024 by Christian Stelzmann Alle Rechte vorbehalten.