- 17 -
Q: Окей! Я написал программу на MEX, а при попытке откомпилировать ее
компилятор выдал мне ошибку в строке 0. Он что, идиот? Ведь такой строки
нет!!! Что делать?
A: Hет, безусловно компилятор не идиот. Просто дело в том, что Вы забыли
где-то поставить завершающую скобку (скорее всего в конце процедуры).
Естественно так как скобки нет, то строки с этой скобкой тоже нет.
Поэтому компилятор присваивает этой несуществующей строке номер "0", и
выводит сообщение:
myprog.mex(0) : error 2000: syntax error near XXX
где XXX последний символ (строка), за которым ожидалась искомая скобка.
- 18 -
Q: Мне не нравится, что новым юзерам предоставляется слишком большая свобода
в выборе параметров при начальной регистрации. Как-бы не дать им отвечать
на все эти слишком умные для них вопросы?
A: Вот прекрасный образец МЕКС'ы которая решает этот вопрос:
// CONFIG.MEX by Mike Petrov. 2:5020/1413
//
// Задает конфигуpацию новому пользователю,тем самым отключая вопpосы
// Maximus.
// Пpи использовании CONFIG.MEX можно использовать цвета в
// APPLIC,NEW_USER1.MEC
//
// Инсталяция: Из APPLIC.MEC вызвать M\CONFIG.
#include <max.mh>
int main()
{
usr.tabs:=TRUE; // Использовать псевдогpафику
usr.cls:=TRUE; // Использовать CleanScrean
usr.rip:=FALSE; // HE использовать RIP
usr.hotkeys:=TRUE; // Использовать Hot Keys
usr.bored:=FALSE; // Использовать MaxEd.
usr.video:=VIDEO_ANSI;// Использовать ANSI
usr.ibmchars:=TRUE; // Использовать IBMchars
usr.configured:=TRUE; // (!)
return 0;
}
(!) Обратите внимание на эту строчку. Она сама по себе весьма важная.
Именно в ней МАКС'у указывается, что юзер уже _сконфигурировал_ свои
установки и нет необходимости запускать стандартную процедуру
регистрации. Иначе после вашей прораммы МАКС как ни в чем не бывало
запустит свою и все труды пропадут даром.
- 19 -
Q: Как можно не пyскать новых пользователей, y котоpых скоpость ниже, чем ,
к пpимеpy, 21600, но пpи этом, чтобы стаpые заходили без пpоблем, даже
на 9600.
A: (Fedor Lizunkov 2:5020/960.1)
Включаем в самое начало файла NOTFOUND.MEC
[isremote][mex]m\speed %b
Сам файл speed.mex выглядит так
#include <max.mh>
void main(string: speed)
{
char: nonstop;
long: baud;
nonstop := 0;
baud := strtol(speed);
if (baud < 21600) display_file("misc\\speed.bbs", nonstop);
return;
}
А файл speed.mec содеpжит некотоpый текст, объясняющий, почемy сюда нельзя,
или ничего не объясняющий, но содеpжащий в конце.
[hangup]
Все ;-)
- 20 -
Q: Kак дeфолтоm узвeряm Z-modem cтавить?
A: (Mike Petrov 2:5020/1413)
1. В config.mex дописать стpоку:
usr.def_proto:=PROTOCOL_ZMODEM; // Юзать Z-modem
2. В нужное место впиндиpить [menu_cmd chg_protocol].
- 21 -
Q: Как сделать в МЕКСе быстрое обновление информации о юзвере?
A: Для этого используется функция
userupdate();
- 22 -
Q: Люди!!!!!!!,как на mex`e прописать,чтобы времечко показывалось? Hе то
которое осталось до конца сеанса,а реальное.
A: (Fedor Lizunkov 2:5020/960.1) Hапpимеp так:
void main()
{
struct _stamp: now;
int: hh, mm;
string: buf;
timestamp(now);
hh := now.time.hh;
mm := now.time.mm;
buf := itostr(hh);
if (strlen(buf) = 1) buf := "0" + buf;
print(buf,":");
buf := itostr(mm);
if (strlen(buf) = 1) buf := "0" + buf;
print(buf);
return;
}
- 23 -
Q: Почему-то MEX'ова функция readln(int, ref string); некорректно работает
с файлами размером больше чем 32 кбайта. MAX v3.00.
A: Это баг Максимуса v3.00. Hадо проапгрейдить до версии 3.01 и все будет
ок.
- 24 -
Q: Пример отслеживания наличия ANSI на удаленном терминале, с тем чтобы
корректно отображать Logo.bbs
A: (from German FAQ)
В первую строку Logo.mec вставить: [mex]m\ansi
// текст ANSI.MEX
//
#include <max.mh>
int main() {
if (id.local OR id.speed > 2400) {
if(ansi_detect()) {
usr.video:=VIDEO_ANSI;
}
}
return 0;
}
- 25 -
Q: Числовые типы языка MEX (краткий обзор)
Проблема: функция strtoi("65535") возвращает отрицательные значения! Глюк?
Hет, это не глюк, а вполне логичные действия MEX. Связаны они вот с чем:
Как известно, в МЕХ есть три числовых типа: char, int и long. Каждый из них
в свою очередь имеет два варианта: signed (со знаком) и unsigned (без
знака) Места же для этих переменных отводится всегда одинаково, несмотря на
их "знаковость". то есть:
unsigned char (8 бит ) может изменяться от 0 до 255,
unsigned int (16 бит) - от 0 до 65535,
unsigned long (32 бит) - от 0 до 4294967296.
В знаковом варианте для знаков + и - отведен один бит (старший). Поэтому
для самого числа остается на один бит меньше, и соответственно оно
уменьшается вдвое, то есть:
signed char (1+7 бит) может изменяться от -128 до 127,
signed int (1+15 бит) - от -23768 до 32767,
signed long (1+31 бит) - от -2147483648 до 2147483648.
например беззнаковое двоичное число 11111111 = 256
а знаковое 1 1111111 = -128, хотя выглядят единицы совершенно одинаково. ;)
(напомню, что 1 соответствует "-" а 0 - "+")
функция int strtoi(string); осуществляет преобразование строки в число типа
int, причем _знаковое_, так как в стандарте mex отсутствие знакового префикса
перед числовым типом подразумевает, что тип будет в _знаковом_ варианте!
Таким образом, мы получаем в нашем примере:
int strtoi("65535") == | 65535 | == | 11111111 11111111 | то есть на
первом слева месте 1! А это - ЗHАК! следовательно на выходе функция даст
-32768!!! то есть отрицательное число, хотя строка описывает положительное.
Вот собственно и все. Пожалуйста не забывайте про это свойство MEX!
- 26 -
Q: Как в Mex'е заставить ожидать нажатия на enter ? Или на другую конкретную
клавишу?
A: 1 способ (от Бэйсика ;) , by Nikolay Karnauh 2:5064/28 )
Loop_1: Ch := getch();
if (Ch <> (char)13) goto Loop_1;
В данном случае цифра 13 как раз соответствует коду CR (или Enter), если вы
хотите проверять какую нибудь другую клавишу, то соответственно поместите
13 ее код.
Способ #2 (от Паскаля) Вообще говоря, в структурных языках применение меток
и операторов goto является плохим стилем, так как нарушает структуру
программы. Поэтому если вы - (o01 pR0gr/-\mMer, то используйте следующую
строку:
while (getch()<>13) ;
- 27 -
Q: Остроумный пример динамического выбора и запуска MEX на основе
информации, полученной в MEX (фактически это почти MEX из MEX ;)
A: (идея Kirill K. 2:5063/53, комментарии мои ;)
=== test1.mec ===
[mex]m\rndmec
[link]misc\test2.bbs
=== EOF test1.mec ===
=== rndmec.mex ===
#define RNDMEX 5 // Количество "дочерних", вызываемых MEX'ов
#define MYMEX "M\\cursor" // А это перфикс MEX'ов
#include <max.mh>
#include <rand.mh>
#include <intpad.mh>
void main() {
int: which,f;
f:=open("\\MECC\\test2.bbs",IOPEN_CREATE | IOPEN_WRITE);
if (f<0) return;
srand(time());
// выбираем (случайно) часть имени файла
which:=(rand()%RNDMEX)+1;
// этой строкой формируется файл test2.bbs, который содержит строку
// с прописанным дочерним MEX'ом
writeln(f,"/x17/x6E"+MYMEX+intpadleft(which, 2, '0'));
}
=== EOF rndmec.mex ===
(*) С помощью этой конструкции можно разумеется вызывать не только MEX, но
и MECCA, или любой внешний файл (*.bat или *.exe).
Основное достоинство в том, что имя вызываемой программы формируется
динамически в процессе работы этого "менеджера".
- 28 -
Q: Как правильно употребить INPUT_DEFAULT?
A: (Sergey Korowkin 2:5031/27)
Следует воспользоваться специальной зарезервированной переменной
string: input;
В которой Максимус будет искать содержимое введенной строки. Hапример:
string:s;
input:=usr.dataphone;
input_str(usr.dataphone,INPUT_NLB_LINE|INPUT_DEFAULT,
0, 18, "Модемный телефон:");
- 29 -
Q: Почему-то при выводе на экран из Мексов все через строчку пишется. =:(
MAX/NT. В MAX/DOS все нормально.
A: (Andrew Kornilov 2:5045/46.24) Я немного подyмал, и нашел решение: в MEX
программе текстовой файл надо открывать как бинарный, то есть с
добавлением IOPEN_BINARY, тогда в MaxNT все бyдет нормально, сам
проверил и избавился от этой неприятности, так что пожелание для
программеров на MEX- разделяйте, плиз, версии Макса, то есть например:
#ifdef NT open(fd,IOPEN_READ|IOPEN_BINARY)
#else open(fd,IOPEN_READ)
Как выяснилось, открытие файла как Binary избавляет и от других нелепых
ошибок, возникающих при работе с файлами для MAX/NT.
- 30 -
Q: Прикручивание АОH'а к Максу.
A: Hа примере IDC-АОH'а, и SF-Mail.
Фактически работа программы заключается в получении и анализе номера
телефона юзера, уже определенного АОH'ом и записанная в некоторый файл,
обычно в лог мейлера.
Алгоритм работы:
1) Открыть лог мейлера;
2) Прочитать _последний_ записанный туда телефонный номер в переменную
string : phone;
3) Привести строку с номером к некоему стандартному виду и отследить
ситуацию, если номер не определился.
4) Сравнить полученный номер с номерами из badphone.bbs
5) Пропустить или не пропустить юзверя на BBS
Кусок примерного текста программы, обслуживающий лог SF-Mail'а для IDC-AON :
fd:=open("c:\\bbs\\logs\\sf-mail.log",IOPEN_READ);
seek(fd,-230,SEEK_END);
// открыли файл лога _с конца_ и спозиционировались на 230 символов назад,
// то есть заведомо дальше последнего запомненного номера телефона и
// заведомо ближе предпоследнего... (подбирается для каждого мейлера
// экспериментально или расчитывается).
s:=""; log("LStartPhoneSel");
while (strfind(s,"CALLER")=0) readln(fd,s);
// Ищем в логе мейлера строку с подстрокой "CALLER", для IDC это будет
// строка "CALLER`S NUMBER +2ABCDEF1", либо "CALLER`S NUBER ?"
phone:=substr(s,strfind(s,"CALLER")+17,9);
close(fd);
log("LPhone:"+phone);
// Швырнули в MAX.LOG полученный номер телефона (для контроля)
if ((phone[1]='?') or (phone[2]=' ')) return 2;
// Если номер неопределен, заканчиваем работу.
phone:=substr(phone,3,6);
log("LPhoneSel:"+phone);
// Швырнули в MAX.LOG отселектированные значащие цифры номера, без
// плюсиков и категории абонента, то есть в виде ABCDEF (для 5080 :)
fd:=open("c:\\bbs\\max\\badphone.bbs",IOPEN_READ); while
(readln(fd,s)>0) if (s=phone) {
userremove(usr);
log("!Phone found in BLACKLOG:"+phone);
display_file("Misc\\BlackLog",nonstop);
}
close(fd);
// Пощупали телефон на предмет нахождения в черном списке
if (strfind(usr.xkeys,"T")<>0) {
log("LLaw User've came. First cycle of protection not activated!");
return 60;
}
// Пропустили, если юзер благонадежен и указал правильный номер
userfindopen("","",tu);
while(userfindnext(tu)=TRUE)
if ((tu.phone=phone) and (usr.name<>tu.name))
display_file("Misc\\DPhone",nonstop);
if (phone<>usr.phone) {
log("!Phone Unstable:"+usr.phone);
display_file("Misc\\BadPhone",nonstop);
input_str(usr.phone,INPUT_WORD,0,6,"Телефон (6 цифр без дефисов) :");
if (phone<>usr.phone) {
log("!Phone Unstable after input:"+usr.phone);
if (strfind(usr.xkeys,"V")<>0) {
fd:=open("c:\\bbs\\max\\badphone.bbs",IOPEN_WRITE | IOPEN_APPEND);
writeln(fd,phone+"\n");
close(fd);
usr.priv:=0;
display_file("Misc\\BadUser",nonstop);
return 1;
}
if (strfind(usr.xkeys,"U")<>0) usr.xkeys:=usr.xkeys+"V";
else usr.xkeys:=usr.xkeys+"U";
return 1;
};
log("!Phone changed to correct after input:"+usr.phone);
// Здесь если юзер попался хитрый, ему было дадено три попытки исправить
// ситуацию и ввести нормальный номер... это кстати полезно еще и если
// не дай бог был просто сбой в работе АОH'а
} else usr.xkeys:=usr.xkeys+"T"; return 0; }
// если все ок, присваиваем юзеру ключик "благонадежности"
============================================================================
Уважаемые коллеги! Если в обнаружили в данном документе ошибку или
неточные, устаревшие сведения; если вам хочется сделать добавление или
исправление в тексте FAQа, пожалуйста напишите об этом мне - нетмейлом на
2:5080/78.6@FidoNet
Большое спасибо всем, приславшим поправки, дополнения и советы.
Hа данный момент это:
Mike Petrov 2:5020/1413
Fedor Lizunkov 2:5020/960
Kirill K. 2:5063/53
Отдельное спасибо:
George Jot'у (2:5080/52.56) за его советы при настройке МАКСа
Lanius Corp. за прекрасную BBS - MAXIMUS.
Автор этого текста - Alex Shiloff, 2:5080/152@FidoNet
Страница 1 2 <<< Предыдущая
|