home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
programs
/
text
/
golded
/
data
/
tools
/
edsource
/
main.c
next >
Wrap
C/C++ Source or Header
|
1995-02-27
|
13KB
|
461 lines
/* -----------------------------------------------------------------------------
ED v0.94 - GoldED quick starter, ©1994 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, char **);
Prototype int wbmain(struct WBStartup *);
Prototype void Action(char *, char *, char *, BOOL, BOOL, ULONG *);
Prototype char *StartGED(char *, char *, BOOL);
Prototype ULONG *SendRexxCommand(char *, char *, struct MsgPort *);
Prototype char *LookForGED(void);
Prototype char *myprintf(char *, char*, ...);
Prototype char *xsprintf(char *, APTR);
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. They
won't have any effect if we manage to pass our list of files to a GoldED
process since we than have to accept that editor's configuration. However,
these options will be considered if we launch a new GoldED process.
Point d'entrée CLI. Analyse de la ligne de commande - crée une chaîne
<argBuffer> contenant les noms de fichiers fournis (les noms des fichiers
sont rendus absolus). Cette chaîne doit ensuite être FreeVec()'é. De plus,
les options de la ligne de commande sont vérifiées. Elles n'auront pas d'
effets si nous arrivons à passer notre liste de fichier à un processus
GoldED car nous devons dans ce cas accepter la configuration de l'éditeur.
Bien sûr, ces options seront prises en compte si nous lançons un nouveau
processus de GoldED.
*/
void
main(argc, argv)
ULONG argc;
char *argv[];
{
char *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]) {
char **nextFile, path[MAX_LEN + 1];
for (nextFile = (char **)args[3]; *nextFile; ++nextFile) {
strcpy(path, *nextFile);
if (strchr(path, ':')) {
BPTR lock;
if (lock = Lock(path, ACCESS_READ)) {
NameFromLock(lock, path, MAX_LEN);
UnLock(lock);
}
}
else {
GetCurrentDirName(path, MAX_LEN);
AddPart(path, *nextFile, MAX_LEN);
}
strcat(argBuffer, xsprintf("\42%s\42", path));
if (strlen(argBuffer) > ARGBUFFER_LIMIT)
break;
}
}
Action(argBuffer, (char *)args[0], (char *)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. Tooltypes are only
considered if we don't find a running GoldED task, i.e. if we don't have to
acccept a running environment.
Point d'entrée Workbench. Lecture des types d'outil de l'icône ED pour dé-
cider si l'utilisateur préfère une configuration/écran public spécifique.
Les types d'outil sont seulement considérés si nous ne trouvons pas de
tâche GoldED, c.à.d. si nous n'avons pas à accepter un environnement existant.
*/
int
wbmain(struct WBStartup *wbs)
{
char *argBuffer;
if (argBuffer = AllocVec(ARGBUFFER_SIZE, MEMF_PUBLIC | MEMF_CLEAR)) {
struct DiskObject *diskObject;
char *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) {
char 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).
Démarre GoldED s'il n'y aucun GED en mémoire (note: le démarrage de GED
ouvrira une première fenêtre (c.à.d. nous aurons à en ouvrir d'autres si
des fichiers sont spécifiés). Envoie ensuite les messages ARexx LOCK pour
démarrer GoldED. Attend une réponse positive, envoie notre liste de fichiers
à cet éditeur, déverrouille l'éditeur (utilise un unlock décalé, sauf si
<sticky> est spécifié). Suggestions d'amélioration: rendez tout cela
asynchrone. Envoyez des messages LOCK à toutes les tâches de GoldED, et
attendez la première réponse (ou timeout).
*/
void
Action(files, config, screen, sticky, hide, line)
char *files, *config, *screen;
ULONG *line;
BOOL sticky, hide;
{
const char *version = "$VER: ED 0.94 (24.3.94)";
BOOL loadGED;
ULONG *result;
char *host;
loadGED = !(host = LookForGED());
if (loadGED)
host = StartGED(config, screen, hide);
if (host && (*files || !(hide || loadGED))) {
struct MsgPort *replyPort;
if (replyPort = CreateMsgPort()) {
if (result = SendRexxCommand(host, "LOCK CURRENT", replyPort)) {
if (*result == RC_OK) {
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"
/* ----------------------------------- LookForGED ----------------------------
Look for running GoldED task (check GOLDED.1 to GOLDED.9)
Recherche d'une tâche GoldED (vérifie GOLDED.1 à GOLDED.9)
*/
char *
LookForGED()
{
static char 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. Return pointer to host name (or NULL).
Screen/config keywords are considered if a new GoldED process has to be
launched, i.e. if we aren't bound to an existing environment.
Démarrer une nouvelle tâche GoldED. Retourne un pointeur sur le nom de l'
hôte (ou NULL). Les mots-clé écran/config sont considérés si un nouveau
processus doit être lancé, c.à.d nous ne sommes pas liés à un environnement
existant.
*/
char *
StartGED(config, screen, hide)
char *config, *screen;
BOOL hide;
{
const char *host = "GOLDED.1";
char command[MAX_LEN + 1];
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)) {
UWORD try;
for (try = 50; try; try--, Delay(10))
if (FindPort(host))
return(host);
}
return(FALSE);
}
/* --------------------------------- xsprintf ----------------------------------
sprintf frontend (returns pointer to static buffer)
façade sprintf (retourne le pointeur sur un tampon statique)
*/
char *
xsprintf(template, data)
char *template;
APTR data;
{
static char buffer[MAX_LEN + 1];
return(myprintf(buffer, template, data));
}
///
/// "ARexx"
/* ---------------------------------- SendRexxCommand -------------------------
Send ARexx message & wait for answer. Return pointer to result or NULL.
Envoie un message ARexx et attend une réponse. Retourne un pointeur
résultat ou NULL.
*/
ULONG *
SendRexxCommand(port, cmd, replyPort)
char *cmd, *port;
struct MsgPort *replyPort;
{
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((char *)answer->rm_Result2);
DeleteArgstring((char *)ARG0(answer));
DeleteRexxMsg(answer);
return(&result);
}
}
}
Permit();
return(NULL);
}
///