home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AMIGA PD 1
/
AMIGA-PD-1.iso
/
Programme_zum_Heft
/
Anwendungen
/
Kurztests
/
GoldED
/
data
/
tools
/
ED
/
main.c
next >
Wrap
C/C++ Source or Header
|
1995-02-25
|
11KB
|
453 lines
/* -----------------------------------------------------------------------------
ED 2.1 - GoldED quick starter, ©1995 Dietmar Eilert. Dice:
dcc main.c sprintf.a -// -proto -mRR -mi -pr -2.0 -o ram:ED
------------------------------------------------------------------------------
*/
/// "includes"
#include <amiga20/exec/exec.h>
#include <string.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <amiga20/intuition/intuition.h>
#include <amiga20/dos/dos.h>
#include <amiga20/dos/dosextens.h>
#include <amiga20/dos/rdargs.h>
#include <amiga20/dos/dostags.h>
#include <amiga20/workbench/startup.h>
#include <amiga20/workbench/workbench.h>
#include <amiga20/rexx/errors.h>
#include <amiga20/rexx/rxslib.h>
#include <amiga20/clib/alib_protos.h>
#include <amiga20/clib/dos_protos.h>
#include <amiga20/clib/exec_protos.h>
#include <amiga20/clib/icon_protos.h>
#include <amiga20/clib/intuition_protos.h>
#include <amiga20/clib/utility_protos.h>
#include <amiga20/clib/rexxsyslib_protos.h>
#include <amiga20/clib/wb_protos.h>
#ifdef PRAGMAS
#include "Pragmas/exec.h"
#include "Pragmas/disk.h"
#include "Pragmas/diskfont.h"
#include "Pragmas/dynamic.h"
#include "Pragmas/gadtools.h"
#include "Pragmas/keymap.h"
#include "Pragmas/graphics.h"
#include "Pragmas/icon.h"
#include "Pragmas/input.h"
#include "Pragmas/intuition.h"
#include "Pragmas/layers.h"
#include "Pragmas/locale.h"
#include "Pragmas/misc.h"
#include "Pragmas/timer.h"
#include "Pragmas/wb.h"
#include "Pragmas/xpkmaster.h"
#include "Pragmas/amigaguide.h"
#include "Pragmas/reqtools.h"
#endif
#define Prototype extern
#define MAX_LEN 120
#define ARGBUFFER_SIZE 10500
#define ARGBUFFER_LIMIT 10000
///
/// "prototypes"
Prototype void main(ULONG, UBYTE **);
Prototype int wbmain(struct WBStartup *);
Prototype void Action(UBYTE *, UBYTE *, UBYTE *, BOOL, BOOL, ULONG *);
Prototype UBYTE *StartGED(UBYTE *, UBYTE *, BOOL);
Prototype ULONG *SendRexxCommand(UBYTE *, UBYTE *, struct MsgPort *);
Prototype UBYTE *LookForGED(void);
Prototype UBYTE *myprintf(UBYTE *, UBYTE*, ...);
Prototype UBYTE *xsprintf(UBYTE *, APTR);
Prototype BOOL FindAssign(UBYTE *);
extern struct Library *IconBase;
extern struct Library *DOSBase;
extern struct Library *SysBase;
extern struct Library *IntuitionBase;
///
/// "entry points"
/* --------------------------------------- main --------------------------------
CLI entry point. Parse command line - create a string <argBuffer> containing
provided file names (file names are made absolute). This string has to be
FreeVec()'ed later on. Additionally, command line options are checked.
*/
void
main(argc, argv)
ULONG argc;
UBYTE *argv[];
{
UBYTE *argBuffer;
if (argBuffer = AllocVec(ARGBUFFER_SIZE, MEMF_PUBLIC | MEMF_CLEAR)) {
struct RDArgs *rdArgs;
ULONG args[] = { 0, 0, 0, 0, 0, 0, 0 };
if (rdArgs = ReadArgs("C=CONFIG/K,S=SCREEN/K,Y=STICKY/S,F=FILE/M,HIDE/S,-STICKY/S,L=LINE/N", args, NULL)) {
if (args[3]) {
UBYTE **nextFile, path[MAX_LEN + 1];
BPTR lock;
for (nextFile = (UBYTE **)args[3]; *nextFile; ++nextFile) {
strcpy(path, *nextFile);
if (lock = Lock(path, ACCESS_READ)) {
NameFromLock(lock, path, MAX_LEN);
UnLock(lock);
}
else if (strchr(path, ':') == NULL) {
GetCurrentDirName(path, MAX_LEN);
AddPart(path, *nextFile, MAX_LEN);
}
strcat(argBuffer, xsprintf("\42%s\42", path));
if (strlen(argBuffer) > ARGBUFFER_LIMIT)
break;
}
}
Action(argBuffer, (UBYTE *)args[0], (UBYTE *)args[1], (BOOL)args[2], (BOOL)args[4] || (BOOL)args[5], (ULONG *)args[6]);
FreeArgs(rdArgs);
}
else
exit(20);
}
exit(0);
}
/* ------------------------------------ wbmain ---------------------------------
Workbench entry point. Read tooltypes of ED icon to decide wether user prefers
a special configuration/public screen.
*/
int
wbmain(struct WBStartup *wbs)
{
UBYTE *argBuffer;
if (argBuffer = AllocVec(ARGBUFFER_SIZE, MEMF_PUBLIC | MEMF_CLEAR)) {
struct DiskObject *diskObject;
UBYTE *config, *screen, progName[MAX_LEN + 1];
BOOL hide;
screen = NULL;
config = NULL;
hide = FALSE;
NameFromLock(GetProgramDir(), progName, MAX_LEN);
AddPart(progName, wbs->sm_ArgList[0].wa_Name, MAX_LEN);
if (diskObject = GetDiskObject(progName)) {
config = FindToolType(diskObject->do_ToolTypes, "CONFIG");
screen = FindToolType(diskObject->do_ToolTypes, "SCREEN");
if (FindToolType(diskObject->do_ToolTypes, "HIDE"))
hide = TRUE;
}
if (--wbs->sm_NumArgs) {
UBYTE file[MAX_LEN + 1];
struct WBArg *wbArg = wbs->sm_ArgList;
while ((wbs->sm_NumArgs)--) {
++wbArg;
NameFromLock( wbArg->wa_Lock, file, MAX_LEN);
AddPart(file, wbArg->wa_Name, MAX_LEN);
strcat(argBuffer, xsprintf("\42%s\42", file));
if (strlen(argBuffer) > ARGBUFFER_LIMIT)
break;
}
}
Action(argBuffer, config, screen, FALSE, hide, NULL);
if (diskObject)
FreeDiskObject(diskObject);
}
exit(0);
}
///
/// "main routine"
/* ------------------------------------ Action ---------------------------------
Run GoldED if no running instance of GED is found (note: running GED will
open a first window, i.e. no need to open a further one unless files are
speciefied). Send LOCK ARexx messages to running GoldED. Wait for positive
reply, pass our list of <files> to that editor, unlock editor (use delayed
unlock unless <sticky> is specified). Suggestions for improvements: Make
the whole thing aynchrounous. Send LOCK messages to all running instances
of GoldED, then wait for first reply (or timeout).
*/
void
Action(files, config, screen, sticky, hide, line)
UBYTE *files, *config, *screen;
ULONG *line;
BOOL sticky, hide;
{
static UBYTE version[] = "$VER: ED 2.1 (" __COMMODORE_DATE__ ")";
BOOL useResident;
ULONG *result;
UBYTE *host;
useResident = ((host = LookForGED()) != NULL);
if (useResident == FALSE)
host = StartGED(config, screen, hide);
if (host && (*files || (useResident && (hide == FALSE)))) {
struct MsgPort *replyPort;
if (replyPort = CreateMsgPort()) {
if (result = SendRexxCommand(host, "LOCK CURRENT", replyPort)) {
if (*result == RC_OK) {
if (config && useResident)
SendRexxCommand(host, xsprintf("PREFS LOAD SMART CONFIG=\42%s\42 ", config), replyPort);
if (*files)
strins(files, "OPEN SMART QUIET ");
else
strcpy(files, "MORE SMART");
SendRexxCommand(host, files, replyPort);
if (line)
SendRexxCommand(host, xsprintf("GOTO LINE=%ld UNFOLD=TRUE", (APTR)*line), replyPort);
SendRexxCommand(host, sticky ? "UNLOCK STICKY" : "UNLOCK DELAY", replyPort);
}
}
DeleteMsgPort(replyPort);
}
}
FreeVec(files);
}
///
/// "misc"
/* -------------------------------- FindAssign ---------------------------------
Check whether assign exists without annoying 'insert drive requester'
*/
BOOL
FindAssign(assign)
UBYTE *assign;
{
BOOL success = (FindDosEntry(LockDosList(LDF_ASSIGNS | LDF_READ), assign, LDF_ASSIGNS) != NULL);
UnLockDosList(LDF_ASSIGNS | LDF_READ);
return(success);
}
/* ----------------------------------- LookForGED ----------------------------
Look for running GoldED task (check GOLDED.1 to GOLDED.9)
*/
UBYTE *
LookForGED()
{
static UBYTE host[] = "GOLDED.1";
UWORD try;
for (try = '1'; try <= '9'; try++) {
host[7] = try;
if (FindPort(host))
return(host);
}
return(NULL);
}
/* ------------------------------------- StartGED -----------------------------
Launch a new GoldED task. Look for "GOLDED:" assign. Add assign if none is
found (defaultPath[] is set by the installer script). Return pointer to host
name (or NULL). Screen/config keywords are considered.
*/
UBYTE *
StartGED(config, screen, hide)
UBYTE *config, *screen;
BOOL hide;
{
static UBYTE defaultPath[255] = "$GOLDED";
UBYTE command[MAX_LEN + 1];
if (FindAssign("GOLDED") == FALSE)
AssignLock("GOLDED", Lock(defaultPath, ACCESS_READ));
strcpy(command, "GOLDED:GOLDED");
if (hide)
strcat(command, " HIDE");
if (config)
strcat(command, xsprintf(" CONFIG=\42%s\42", config));
if (screen)
strcat(command, xsprintf(" SCREEN=%s", screen));
if (!SystemTags(command, SYS_Asynch, TRUE, SYS_Input, NULL, SYS_Output, NULL, NP_StackSize, 8192, TAG_DONE)) {
static UBYTE host[] = "GOLDED.1";
UWORD try;
for (try = 50; try; try--, Delay(10))
if (FindPort(host))
return(host);
}
return(FALSE);
}
/* --------------------------------- xsprintf ----------------------------------
sprintf frontend (returns pointer to static buffer)
*/
UBYTE *
xsprintf(template, data)
UBYTE *template;
APTR data;
{
static UBYTE buffer[MAX_LEN + 1];
return(myprintf(buffer, template, data));
}
///
/// "ARexx"
/* ---------------------------------- SendRexxCommand -------------------------
Send ARexx message & wait for answer. Return pointer to result or NULL.
*/
ULONG *
SendRexxCommand(port, cmd, replyPort)
struct MsgPort *replyPort;
UBYTE *cmd, *port;
{
struct MsgPort *rexxport;
Forbid();
if (rexxport = FindPort(port)) {
struct RexxMsg *rexxMsg, *answer;
if (rexxMsg = CreateRexxMsg(replyPort, NULL, NULL)) {
if (rexxMsg->rm_Args[0] = CreateArgstring(cmd, strlen(cmd))) {
static ULONG result;
rexxMsg->rm_Action = RXCOMM | RXFF_RESULT;
PutMsg(rexxport, &rexxMsg->rm_Node);
do {
WaitPort(replyPort);
if (answer = (struct RexxMsg *)GetMsg(replyPort))
result = answer->rm_Result1;
} while (!answer);
Permit();
if (answer->rm_Result1 == RC_OK)
if (answer->rm_Result2)
DeleteArgstring((UBYTE *)answer->rm_Result2);
DeleteArgstring((UBYTE *)ARG0(answer));
DeleteRexxMsg(answer);
return(&result);
}
}
}
Permit();
return(NULL);
}
///