home *** CD-ROM | disk | FTP | other *** search
- /* Rexx support for db */
-
- /**********************************************************************/
- /* Includes */
- /**********************************************************************/
-
- #include <proto/rexxsyslib.h>
- #include <proto/utility.h> /* Stricmp() */
- #include <proto/exec.h>
- #include <string.h>
- #include <stdlib.h> /* atoi() */
-
- /* Included for compatibility */
- #include <libraries/gadtools.h>
- #include <intuition/intuition.h> /* struct EasyStruct */
- #include <proto/gadtools.h>
- #include <proto/intuition.h>
- #include <proto/dos.h> /* Unlock() */
-
- #include "dbGUI.h"
- #include "db.h"
- #include "dbRexx.h"
- // #include "dbParser.h"
-
- /* Included for compatibility */
- #include "dbtexts.h"
-
- /**********************************************************************/
- /* Defines */
- /**********************************************************************/
-
- #define REXXPORTNAMELENGTH 50
-
- /**********************************************************************/
- /* Globals */
- /**********************************************************************/
-
- /* ARexx specifics */
- struct MsgPort *MyRexxPort = NULL;
- char MyRexxPortName[REXXPORTNAMELENGTH] ="\0";
-
- int OutstandingRexxCommands = 0;
- /* End of Rexx specifics */
-
-
- /**********************************************************************/
- /* Prototypes */
- /**********************************************************************/
-
- extern int DB_SAVE( void ); /* I don't want to include dbGUI.h for this one line */
-
- typedef struct {
- char *arg;
- struct RexxMsg *rxmessage;
- int RC;
- char *Result;
- char buf[10]; /* Sometimes Result points here */
- } RXInfo;
-
- /**********************************************************************/
- /* Functions */
- /**********************************************************************/
-
- char *NextWord(const char *s)
- {
- /* Just steps forward all non space characters + one space character */
- if (!s) return NULL;
- while (*s && (*s++ != ' '));
- return s;
- }
-
- int GetFldIndex(struct Pro *Pr, char *s)
- {
- /* Returns the fieldindex of the matching field or -1 if not found */
- int i=0;
- struct FldInfo *f = Pr->FirstFldInfo;
-
- for (; f; f=f->Next, i++) if (!Stricmp(f->Name, s)) return i;
- return -1;
- }
-
- Field RXGetFld(struct Pro *Pr, char *fieldname)
- {
- /* Returning NULL indicates an error */
- int i;
- if ((i = GetFldIndex(Pr, fieldname)) == -1) return NULL;
- return GetFld(*Pr->Recpp, i);
- }
-
- LONG EasyRexxRequest(struct Window *w, struct EasyStruct *es, ULONG *idcmp,
- char *string)
- {
- BOOL blocked;
- /* Displays an EasyRequest where the strings are locale string-indexes */
- LONG ret_val;
- struct EasyStruct nes;
- nes.es_StructSize = sizeof(struct EasyStruct);
- nes.es_Flags = 0;
- nes.es_Title = GetAppStr((LONG)es->es_Title);
- nes.es_TextFormat = string;
- nes.es_GadgetFormat = GetAppStr((LONG)es->es_GadgetFormat);
-
- blocked = IsInputBlocked();
- if (w) BlockInput(w, TRUE);
- ret_val = EasyRequestArgs(w, &nes, idcmp, NULL);
- if (w && !blocked) FreeInput(w);
- return ret_val;
- }
-
-
- struct MsgPort *SetupRexxPort(char *basename)
- {
- struct MsgPort *port;
- int num=1;
-
- Forbid();
-
- do { /* Make a unique portname db.<num> */
- sprintf(MyRexxPortName, "%s.%d", basename, num++);
- } while (FindPort(MyRexxPortName));
- port = CreatePort(MyRexxPortName, 0L);
-
- Permit();
- return port;
- }
-
-
- void ReplyRexxCommand(struct RexxMsg *rxmessage, long rc, char *result)
- {
- long rc2 = 0;
- if (!rc && (rxmessage->rm_Action & 1L<<RXFB_RESULT))
- if (result) rc2 = (long)CreateArgstring(result, strlen(result));
- rxmessage->rm_Result1 = rc;
- rxmessage->rm_Result2 = rc2;
- ReplyMsg((struct Message *)rxmessage);
- }
-
-
- /**********************************************************************/
- /* ARexx command handlers */
- /**********************************************************************/
-
- extern struct SortInfo {
- struct SortOrder *so;
- size_t norders;
- char SortDir;
- BOOL UnSort; /* Sort the database based upon each record's address instead */
- }SI;
-
-
- static void Rx_SortOrder(RXInfo *ri)
- {
- int order;
-
-
- if(*ri->arg)
- {
- order = atoi(ri->arg);
-
- switch(order)
- {
- case 0:
- SI.SortDir = SORT_DIR_AZ;
- break;
-
- case 1:
- SI.SortDir = SORT_DIR_ZA;
- break;
-
- default:
- ri->RC = RC_ERROR;
- break;
- }
- }
- else
- {
- stci_d(ri->buf, SI.SortDir);
- ri->Result = ri->buf;
- }
-
- }
-
-
-
- static void Rx_Add(RXInfo *ri)
- {
- DB_ADD();
- }
-
- static void Rx_Kill(RXInfo *ri)
- {
- DB_KILL();
- }
-
- static void Rx_FirstRecord(RXInfo *ri)
- {
- UpdateRecord(CurrentPro);
- if (CurrentPro->Mode == MODE_NORMAL) UpdateRecord(CurrentPro);
- JumpList(CurrentPro, -CurrentPro->RecNum);
- if (CurrentPro->Mode == MODE_NORMAL) {
- UpdateWindow(CurrentPro);
- UpdateDragBar(CurrentPro);
- }
- if (ReactivateGad) ActivateGadget(LastGad, CurrentPro->CurrentLayout->Window, NULL);
-
- stci_d(ri->buf, CurrentPro->RecNum+1);
- ri->Result = ri->buf;
- }
-
- static void Rx_NextRecord(RXInfo *ri)
- {
- if (CurrentPro->RecNum < (CurrentPro->RecSum-1)) {
- if (CurrentPro->Mode == MODE_NORMAL) UpdateRecord(CurrentPro);
- JumpList(CurrentPro, 1);
- if (CurrentPro->Mode == MODE_NORMAL) {
- UpdateWindow(CurrentPro);
- UpdateDragBar(CurrentPro);
- }
- if (ReactivateGad) ActivateGadget(LastGad, CurrentPro->CurrentLayout->Window, NULL);
- }
- else ri->RC = RC_WARN;
- stci_d(ri->buf, CurrentPro->RecNum+1);
- ri->Result = ri->buf;
- }
-
- static void Rx_CurrentRecord(RXInfo *ri)
- {
- int recnum;
- if (*ri->arg) {
- recnum = atoi(ri->arg)-1;
- if (recnum >= 0 && recnum < CurrentPro->RecSum) {
- if (CurrentPro->Mode == MODE_NORMAL) UpdateRecord(CurrentPro);
- JumpList(CurrentPro, -CurrentPro->RecNum+recnum);
- if (CurrentPro->Mode == MODE_NORMAL) {
- UpdateWindow(CurrentPro);
- UpdateDragBar(CurrentPro);
- }
- if (ReactivateGad) ActivateGadget(LastGad, CurrentPro->CurrentLayout->Window, NULL);
- }
- else ri->RC = RC_WARN;
- }
- stci_d(ri->buf, CurrentPro->RecNum+1);
- ri->Result = ri->buf;
- }
-
- static void Rx_RecordSum(RXInfo *ri)
- {
- stci_d(ri->buf, CurrentPro->RecSum);
- ri->Result = ri->buf;
- }
-
- static void Rx_FindFirst(RXInfo *ri)
- {
- if (!FindRecord(CurrentPro,0,1)) ri->RC = RC_WARN;
- stci_d(ri->buf, CurrentPro->RecNum+1);
- ri->Result = ri->buf;
- }
-
- static void Rx_FindNext(RXInfo *ri)
- {
- if (!FindRecord(CurrentPro,CurrentPro->RecNum+1,1)) ri->RC = RC_WARN;
- stci_d(ri->buf, CurrentPro->RecNum+1);
- ri->Result = ri->buf;
- }
-
- static void Rx_Cut(RXInfo *ri)
- {
- DB_CUT();
- }
-
- static void Rx_Copy(RXInfo *ri)
- {
- DB_COPY();
- }
-
- static void Rx_Paste(RXInfo *ri)
- {
- DB_PASTE();
- }
-
- static void Rx_Merge(RXInfo *ri)
- {
- UpdateRecord(CurrentPro);
- PasteFromClipboard(CurrentPro, *CurrentPro->Recpp);
- CurrentPro->Modified |= PROMODIFIED;
- UpdateGadgets(CurrentPro);
- }
-
- static void Rx_FirstField(RXInfo *ri)
- {
- struct FldInfo *fi;
- if (fi = GetFldInfo(CurrentPro, 0)) {
- CurrentPro->CurrentFldOffset = 0;
- ri->Result = fi->Name;
- }
- else ri->RC = RC_WARN; /* No fields at all */
- }
-
- static void Rx_NextField(RXInfo *ri)
- {
- struct FldInfo *fi;
- if (fi = GetFldInfo(CurrentPro, CurrentPro->CurrentFldOffset+1)) {
- CurrentPro->CurrentFldOffset++;
- ri->Result = fi->Name;
- }
- else ri->RC = RC_WARN;
- }
-
- static void Rx_CurrentField(RXInfo *ri)
- {
- int offset;
- struct FldInfo *fi;
-
- if (*ri->arg) {
- if ((offset = GetFldIndex(CurrentPro, ri->arg)) == -1) {
- ri->RC = RC_WARN;
- return;
- }
- CurrentPro->CurrentFldOffset = offset;
- }
- if (fi = GetFldInfo(CurrentPro, CurrentPro->CurrentFldOffset)) ri->Result = fi->Name;
- else ri->RC = RC_WARN; /* Should never happen */
- }
-
-
- static void Rx_GetField(RXInfo *ri) /* ri->arg is fieldname */
- {
- UpdateRecord(CurrentPro);
- if (*ri->arg) ri->Result = RXGetFld(CurrentPro, ri->arg);
- else ri->Result = GetFld(*CurrentPro->Recpp, CurrentPro->CurrentFldOffset);
- if (!ri->Result) ri->RC = RC_WARN;
- }
-
-
- static void Rx_PutField(RXInfo *ri)
- {
- UpdateRecord(CurrentPro);
- if (UpdateFld(*CurrentPro->Recpp, CurrentPro->CurrentFldOffset, ri->arg) &&
- CurrentPro->Mode == MODE_NORMAL)
- CurrentPro->Modified |= PROMODIFIED;
- UpdateGadgets(CurrentPro);
- }
-
- static void Rx_Mode(RXInfo *ri)
- {
- if (*ri->arg) {
- if (!Stricmp(ri->arg, "Normal")) SetProMode(CurrentPro, MODE_NORMAL);
- else if (!Stricmp(ri->arg, "Find")) SetProMode(CurrentPro, MODE_FIND);
- else if (!Stricmp(ri->arg, "Sort")) SetProMode(CurrentPro, MODE_SORT);
- else ri->RC = RC_ERROR;
- }
-
- switch (CurrentPro->Mode) {
- case MODE_NORMAL:
- ri->Result = "Normal";
- break;
- case MODE_FIND:
- ri->Result = "Find";
- break;
- case MODE_SORT:
- ri->Result = "Sort";
- break;
- }
- }
-
- static void Rx_Save(RXInfo *ri)
- {
- DB_SAVE();
- }
-
- static void Rx_Sort(RXInfo *ri)
- {
- DoSort(CurrentPro, -1);
- }
-
- static void Rx_Quit(RXInfo *ri)
- {
- ReplyRexxCommand(ri->rxmessage, RC_OK, 0);
- ByeBye();
- }
-
- static void Rx_UpdateGUI(RXInfo *ri)
- {
- BOOL save = CurrentPro->Quiet;
- CurrentPro->Quiet = FALSE;
- SetProMode(CurrentPro, CurrentPro->Mode);
- CurrentPro->Quiet = save;
- }
-
- static void Rx_WindowToFront(RXInfo *ri)
- {
- if (CurrentPro->CurrentLayout->Window)
- WindowToFront(CurrentPro->CurrentLayout->Window);
- else ri->RC = RC_WARN;
-
- }
-
- static void Rx_ScreenToFront(RXInfo *ri)
- {
- ScreenToFront(Scr);
- }
-
- static void Rx_ActivateWindow(RXInfo *ri)
- {
- if (CurrentPro->CurrentLayout->Window)
- ActivateWindow(CurrentPro->CurrentLayout->Window);
- else ri->RC = RC_WARN;
- }
-
- static void Rx_BlockInput(RXInfo *ri)
- {
- BlockInput(CurrentPro->CurrentLayout->Window, TRUE);
- UpdateRecord(CurrentPro);
- CurrentPro->Quiet = TRUE; /* Don't do any GUI stuff from now on */
- }
-
- static void Rx_FreeInput(RXInfo *ri)
- {
- FreeInput(CurrentPro->CurrentLayout->Window);
- CurrentPro->Quiet = FALSE; /* Release GUI now */
- Rx_UpdateGUI(ri);
- }
-
- static void Rx_Dial(RXInfo *ri)
- {
- ri->RC = DoDial(ri->arg);
- }
-
- static void Rx_DisplayBeep(RXInfo *ri)
- {
- DisplayBeep(Scr);
- }
-
- static void Rx_Okay1(RXInfo *ri)
- {
- EasyRexxRequest(CurrentPro->CurrentLayout->Window, &ES_RexxOkay1, NULL, ri->arg);
- }
-
- static void Rx_Okay2(RXInfo *ri)
- {
- stci_d(ri->buf, EasyRexxRequest(CurrentPro->CurrentLayout->Window, &ES_RexxOkay2, NULL, ri->arg));
- ri->Result = ri->buf;
- }
-
- static void Rx_CurrentGadget(RXInfo *ri)
- {
- int gadindex;
- struct VisFldInfo *vf;
-
- NextGad = NULL;
- if (*ri->arg) {
- gadindex = atoi(ri->arg);
- if (!gadindex--) { /* string argument, not a number */
- for(vf=CurrentPro->CurrentLayout->FirstVisFldInfo; vf; vf = vf->Next)
- if (!Stricmp(ri->arg, vf->Name)) break;
- }
- else for (vf = CurrentPro->CurrentLayout->FirstVisFldInfo; vf && gadindex > 0; vf = vf->Next, gadindex--);
- if (vf) LastGad = vf->Gadget;
- }
- if (LastGad) {
- for(gadindex=1, vf=CurrentPro->CurrentLayout->FirstVisFldInfo; vf; vf = vf->Next, gadindex++)
- if (vf->Gadget == LastGad) break;
-
- stci_d(ri->buf, gadindex);
- ri->Result = ri->buf;
-
- }
- else ri->RC = RC_WARN;
- }
-
- static void Rx_RetryInput(RXInfo *ri)
- {
- NextGad = NULL; /* Don't activate NextGad if tabcycling */
- ActivateGadget(LastGad, CurrentPro->CurrentLayout->Window, NULL);
- }
-
- static void Rx_CurrentView(RXInfo *ri)
- {
- int viewindex;
- struct Layout *lay = CurrentPro->FirstLayout;
-
- if (*ri->arg) {
- viewindex = atoi(ri->arg);
- if (!viewindex--) { /* string argument, not a number */
- for (; lay; lay = lay->NextLayout)
- if (!Stricmp(ri->arg, lay->Name)) break;
- } else for (; lay && viewindex; lay = lay->NextLayout, viewindex--);
- ChangeView(lay);
- }
- else for (viewindex=1; lay != CurrentPro->CurrentLayout; lay = lay->NextLayout, viewindex++);
-
- stci_d(ri->buf, viewindex);
- ri->Result = ri->buf;
- }
-
- static void Rx_UndoBuffer(RXInfo *ri)
- {
- if (LastGad && LastGad->GadgetID == STRING_KIND)
- ri->Result = ((struct StringInfo *)LastGad->SpecialInfo)->UndoBuffer;
- else ri->RC = RC_WARN;
- }
-
- static void Rx_GetPortName(RXInfo *ri) /* Undocumented. The ARexx function Address() should do this job */
- {
- ri->Result = MyRexxPortName;
- }
-
-
- /**********************************************************************/
- /* ARexx command dispatcher */
- /**********************************************************************/
-
- typedef struct {
- char *name;
- void (*cmd)(RXInfo *);
- } Comm;
-
- static Comm Commands[] = {
- { "Add", Rx_Add },
- { "Kill", Rx_Kill },
- { "FirstRecord", Rx_FirstRecord, },
- { "NextRecord", Rx_NextRecord },
- { "CurrentRecord", Rx_CurrentRecord },
- { "RecordSum", Rx_RecordSum },
- { "FindFirst", Rx_FindFirst },
- { "FindNext", Rx_FindNext },
- { "Cut", Rx_Cut },
- { "Copy", Rx_Copy },
- { "Paste", Rx_Paste },
- { "Merge", Rx_Merge },
- { "FirstField", Rx_FirstField },
- { "NextField", Rx_NextField },
- { "CurrentField", Rx_CurrentField },
- { "GetField", Rx_GetField },
- { "PutField", Rx_PutField },
- { "Mode", Rx_Mode },
- { "Save", Rx_Save },
- { "Sort", Rx_Sort },
- { "SortOrder", Rx_SortOrder },
- { "Quit", Rx_Quit },
- { "UpdateGUI", Rx_UpdateGUI },
- { "WindowToFront", Rx_WindowToFront },
- { "ScreenToFront", Rx_ScreenToFront },
- { "ActivateWindow", Rx_ActivateWindow },
- { "BlockInput", Rx_BlockInput },
- { "FreeInput", Rx_FreeInput },
- { "Dial", Rx_Dial },
- { "DisplayBeep", Rx_DisplayBeep },
- { "Okay1", Rx_Okay1 },
- { "Okay2", Rx_Okay2 },
- { "CurrentGadget", Rx_CurrentGadget },
- { "UndoBuffer", Rx_UndoBuffer },
- { "RetryInput", Rx_RetryInput },
- { "CurrentView", Rx_CurrentView },
- { "GetPortName", Rx_GetPortName },
- { NULL, NULL }
- };
-
-
- void HandleRexxCommand(struct RexxMsg *rxmessage)
- {
- int i, namelen;
- char name[40];
- char *cmdline = ARG0(rxmessage);
- RXInfo ri;
-
- ri.rxmessage = rxmessage; /* QUIT needs to answer itself */
- ri.RC = RC_OK;
- ri.Result = NULL;
-
- /* Split cmdline into name and arg without affecting cmdline */
- for (i=0; i<30 && cmdline[i] && cmdline[i] != ' '; i++)
- name[i] = cmdline[i];
- name[i] = '\0';
- namelen = strlen(name);
- ri.arg = NextWord(cmdline);
-
- /* Do the dispatch */
- for (i=0; Commands[i].name; i++) {
- if (!Strnicmp(Commands[i].name, name, namelen)) {
- Commands[i].cmd(&ri); /* Run this command */
- ReplyRexxCommand(rxmessage, ri.RC, ri.Result);
- return;
- }
- }
- ReplyRexxCommand(rxmessage,RC_ERROR,NULL); /* Command not found */
- }
-
-
- void FreeRexxCommand(struct RexxMsg *rxmessage)
- {
- struct Window *win = (CurrentPro->CurrentLayout) ?
- CurrentPro->CurrentLayout->Window : NULL;
-
- if (rxmessage->rm_Result1) {
- if (rxmessage->rm_Result2 == ERR10_001) /* Program not found */
- EasyLocRequest(win, &ES_RexxProgNotFound, NULL, ARG0(rxmessage));
- else EasyLocRequest(win, &ES_RexxError, NULL, ARG0(rxmessage), rxmessage->rm_Result2);
- }
- DeleteArgstring(rxmessage->rm_Args[0]); /* The command name */
-
- /* In SendRexxCommand we cd to project's dir, cd back and unlock now */
- UnLock(CurrentDir((BPTR)rxmessage->rm_Args[15]));
- DeleteRexxMsg(rxmessage);
- OutstandingRexxCommands--;
- }
-
-
- void CloseRexxPort(struct MsgPort *rexxport)
- {
- struct RexxMsg *rxmessage;
-
- do {
- while (rxmessage = (struct RexxMsg *)GetMsg(rexxport)) {
- if (rxmessage->rm_Node.mn_Node.ln_Type == NT_REPLYMSG)
- FreeRexxCommand(rxmessage); /* A command finished */
- else ReplyRexxCommand(rxmessage, ERR10_013, NULL); /* 'Host not found' */
- }
- if (OutstandingRexxCommands) WaitPort(rexxport);
- } while (OutstandingRexxCommands); /* Wait out all commands we've sent */
-
- DeletePort(rexxport);
- }
-
-
- BOOL SendRexxCommand(char *name)
- {
- struct MsgPort *rexxport; /* System's Rexx port */
- struct RexxMsg *rxmessage;
-
- Forbid();
- if (!(rexxport = FindPort(RXSDIR))) {
- Permit();
- return FALSE;
- }
- if (!(rxmessage = CreateRexxMsg(MyRexxPort,
- NULL, MyRexxPort->mp_Node.ln_Name))) {
- Permit();
- return FALSE;
- }
-
- if (!(rxmessage->rm_Args[0] = CreateArgstring(name, strlen(name)))) {
- Permit();
- return FALSE;
- }
- rxmessage->rm_Action = RXCOMM | RXFB_NOIO; /* OR a stringcommand here */
-
- /* Change to the directory of the project */
- /* We put the old lock in Args[15] for FreeRexxCommand() */
- rxmessage->rm_Args[15] =
- (STRPTR)CurrentDir(Lock(CurrentPro->Drawer,ACCESS_READ));
- PutMsg(rexxport, (struct Message *)rxmessage); /* Send it */
- OutstandingRexxCommands++; /* For graceful cleanup */
- Permit();
- return TRUE;
- }
-
-
- BOOL SendRexxStrCommand(char *name)
- {
- char *str;
- BOOL success;
- int bufsize = strlen(name)+3;
-
- if (!(str = AllocMem(bufsize, 0))) {
- return FALSE;
- }
- sprintf(str,"\"%s\"", name);
-
- success = SendRexxCommand(str);
-
- FreeMem(str, bufsize);
- return success;
- }
-
-
- BOOL HandleRexxMessage(struct MsgPort *rexxport)
- {
- BOOL finished = FALSE;
- struct RexxMsg *rxmessage;
- /* returns TRUE when command is finished */
-
- /* Is this a reply? ie has a command finished? */
- while (rxmessage = (struct RexxMsg *)GetMsg(rexxport)) {
- if (rxmessage->rm_Node.mn_Node.ln_Type == NT_REPLYMSG) {
- FreeRexxCommand(rxmessage);
- finished = TRUE;
- CurrentPro->Quiet = FALSE;
- if (CurrentPro->CurrentLayout)
- FreeInput(CurrentPro->CurrentLayout->Window);
- }
- else HandleRexxCommand(rxmessage);
- }
- return finished;
- }
-
-