Интерпретатор сценариев

  1.  Введение в FSHELL
    1. Программная реализация
    2. Область применения
    3. Синтаксис языка FSHELL
    4. Стратегия выполнения сценария
  2. Описание языка FSHELL
    1. Ключевые слова
    2. Переменные
    3. Выражения
    4. Условный оператор
    5. Операторы циклов
    6. Метки, процедуры, операторы безусловного перехода
    7. Вызов функций
    8. Препроцессор
    9. Комментарии
    10. Структура программы
    11. БНФ
  3. Варианты реализации
    1. FSHELL.EXE
    2. FSHELL.DLL
    3. FSHELL.OCX
  4. Встроенные функции
    1. Введение
    2. Функции общего назначения
    3. Функции Microsoft® Win32® API
    4. Специальные функции
    5. Другие полезные функции
  5. Особенности программирования
    1. Многопоточные приложения
    2. Методика отладки
    3. Необходимые динамические библиотеки

Введение в FSHELL

Программная реализация

Интерпретатор FSHELL предназначен для выполнения сценариев по управлению разнообразными ресурсами прикладных систем в операционной среде Windows. FSHELL реализован в нескольких вариантах:

  • EXE — консольное приложение;
  • DLL — многопоточная динамическая библиотека;
  • OCX — ActiveX элемент.

Область применения

FSHELL имеет возможность задания в сценариях (программах) обращений к достаточно большому набору функций библиотеки периода выполнения Visual C++.

FSHELL обеспечивает возможность подключения динамических библиотек — пользовательских и системных. Ограничением является обращение к функциям из динамических библиотек, работающих с уже установленным окном Windows (поскольку FSHELL своего собственного окна не имеет).

FSHELL может быть использован как отдельное приложение, так и в качестве многопоточной динамической библиотеки, обеспечивающей сервис по интерпретации сценариев для другой прикладной задачи. При этом предоставляются средства для экспорта переменных и функций прикладной задачи на уровень FSHELL — программы.

FSHELL полезен при разработке INTERNET/INTRANET — проектов для формирования клиентских страниц, как CGI — приложение, так и в составе динамических библиотек стандарта ISAPI.

Синтаксис языка FSHELL

Переменные программы объявляются оператором присваивания := , либо с помощью функции выделения памяти _newchar.

FSHELL распознает только два типа переменных — целое и указатель обобщенного вида. Этого достаточно для вызова различных системных функций, типы параметров которых могут отличаться, но все равно передаются в Windows через 32-х разрядные слова.

FSHELL предоставляет возможность использования циклов for и while, выхода из циклов по оператору break, безусловного перехода goto, вызова FSHELL — процедуры без параметров оператором call.

Логика программы задается с помощью операторов if.

Точка входа в программу определяется меткой main:. Выход из цикла интерпретации осуществляется оператором exit либо leave.

Препроцессор FSHELL обрабатывает операторы #define, #include (вложенные операторы #include не поддерживаются), #import.

Стратегия выполнения сценария

На этапе предкомпилляции FSHELL осуществляет:

  • преобразование условных операторов, операторов организации циклов в команды псевдокода;
  • формирование таблицы переменных и литералов;
  • заполнение таблицы встроенных функций;
  • заполнение таблицы меток и процедур FSHELL.

Предкомпиляция выражений не производится.

Информация об ошибках, обнаруженных во время предкомпилляции, выводится в STDOUT. После этого производится выполнение FSHELL — программы (вне зависимости от наличия ошибок).

Выполнение функций (встроенных и импортируемых из других библиотек) защищено операторами обработки исключений. Возникновение исключения при выполнении функции не приводит к аварийному завершению сценария.

В общем виде стратегия выполнения сценария сводится к попытке выполнить его «ВО ЧТО БЫ ТО НИ СТАЛО». Во многих случаях это оказывается удобным.

FSHELL (как динамическая библиотека) допускает повторный запуск из приложения с помощью функции fshell_run(). При этом выполнение сценария продолжается с точки, определяемой последним выполненным оператором exit или leave. Это дает возможность управлять поведением приложения из сценария.

Описание языка FSHELL

Ключевые слова

FSELL использует следующие ключевые слова:

Ключевое слово Описание
break
call
do
else
endif
endwhile
end
exit
for
goto
if
jnt
leave
next
return
tst
then
to
while
Выход из циклов for и while
Вызов процедуры FSHELL
Используется в операторах for, while
Используется в операторе if
Используется в операторе if
Используется в операторе while
Синоним exit
Выход из сценария
Оператор цикла
Безусловный переход к метке
Условный оператор
Псевдокод (jump not true)
Выход из сценария
Используется в операторе for
Возврат из процедуры
Псевдокод (test)
Используется в операторе if
Используется в операторе for
Оператор цикла

Переменные

Идентификатор — это последовательность символов, начинающаяся с латинской буквы на любом регистре.

Переменная представляет собой идентификатор.

Возможны два типа переменных — целое (4 байта) и указатель обобщенного вида. Тип указателя определяется контекстом используемой функции.

Переменные объявляются четырьмя способами.

Первый способ — оператор присваивания:

Var1 := 100 // десятичная константа

FileName := «d:\fshell\fshell.exe»

Второй способ — оператор #define:

#define LF 0x0A // шестнадцатеричная константа

#define Signature «SMF-70»

Третий способ — оператор _newchar:

pArray := _newchar(256)

_strcpy(pArray,»Hello World»)

puts(pArray)

_delete(pArray)

Четвертый способ — вызов функции fshell_export_var из приложения. Пример для Visual C++:

int fh = fshell_alloc()

char VarToExport[MAX_PATH]; // экспортируемая переменная>

strcpy(VarToExport, «Welcome to FSHELL programming !»);

fshell_export_var(fh, «ApplicationVar», VarToExport, MAX_PATH, 1);

fshell_compile(fh, «script.f»);

fshell_run(fh);

fshell_free(fh);

Во время выполнения сценария переменная VarToExport будет доступна из скрипта «script.f» под именем ApplicationVar:

_strcpy(ApplicationVar, «Новое значение»)

_printf(«Переменная VarToExport: %s», ApplicationVar)

ЗАМЕЧАНИЕ 1

Предусмотрен доступ к встроенным переменным с именами a … z. Доступ к этим переменным осуществляется быстрее, так как не связан с поиском в общей таблице переменных.

ЗАМЕЧАНИЕ 2

При задании строковых переменных обработка символов вида ‘\<значение>’ не производится (‘\n’, ‘\t’, …). Например, в строке «\\\\» будет содержаться четыре обратных косых черты, а не две, как это было бы в программе на языке С.

Выражения

Выражения состоят из подвыражений, связанных знаками операций. Отдельные элементы выражения могут быть заключены в круглые скобки.

Вычисление выражений производится методом рекурсивного спуска на этапе выполнения сценария. Обнаружение ошибок вычисления не приводит к завершению сценария.

Допустимыми операциями являются:

 

Арифметические целочисленные операции: + сложение
— вычитание
* умножение
/ деление
% остаток от деления
^ возведение в степень
Арифметические целочисленные унарные операции: + унарный плюс
— унарный минус
Логические унарные операции ! логическое отрицание
Логические операции & логическое И| логическое ИЛИ
Операции сравнения > больше< меньше
= равно
# не равно
Битовые операции ~ побитовая инверсия
Оператор присваивания <переменная>:=<выражение>

Пример использования логических операций:

_printf( «*** Операция ‘|’ » )

x1 := 0 | 0

x2 := 0 | 1

x3 := 1 | 0

x4 := 1 | 1

_printf( «0 | 0 = %d», x1 )

_printf( «0 | 1 = %d», x2 )

_printf( «1 | 0 = %d», x3 )

_printf( «1 | 1 = %d», x4 )

РЕЗУЛЬТАТ:

*** Операция ‘|’

0 | 0 = 0

0 | 1 = 1

1 | 0 = 1

1 | 1 = 1

 

_printf( «*** Операция ‘&’ » )

x1 := 0 & 0

x2 := 0 & 1

x3 := 1 & 0

x4 := 1 & 1

_printf( «0 & 0 = %d», x1 )

_printf( «0 & 1 = %d», x2 )

_printf( «1 & 0 = %d», x3 )

_printf( «1 & 1 = %d», x4 )

РЕЗУЛЬТАТ:

*** Операция ‘&’

0 & 0 = 0

0 & 1 = 0

1 & 0 = 0

1 & 1 = 1

 

_printf( «*** Унарные операции» )

_printf( «— ‘НЕ’ » )

x1 := !0

x2 := !1

x3 := !2

_printf( «!0 = %d», x1 )

_printf( «!1 = %d», x2 )

_printf( «!2 = %d», x3 )

РЕЗУЛЬТАТ:

*** Унарные операции

— ‘НЕ’

!0 = 1

!1 = 0

!2 = 0

 

_printf( «— ‘Инверсия’ » )

x1 := ~0

x2 := ~1

_printf( «~0 = %d», x1 )

_printf( «~1 = %d», x2 )

x1 := 100

_printf( «x = %d (%.8X)», x1, x1 )

y1 := ~x1

_printf( «~x = %d (%.8X)», y1, y1 )

z1 := ~y1

_printf( «~~x = %d (%.8X)», z1, z1 )

РЕЗУЛЬТАТ:

— ‘Инверсия’

~0 = -1

~1 = -2

x = 100 (00000064)

~x = -101 (FFFFFF9B)

~~x = 100 (00000064)

Условный оператор

Условный оператор имеет следующий вид:

if ( условие ) then

// действие, если условие = 1

else

// действие, если условие = 0

endif

Допускается до 50 уровней вложенности операторов if.

Пример:

a := 100

b := 200

If ( a = 100) then

If (b = 200 ) then

Res := 1

else

Res := -1

endif

else

Res := -1

endif

_printf(«Result equals %d», res);

Операторы циклов

Предусмотрены два вида операторов цикла: while и for.

Оператор while имеет следующую структуру:

while ( <выражение> ) do

// тело цикла

endwhile

Оператор for имеет следующую структуру:

for i := <переменная> := <начальное значение> to <конечное значение> do

// тело цикла

next

Допускается до 50 уровней вложенности операторов while и for.

Выход из цикла может быть осуществлен оператором break.

Пример:

i := 0

while (1) do

i := i + 1

if ( i = 100 ) then break endif

endwhile

_printf(«while cycle iterated %d times», i)

Метки, процедуры, операторы безусловного перехода

Метка определяется следующим образом:

<идентификатор>:

Начало процедуры определяется меткой, обозначающей точку входа, завершается процедура оператором ‘return’, обозначающим выход из процедуры. Процедура может иметь несколько точек входа.

Оператор call предназначен для организации в программе перехода на начало процедуры, которая завершается оператором ‘return’.

call <метка>

Оператор безусловного перехода ‘ goto ‘ предназначен для организации в программе безусловного перехода к метке.

goto <метка>

Вызов функций

При вызове функций ( встроенных и импортируемых ) используется следующий синтаксис:

_<имя функции>([<список параметров, разделенных запятыми>])

Такая форма вызова позволяют ускорить поиск в таблицах описаний функций.

ЗАМЕЧАНИЕ 1

При объявлении импортируемой функции следует добавлять префикс ‘_’ перед именем, например для доступа к функции ‘ WSAStartup ‘ необходимо указать

_import(«_WSAStartup», «wsock32.dll», 2)

либо

#import _WSAStartup wsock32.dll 2

ЗАМЕЧАНИЕ 2

В данной версии интерпретатора FSHELL не обеспечивается вычисление выражений в аргументах и , как следствие, указание вызова функции как аргумента другой функции.

Препроцессор

Препроцессор FSHELL обрабатывает следующие директивы:

#define ABC 123

— определяет константу. Директива представляет собой полный аналог оператора присваивания ( ABC := 123 ) с той разницей, что директива #define заносит значение переменной до выполнения программы, при этом сам код оператора присваивания отсутствует.

#import _Function func.dll 3

— определяет импортируемую функцию. Директива представляет собой полный аналог вызова _import с той разницей, что директива #import регистрирует функцию до выполнения программы, при этом сам вызов _import отсутствует.

#include «header.h»

— включает файл заголовка. Вложенные вызовы #include не поддерживаются.

Комментарии

Строки комментария начинаются двумя символами «//» и могут быть размещены в любом месте программы.

Структура программы

Программа ( сценарий, скрипт ) FSHELL имеет следующую структуру:

//// директивы препроцессора

//// определения констант

#define LF 0x0A

//// указание включаемых файлов, которые могут содержать

//// операторы #define , #import и описания процедур

#include «prg.h»

//// описания функций, импортируемых из динамических библиотек

#import _ExtraFunction extra.dll 1

//// главный модуль, определяемый меткой main:

main:

// тело главного модуля

// может содержать дополнительные операторы exit,

// вызовы импортируемых и встроенных функций

// и объявленных процедур

//// выход, может быть осуществлен оператором leave (<выражение>)

exit

//// описания процедур

procedure_1:

// тело процедуры

return

ЗАМЕЧАНИЕ

Оператор exit всегда возвращает 0 в вызывающую программу, оператор leave — выражение, указанное вторым операндом.

БНФ

Для любителей русской словесности приводим сокращенное описание правил образования выражений языка FSHELL в форме Бэкуса-Наура.

<буква> ::= a | b … | z | A | B … | Z

<цифра> ::= 1 | 2 … | 9

<подчеркивание> ::= ‘_’

<пробел> ::= ‘ ‘

<разделитель> ::= один из {;,+-<>/*%^=()&|!~#:\n\r\t} | <пробел>

<символ> ::= { любой ASCII символ, имеющий визуальное представление }

<идентификатор> ::= <буква> |

< идентификатор > <подчеркивание> |

< идентификатор > <буква> |

< идентификатор ><цифра>

<число> ::= <цифра> | <число><цифра> | 0x< число > | 0X< число >

<строка> ::= «<символ> | < строка ><символ >|»

<аргумент> ::= <идентификатор> | <число> | <строка>

<список аргументов> ::=[] | [ <аргумент>] | [<список аргументов>, <аргумент>]

<вызов функции> ::= _<идентификатор>(<список аргументов>)

<унарная операция> ::= + | — | ~ | !

<степень> ::= ^

<мультипликативная операция> ::= * | / | %

<аддитивная операция> ::= + | —

<логическая операция> ::= | & | < | > | = | #

<операнд> ::= [<унарная операция>]<идентификатор> |

[<унарная операция>]<вызов функции> |

[<унарная операция>]<выражение в скобках>

<множитель> ::= <операнд><степень><операнд>

< слагаемое > ::= <множитель> <мультипликативная операция> <множитель>

< выражение > ::= < слагаемое ><аддитивная операция>< слагаемое > |

< слагаемое ><логическая операция>< слагаемое >

<выражение в скобках > ::= (< выражение >)

ЗАМЕЧАНИЕ

В данной версии интерпретатора FSHELL не обеспечивается указание вызова функции как аргумента другой функции.

Варианты реализации

FSHELL.EXE

FSHELL.EXE представляет собой консольное приложение. В данной версии единственным аргументом командной строки является имя файла сценария.

fshell.exe script.f

Расширение файла сценария не анализируется.

При запуске без аргументов FSHELL.EXE предполагает, что он используется как CGI — приложение. В этом случае производится попытка доступа к переменной среды ‘PATH_INFO’. Значение этой переменной интерпретируется как имя файла сценария. Данная схема применяется при вызове FSHELL.EXE сервером Web.

FSHELL.DLL

FSHELL.DLL представляет собой многопоточную динамическую библиотеку, экспортирующую следующие функции:

fshell_alloc — распределение блока управления сценарием

fshell_add_var — добавление переменной в сценарий

fshell_export_var — экспорт переменной приложения в сценарий

fshell_export_func — экспорт функции приложения в сценарий

fshell_step_func — указание функции приложения для трассировки

fshell_compile — предкомпиляция сценария

fshell_run — запуск сценария

fshell_free — удаление блока управления сценарием

Таким образом предоставляется возможность выполнения разных сценариев в разных потоках приложения и вызов нескольких сценариев внутри одного потока.

FSHELL.OCX

FSHELL.OCX представляет собой AciveX — элемент, построенный с использованием MFC ActiveX ControlWizard среды Visual C++ версии 5.0.

Работа с этим элементом осуществляется с использованием следующих методов:

Alloc, ExportVar, ExportFunc, StepFunc, Compile, Run, Free

Эти методы являются функциональными аналогами функций FSHELL.DLL.

FSHELL.OCX легко встраивается в пользовательское приложение, а также — в HTML страницу. Для этого достаточно добавить к странице следующий тег:

<OBJECT ID=»Fshell1″ WIDTH=100 HEIGHT=50

CLASSID=»CLSID:223DE972-61B2-11D1-8763-484F4D005CDA»>

<PARAM NAME=»_Version» VALUE=»65536″>

<PARAM NAME=»_ExtentX» VALUE=»2117″>

<PARAM NAME=»_ExtentY» VALUE=»1058″>

<PARAM NAME=»_StockProps» VALUE=»0″>

</OBJECT>

Встроенные функции

Введение

В настоящем разделе перечислены встроенные функции FSHELL. Все функции возвращают значение — 4-х байтовый код, который может быть либо числом, либо указателем на область памяти.

В том случае, если «C» — аналог рассматриваемой функции, не возвращает значения, исполнительная система FSHELL все равно его формирует (только в этом случае он будет равным нулю).

Параметры функций также могут быть либо числами, либо указателями на области памяти, что определяется контекстом используемой функции.

Если программист сталкивается с необходимостью доступа к структурам данных, он может производить выборку и запись значений байтов, коротких слов (2 байта) и длинных слов (4 байта) с помощью функций _byte, _short, _long и _setbyte, _setshort, _setlong.

Вызов любой функции распознается FSHELL по префиксу ‘_’.

ЗАМЕЧАНИЕ:

В данной версии FSHELL допускается передавать функциям до 10 параметров.

Функции общего назначения

Ниже перечислены функции библиотеки периода выполнения «C» (runtime), общие для многих компиляторов «C». Их описание можно получить в оперативной справке любого компилятора.

_srand, _rand, _printf, _sprintf, _fprintf, _scanf, _sscanf, _fscanf, _gets, _puts, _strchr, _strrchr, _strstr, _strcmp, _strncmp, _stricmp, _strnicmp, _toupper, _tolower, _strlen, _strcat, _strncat, _strcpy, _strncpy, _strset, _strnset, _access, _fopen, _fclose, _fgets, _fputs, _feof, _fflush, _fseek, _ftell, _fread, _fwrite, _time, _ctime, _localtime, _asctime, _strftime, _findfirst, _findnext, _findclose, _system, _kbhit, _getch, _getche, _rename, _unlink, _setvbuf, _getenv

Функции Microsoft® Win32® API

Данные функции предназначены для работы с ядром Windows. Их описание лучше всего посмотреть в оперативной справке Visual C++ версии 5.0.

_Sleep, _CreateSemaphore, _ReleaseSemaphore, _WaitForSingleObject, _CloseHandle, _InitializeCriticalSection, _EnterCriticalSection, _LeaveCriticalSection, _DeleteCriticalSection, _GetCurrentThread, _MoveFile, _MoveFileEx, _CopyFile, _DeleteFile, _CreateDirectory, _RemoveDirectory, _GetCurrentDirectory, _SetCurrentDirectory, _GetFullPathName, _MultiByteToWideChar, SystemParametersInfo, _GetCommandLine

Специальные функции

Данная группа функций обеспечивает работу с памятью, импортом функций из других динамических библиотек, переносом и копированием файлов, а также — решением других общественно необходимых задач.

_import(fname, dllname, qa)

Указывает FSHELL, в какой динамической библиотеке искать указанную функцию.

ПАРАМЕТРЫ:

fname — имя функции, должно начинаться с символа ‘_’;

dllname — имя динамической библиотеки (короткое либо полное);

qa — количество аргументов (в данной версии не используется).

_stop()

Переводит FSHELL в режим пошагового выполнения сценария. При этом выводится диалоговое окно с кнопками управления выполнением.

_offset(addr, off)

Формирует новый адрес, складывая адрес addr и смещение off.

Несколько устарела.

_byte(addr, off)

Производит выборку байта из области памяти, задаваемой адресом addr со смещением off.

ПАРАМЕТРЫ:

addr — адрес области памяти;

off — смещение.

_short(addr, off)

Производит выборку короткого слова (2 байта) из области памяти, задаваемой адресом addr со смещением off.

ПАРАМЕТРЫ:

addr — адрес области памяти;

off — смещение.

_long(addr, off)

Производит выборку длинного слова (4 байта) из области памяти, задаваемой адресом addr со смещением off.

ПАРАМЕТРЫ:

addr — адрес области памяти;

off — смещение.

_setbyte(addr, off, value)

Производит запись байта со значением value в область памяти, задаваемой адресом addr со смещением off.

ПАРАМЕТРЫ:

addr — адрес области памяти;

off — смещение;

value — значение байта.

_setshort(addr, off, value)

Производит запись короткого слова (2 байта) со значением value в область памяти, задаваемой адресом addr со смещением off.

ПАРАМЕТРЫ:

addr — адрес области памяти;

off — смещение;

value — значение байта.

_setlong(addr, off, value)

Производит запись длинного слова (4 байта) со значением value в область памяти, задаваемой адресом addr со смещением off.

ПАРАМЕТРЫ:

addr — адрес области памяти;

off — смещение;

value — значение байта.

_newchar(size)

Распределяет память заданного объема.

ПАРАМЕТРЫ:

size — размер запрашиваемой памяти.

_delete(addr)

Освобождает память, распределенную функцией _newchar.

ПАРАМЕТРЫ:

addr — адрес памяти, который вернула функция _newchar.

_fmove (source, dest)

Аналог MoveFileEx с установленными режимами MOVEFILE_COPY_ALLOWED и MOVEFILE_REPLACE_EXISTING (см. справку по Visual C++).

_fmovetodir (p_source, p_destdir)

Производит перенос файла в заданный каталог.

ПАРАМЕТРЫ:

p_source — имя файла;

p_destdir — имя каталога.

_fcopytodir (source, destdir)

Производит копирование файла в заданный каталог.

ПАРАМЕТРЫ:

source — имя файла;

destdir — имя каталога.

_MessageBox(text, title, style)

Выводит диалоговое окно с кнопками.

ПАРАМЕТРЫ:

text — текст окна;

title — заголовок окна;

style — стиль окна (см. справку Visual C++ по функции MessаgeBox).

_findvar(varname)- Ищет переменную с именем varname в словаре переменных FSHELL. Возвращает 1 в случае успеха и 0 в противном случае.

_fork() — Производит запуск копии FSHELL с сохраненными значениями переменных и счетчика команд в отдельном потоке (а не в процессе, как в UNIX).

_gettid() — Возвращает идентификатор потока, запущенного функцией fork.

Другие полезные функции

Эти функции помогут украсить Ваши сценарии.

_PlaySound(file, mode)

Аналог функции sndPlaySound (см. справку по Visual C++).

ПАРАМЕТРЫ:

file — «проигрываемый» файл;

mode — режим (0 — синхронный, 1 — асинхронный, …)

_ShellExecute(fname, pars, dir, sh)

«Выполняет» файл с расширением, зарегистрированным в системе (*.wav, *.avi, *.doc …). Возможности несколько урезаны по сравнению с оригиналом функции из SHELLAPI.

ПАРАМЕТРЫ:

fname — имя «выполняемого» файла

pars -дополнительные параметры (если fname является именем программы)

dir — рабочий каталог по умолчанию

sh — вид окна (если fname является именем программы). Допустимые значения описаны в справке Visual C++ по функции ShellExecute.

Особенности программирования

Многопоточные приложения

FSHELL.DLL является многопоточной библиотекой. Каждый вызов функции fshell_alloc() формирует в памяти новый блок управления интерпретацией. Таким образом предоставляется возможность запускать из потоков Вашего приложения FSHELL — сценарии параллельно.

Запуска сценария производится в следующей последовательности:

int fh; // дескриптор блока управления сценарием

fh = fshell_alloc(); // распределение блока управления

// здесь можно произвести настройку сценария

// — добавить либо экспортировать переменные приложения

// — экспортировать функции

fshell_compile(fh, «first.f») // предкомпиляция сценария «first.f»

fshell_run(fh); // запуск сценария

fshell_free(fh); //удаление блока управления сценарием

При использовании FSHELL.OCX применяется такая же схема запуска.

Методика отладки

Сценарии FSHELL легко отлаживаются с помощью тестовых сообщений вызовом функций _printf, _puts, _MessageBox.

При отладке оконного приложения, разработанного в среде Visual C++, использующего FSHELL как динамическую библиотеку можно использовать функцию _MessageBox, либо присоединение консоли с помощью функции AllocConsole(). В последнем случае вывод функций _printf и _puts будет перенаправлен в новое консольное окно.

Если возникает необходимость трассировки выполнения скрипта, вставьте в его текст вызов функции _stop. После каждого выполненного оператора будет выводиться окно с информацией об этом операторе (в предкомпилированном виде).

В сложных случаях отладки, например — для ISAPI — приложений можно рекомендовать вывод тестовой информации в файл.

Необходимые динамические библиотеки

Для работы FSHELL требуются следующие библиотеки:

— mfc42.dll;

— msvcirt.dll;

— msvcrt.dll.