DEADSOFTWARE

00a7935d943d72e04a795f1e86d35f537638d2cb
[cpc.git] / src / posix / generic / Host / Mod / Lang.cp
1 MODULE HostLang;
3 IMPORT S := SYSTEM, Kernel, stdlib := C99stdlib, locale := C99locale,
4 iconv := C99iconv, errno := C99errno, macro := C99macro;
6 CONST
7 maxLen = 32;
9 VAR
10 lang-, country-, encoding-: ARRAY maxLen OF CHAR;
11 c2sc, sc2c, invalid: iconv.iconv_t;
13 (* PEP 383 *)
15 PROCEDURE StringToHost* (IN in: ARRAY OF CHAR; OUT out: ARRAY OF SHORTCHAR; low: BOOLEAN; OUT res: INTEGER);
16 VAR i, j, err: INTEGER; maxlen, len, count: iconv.size_t; inadr, outadr: Kernel.ADDRESS; ch: SHORTCHAR;
17 BEGIN
18 ASSERT(c2sc # invalid, 100);
19 i := 0; err := 0;
20 outadr := S.ADR(out[0]);
21 maxlen := LEN(out) - 1;
22 WHILE (err = 0) & (in[i] # 0X) DO
23 j := i;
24 WHILE (in[i] # 0X) & ((in[i] < 0D800X) OR (in[i] > 0D8FFX)) DO INC(i) END;
25 len := (i - j) * 2;
26 WHILE (err = 0) & (len > 0) & (maxlen > 0) DO
27 inadr := S.ADR(in[j]);
28 count := iconv.iconv(c2sc, inadr, len, outadr, maxlen);
29 IF count # 0 THEN
30 CASE macro.errno() OF
31 | errno.EILSEQ:
32 (* !!! HALT(101)*) (* invalid input char *)
33 IF maxlen < 1 THEN
34 err := 1
35 ELSE
36 ch := "?";
37 S.PUT(outadr, ch); INC(outadr); DEC(maxlen);
38 INC(j); DEC(len, 2)
39 END
40 | errno.E2BIG: err := 1 (* unexpected end of out *)
41 | errno.EINVAL: HALT(102) (* unexpected end of input *)
42 | errno.EBADF: HALT(103) (* invalid iconv descriptor *)
43 ELSE HALT(104) (* unknown error *)
44 END
45 END
46 END;
47 WHILE (err = 0) & (in[i] >= 0D800X) & (in[i] <= 0D8FFX) DO
48 IF maxlen < 1 THEN
49 err := 1
50 ELSE
51 ch := SHORT(CHR(ORD(in[i]) MOD 256));
52 IF low OR (ch > 7FX) THEN
53 S.PUT(outadr, ch); INC(outadr); DEC(maxlen);
54 INC(i)
55 ELSE
56 err := 3 (* invalid char *)
57 END
58 END
59 END
60 END;
61 ch := 0X;
62 S.PUT(outadr, ch);
63 res := err
64 END StringToHost;
66 PROCEDURE HostToString* (IN in: ARRAY OF SHORTCHAR; OUT out: ARRAY OF CHAR; low: BOOLEAN; OUT res: INTEGER);
67 VAR err: INTEGER; maxin, maxout, count: iconv.size_t; inadr, outadr: Kernel.ADDRESS; sch: SHORTCHAR; ch: CHAR;
68 BEGIN
69 ASSERT(sc2c # invalid, 100);
70 err := 0;
71 inadr := S.ADR(in[0]);
72 outadr := S.ADR(out[0]);
73 maxin := LEN(in$); maxout := LEN(out) * 2 - 2;
74 WHILE (err = 0) & (maxout > 1) & (maxin > 0) DO
75 count := iconv.iconv(sc2c, inadr, maxin, outadr, maxout);
76 IF count # 0 THEN
77 CASE macro.errno() OF
78 | errno.EILSEQ, errno.EINVAL, errno.E2BIG:
79 IF maxout < 2 THEN
80 err := 1 (* unexpected end of output buffer *)
81 ELSIF maxin < 1 THEN
82 err := 2 (* unexpected end of input buffer *)
83 ELSE
84 S.GET(inadr, sch); INC(inadr); DEC(maxin);
85 ch := CHR(0D800H + ORD(sch));
86 IF low OR (ch > 7FX) THEN
87 S.PUT(outadr, ch); INC(outadr, 2); DEC(maxout, 2)
88 ELSE
89 err := 3 (* invalid char *)
90 END
91 END
92 | errno.EBADF: HALT(101)
93 ELSE HALT(102)
94 END
95 END
96 END;
97 ch := 0X;
98 S.PUT(outadr, ch);
99 res := err
100 END HostToString;
102 PROCEDURE Init;
103 VAR p: POINTER TO ARRAY [untagged] OF SHORTCHAR; i, j: INTEGER; enc: ARRAY 32 OF SHORTCHAR;
104 BEGIN
105 invalid := S.VAL(iconv.iconv_t, -1);
106 p := locale.setlocale(locale.LC_ALL, "");
107 IF p = NIL THEN
108 p := stdlib.getenv("LANG");
109 IF p = NIL THEN
110 p := ""
111 END
112 END;
113 i := 0; j := 0;
114 WHILE (p[i] # 0X) & (p[i] # "_") & (p[i] # ".") DO
115 lang[j] := p[i];
116 INC(i); INC(j)
117 END;
118 lang[j] := 0X;
119 IF p[i] = "_" THEN
120 INC(i); j := 0;
121 WHILE (p[i] # 0X) & (p[i] # ".") DO
122 country[j] := p[i];
123 INC(i); INC(j)
124 END;
125 country[j] := 0X
126 END;
127 enc := "ASCII";
128 IF p[i] = "." THEN
129 INC(i); j := 0;
130 WHILE p[i] # 0X DO
131 enc[j] := p[i];
132 INC(i); INC(j)
133 END;
134 enc[j] := 0X
135 END;
136 IF (lang = "C") OR (lang = "POSIX") THEN
137 lang := ""
138 END;
139 sc2c := invalid; c2sc := invalid;
140 IF Kernel.littleEndian THEN sc2c := iconv.iconv_open("UCS-2LE", enc)
141 ELSE sc2c := iconv.iconv_open("UCS-2BE", enc)
142 END;
143 IF sc2c = invalid THEN enc := "ASCII";
144 IF Kernel.littleEndian THEN sc2c := iconv.iconv_open("UCS-2LE", enc)
145 ELSE sc2c := iconv.iconv_open("UCS-2BE", enc)
146 END;
147 ASSERT(c2sc # invalid, 100) (* ascii to ucs2 not supported? *)
148 END;
149 IF Kernel.littleEndian THEN c2sc := iconv.iconv_open(enc, "UCS-2LE")
150 ELSE c2sc := iconv.iconv_open(enc, "UCS-2BE");
151 END;
152 ASSERT(c2sc # invalid, 101); (* ucs2 to ascii not supported? *)
153 encoding := enc$
154 END Init;
156 (**
157 Do not close iconv descriptors!
158 It can lead to quiet traps on program termination and bugs like
159 not removed temp files.
160 **)
162 BEGIN
163 Init
164 END HostLang.