В принципе, для системы
A2 есть вариант сборки её главного приложения с включением консольной оболочки. На основе этого приложения уже можно сделать любое консольное приложение, более того, весьма гибкое приложение, так как у традиционных статически собранных консольных приложений одна-единственная "точка входа", а здесь можно сделать одно консольное приложение со множеством "точек входа" и потом легко за эти точки входа дёргать в процессе работы
Это всё за счёт динамической модульности унаследованной
ОС А2 от
ОС ETH Oberon.
Вот, например, я взял стандартный (с включенной консольной оболочкой) главный запускаемый модуль
Unix A2 x64, добавил один-единственный модуль, скомпилировал его под
Linux 64.
Дальше я написал простейший командный файл для исполнения в консольной оболочке
A2 и получил в результате готовый
CGI скрипт, который можно скопировать на сервер и он работает
Код: "OBERON"
MODULE env; (** AUTHOR "Yaroslav Romanchenko"; PURPOSE "Simple example of reading environment variables on Unix"; *)
IMPORT
SYSTEM, Commands, Unix;
PROCEDURE GetEnvVar(aName: ARRAY OF CHAR; VAR aVar: ARRAY OF CHAR): BOOLEAN;
VAR
addr: ADDRESS;
i, max: LONGINT;
c: CHAR;
bOk: BOOLEAN;
BEGIN
bOk := FALSE;
max := LEN(aVar) - 1;
(* For reading even one char we need at least array of length 2 *)
IF max >= 1 THEN
addr := Unix.getenv(ADDRESSOF(aName));
IF addr = 0 THEN
(* There is no such variable. Result is FALSE *)
aVar[0] := 0X
ELSE
REPEAT
SYSTEM.GET(addr, c);
aVar[i] := c;
INC(addr);
INC(i)
UNTIL (c = 0X) OR (i = max);
aVar[i] := 0X;
bOk := TRUE
END
END;
RETURN bOk
END GetEnvVar;
PROCEDURE var*(context: Commands.Context);
VAR
aName, aVar: ARRAY 256 OF CHAR;
BEGIN
context.arg.SkipWhitespace();
context.arg.Token(aName);
IF (aName[0] # 0X) & GetEnvVar(aName, aVar) THEN
context.out.String(aName);
context.out.Char('=');
context.out.String(aVar);
context.out.Ln
END;
END var;
END env.
Скрипт для
Linux, а модуль я компилировал, из-под
Win A2 x64. Кросс-компиляция в действии!
Поскольку в такой ситуации в системе просто нет необходимых объектных модулей для
Linux, процесс компиляции таков:
1. Окидываем взором наш модуль, который нам надо скомпилировать, видим, что: а)
SYSTEM - модуль встроенный в компилятор, независимый от платформы; б)
Commands - скорее-всего зависим от платформы, список зависимостей нам понадобится; в)
Unix - зависимость понятна
2. Получаем список зависимостей для модулей, для которых нам надо его получить.
Для этого выполняем такую команду, первый параметр - платформа, второй - модуль, для которого строим список зависимостей:
Цитата:
Release.RequiredModules Linux64 Commands ~
Получаем такой список:
Цитата:
AMD64.Builtins.Mod Trace.Mod Linux.Glue.Mod Linux.Unix.Mod Unix.Machine.Mod
Heaps.Mod Modules.Mod Unix.Objects.Mod KernelLog.Mod RealConversions.Mod
Streams.Mod
3. Повторяем п. 2 пока не получим полный список всех зависимостей.
4. Составляем команду компиляции нашего модуля под заданную платформу, перечислив все модули, которые надо скомпилировать:
Цитата:
Compiler.Compile -p=Unix64
AMD64.Builtins.Mod Trace.Mod Linux.Glue.Mod Linux.Unix.Mod Unix.Machine.Mod
Heaps.Mod Modules.Mod Unix.Objects.Mod KernelLog.Mod RealConversions.Mod
Streams.Mod
Commands.Mod
env.Mod
~
Команды для исполнения в оболочке написал такие (как видите, тут используется стандартный
Unix-овый приём
Шебанг, для указания, чем данный скрипт надо исполнить):
Цитата:
#!./oberon run
System.Show Content-type: text/html~
System.Ln ~
System.Ln ~
System.Show <HTML> ~
System.Ln ~
System.Show <HEAD><TITLE>Hello from A2 OS</TITLE></HEAD> ~
System.Ln ~
System.Show <BODY> ~
System.Ln ~
System.Show <H1>Hello from A2 OS!</H1> ~
System.Ln ~
System.Show <H2>Version information:</H2> ~
System.Version ~
System.Ln ~
System.Show <H2>Some environment variables:</H2> ~
System.Ln ~
env.var HTTP_HOST ~
System.Show <BR> ~
System.Ln ~
env.var HTTP_USER_AGENT ~
System.Show <BR> ~
System.Ln ~
env.var REQUEST_URI ~
System.Show <BR> ~
System.Ln ~
env.var REQUEST_METHOD ~
System.Show <BR> ~
System.Ln ~
env.var SERVER_NAME ~
System.Show <BR> ~
System.Ln ~
env.var SERVER_SOFTWARE ~
System.Show <BR> ~
System.Ln ~
env.var SERVER_SIGNATURE ~
System.Show <BR> ~
System.Ln ~
env.var UNIQUE_ID ~
System.Show <BR> ~
System.Ln ~
System.Show <H2>Loaded modules:</H2> ~
System.ListModules ~
System.Ln ~
System.Show <H2>To be continued... Stay tuned!</H2> ~
System.Show </BODY></HTML> ~
System.Ln ~
System.PowerDown ~
И как видите, в каждой строчке вызывается какая-то команда какого-либо модуля (т.е. мы вызываем разные точки входа одного приложения).
Результат работы данных команд
Hello from A2 OS!При желании можно проанализировать все зависимости и пересобрать данное приложение, оставив только те модули, которые реально нужны. Такую пересборку, естественно, тоже можно выполнить из-под A2.
А можно оставить главный модуль и как есть, лишь добавляя функционал, дописывая новые модули.
Я высказал идею, что можно вообще сделать целый пакет полезных и удобных консольных утилит на все случаи жизни в
"A2 в качестве командного интерпретатора" и по-немногу дописываю всякие утилиты.