[erledigt] Quelltexte portieren zwischen Linux und Windows

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
alfware17
Beiträge: 134
Registriert: Di 14. Dez 2010, 23:27

[erledigt] Quelltexte portieren zwischen Linux und Windows

Beitrag von alfware17 »

Hallo, ich habe ein kleines Verständnisproblem und eine mittelschwere Krise mit diesem UTF8-Krams.
Ich möchte Programme entwickeln in Windows (7,10,XP) und auch laufen lassen in Linux(Mint).
Mein Windows nutzt wohl CP1252 und sowohl Lazarus als auch FPC können die Umlaute "normal" nicht richtig darstellen,
da die meisten Pascal-Quelltexte noch aus Turbo-Pascal Zeiten stammen,
Beim Laufenlassen sind die Umlaute dann aber korrekt,
Für Linux habe ich mir ein Konvertierungsprogramm gebastelt, welches die Quelltexte dann one-way umwandelt
und dann wird es auch in Linux ordentlich dargestellt.
Im Batch (Konsole) noch mal wieder anders als im Online, zB meine Textviews oder Bedienelemente wandele ich
dann mit einer Funktion noch einmal in UTF8 um. So weit so gut oder schlecht.

Nun habe ich aber heute einen sehr sehr merkwürdigen Effekt gefunden. Ich dachte erst, ich habe die WIndows-Linux Konvertierung
vergessen und wiederholte das, die Umlaute blieben kryptisch. Letztlich fand ich heraus, es gibt einen Unterschied zwischen
writeln('Hallo ' + 'Änne') und writeln('Hallo ', 'Änne') jetzt mal vereinfacht ausgedrückt Komma statt Plus. Komma war richtig,
ich habe das für dieses Projekt schnell nachgesehen es wäre egal also repariert. Aber warum? Es kommen auch keine Hints oder
Warnings vom Compiler wegen String-Typen usw.

Schon leicht angesäuert und in Erinnerung einer Erfahrung in Java (gleiches Problem, nur daß ich da UTF8Cast nahm) wo ich Weihnachten
die grandiose Idee hatte, es doch einfach im UTF8 zu lassen und das geht sogar im Windows. Das wollte ich nun für Pascal auch:
also Quelle im Linux erfaßt, laufen lassen, über NTFS auf Windows zurück und dort auch Lazarus anbieten. Ergebnis: Die Quelle wird
noch richtig angezeigt aber es läuft nicht, die Umlaute sind falsch. Auch neu eingetippte Zeichen in dieses Quellfile sind anscheinend
schon "verseucht", denn nichts geht mehr. Wenn ich ein neues File nehme vom Scratch, gleicher Inhalt sind es 10 Bytes weniger und
es läuft mit korrekten Umlauten.

Ich hoffe Ihr seht mein Dilemma. Ich kann gern ein Beispiel bringen aber meine Frage bleibt generell: Wie macht Ihr das denn?
Wahrscheinlich stelle ich mich an wie der erste Mensch... Ich möchte doch nur möglichst einfach und unfallfrei die Umlaute in den
Strings und ggf Kommentaren sowohl in Linux wie auch in Windows in deutscher Schrift sehen. Klar kann ich mich auf Ascii Zeichen
kleiner als 128 beschränken. EIn Tip kam auch mal Unicodes (sowas mit slash oder backslash glaube ich aber weiß nicht wo dann?
im Windows? und verstehen das ggf. auch noch Linux und DOS dann?).
Vielleicht macht jemand von euch das schon jahrelang und es gibt eine best practice? Ich tue mich da unheimlich schwer,
bin aber gerne bereit neues anzunehmen. Das "eine große Ding" wie einfach UTF8 aus dem Linux in Windows verwenden wie bei
Java scheint es in Pascal nicht zu sein...
Zuletzt geändert von alfware17 am Mo 4. Mär 2024, 10:04, insgesamt 1-mal geändert.

alfware17
Beiträge: 134
Registriert: Di 14. Dez 2010, 23:27

Re: Quelltexte portieren zwischen Linux und Windows

Beitrag von alfware17 »

Vielleicht habe ich mich zu kompliziert ausgedrückt. Daher hier mal ein Beispiel/Lösungsansatz, der aber leider nicht funktioniert wie es soll.
Um das leidige Problem zu umgehen, daß meine Quelltextseiten schon Ansi/UTF8-codiert sind (ich glaube das hängt von 2 unsichtbaren Bytes am Anfang ab), wollte ich mich voll auf ASCII bis 128 und dann die CHR-Funktion konzentrieren
Folgendes Hauptprogramm

Code: Alles auswählen

program Unc21;

{$mode objfpc}{$H+}
{$I OsWahl.inc}

uses Unc;

begin
   Write('AE ' + UML(1));  Write(' '); Write(UML(1));  Write(' ' , UML(1));  Write(' ' + _AE2); Writeln(' ' , _AE2);
   Write('OE ' + UML(2));  Write(' '); Write(UML(2));  Write(' ' , UML(2));  Write(' ' + _OE2); Writeln(' ' , _OE2);
   Write('UE ' + UML(3));  Write(' '); Write(UML(3));  Write(' ' , UML(3));  Write(' ' + _UE2); Writeln(' ' , _UE2);
   Write('ae ' + UML(11)); Write(' '); Write(UML(11)); Write(' ' , UML(11)); Write(' ' + _ae);  Writeln(' ' , _ae);
   Write('oe ' + UML(12)); Write(' '); Write(UML(12)); Write(' ' , UML(12)); Write(' ' + _oe);  Writeln(' ' , _oe);
   Write('ue ' + UML(13)); Write(' '); Write(UML(13)); Write(' ' , UML(13)); Write(' ' + _ue);  Writeln(' ' , _ue);
   Write('sz ' + UML(0));  Write(' '); Write(UML(0));  Write(' ' , UML(0));  Write(' ' + _sz);  Writeln(' ' , _sz);
   Write('eu ' + UML(21)); Write(' '); Write(UML(21)); Write(' ' , UML(21)); Write(' ' + _eu);  Writeln(' ' , _eu);
   Write('gr ' + UML(22)); Write(' '); Write(UML(12)); Write(' ' , UML(22)); Write(' ' + _gr);  Writeln(' ' , _gr);
   Write('h2 ' + UML(23)); Write(' '); Write(UML(23)); Write(' ' , UML(23)); Write(' ' + _h2);  Writeln(' ' , _h2);
   Write('h3 ' + UML(24)); Write(' '); Write(UML(24)); Write(' ' , UML(24)); Write(' ' + _h3);  Writeln(' ' , _h3);
   Write('pg ' + UML(25)); Write(' '); Write(UML(25)); Write(' ' , UML(25)); Write(' ' + _pg);  Writeln(' ' , _pg);

   Writeln(zeichensatz1);
   Writeln(zeichensatz2);
   Writeln(_ae + _oe + _ue + _AE2 + _OE2 + _UE2 + _sz);
   Writeln(zeichensatz + _ae + _oe + _ue + _AE2 + _OE2 + _UE2 + _sz);
   Writeln(zeichensatz + _ae , _oe , _ue , _AE2 , _OE2 , _UE2 , _sz);
   Writeln(zeichensatz + _ae + _oe + _ue + _AE2 + _OE2 + _UE2 + _sz + _eu + _gr + _h2 + _h3 + _pg);
   Writeln(zeichensatz , _ae , _oe , _ue , _AE2 , _OE2 , _UE2 , _sz , _eu , _gr , _h2 , _h3 , _pg);
   Writeln(uml(1) + uml(2) + uml(3) + uml(11) + uml(12) + uml(13) + uml(0));
   Writeln(zeichensatz + uml(1) + uml(2) + uml(3) + uml(11) + uml(12) + uml(13) + uml(0));
   Writeln(zeichensatz + uml(1) , uml(2) , uml(3) , uml(11) , uml(12) , uml(13) , uml(0));
   Writeln(zeichensatz + uml(1) + uml(2) + uml(3) + uml(11) + uml(12) + uml(13) + uml(0) + _eu + _gr + _h2 + _h3 + _pg);
   Writeln(zeichensatz , uml(1) , uml(2) , uml(3) , uml(11) , uml(12) , uml(13) , uml(0) , _eu , _gr , _h2 , _h3 , _pg);

   Writeln('Wenn ich nur w' + _ue + _sz + 'te was ich falsch mache?');
   Writeln('Dann w' + _ae + 're ich ja sch', _oe, 'n zufrieden. ', _AE2, 'rgern tut mich das');
   Writeln(_OE2 + ' und ' + _UE2);
   Writeln('Menno mit Komma ', _oe , ' ich bin gar nicht bl' + _oe + 'd?');
   Writeln;
   Writeln('Wenn ich nur w' + uml(3) + uml(0) + 'te was ich falsch mache?');
   Writeln('Dann w' + uml(1) + 're ich ja sch', uml(2), 'n zufrieden. ', uml(11), 'rgern tut mich das');
   Writeln(uml(12) + ' und ' + uml(13));
   Writeln('Menno mit Komma ', uml(2), ' ich bin gar nicht bl' + uml(2) + 'd?');

   Readln;
end.

Und die zugehörige Unit

Code: Alles auswählen

UNIT Unc;

{$I OsWahl.inc}

{$IFDEF DOS} {$M 65520,0,655360} {$N+}
{$ELSE} {$mode objfpc} {$H-}
        {$IFDEF X86_64} {$MAXSTACKSIZE $7FFFFFF} {$ENDIF}
{$ENDIF}

INTERFACE

VAR zeichensatz, zeichensatz1, zeichensatz2,
    _ae, _oe, _ue, _AE2, _OE2, _UE2, _sz, _eu, _gr, _h2, _h3, _pg : STRING;

FUNCTION uml(nr: BYTE):STRING;
(* Umlaute ueber chr *)

IMPLEMENTATION

FUNCTION uml(nr: BYTE):STRING;
BEGIN
   CASE nr OF
     (* SZ CP850: E1/225 CP1252: DF/223 UTF8: C3+9F/195+159 *)
     0 : uml:={$IFDEF LINUX} chr(195) + chr(159) {$ELSE}
              '' + chr( {$IFDEF DOS} 225 {$ELSE} 223 {$ENDIF} ) {$ENDIF} ;

     (* AE CP850: 8E/142 CP1252: C4/196 UTF8: C3+84/195+132 *)
     1 : uml:={$IFDEF LINUX} chr(195) + chr(132) {$ELSE}
              '' + chr( {$IFDEF DOS} 142 {$ELSE} 196 {$ENDIF} ) {$ENDIF} ;

     (* OE CP850: 99/153 CP1252: D6/214 UTF8: C3+96/195+150 *)
     2 : uml:={$IFDEF LINUX} chr(195) + chr(150) {$ELSE}
              '' + chr( {$IFDEF DOS} 153 {$ELSE} 214 {$ENDIF} ) {$ENDIF} ;

     (* UE CP850: 9A/154 CP1252: DC/220 UTF8: C3+9C/195+156 *)
     3 : uml:={$IFDEF LINUX} chr(195) + chr(156) {$ELSE}
              '' + chr( {$IFDEF DOS} 154 {$ELSE} 220 {$ENDIF} ) {$ENDIF} ;

     (* ae CP850: 84/132 CP1252: E4/228 UTF8: C3+A4/195+164 *)
    11 : uml:={$IFDEF LINUX} chr(195) + chr(164) {$ELSE}
              '' + chr( {$IFDEF DOS} 132 {$ELSE} 228 {$ENDIF} ) {$ENDIF} ;

     (* oe CP850: 94/148 CP1252: F6/246 UTF8: C3+B6/195+182 *)
    12 : uml:={$IFDEF LINUX} chr(195) + chr(182) {$ELSE}
              '' + chr( {$IFDEF DOS} 148 {$ELSE} 246 {$ENDIF} ) {$ENDIF} ;

     (* ue CP850: 81/129 CP1252: FC/252 UTF8: C3+BC/195+188 *)
    13 : uml:={$IFDEF LINUX} chr(195) + chr(188) {$ELSE}
              '' + chr( {$IFDEF DOS} 129 {$ELSE} 252 {$ENDIF} ) {$ENDIF} ;

     (* eu CP850: 9D/157 CP1252: 80/128 UTF8: E2+82+AC/226+130+172 *)
    21 : uml:={$IFDEF LINUX} chr(226) + chr(130) + chr(172) {$ELSE}
              '' + chr( {$IFDEF DOS} 157 {$ELSE} 128 {$ENDIF} ) {$ENDIF} ;

     (* gr CP850: F2/242 CP1252: FC/248 UTF8: C2+B0/194+176 *)
    22 : uml:={$IFDEF LINUX} chr(194) + chr(176) {$ELSE}
              '' + chr( {$IFDEF DOS} 242 {$ELSE} 248 {$ENDIF} ) {$ENDIF} ;

     (* h2 CP850: F3/243 CP1252: FC/253 UTF8: C2+B2/194+178 *)
    23 : uml:={$IFDEF LINUX} chr(194) + chr(178) {$ELSE}
              '' + chr( {$IFDEF DOS} 243 {$ELSE} 253 {$ENDIF} ) {$ENDIF} ;

     (* h3 CP850: F8/248 CP1252: FC/252 UTF8: C2+B3/194+179 *)
    24 : uml:={$IFDEF LINUX} chr(194) + chr(179) {$ELSE}
              '' + chr( {$IFDEF DOS} 248 {$ELSE} 252 {$ENDIF} ) {$ENDIF} ;

     (* pg CP850: A7/167 CP1252: FC/245 UTF8: C2+A7/194+167 *)
    25 : uml:={$IFDEF LINUX} chr(194) + chr(167) {$ELSE}
              '' + chr( {$IFDEF DOS} 167 {$ELSE} 245  {$ENDIF} ) {$ENDIF} ;
    ELSE uml:='';
   END
END;

BEGIN
  _ae:= uml(1);
  _oe:= uml(2);
  _ue:= uml(3);
  _AE2:=uml(11);
  _OE2:=uml(12);
  _UE2:=uml(13);
  _sz:= uml(0);
  _eu:= uml(21);
  _gr:= uml(22);
  _h2:= uml(23);
  _h3:= uml(24);
  _pg:= uml(25);
  zeichensatz:= 'ABCDEFGHIJKLMNOPQRSTUVWXYYZabcdefghijklmnopqrstuvwxyz1234567890!"$%&/()=?`[]{}\+*~''#,.-;:_<>|';
  zeichensatz1:=zeichensatz + _ae + _oe + _ue + _AE2 + _OE2 + _UE2 + _sz + _eu + _gr + _h2 + _h3 + _pg;
  zeichensatz2:=zeichensatz + uml(1)+ uml(2)+ uml(3)+ uml(11)+ uml(12)+ uml(13)+ uml(0) + _eu + _gr + _h2 + _h3 + _pg;
END.
Die Codes habe ich selbst zusammengestellt und sollten so stimmen, mit Linux und 16bit habe ich auch schon probiert,
einzeln geht oft/meistens alles aber das Problem mit den Kommas oder Plus macht mich fertig. Vielleicht ist es ein dummer
Anfängerfehler... Der Typ String der uml-Funktion macht mir natürlich Bauchschmerzen aber wie soll ich sonst regeln, daß es im
Linux eben 2 bzw 3 Bytecodes sind?

Hat jemand einen Tip? Oder gehe ich generell falsch an die Sache heran?
Dateianhänge
unc21.zip
(36.65 KiB) 60-mal heruntergeladen

Benutzeravatar
theo
Beiträge: 10499
Registriert: Mo 11. Sep 2006, 19:01

Re: Quelltexte portieren zwischen Linux und Windows

Beitrag von theo »

Hattest du das nicht so ähnlich schon mal gefragt?
viewtopic.php?t=12779

CCRDudeLaz
Beiträge: 29
Registriert: Do 25. Jan 2024, 08:33
OS, Lazarus, FPC: Win/macOS/Linux (L trunk FPC trunk)
CPU-Target: 32+64

Re: Quelltexte portieren zwischen Linux und Windows

Beitrag von CCRDudeLaz »

Keine direkte Antwort, aber eine Erklärung, warum das bei mir nicht auftritt: ich formuliere alles in Englisch. Lokalisierung in's Deutsche kommt das später über i18n zur Laufzeit. Damit gibt's dann keine Umlautprobleme mehr :)

Die unsichtbaren Bytes sind der BOM (Byte Order Marker).

Evtl. suchst Du {$codepage ...}?

alfware17
Beiträge: 134
Registriert: Di 14. Dez 2010, 23:27

Re: Quelltexte portieren zwischen Linux und Windows

Beitrag von alfware17 »

theo hat geschrieben:
Do 25. Jan 2024, 22:50
Hattest du das nicht so ähnlich schon mal gefragt?
viewtopic.php?t=12779
Ja habe ich und eure Tips damals auch ausprobiert. Letztlich habe ich mir dann einen Konverter ANSI-UTF8 geschrieben.
Die Quellseiten in UTF8 umzuformatieren ist leider für mich nicht hilfreich, da ich dann den Rückweg zum 16bit/DOS verliere.

Ich habe jetzt ein paar kleine Fehlerchen in meinen Codetabellen bereinigt und kann mit der chr-Funktion in CP850/437, 1252 und im UTF8 ausgeben,.
Nur ausgerechnet das € Zeichen nicht, weiß nicht was das ist, habe alles probiert mit SetConsoleCP und SetConsoleOutputCP (Effekt gleich?).
Da mich das nervt werde ich eben E EU oder EUR ausgeben, wenn das so schwierig scheint.

In meinen Programmkommentaren kann ich auch die _sz oder _AE2 usw benutzen genauso wie in den Stringkonstanten für das Writeln.

Das einzige was mir unklar bleibt - warum gibt es einen Unterschied zwischen Writeln('Hallo ' + 'Änne') (richtige Ausgabe) und
Writeln('Hallo ', 'Änne') (falsche Ausgabe IMMER mit Komma). Ja schon, Writeln ist eine generische Funktion (heißt das so),
1-n Parameter. Aber was hat das mit den Codepages bzw Zeichensätzen zu tun?!

Antworten