浏览代码

HostLang: Dialog.LanguageHook implementation and LANG environment variable support

Alexander Shiryaev 12 年之前
父节点
当前提交
207e27a87e

二进制
BlackBox/Linux/Host/Mod/Console.odc


+ 3 - 37
BlackBox/Linux/Host/Mod/Console.txt

@@ -9,7 +9,7 @@ MODULE HostConsole;
 		Console implementation for Linux
 	*)
 
-	IMPORT SYSTEM, Console, Libc := LinLibc, Codecs := EncCodecs;
+	IMPORT SYSTEM, Console, Libc := LinLibc, Codecs := EncCodecs, HostLang;
 
 	CONST
 		defEnc = "ASCII";
@@ -23,38 +23,6 @@ MODULE HostConsole;
 		e: Codecs.Encoder;
 		d: Codecs.Decoder;
 
-	PROCEDURE GetEnc (OUT enc: Codecs.Encoding);
-		VAR lang: Libc.PtrSTR;
-			i, j: INTEGER;
-	BEGIN
-		lang := Libc.getenv("LANG");
-		IF lang # NIL THEN
-			IF lang$ = "C" THEN
-				enc := "ASCII"
-			ELSE
-				i := 0; WHILE (lang[i] # 0X) & (lang[i] # '.') DO INC(i) END;
-				IF lang[i] # 0X THEN
-					INC(i);
-					j := 0;
-					WHILE (j < LEN(enc) - 1) & (lang[i] # 0X) DO
-						enc[j] := lang[i];
-						INC(j);
-						INC(i)
-					END;
-					IF j < LEN(enc) - 1 THEN
-						enc[j] := 0X
-					ELSE
-						enc := defEnc
-					END
-				ELSE
-					enc := defEnc
-				END
-			END
-		ELSE
-			enc := defEnc
-		END
-	END GetEnc;
-
 	PROCEDURE (cons: Cons) ReadLn (OUT s: ARRAY OF CHAR);
 		CONST
 			maxLineLen = 1023; (* without null terminating shortchar *)
@@ -145,12 +113,10 @@ MODULE HostConsole;
 	END WriteLn;
 
 	PROCEDURE Init;
-		VAR enc: Codecs.Encoding;
 	BEGIN
 		IF Codecs.dir # NIL THEN
-			GetEnc(enc);
-			e := Codecs.dir.NewEncoder(enc);
-			d := Codecs.dir.NewDecoder(enc)
+			e := Codecs.dir.NewEncoder(HostLang.enc);
+			d := Codecs.dir.NewDecoder(HostLang.enc)
 		END;
 
 		NEW(cons);

+ 1 - 0
BlackBox/Linux/Host/Mod/Lang.odc

@@ -0,0 +1 @@
+../../../OpenBSD/Host/Mod/Lang.odc

+ 1 - 0
BlackBox/Linux/Host/Mod/Lang.txt

@@ -0,0 +1 @@
+../../../OpenBSD/Host/Mod/Lang.txt

二进制
BlackBox/OpenBSD/Host/Mod/Console.odc


+ 3 - 37
BlackBox/OpenBSD/Host/Mod/Console.txt

@@ -9,7 +9,7 @@ MODULE HostConsole;
 		Console implementation for OpenBSD
 	*)
 
-	IMPORT SYSTEM, Console, Libc := LinLibc, Codecs := EncCodecs;
+	IMPORT SYSTEM, Console, Libc := LinLibc, Codecs := EncCodecs, HostLang;
 
 	CONST
 		defEnc = "ASCII";
@@ -23,38 +23,6 @@ MODULE HostConsole;
 		e: Codecs.Encoder;
 		d: Codecs.Decoder;
 
-	PROCEDURE GetEnc (OUT enc: Codecs.Encoding);
-		VAR lang: Libc.PtrSTR;
-			i, j: INTEGER;
-	BEGIN
-		lang := Libc.getenv("LANG");
-		IF lang # NIL THEN
-			IF lang$ = "C" THEN
-				enc := "ASCII"
-			ELSE
-				i := 0; WHILE (lang[i] # 0X) & (lang[i] # '.') DO INC(i) END;
-				IF lang[i] # 0X THEN
-					INC(i);
-					j := 0;
-					WHILE (j < LEN(enc) - 1) & (lang[i] # 0X) DO
-						enc[j] := lang[i];
-						INC(j);
-						INC(i)
-					END;
-					IF j < LEN(enc) - 1 THEN
-						enc[j] := 0X
-					ELSE
-						enc := defEnc
-					END
-				ELSE
-					enc := defEnc
-				END
-			END
-		ELSE
-			enc := defEnc
-		END
-	END GetEnc;
-
 	PROCEDURE (cons: Cons) ReadLn (OUT s: ARRAY OF CHAR);
 		CONST
 			maxLineLen = 1023; (* without null terminating shortchar *)
@@ -145,12 +113,10 @@ MODULE HostConsole;
 	END WriteLn;
 
 	PROCEDURE Init;
-		VAR enc: Codecs.Encoding;
 	BEGIN
 		IF Codecs.dir # NIL THEN
-			GetEnc(enc);
-			e := Codecs.dir.NewEncoder(enc);
-			d := Codecs.dir.NewDecoder(enc)
+			e := Codecs.dir.NewEncoder(HostLang.enc);
+			d := Codecs.dir.NewDecoder(HostLang.enc)
 		END;
 
 		NEW(cons);

二进制
BlackBox/OpenBSD/Host/Mod/Lang.odc


+ 119 - 0
BlackBox/OpenBSD/Host/Mod/Lang.txt

@@ -0,0 +1,119 @@
+MODULE HostLang;
+
+	(* THIS IS TEXT COPY OF Lang.odc *)
+	(* DO NOT EDIT *)
+
+	(*
+		A. V. Shiryaev, 2012.10
+
+		LANG environment variable support
+		Dialog.LanguageHook implementation
+	*)
+
+	IMPORT Dialog, Libc := LinLibc, Codecs := EncCodecs;
+
+	CONST
+		defLang = "";
+		defCountry = "";
+		defEnc = "ASCII";
+
+	TYPE
+		LanguageHook = POINTER TO RECORD (Dialog.LanguageHook) END;
+
+	VAR
+		lang-: Dialog.Language;
+		enc-: Codecs.Encoding;
+
+	PROCEDURE ParseLang (OUT lang, country, enc: ARRAY OF CHAR);
+		VAR env: Libc.PtrSTR;
+			i, j: INTEGER;
+
+		PROCEDURE Default;
+		BEGIN
+			lang := defLang;
+			country := defCountry;
+			enc := defEnc
+		END Default;
+
+		PROCEDURE IsValidEncChar (x: SHORTCHAR): BOOLEAN;
+		BEGIN
+			RETURN ((x >= 'A') & (x <= 'Z')) OR ((x >= '0') & (x <= '9')) OR (x = '-') OR (x = '_')
+				OR ((x >= 'a') & (x <= 'z'))
+		END IsValidEncChar;
+
+	BEGIN
+		env := Libc.getenv("LANG");
+		IF env # NIL THEN
+			IF env$ = "C" THEN
+				lang := ""; country := ""; enc := "ASCII"
+			ELSE
+				i := 0;
+				WHILE (i < 2) & (env[i] >= 'a') & (env[i] <= 'z') & (i < LEN(lang) - 1) DO
+					lang[i] := env[i];
+					INC(i)
+				END;
+				IF (i = 2) & (env[i] = '_') & (i < LEN(lang)) THEN
+					lang[i] := 0X;
+					INC(i);
+					j := 0;
+					WHILE (i < 5) & (env[i] >= 'A') & (env[i] <= 'Z') & (j < LEN(country) - 1) DO
+						country[j] := env[i];
+						INC(j); INC(i)
+					END;
+					IF (i = 5) & (env[i] = '.') & (j < LEN(country)) THEN
+						country[j] := 0X;
+						INC(i);
+						j := 0;
+						WHILE IsValidEncChar(env[i]) & (j < LEN(enc)) DO
+							enc[j] := env[i];
+							INC(j); INC(i)
+						END;
+						IF j < LEN(enc) - 1 THEN
+							enc[j] := 0X
+						ELSE Default
+						END
+					ELSE Default
+					END
+				ELSE Default
+				END
+			END
+		ELSE Default
+		END
+	END ParseLang;
+
+	PROCEDURE (hook: LanguageHook) SetLanguage (
+		lang: Dialog.Language; persistent: BOOLEAN; OUT ok: BOOLEAN
+	);
+	BEGIN
+		ok := (lang = "") OR (LEN(lang$) = 2);
+(*
+		IF ok & persistent THEN HostRegistry.WriteString("language", lang) END
+*)
+	END SetLanguage;
+
+	PROCEDURE (hook: LanguageHook) GetPersistentLanguage (OUT l: Dialog.Language);
+		VAR res: INTEGER; s: ARRAY 32 OF CHAR;
+	BEGIN
+(*
+		HostRegistry.ReadString("language", s, res);
+		IF res = 0 THEN
+			ASSERT((s = "") OR (LEN(s$) = 2), 100);
+			lang := s$
+		ELSE lang := ""
+		END
+*)
+		l := lang
+	END GetPersistentLanguage;
+
+	PROCEDURE Init;
+		VAR
+			languageHook: LanguageHook;
+			country: ARRAY 3 OF CHAR;
+	BEGIN
+		ParseLang(lang, country, enc);
+		NEW(languageHook); Dialog.SetLanguageHook(languageHook); Dialog.ResetLanguage
+	END Init;
+
+BEGIN
+	Init
+END HostLang.

+ 1 - 0
BlackBox/build

@@ -13,6 +13,7 @@ Dev0Compiler.Compile('System/Mod', 'Meta.txt')
 Dev0Compiler.Compile('System/Mod', 'Dialog.txt')
 
 Dev0Compiler.Compile('Enc/Mod', 'Codecs.txt')
+Dev0Compiler.Compile('Host/Mod', 'Lang.txt')
 Dev0Compiler.Compile('Host/Mod', 'Files.txt')
 Dev0Compiler.Compile('Host/Mod', 'Console.txt')
 

+ 3 - 2
BlackBox/build-dev0

@@ -28,15 +28,16 @@ Dev0Compiler.Compile('Dev0/Mod', 'ElfLinker16.txt')
 Dev0Compiler.Compile('Dev0/Mod', 'Linker.txt')
 
 Dev0Compiler.Compile('Enc/Mod', 'Codecs.txt')
+Dev0Compiler.Compile('Host/Mod', 'Lang.txt')
 Dev0Compiler.Compile('Host/Mod', 'Files.txt')
 Dev0Compiler.Compile('Host/Mod', 'Console.txt')
 
-### simple dev interpreter (include Dev0Compiler, Dev0ElfLinker and Dev0Linker)
+### simple dev interpreter (include Dev0Compiler, Dev0ElfLinker)
 
 Dev0Compiler.Compile('', 'Views.txt')
 Dev0Compiler.Compile('Std/Mod', 'Interpreter.txt')
 
 Dev0Compiler.Compile('Dev0/Mod', 'Interp.txt')
 
-Dev0ElfLinker.LinkDll('libBB0.so := Kernel+ EncCodecs Console Math Strings HostConsole Files HostFiles Dev0CPM Dev0CPT Dev0CPS Dev0CPH Dev0CPB Dev0CPP Dev0CPE Dev0CPL486 Dev0CPC486 Dev0CPV486 Dev0Compiler Dev0ElfLinker Dev0Linker Dialog Meta Views StdInterpreter Dev0Interp')
+Dev0ElfLinker.LinkDll('libBB0.so := Kernel+ Console Math Strings Files HostFiles Dev0CPM Dev0CPT Dev0CPS Dev0CPH Dev0CPB Dev0CPP Dev0CPE Dev0CPL486 Dev0CPC486 Dev0CPV486 Dev0Compiler Dev0ElfLinker Dialog Meta Views StdInterpreter EncCodecs HostLang HostConsole Dev0Interp')
 DATA

+ 1 - 0
README

@@ -108,6 +108,7 @@ Files:
 			Compiler.odc: console interface to Dev compiler
 			Log.odc: Log.Hook console implementation
 		Enc: encodings conversion subsystem
+		{OpenBSD,Linux}/Host/Mod/Lang.odc: Dialog.LanguageHook implementation and LANG environment variable support
 
 		{OpenBSD,Linux}/libBB.so: compiled and linked shared library to run BlackBox
 		{OpenBSD,Linux}/libBB0.so: compiled and linked shared library to run simple development interpreter