DEADSOFTWARE

added conversion modes in HostLang
[cpc.git] / src / posix / generic / Host / Mod / Lang.cp
index 836888e49fbb91da14fc49d14638785bd4aab361..c3b60a2b1a4b169740001bb83ac3f95d792f7bd0 100644 (file)
@@ -6,15 +6,17 @@ MODULE HostLang;
   CONST
     maxLen = 32;
 
+    (* modes *)
+    replace* = 0; pep383x* = 1; pep383* = 2;
+
   VAR
     lang-, country-, encoding-: ARRAY maxLen OF CHAR;
     c2sc, sc2c, invalid: iconv.iconv_t;
 
-  (* PEP 383 *)
-
-  PROCEDURE StringToHost* (IN in: ARRAY OF CHAR; OUT out: ARRAY OF SHORTCHAR; low: BOOLEAN; OUT res: INTEGER);
-    VAR i, j, err: INTEGER; maxlen, len, count: iconv.size_t; inadr, outadr: Kernel.ADDRESS; ch: SHORTCHAR;
+  PROCEDURE StringToHost* (IN in: ARRAY OF CHAR; OUT out: ARRAY OF SHORTCHAR; mode: INTEGER; OUT res: INTEGER);
+    VAR i, j, err: INTEGER; maxlen, len, count: iconv.size_t; inadr, outadr: Kernel.ADDRESS; sch: SHORTCHAR;
   BEGIN
+    ASSERT(mode IN {replace..pep383}, 20);
     ASSERT(c2sc # invalid, 100);
     i := 0; err := 0;
     outadr := S.ADR(out[0]);
@@ -29,18 +31,21 @@ MODULE HostLang;
         IF count # 0 THEN
           CASE macro.errno() OF
           | errno.EILSEQ:
-               (* !!! HALT(101)*) (* invalid input char *)
-               IF maxlen < 1 THEN
-                 err := 1
+               IF mode = replace THEN
+                 IF maxlen < 1 THEN
+                   err := 1
+                 ELSE
+                   sch := "?";
+                   S.PUT(outadr, sch); INC(outadr); DEC(maxlen);
+                   INC(j); DEC(len, 2)
+                 END
                ELSE
-                 ch := "?";
-                 S.PUT(outadr, ch); INC(outadr); DEC(maxlen);
-                 INC(j); DEC(len, 2)
-               END
+                 err := 3
+               END;
           | errno.E2BIG: err := 1 (* unexpected end of out *)
-          | errno.EINVAL: HALT(102) (* unexpected end of input *)
-          | errno.EBADF: HALT(103) (* invalid iconv descriptor *)
-          ELSE HALT(104) (* unknown error *)
+          | errno.EINVAL: HALT(101) (* unexpected end of input *)
+          | errno.EBADF: HALT(102) (* invalid iconv descriptor *)
+          ELSE HALT(103) (* unknown error *)
           END
         END
       END;
@@ -48,24 +53,25 @@ MODULE HostLang;
         IF maxlen < 1 THEN
           err := 1
         ELSE
-          ch := SHORT(CHR(ORD(in[i]) MOD 256));
-          IF low OR (ch > 7FX) THEN
-            S.PUT(outadr, ch); INC(outadr); DEC(maxlen);
+          sch := SHORT(CHR(ORD(in[i]) MOD 256));
+          IF (mode IN {replace, pep383x}) OR (sch > 7FX) THEN
+            S.PUT(outadr, sch); INC(outadr); DEC(maxlen);
             INC(i)
           ELSE
-            err := 3 (* invalid char *)
+            err := 3
           END
         END
       END
     END;
-    ch := 0X;
-    S.PUT(outadr, ch);
+    sch := 0X;
+    S.PUT(outadr, sch);
     res := err
   END StringToHost;
 
-  PROCEDURE HostToString* (IN in: ARRAY OF SHORTCHAR; OUT out: ARRAY OF CHAR; low: BOOLEAN; OUT res: INTEGER);
+  PROCEDURE HostToString* (IN in: ARRAY OF SHORTCHAR; OUT out: ARRAY OF CHAR; mode: INTEGER; OUT res: INTEGER);
     VAR err: INTEGER; maxin, maxout, count: iconv.size_t; inadr, outadr: Kernel.ADDRESS; sch: SHORTCHAR; ch: CHAR;
   BEGIN
+    ASSERT(mode IN {replace..pep383}, 20);
     ASSERT(sc2c # invalid, 100);
     err := 0;
     inadr := S.ADR(in[0]);
@@ -81,9 +87,13 @@ MODULE HostLang;
             ELSIF maxin < 1 THEN
               err := 2 (* unexpected end of input buffer *)
             ELSE
-              S.GET(inadr, sch); INC(inadr); DEC(maxin);
-              ch := CHR(0D800H + ORD(sch));
-              IF low OR (ch > 7FX) THEN
+              IF mode = replace THEN
+                sch := "?"; ch := "?"; INC(inadr); DEC(maxin);
+              ELSE
+                S.GET(inadr, sch); INC(inadr); DEC(maxin);
+                ch := CHR(0D800H + ORD(sch));
+              END;
+              IF (mode IN {replace, pep383x}) OR (sch > 7FX) THEN
                 S.PUT(outadr, ch); INC(outadr, 2); DEC(maxout, 2)
               ELSE
                 err := 3 (* invalid char *)
@@ -153,15 +163,12 @@ MODULE HostLang;
     encoding := enc$
   END Init;
 
-  PROCEDURE Fin;
-    VAR res: iconv.int;
-  BEGIN
-    res := iconv.iconv_close(sc2c); sc2c := invalid;
-    res := iconv.iconv_close(c2sc); c2sc := invalid
-  END Fin;
+  (**
+    Do not close iconv descriptors!
+    It can lead to quiet traps on program termination and bugs like
+    not removed temp files.
+  **)
 
 BEGIN
   Init
-CLOSE
-  Fin
 END HostLang.