compiled!

This commit is contained in:
norayr 2017-04-14 23:16:31 +04:00
parent 4c73f414b0
commit f3c9e3e006
2 changed files with 185 additions and 115 deletions

263
IRC.Mod
View file

@ -5,7 +5,6 @@ CONST
msgLen* = 512; (* message length not more than 512 characters *)
cmdPing* = "PING";
cmdPong* = "PONG";
zzo* = "001";
cmdMode* = "MODE";
cmdJoin* = "JOIN";
cmdUser* = "USER";
@ -13,20 +12,30 @@ CONST
CR* = 0DX;
LF* = 0AX;
numRPLWELCOME = "001";
numRPLYOURHOST = "002";
numRPLCREATED = "003";
numRPLMYINFO = "004";
TYPE
chn* = ARRAY 32 OF CHAR;
chnlist* = POINTER TO ARRAY OF chn;
msg* = ARRAY msgLen OF CHAR;
callBack* = PROCEDURE(VAR in: ARRAY OF CHAR);
instance* = RECORD
owner*, user*, nick*, host*, port*: chn;
connection*: Internet.Socket;
channelList*: chnlist;
callback*: callBack;
END;
VAR
connection : Internet.Socket;
eol* : ARRAY 3 OF CHAR;
channelList: chnlist;
PROCEDURE setChannelList*(VAR chnl: chnlist);
BEGIN
channelList := chnl;
END setChannelList;
(* string operations *)
(* cuts line, takes the part till the eol *)
PROCEDURE cutLine(VAR src, dst: ARRAY OF CHAR);
@ -44,13 +53,26 @@ BEGIN
REPEAT
dst[i] := src[i];
INC(i);
UNTIL i = pos;
UNTIL (i = pos) OR (i = LEN(dst)-2);
dst[i] := src[i];
INC(i);
dst[i] := 0X;
dst[i+1] := 0X
END;
END cutLine;
PROCEDURE terminateLine(VAR str: ARRAY OF CHAR);
VAR
found: BOOLEAN;
pos : INTEGER;
pattern : ARRAY 1 OF CHAR;
BEGIN
pattern[0] := LF;
Strings.FindNext(pattern, str, 0, found, pos);
IF found THEN
IF (pos + 1) < LEN(str) THEN
str[pos + 1] := 0X
END
END;
END terminateLine;
PROCEDURE formUserLine(VAR user, owner, result: ARRAY OF CHAR);
BEGIN
@ -73,71 +95,22 @@ BEGIN
Strings.Append(eol, result);
END formNickLine;
PROCEDURE Auth*(user, owner, nick: ARRAY OF CHAR): BOOLEAN;
VAR
userRequest, nickRequest: ARRAY 255 OF CHAR;
b : BOOLEAN;
PROCEDURE formModeLine(VAR str, nick: ARRAY OF CHAR);
BEGIN
COPY (cmdMode, str);
Strings.Append(" ", str);
Strings.Append(nick, str);
Strings.Append(" +B", str);
Strings.Append(eol, str);
END formModeLine;
formUserLine(user, owner, userRequest);
Out.String("sending:"); Out.Ln;
Out.String(userRequest); Out.Ln;
b := Internet.Write(connection, userRequest);
IF b THEN Out.String("wrote!"); Out.Ln ELSE Out.String("write failed"); Out.Ln END;
formNickLine(nick, nickRequest);
Out.String("sending:"); Out.Ln;
Out.String(nickRequest); Out.Ln;
IF b THEN Out.String("wrote!"); Out.Ln ELSE Out.String("write failed"); Out.Ln END;
RETURN b
END Auth;
PROCEDURE Receive*(VAR str: ARRAY OF CHAR): BOOLEAN;
VAR
b: BOOLEAN;
PROCEDURE formJoinLine(VAR ln, chan: ARRAY OF CHAR);
BEGIN
b := Internet.Read(connection, str);
IF b THEN
Out.String("received:"); Out.Ln;
Out.String(str); Out.Ln;
ELSE
Out.String("receive failed"); Out.Ln;
END;
RETURN b
END Receive;
PROCEDURE Send*(str: ARRAY OF CHAR): BOOLEAN;
VAR
b : BOOLEAN;
BEGIN
b := Internet.Write(connection, str);
IF b THEN
Out.String("sent:"); Out.Ln;
Out.String(str); Out.Ln;
ELSE
Out.String("sending failed"); Out.Ln;
END;
RETURN b
END Send;
PROCEDURE Connect*(host, port: ARRAY OF CHAR): BOOLEAN;
VAR
res: BOOLEAN;
BEGIN
res := Internet.Connect(host, port, connection);
RETURN res
END Connect;
PROCEDURE Disconnect*;
BEGIN
Internet.Disconnect(connection);
END Disconnect;
COPY(cmdJoin, ln);
Strings.Append(" ", ln);
Strings.Append(chan, ln);
Strings.Append(eol, ln);
END formJoinLine;
PROCEDURE isPing(VAR line: ARRAY OF CHAR): BOOLEAN;
VAR
@ -151,51 +124,139 @@ BEGIN
END
END isPing;
PROCEDURE Pong(VAR line: ARRAY OF CHAR);
PROCEDURE serverMsg(VAR line: ARRAY OF CHAR): BOOLEAN;
BEGIN
IF line[0] = ':' THEN RETURN TRUE ELSE RETURN FALSE END
END serverMsg;
PROCEDURE rplWelcome(VAR line : ARRAY OF CHAR): BOOLEAN;
VAR
found: BOOLEAN;
pos : INTEGER;
i : INTEGER;
BEGIN
Strings.FindNext(numRPLWELCOME, line, 0, found, pos);
IF found THEN RETURN TRUE ELSE RETURN FALSE END
END rplWelcome;
(* instance functions *)
PROCEDURE setChannelList*(VAR inst: instance; chnl: chnlist);
BEGIN
inst.channelList := chnl;
END setChannelList;
PROCEDURE Receive*(VAR inst: instance; VAR str: ARRAY OF CHAR): BOOLEAN;
VAR
b: BOOLEAN;
BEGIN
b := Internet.Read(inst.connection, str);
IF b THEN
Out.String("received:"); Out.Ln;
Out.String(str); Out.Ln;
ELSE
Out.String("receive failed"); Out.Ln;
END;
RETURN b
END Receive;
PROCEDURE Send*(VAR inst: instance; str: ARRAY OF CHAR): BOOLEAN;
VAR
b : BOOLEAN;
BEGIN
terminateLine(str);
b := Internet.Write(inst.connection, str);
IF b THEN
Out.String("sent:"); Out.Ln;
Out.String(str); Out.Ln;
ELSE
Out.String("sending failed"); Out.Ln;
END;
RETURN b
END Send;
PROCEDURE Auth*(inst: instance): BOOLEAN;
VAR
userRequest, nickRequest: ARRAY 255 OF CHAR;
b : BOOLEAN;
BEGIN
formUserLine(inst.user, inst.owner, userRequest);
b := Send(inst, userRequest);
IF b THEN
formNickLine(inst.nick, nickRequest);
b := Send(inst, nickRequest);
END;
RETURN b
END Auth;
PROCEDURE Connect*(VAR inst: instance): BOOLEAN;
VAR
res: BOOLEAN;
BEGIN
res := Internet.Connect(inst.host, inst.port, inst.connection);
RETURN res
END Connect;
PROCEDURE Disconnect*(VAR inst: instance);
BEGIN
Internet.Disconnect(inst.connection);
END Disconnect;
PROCEDURE Pong(VAR inst: instance; VAR line: ARRAY OF CHAR);
VAR
tmp: ARRAY msgLen OF CHAR;
b : BOOLEAN;
BEGIN
cutLine(line, tmp);
tmp[1] := 'O'; (* replace "PING" by "PONG" *)
b := Send(tmp);
b := Send(inst, tmp);
END Pong;
PROCEDURE processResponse(VAR line: ARRAY OF CHAR);
PROCEDURE Mode(VAR inst: instance);
VAR
str : ARRAY msgLen OF CHAR;
b : BOOLEAN;
BEGIN
IF isPing(line) THEN Pong(line) END;
(*
IF line[0] = ':' THEN
IF contains001(line) THEN
sendMode(line);
sendJoin;
END;
Strings.FindNext(IRC.zzo, str, 0, patternFound, patternPos);
IF patternFound THEN
Out.String("001 found"); Out.Ln;
COPY ("MODE ", str3);
Strings.Append(nick, str3);
Strings.Append(" +B", str3);
Strings.Append(eol, str3);
Strings.Append(0X, str3);
b2 := IRC.Send(str3);
COPY("JOIN ", str3);
Strings.Append("#oberon", str3);
Strings.Append(eol, str3);
Strings.Append(0X, str3);
b2 := IRC.Send(str3);
END;
END;*)
formModeLine(str, inst.nick);
b := Send(inst, str);
END Mode;
PROCEDURE Join(VAR inst: instance);
VAR
str: ARRAY msgLen OF CHAR;
b: BOOLEAN;
BEGIN
formJoinLine(str, inst.channelList^[0]);
b := Send(inst, str);
END Join;
PROCEDURE processResponse(VAR inst: instance; VAR line: ARRAY OF CHAR);
BEGIN
IF isPing(line) THEN Pong(inst, line) END;
IF serverMsg(line) THEN
IF rplWelcome(line) THEN
Mode(inst);
Join(inst);
ELSE
inst.callback(line);
END;
END;
END processResponse;
PROCEDURE Loop*;
PROCEDURE Loop*(VAR inst: instance);
VAR
b : BOOLEAN;
str : ARRAY msgLen OF CHAR;
BEGIN
REPEAT
b := Receive(str);
processResponse(str);
b := Receive(inst, str);
processResponse(inst, str);
UNTIL ~b;
END Loop;

View file

@ -2,32 +2,41 @@ MODULE test;
IMPORT IRC, Out, Strings := ooc2Strings;
VAR
owner, user, nick, host, port, channel: ARRAY 32 OF CHAR;
PROCEDURE clbk(VAR in: ARRAY OF CHAR);
BEGIN
Out.String("callback procedure is running, youhoo!"); Out.Ln;
Out.String("input:"); Out.Ln;
Out.String(in); Out.Ln;
Out.Ln;
END clbk;
PROCEDURE testBot;
VAR
b: BOOLEAN;
inst: IRC.instance;
channels : IRC.chnlist;
b: BOOLEAN;
BEGIN
inst.owner := "norayr_shimamoto";
inst.user := "nakata_san";
inst.nick := "oshima";
inst.host := "irc.freenode.net";
inst.port := "6667";
inst.callback := clbk;
NEW(channels, 1);
channels[0] := channel;
IRC.setChannelList(channels);
channels[0] := "#oberon";
IRC.setChannelList(inst, channels);
IF IRC.Connect(host, port) # FALSE THEN
b := IRC.Auth(user, nick, owner);
IRC.Loop;
IF IRC.Connect(inst) # FALSE THEN
b := IRC.Auth(inst);
IRC.Loop(inst);
END;
END testBot;
BEGIN
owner := "norayr_tanakian";
user := "norayr_tanakian";
nick := "vocbot";
host := "irc.freenode.net";
port := "6667";
channel := "#oberon";
testBot;