跳转到内容

Aros/开发者/文档/Rexx

来自Wikibooks,开放世界中的开放书籍
Aros 维基教科书的导航栏
Aros 用户
Aros 用户文档
Aros 用户常见问题
Aros 用户应用程序
Aros 用户DOS Shell
Aros/用户/AmigaLegacy
Aros 开发文档
Aros 开发者文档
从AmigaOS/SDL移植软件
Zune 初学者指南
Zune .MUI 类
SDL 初学者指南
Aros 开发者构建系统
特定平台
Aros x86 完整系统 HCL
Aros x86 音频/视频支持
Aros x86 网络支持
Aros 英特尔 AMD x86 安装
Aros 存储支持 IDE SATA 等
Aros Poseidon USB 支持
x86-64 支持
摩托罗拉 68k Amiga 支持
Linux 和 FreeBSD 支持
Windows Mingw 和 MacOSX 支持
Android 支持
Arm 覆盆子派支持
PPC Power Architecture
其他
Aros 公共许可证

一种用于处理文本和文件的脚本语言。

脚本只是一个纯文本文件。

rx script.rexx

IBM 的 Rexx 的版权(William S. Hawes)扩展

ARexx 是一种脚本语言,虽然您可以使用它来启动应用程序,但如果需要,最好使用常规的 DOS 脚本。

ARexx 比 DOS 强大得多,但实际上并非旨在替代它。ARexx 的主要优势在于它允许您编写可以与“主机”通信的脚本;也就是说,任何具有 ARexx 端口的应用程序。这允许 ARexx 控制应用程序(在它向 ARexx 公开的功能范围内)。由于单个脚本可以与多个主机通信,因此它可以协调应用程序之间的活动。它不理解的任何命令,它都会转发到当前选定的主机。默认情况下,主机是 shell 本身。

您调用 CALL 搜索库中的函数(根据此搜索顺序中的文档):1) 内部函数 2) 内置函数 3) 函数库和函数主机 4) 外部 AREXX 程序 - 将 Msg 转发到 AREXX 进程本身并扫描加载的文件

有三种不同的“模式”:- ARexx 命令主机 - 函数主机 - 函数库

  /* A simple program */
  say 'Hello World'

DO 控制结构始终以 DO 开始,以 END 结束。

DO UNTIL

   DO UNTIL [condition]
   [instructions]
   END

DO WHILE

   DO WHILE [condition is true]
   [instructions]
   END

遍历变量

   DO i = x TO y BY z
   [instructions]
   END

无限循环,直到使用 LEAVE 退出 - BREAK 有其他可能性,但您可能需要 LEAVE

   DO FOREVER
     IF [condition] THEN LEAVE
   END

循环固定次数

   DO i = x TO y BY z FOR a
   [instructions]
   END

条件语句

[编辑 | 编辑源代码]
   IF [condition] THEN
     [instruction]
   ELSE
     [instruction]

测试多个条件

   SELECT
     WHEN [condition] THEN
     DO
     [instruction]
     END
   OTHERWISE
     DO
     [instruction] or NOP
     END

NOP 表示不执行任何指令。

有一个命令可以检查变量是否为整数... DATATYPE(WHOLE)

命令和函数

[编辑 | 编辑源代码]

Rexx 区分命令和函数。使用 ADDRESS,您可以指示将命令发送到的位置。命令始终为一行。函数必须位于具有 ARexx 支持的库中,并使用 addlib 添加。您似乎想要函数语法,但正在使用命令端口。

更改命令行上传递的参数对调用的 Rexx 程序的可用方式。使用此开关,命令行上的每个参数都可用作单独的参数,而不是仅将组合的命令行参数作为单个内部参数提供的正常行为。

似乎“命令”模式确实不接收超过 1 个参数(arg[0])。

PARSE 指令特别强大;它结合了一些有用的字符串处理函数

parse [upper] origin template

其中 origin 指定源

  • arg(命令行变量)
  • linein(键盘)
  • pull(REXX 数据队列)
  • value(文字或函数)**带**required 指示文字的结束位置
  • var(变量)
  • version(版本/发行版号)

模板可以是

  • 变量列表
  • 列号分隔符
  • 文字分隔符

upper 是可选的;如果指定它,数据将转换为大写。如果您不希望输入大写,请使用“PARSE PULL var”。“PULL var”与“PARSE UPPER PULL var”相同

示例

使用变量列表作为模板

   myVar = "John Smith"
   parse var MyVar firstName lastName
   say "First name is:" firstName
   say "Last name is:"  lastName

显示以下内容

   First name is: John
   Last name is: Smith

使用分隔符作为模板

   myVar = "Smith, John"
   parse var MyVar LastName "," FirstName
   say "First name is:" firstName
   say "Last name is:"  lastName

还显示以下内容

   First name is: John
   Last name is: Smith

使用列号分隔符

   myVar = "(202) 123-1234"
   parse var MyVar 2 AreaCode 5  7 SubNumber
   say "Area code is:" AreaCode
   say "Subscriber number is:" SubNumber

显示以下内容

   Area code is: 202
   Subscriber number is: 123-1234

模板可以使用变量、文字分隔符和列号分隔符的组合。

高级数据结构

[编辑 | 编辑源代码]
array(var, var)
record.field1
record.field2
/* check if a library function is available */
SHOW (L, 'rexxsupport.library')

/* if function not available - add library*/
ADDLIB ('rexxsupport.library',0,-30,0)

/* SHOWDIR (directory, {mode), [pad]) */
SHOWDIR ('sys:')

/* if function  - remove library*/
REMLIB ('rexxsupport.library')
parse arg height, width, depth
PROCEDURE EXPOSE WORD

您可以通过“PROCEDURE EXPOSE”语句将整个词干传递给在同一脚本中声明的函数,例如

...
test: procedure expose stem.
say stem.1 stem.a stem.a.ciao
...

(注意要放置“.”,否则只有词干变量对函数“test”可见,而不是所有词干。对“stem.”的任何修改都是全局的。无法将词干传递给外部函数

ARexx 还将在与它同名的文件中以及<name>.rexx) 中搜索函数,这两者都在当前目录和 REXX: 中。不要在我的文件上放置 .rexx,因为 ~(*:*) 匹配函数,*.rexx 普通脚本,*.ced ...

文件操作

[编辑 | 编辑源代码]
/* Create a file */
if open('file', 'ram:test', 'w') then
  call writeln('file' 'data')
  call close('file')
else
  say 'unable to open'
/* Read a file */
if open('file', 'ram:test', 'r') then
  call readch('file' var) /* read first var characters */
  do while ~eof('file')
    say line
    line=readln('file') /* read next line */
  end
  call close('file')
/* Read a file */
if open('file', 'ram:test', 'a') then
  say 'it is here'
else 
  say 'it is not here'
position = seek ('file', var, string) /* var is +/- bytes from start and string can be b, c or e */

IBM EOL (end of line) = <CR><LF> or (^M^J)
Amiga/UNIX EOL = <LF> or (^J)
Macintosh EOL = <CR> or (^M)
IBM EOF = <EOL><CTRL-Z> or (^M^J^Z)
Amiga EOF = <NULL> or (), optionally <LF> or (^J)

当然,空值表示没有任何数据。

IBM 文本编辑器在每个<RETURN>处执行<CR><LF>。据我所知,大多数 Amiga 软件只执行<LF>,并且当没有更多字节要读取时,文件末尾只是用指示符表示。

ARexx EOF() 指示您何时用完从文件中读取的内容。据我所知,它不会四处查找 IBM 认为表示文件末尾的内容,而只是在注意到文件已达到其容量末尾时(例如,您有一个 1024 字节的文件,在读取 1024 字节后,您将到达文件末尾或 EOF)。

do UNTILEF("FILE") /* 在此处执行一些读取操作或其他操作 */ end

将“call readch('rfile',1)”更改为“say c2d(readch('rfile',1))”以显示“ascii”代码。(请注意,只有字符代码< 127 是 ASCII)

语法、循环错误等。

跟踪

信号

程序IPC

[编辑 | 编辑源代码]
rx "address command Dir"

与DOS通信,

address "program-name"

您可以使用HELP命令获取任何MUI程序的ARexx命令。以下是以IBrowse为例。

/* CheckIB.rexx*/

address IBrowse

'HELP vd0:IB.txt'

HELP命令后的驱动器规范是输出的驱动器和文件名。当然,您正在检查的程序必须正在运行,以便端口可用。输出将显示每个MUI程序具有的标准ARexx命令,然后是正在检查的特定程序的特定命令。

通常,您会为您的应用程序提供一个命令列表,这些命令将由安装的钩子“自动”处理。

当您使用未“自动”处理的命令(因为它们不在命令列表中)时,您需要使用您提供的功能(例如MUIA_Application_RexxHook)。

由于这些属性似乎没有到位,您需要回退到普通的方式,这意味着您将以某种方式“发明”如何将您的普通命令与arexx命令“同步”。

Regina 3.00

CALL {symbol | string} [expression] [,expression,...]
DO [var=exp] [To exp] [BY exp]] [FOR exp] [FOREVER] [WHILE exp | UNTIL exp]
DROP variable [variable...]
ELSE [;] [conditional statement]
END [variable]
EXIT [expression]
IF expression [THEN] [;] [conditional statement]
INTERPRET expression
ITERATE [variable]
LEAVE [variable]
NOP
NUMERIC {DIGITS | FUZZ} expression  or: NUMERIC FORM {SCIENTIFIC | ENGINEERING}
OPTIONS [FAILAT expression]  or: OPTIONS [PROMPT expression]   or: OPTIONS [RESULTS]
OTHERWISE [;] [conditional statement]
PARSE [UPPER] inputsorce [template] [,template...]
PROCEDURE [EXPOSE variable [variable...]]
PULL [template] [,template...]
PUSH [expression]
QUEUE [expression]
RETURN
SAY [expression]
SELECT
SHELL [symbol | string] [expression]
SIGNAL {ON |OFF} condition   or: SIGNAL [VALUE] expression
THEN[;] [conditional statement]
TRACE [symbol|string|[[VALUE] expression]]
UPPER variable [variable...]
WHEN expression [THEN [;] [conditional statement]]
ABBREV
ABS
ADDLIB
ADDRESS [Symbol|string|VALUE] [expression]]
ALLOCATED
ARG [template] [,template...]
B2C
B2X
BEEP
BITAND
BITCHG
BITCLR
BITCOMP
BITOR
BITSET
BITTST
BITXOR
BUFTYPE
C2B
C2D
C2X
CD
CENTER
CENTRE
CHANGESTR
CHARIN
CHAROUT
CHARS
CHDIR
CLOSE
COMPARE
COMPRESS
CONDITION
COPIES
COUNTSTR
CRYPT
D2C
D2X
DATATYPE
DATE
DELSTR
DELWORD
DESBUF
DIGITS
DIRECTORY
DROPBUF
DUMPFILES
DUMPTREE
DUMPVARS
EOF
ERRORTEXT
EXISTS
EXPORT
FREELISTS
FREESPACE
FUZZ
GETCLIP
GETENV
GETPATH
GETPID
GETSPACE
GETTID
HASH
IMPORT
INDEX
INSERT
JUSTIFY
LASTPOS
LEFT
LENGTH
LINEIN
LINEOUT
LINES
LISTLEAKED
MAKEBUF
MAX
MEMORYSTATS
MIN
OPEN
OVERLAY
POPEN
POS
PRAGMA
QUALIFY
QUEUED
RANDOM
RANDU
READCH
READLN
REMLIB
REVERSE
RIGHT
RXFUNCADD
RXFUNCDROP
RXFUNCERRMSG
RXFUNCQUERY
RXQUEUE
SEEK
SETCLIP
SHOW
SIGN
SLEEP
SOURCELINE
SPACE
STATE
STREAM
STRIP
STORAGE
SUBSTR
SUBWORD
SYMBOL
TIME
TRACE
TRIM
TRACEBACK
TRANSLATE
TRUNC
UNAME
UNIXERROR
UPPER
USERID
VALUE
VERIFY
WORD
WORDINDEX
WORDLENGTH
WORDPOS
WORDS
WRITECH
WRITELN
X2B
X2C
X2D
XRANGE

运算符

[编辑 | 编辑源代码]
OPERATOR		PRIORITY		OPERATOR DEFINITION

~			8			Logical NOT
+			8			Prefix Conversion
-			8			Prefix Negation
**			7			Exponentiation
*			6			Multiplication
/			6			Division
%			6			Integer Division
//			6			Remainder
+			5			Addition
-			5			Subtraction
||			4			Concatenation
(blank)			4			Blank Concatenation
==			3			Exact Equality
~==			3			Exact Inequality
=			3			Equality
~=			3			Inequality
>			3			Greater Than
>=,~<			3			Greater Than or Equal To
<			3			Less Than
<=,~>			3			Less Than or Equal To
&			2			Logical AND
|			1			Logical Inclusive OR
^,&&			1			Logical Exclusive OR

RexxSupport

[编辑 | 编辑源代码]
LONG rxsupp_allocmem(struct Library *, struct RexxMsg *, UBYTE **);
LONG rxsupp_baddr(struct Library *, struct RexxMsg *, UBYTE **);
LONG rxsupp_closeport(struct Library *, struct RexxMsg *, UBYTE **);
LONG rxsupp_delay(struct Library *, struct RexxMsg *, UBYTE **);
LONG rxsupp_delete(struct Library *, struct RexxMsg *, UBYTE **);
LONG rxsupp_forbid(struct Library *, struct RexxMsg *, UBYTE **);
LONG rxsupp_freemem(struct Library *, struct RexxMsg *, UBYTE **);
LONG rxsupp_getarg(struct Library *, struct RexxMsg *, UBYTE **);
LONG rxsupp_getpkt(struct Library *, struct RexxMsg *, UBYTE **);
LONG rxsupp_makedir(struct Library *, struct RexxMsg *, UBYTE **);
LONG rxsupp_next(struct Library *, struct RexxMsg *, UBYTE **);
LONG rxsupp_null(struct Library *, struct RexxMsg *, UBYTE **);
LONG rxsupp_offset(struct Library *, struct RexxMsg *, UBYTE **);
LONG rxsupp_openport(struct Library *, struct RexxMsg *, UBYTE **);
LONG rxsupp_permit(struct Library *, struct RexxMsg *, UBYTE **);
LONG rxsupp_rename(struct Library *, struct RexxMsg *, UBYTE **);
LONG rxsupp_reply(struct Library *, struct RexxMsg *, UBYTE **);
LONG rxsupp_showdir(struct Library *, struct RexxMsg *, UBYTE **);
LONG rxsupp_showlist(struct Library *, struct RexxMsg *, UBYTE **);
LONG rxsupp_statef(struct Library *, struct RexxMsg *, UBYTE **);
LONG rxsupp_typepkt(struct Library *, struct RexxMsg *, UBYTE **);
LONG rxsupp_waitpkt(struct Library *, struct RexxMsg *, UBYTE **);

RexxSyslib

[编辑 | 编辑源代码]
UBYTE *CreateArgstring(UBYTE *string, ULONG length) (A0, D0)
void DeleteArgstring(UBYTE *argstring) (A0)
ULONG LengthArgstring(UBYTE *argstring) (A0)
struct RexxMsg *CreateRexxMsg(struct MsgPort *port, UBYTE *extension, UBYTE *host) (A0, A1, D0)
void DeleteRexxMsg(struct RexxMsg *packet) (A0)
void ClearRexxMsg(struct RexxMsg *msgptr, ULONG count) (A0, D0)
BOOL FillRexxMsg(struct RexxMsg *msgptr, ULONG count, ULONG mask) (A0, D0, D1)
BOOL IsRexxMsg(struct RexxMsg *msgptr) (A0)
void LockRexxBase(ULONG resource) (D0)
void UnlockRexxBase(ULONG resource) (D0)

将Regina/Rexx添加到程序中

[编辑 | 编辑源代码]

http://aminet.net/search?query=Minrexx http://www.pcguru.plus.com/tutorial/introduction.html

设置您自己的Rexx端口非常容易。它只是一个标准的MsgPort。如果您只是在任何消息上退出并且不解析发送到端口的命令,那么您甚至不需要打开rexxsyslib.library...

struct MsgPort *CreatePubPort (UBYTE *name, LONG pri)
/* create a port if port name is not already used */
{
struct MsgPort *pubport;

port = NULL;
Forbid ();
if (FindPort (name) == NULL)
pubport = CreateMsgPort (name, pri);
Permit ();
return (pubport);
}

现在端口已创建,我们只需要等待消息。

static void PubPortWait (struct MsgPort *pubport)
/* wait for a message or signal on our pubport */
{
ULONG port_mask, signals;
struct RexxMsg *msg;

port_mask = (1L << RexxPort->mp_SigBit);
while (1)
	{
	signals = Wait (port_mask | SIGBREAKF_CTRL_C);
	if (signals & SIGBREAKF_CTRL_C)
	Quit("Aborting");
	if (signals & port_mask)
		{
		while ((msg = (struct RexxMsg *) GetMsg (pubport)) != NULL)
			{
			ProcessRexxMsg (msg); /* routine parses the REXX message */
			ReplyMsg ((struct Message *) msg);
			}
		}
	}
}

ProcessRexxMsg()可以打印您的消息并退出,但请记住使用ReplyMsg()。如果您想解析Arexx命令,则工作量不会增加太多。以上内容来自较长的打印代码示例,并使用来自“arexx.h”和“arexxsyslib.h”的一些REXX包含,但如果您将在端口接收到的任何消息上退出,则无需打开rexxsyslib.library。

http://utilitybase.com/forum/index.php?action=vthread&forum=15&topic=1915

/*
#include <proto/exec.h>
#include <proto/alib.h>
#include <proto/rexxsyslib.h>

#include <exec/ports.h>
#include <rexx/errors.h>
#include <rexx/storage.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
    struct MsgPort *port;
    struct RexxMsg *msg;
    struct Library *RexxSysBase;
    char *value;
    
    RexxSysBase = OpenLibrary("rexxsyslib.library", 0);
    if (RexxSysBase == NULL)
    {
	puts("Error opening rexxsyslib.library");
	return 20;
    }
    
    port = CreatePort("VARTEST", 1);
    if (port == NULL)
    {
	puts("Error creating port");
	CloseLibrary(RexxSysBase);
	return 20;
    }

    printf("Port created %x, waiting for message\n", port);
    WaitPort(port);
    msg = (struct RexxMsg *)GetMsg(port);
    puts("Got a message");
    if (!IsRexxMsg(msg))
    {
	puts("Message is not a rexxmsg");
	ReplyMsg((struct Message *)msg);
	DeletePort(port);
	CloseLibrary(RexxSysBase);
	return 20;
    }

    puts("Is a rexx message");
    if (!CheckRexxMsg(msg))
    {
	puts("Message is not from rexx interpreter");
	msg->rm_Result1 = RC_ERROR;
	ReplyMsg((struct Message *)msg);
	DeletePort(port);
	CloseLibrary(RexxSysBase);
	return 20;
    }

    puts("Message is from the rexx interpreter");
    if (!GetRexxVar(msg, "A", &value))
    {
	puts("Error during retrieval of value");
	return 20;
    }
    printf("Length string: %d\n", strlen(value));
    printf("Value of A: %s\n", value);
    
    SetRexxVar(msg, "A", "2", 1);
    msg->rm_Result1 = RC_OK;
    msg->rm_Result2 = NULL;
    ReplyMsg((struct Message *)msg);
    DeletePort(port);
    CloseLibrary(RexxSysBase);
    
    return 0;
}

您现在可以使用以下脚本向此小程序发送消息

/* Testing the variable interface */
a = 1
say 'a before call' a
ADDRESS 'VARTEST' test
say 'a after call' a

将其保存为(例如)'vartest.rexx',并使用以下命令运行:

rx vartest.rexx

示例脚本

[编辑 | 编辑源代码]

更多示例

  /* Calculate some squares and cubes      */
  do i = 1 to 10      /* 10 interations    */
     say i i**2 i**3  /* calculations      */
     end
  say ' all done '
  /* Even or odd? */
  do i = 1 to 10
     if i//2 = 0 then type = 'even'
                 else type = 'odd'
     say i 'is' type
     end
  /* Defining and calling a function     */
  do i = 1 to 5
     say i square(i)     /* call square  */
     end
  exit            /* all done            */
  square:		/* function name       */
  arg x		/* get the "argument"  */
  return x**2     /* square it and return*/
  /* Demonstrate "results" tracing */
  trace results
  sum=0;sumsq=0;
  do i = 1 to 5
     sum = sum + i
     sumsq = sumsq + i**2
     end
  say 'sum=' sum 'sumsq=' sumsq
  /* Calculate age in days */
  say 'Please enter your age'
  pull age
  say 'You are about' age*365 'days old'
DO .... ; you have the code already
  line = READLN(textfile)
  IF line = marker line THEN DO
    target = READLN(textfile)
  END
END
/* File to read */
IF ~OPEN("in", "Path:yourTextFile", "READ") THEN DO
SAY "Can't open 'Path:yourTextFile' for reading."
CALL CLOSE('in')
EXIT
END

/* File to write */
IF ~OPEN("out", "Ram:filename", "WRITE") THEN DO
SAY "Can't open 'Ram:filename' for writing."
CALL CLOSE('out')
EXIT
END

/* Write lines that start with "(" to Ram:filename */
DO UNTIL EOF('in')
line = READLN('in')
temp = STRIP(line, 'L')
IF LEFT(temp, 1) = '(' THEN CALL WRITELN('out', line)
END
/* */
options results

arg sourcefile

if open(input, sourcefile, R) then do
if ~open(output, "ram:output", W) then call error

Do until eof(input)
line=readln(input)
if pos('(',line)=1 then writeln(output,line)    /* line begins with '(' at POS 1 */
end
close(input)
close(output)
end
EXIT

/* function */
ERROR:
SAY "ERROR"
EXIT
/*Bin2AHex*/
/* Convert a binary file to a ASCII representation of Hex.*/

if ~open('bufbin', 'RAM:buffer.bin', 'READ') then do
say "Can't open 'RAM:buffer.bin' for reading."
exit
end

if ~open('buftxt', 'RAM:buffer.txt','WRITE') then do
say "Can't open 'RAM:buffer.txt' for writing."
exit
end

/* 500 seems do be the max for c2x() */
max = 500
in = readch('bufbin', max)
DO until eof('bufbin')
call writech('buftxt',c2x(in))
in = readch('bufbin', max)
END

call close('bufbin')
call close('buftxt')

/* That's All Folks! */
/* Here's a more visible way to enter the control codes */
CSI='9b'x /* control sequence introducer */
boldOn=CSI'1m'
boldOff=CSI'22m'
IF OPEN("Env", "Env:File", "R") THEN DO
filename = READLN("Env")
CALL CLOSE("Env")
END
/* OPEN alone will pop up a filerequester */
OPEN NAME <filename>
/* Displays the data in the source string */
parse source source   /* type results called resolved extension host */
words=words(source)
shell command 'RequestChoice >Nil: Source',
'"Invocation type:' word(source,1)'*n',
||'Result requested:' word(source,2)'*n',
||'Called name:' word(source,3)'*n',
||'Resolved name:' DelWord(trim(DelWord(source,words-1)),1,3)'*n',
||'Search extension:' word(source,words-1)'*n',
||'Initial command host:' word(source,words)'"',
'OK'
/* Grabs the Users Hz thus the tick rate per second of the persons machine
(either 50 or 60 generally) amd pouts it into variable 'f' */
PARSE UPPER VERSION f
f=SUBSTR(WORD(f,6),1,2)

DO UNTIL <expression is valid> | i=<value ya want>
/* Call a delay and do nothing for value times(*) variable 'f' */
Call Delay(1*f)
i=i+1
End

您可以使其使某个值变为真或无限期尝试。否则,您可以在DO UNTIL部分的任何阶段使用“Leave”命令退出循环。

因此,以下加载库工作良好…

libs = "rexxreqtools.library rexxdossupport.library rexxkuang11.library
rexxsupport.library rexxtricks.library"
DO UNTIL libs='';PARSE VAR libs lib libs
IF EXISTS('libs:'lib)|EXISTS('Libs/'lib)|EXISTS(lib) THEN DO
IF ~show('L',lib) THEN call addlib(lib,0,-30,0);END;ELSE DO
/* error output line whether say or echo or defined */
cECHO('Cannot load 'lib);END;END

查找每个键的键码,这可以在ARexx中完成…

rx <RAW: "
do while 1;
z=readch(stdin,1);
c=c2d(z);
if c2d(bitand('7f'x,z)) < 33 then
z='<'c'>';
call writech(stdout,z);
end

(所有内容都在一行上)

CTRL-C将停止此操作。请注意,以上和RAW-KEY Intui消息(OpenWindow()/intuition,IDCMP标志)是获取按键信息的唯一简单且*系统合法*的方式。

这将提取文件名扩展名(例如.lha或.8svx)及其长度。在重命名文件时,它可能很有用。在转换脚本中使用它,该脚本可以转换不同的文件类型,因此archive.lha变为archive.lzx,pic.gif变为pic.png。

STRING = ExtPart(filename)
PARSE VAR string extlen ext
/* ExtPart(filename)
** Returns filename extension and length of extension
** freely usable, freely distributable, intellectual property:
** Andreas Mixich <humpty@...>
*/

PARSE ARG filename

posi = LastPos('.',filename)
ext = SubStr(filename,(posi+1))
extlen = Length(SubStr(filename,posi))-1
extpartinfo = extlen||' '||ext
RETURN(extpartinfo)

这个创建了一个有效的路径,使用它更好。不再有RAM:Envfilename错误,而是RAM:Env/filename 此外,它使RAM:脱离Ram Disk

没什么特别的,不过,您可以通过使用rexxdossupport.library/AddPart(pathname,“”)获得相同的结果(除了RAM:<-Ram Disk:) - 不要忘记“” 。

STRING = ValPath("sys:Tools")
/* ValPath()
** make a vaild path out of path (in case it lacks '/')
** Concentrates "Ram Disk:" to "Ram:", so we get rid of this annoying space
** Freely usabel, freely distributable, intellectual property of
** Andreas Mixich <humpty@...>
*/

valpath:
PARSE ARG path

IF (LastPos('/',path) ~= Length(path) & Pos('/',path) ~= 0) THEN
path = path||'/'
ELSE
IF (LastPos(':',path) ~= Length(path) & Pos('/',path) = 0) THEN
path = path||'/'

IF Left(path,9) = "Ram Disk:" THEN
path = Insert("Ram",DelStr(path,1,8))

RETURN(path)

这个小程序用在我的所有ARexx脚本中,这些脚本需要外部端口可用。(WaitForPort)由于不喜欢在任何脚本中写相同的代码行,只需从GoldED列表请求器中选择此例程,它就会附加到我的源代码中。该函数很简单

BOOL = IfPort(portname, prog, mode)

portname是应用程序的ARexx端口名称,prog是应用程序的完整路径,如果需要启动,mode可以为空或WB。如果使用WB,它将使用WBRun启动。有时这很有用。

该函数的结果为BOOL(TRUE或FALSE),因此易于处理流程控制。

在这个例程中,您会发现我使用的另一个函数

myERR()

您可以将其替换为您想要的任何内容或将其删除。使用这样的通用例程,因为它们更强大,因此可以在myERR()或WB请求器或任何其他内容中进行一些日志记录。

/*///------------------------------ "IfPort(portname,prog,mode)" ------------------------------ */

/*
** IfPort(portname, prog, mode)
** Shows if portname is available, attempts to launch program if not
** Freely usable, freely distributable, intellectual properties:
** Andreas Mixich <humpty@...>
*/

ifport:

PARSE ARG portname, prog, mode

IF ~Show(P,portname) THEN
DO
IF mode = WB THEN
ADDRESS COMMAND wbrun||' >NIL: '||prog
ELSE
ADDRESS COMMAND 'run >NIL: '||prog

ADDRESS COMMAND 'WaitForPort '||portname
IF RC ~= 0 THEN
DO
Call myERR('Error: Could not start '||prog)
RETURN(FALSE)
END
ELSE
RETURN(TRUE)
END
RETURN(TRUE)
/*\\\*/

给你,这是我在Rexx中见过的最快的SQRT函数,在c.l.rexx中找到的

/* */
parse arg N
if N <= 0 then exit
s = time('e')
call MethodB(N)
say time('e') - s
exit
MethodB:
x1 = 1
x0 = N
if N ~= 0 then
do until x1 = x0
x0 = x1
x1 = ((x0 * x0) + N) / (2 * x0)
end
else x1 = 0
say x1
return

一个非常简单的函数,很少使用,但作为Translate()函数的一些示例提供给新手,并使函数集更完整。(由于有Upper(),为什么不应该也有Lower())

/*
** Lower()
** Like Upper(), but this one makes a string lowercase.
** Considers german unmlauts and some accents.
** TODO: Add more national characters. Do you know of any missing
** (and where to find them on the keyboard) ?
*/
Lower: PROCEDURE
PARSE ARG string
res =
Translate(string,'abcdefghijklmnopqrstuvwxyzäöüáéíóú','ABCDEFGHIJKLMNOPQRSTUVWXY\
ZÄÖÜÁÉÍÓÚ')
RETURN(res)
/* convert a file into sentences */
arg fileid .
input=''
do until LINES(fileid)=0
in=LINEIN(fileid)
input=input in
end
t=LINEOUT("sentence.txt","--- "fileid" ---")
out=''
do i=1 to LENGTH(input)
char=SUBSTR(input,i,1)
out=out||char
if char="." then do
out=STRIP(SPACE(out))
t=LINEOUT("sentence.txt",out)
out=''
end
end
out=STRIP(SPACE(out))
t=LINEOUT("sentence.txt",out)
exit

建议您在打开文件时执行类似以下操作以检查文件是否已成功打开

if open(tempfile,'t:ms_scenes',w) then do
call writeln(tempfile,'SCENE1')
/* blah, blah... */
call close(file)
end
else do
say 'Unable to open temp file!'
exit
end

获取文件大小

/* */

parse arg file

if file="" then do
say "no file given"
exit
end

s=statef(file)
if s="" then do
say "can't find file '"file"'"
exit
end

parse var s type size d d d d d comment
if type~="FILE" then do
say "'"file"' is not a valid file name"
exit
end
say "file '"file"':" size


华夏公益教科书