ARexx support

This commit is contained in:
Carsten Sonne Larsen 2021-01-11 20:33:26 +01:00
parent 3a52c27a9c
commit 6eb56b056e
6 changed files with 325 additions and 11 deletions

19
.vscode/c_cpp_properties.json vendored Normal file
View File

@ -0,0 +1,19 @@
{
"configurations": [
{
"name": "amiga",
"includePath": [
"/opt/amiga/m68k-amigaos/ndk-include/",
"/opt/amiga/m68k-amigaos/clib2/include/",
"${workspaceFolder}/src/lib/"
],
"defines": ["AMIGA"],
"compilerPath": "/opt/amiga/bin/m68k-amigaos-gcc",
"cStandard": "c99",
"cppStandard": "c++98",
"intelliSenseMode": "${default}",
"compilerArgs": []
}
],
"version": 4
}

View File

@ -1,10 +1,13 @@
#!/bin/sh #!/bin/sh
# #
# This file is public domain # This file is public domain
# #
# Project homepage: # Project homepage:
# https://amath.innolan.net # https://amath.innolan.net
# #
# Add compiler path before invoking. Fx:
# export PATH="/opt/m68k-amigaos/bin/:$PATH"
set -e set -e

11
configure vendored
View File

@ -1,8 +1,8 @@
#!/bin/sh #!/bin/sh
# #
# Copyright {c} 2014-2018 Carsten Sonne Larsen <cs@innolan.net> # Copyright {c} 2014-2018 Carsten Sonne Larsen <cs@innolan.net>
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions # modification, are permitted provided that the following conditions
# are met: # are met:
@ -11,7 +11,7 @@
# 2. Redistributions in binary form must reproduce the above copyright # 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the # notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution. # documentation and/or other materials provided with the distribution.
# #
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -23,7 +23,7 @@
# LIABILITY, OR TORT {INCLUDING NEGLIGENCE OR OTHERWISE} ARISING IN ANY WAY # LIABILITY, OR TORT {INCLUDING NEGLIGENCE OR OTHERWISE} ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE. # SUCH DAMAGE.
# #
set -e set -e
@ -264,7 +264,7 @@ if $stdlibm; then
mflags="-DLIBM " mflags="-DLIBM "
dlibm=true dlibm=true
fi fi
if $openlibm; then if $openlibm; then
libm="-lopenlibm " libm="-lopenlibm "
mflags="-DLIBM " mflags="-DLIBM "
@ -306,6 +306,7 @@ values.cpp
viewer.cpp viewer.cpp
' '
SYSSRCS=' SYSSRCS='
amiga_arexx.cpp
console.cpp console.cpp
console_amiga.cpp console_amiga.cpp
console_stdc.cpp console_stdc.cpp

208
src/system/amiga_arexx.cpp Normal file
View File

@ -0,0 +1,208 @@
/*-
* Copyright (c) 2014-2018 Carsten Sonne Larsen <cs@innolan.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Project homepage:
* https://amath.innolan.net
*
*/
#include "amathc.h"
#include "amiga_arexx.h"
#include "lib/charbuf.h"
#include "main/evaluator.h"
#if defined(AMIGA)
#include <dos/dostags.h>
#include <rexx/storage.h>
#include <rexx/rxslib.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/rexxsyslib_protos.h>
#ifndef RXSNAME
#define RXSNAME "rexxsyslib.library"
#endif
struct RxsLib *RexxSysBase = NULL;
AmigaARexx::AmigaARexx()
{
RexxSysBase = (struct RxsLib *)OpenLibrary((STRPTR)RXSNAME, 0);
}
AmigaARexx::~AmigaARexx()
{
if (RexxSysBase != NULL)
{
CloseLibrary((struct Library *)RexxSysBase);
}
}
void AmigaARexx::CreatePort()
{
port = CreateMsgPort();
if (port != NULL)
{
PublishPort();
}
}
void AmigaARexx::DestroyPort()
{
if (port != NULL)
{
RemPort(port);
struct Message *msg;
while ((msg = GetMsg(port)))
{
ReplyMsg(msg);
}
DeleteMsgPort(port);
}
}
void AmigaARexx::PublishPort()
{
CharBuffer *buf = new CharBuffer(12);
bool published = false;
int c = 0;
do
{
c++;
buf->ClearAndCopy(AREXXPORTNAME);
buf->AppendNumber(c);
buf->CopyTo(portName);
Forbid();
struct MsgPort *msgPort = FindPort((CONST_STRPTR)portName);
if (msgPort == NULL)
{
port->mp_Node.ln_Pri = 0;
port->mp_Node.ln_Name = portName;
AddPort((struct MsgPort *)port);
published = true;
}
Permit();
} while (!published);
delete buf;
}
static AmigaARexx *newProcess;
void AmigaARexx::ProcessEntry()
{
newProcess->Process();
}
bool AmigaARexx::Start()
{
Forbid();
newProcess = this;
process = CreateNewProcTags(
NP_Entry, (void *)ProcessEntry,
NP_Name, (APTR)AREXXPROCNAME,
NP_StackSize, 64 * 1024,
TAG_DONE);
Permit();
return (process != NULL);
}
void AmigaARexx::Stop()
{
if (port == NULL)
{
return;
}
struct MsgPort *replyPort = CreateMsgPort();
if (replyPort != NULL)
{
struct RexxMsg *message = (struct RexxMsg *)AllocVec(sizeof(struct RexxMsg), MEMF_ANY | MEMF_CLEAR);
if (message != NULL)
{
message->rm_Node.mn_Node.ln_Type = NT_MESSAGE;
message->rm_Node.mn_Length = sizeof(struct RexxMsg);
message->rm_Node.mn_ReplyPort = replyPort;
message->rm_Result1 = 99;
Forbid();
PutMsg(port, (struct Message *)message);
Permit();
WaitPort(replyPort);
GetMsg(replyPort);
FreeVec(message);
}
DeleteMsgPort(replyPort);
}
}
void AmigaARexx::Process()
{
CreatePort();
if (port != NULL)
{
bool loop = true;
do
{
WaitPort(port);
struct RexxMsg *msg;
while ((msg = (struct RexxMsg *)GetMsg(port)))
{
loop &= HandleMessage(msg);
ReplyMsg((struct Message *)msg);
}
} while (loop);
}
DestroyPort();
}
bool AmigaARexx::HandleMessage(struct RexxMsg *message)
{
if (message->rm_Result1 == 99)
{
return false;
}
message->rm_Result1 = 0;
if (message->rm_Action & RXFF_RESULT)
{
Evaluator *evaluator = new Evaluator(message->rm_Args[0]);
evaluator->Evaluate();
const char *result = evaluator->GetResult();
message->rm_Result2 = (LONG)CreateArgstring((STRPTR)result, (LONG)StrLen(result));
delete evaluator;
}
return true;
}
#endif

75
src/system/amiga_arexx.h Normal file
View File

@ -0,0 +1,75 @@
/*-
* Copyright (c) 2014-2018 Carsten Sonne Larsen <cs@innolan.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Project homepage:
* https://amath.innolan.net
*
*/
#ifndef AMATH_AREXX
#define AMATH_AREXX
/**
* @file console.h
* @brief Generic console system calls.
*
*/
#if defined(AMIGA)
#ifndef AREXXPORTNAME
#define AREXXPORTNAME "AMATH."
#endif
#ifndef AREXXPROCNAME
#define AREXXPROCNAME "amath ARexx process"
#endif
/**
* @brief Abstract base class encapsulating console logic.
*
*/
class AmigaARexx
{
public:
AmigaARexx();
~AmigaARexx();
bool Start();
void Stop();
private:
static void ProcessEntry();
void Process();
void CreatePort();
void PublishPort();
void DestroyPort();
bool HandleMessage(struct RexxMsg *message);
char portName[10];
struct Process *process;
struct MsgPort *port;
};
#endif
#endif

View File

@ -24,7 +24,7 @@
* *
* Project homepage: * Project homepage:
* https://amath.innolan.net * https://amath.innolan.net
* *
*/ */
#include "amath.h" #include "amath.h"
@ -39,6 +39,7 @@
#include "preferences_amiga.h" #include "preferences_amiga.h"
#include "lib/charbuf.h" #include "lib/charbuf.h"
#include "main/evaluator.h" #include "main/evaluator.h"
#include "amiga_arexx.h"
#if defined(AMIGA) #if defined(AMIGA)
#define ARGS_FORMAT "SHELL/S,NOANSI/S,INPUT/F" #define ARGS_FORMAT "SHELL/S,NOANSI/S,INPUT/F"
@ -83,7 +84,7 @@ void AmigaProgram::Initialize(int argc, char **argv)
shellMode = args.shell ? true : false; shellMode = args.shell ? true : false;
ansiMode = args.noansi ? false : true; ansiMode = args.noansi ? false : true;
if (shellMode || args.input != nullptr) if (shellMode || args.input != nullptr)
{ {
Console = new AmigaShellConsole(Preferences->GetPrompt()); Console = new AmigaShellConsole(Preferences->GetPrompt());
@ -92,7 +93,7 @@ void AmigaProgram::Initialize(int argc, char **argv)
{ {
Console = new AmigaWindow(Preferences->GetPrompt(), Language); Console = new AmigaWindow(Preferences->GetPrompt(), Language);
} }
InitAnsiMode(); InitAnsiMode();
} }
@ -116,7 +117,14 @@ void AmigaProgram::Start()
return; return;
} }
AmigaARexx *arexx = new AmigaARexx();
arexx->Start();
Console->Start(); Console->Start();
arexx->Stop();
delete arexx;
return; return;
} }