Hint added.
[AROS.git] / workbench / utilities / MultiView / ARexx / MultiView.c
blobb6e6b6736fb78fd057a4b22195133acda8963cae
1 /*
2 * Source generated with ARexxBox 1.12 (May 18 1993)
3 * which is Copyright (c) 1992,1993 Michael Balzer
4 */
6 #include <exec/types.h>
7 #include <exec/memory.h>
8 #include <dos/dos.h>
9 #include <rexx/storage.h>
10 #include <rexx/rxslib.h>
12 #ifdef __GNUC__
13 /* GCC needs all struct defs */
14 #include <dos/exall.h>
15 #include <graphics/graphint.h>
16 #include <intuition/classes.h>
17 #include <devices/keymap.h>
18 #include <exec/semaphores.h>
19 #endif
21 #include <clib/alib_protos.h>
22 #include <clib/exec_protos.h>
23 #include <clib/dos_protos.h>
24 #include <clib/rexxsyslib_protos.h>
26 #ifndef __NO_PRAGMAS
28 #ifdef AZTEC_C
29 #include <pragmas/exec_lib.h>
30 #include <pragmas/dos_lib.h>
31 #include <pragmas/rexxsyslib_lib.h>
32 #endif
34 #ifdef LATTICE
35 #include <pragmas/exec_pragmas.h>
36 #include <pragmas/dos_pragmas.h>
37 #include <pragmas/rexxsyslib_pragmas.h>
38 #endif
40 #endif /* __NO_PRAGMAS */
42 #include <stdlib.h>
43 #include <stdio.h>
44 #include <string.h>
45 #include <ctype.h>
47 #ifdef LATTICE
48 #undef toupper
49 #define inline __inline
50 #endif
52 #ifdef __GNUC__
53 #undef toupper
54 static inline int toupper( int c )
56 return( islower(c) ? c - 'a' + 'A' : c );
58 #endif
60 #ifdef AZTEC_C
61 #define inline
62 #endif
64 #include <dos/rdargs.h>
66 #include "MultiView.h"
68 struct rxs_stemnode
70 struct rxs_stemnode *succ;
71 char *name;
72 char *value;
76 extern struct ExecBase *SysBase;
77 extern struct DosLibrary *DOSBase;
78 extern struct RxsLib *RexxSysBase;
80 void (*ARexxResultHook)( struct RexxHost *, struct RexxMsg * ) = NULL;
84 void ReplyRexxCommand(
85 struct RexxMsg *rexxmessage,
86 long primary,
87 long secondary,
88 char *result )
90 if( rexxmessage->rm_Action & RXFF_RESULT )
92 if( primary == 0 )
94 secondary = result
95 ? (long) CreateArgstring( result, strlen(result) )
96 : (long) NULL;
98 else
100 char buf[16];
102 if( primary > 0 )
104 sprintf( buf, "%ld", secondary );
105 result = buf;
107 else
109 primary = -primary;
110 result = (char *) secondary;
113 SetRexxVar( (struct Message *) rexxmessage,
114 "RC2", result, strlen(result) );
116 secondary = 0;
119 else if( primary < 0 )
120 primary = -primary;
122 rexxmessage->rm_Result1 = primary;
123 rexxmessage->rm_Result2 = secondary;
124 ReplyMsg( (struct Message *) rexxmessage );
128 void FreeRexxCommand( struct RexxMsg *rexxmessage )
130 if( !rexxmessage->rm_Result1 && rexxmessage->rm_Result2 )
131 DeleteArgstring( (char *) rexxmessage->rm_Result2 );
133 if( rexxmessage->rm_Stdin &&
134 rexxmessage->rm_Stdin != Input() )
135 Close( rexxmessage->rm_Stdin );
137 if( rexxmessage->rm_Stdout &&
138 rexxmessage->rm_Stdout != rexxmessage->rm_Stdin &&
139 rexxmessage->rm_Stdout != Output() )
140 Close( rexxmessage->rm_Stdout );
142 DeleteArgstring( (char *) ARG0(rexxmessage) );
143 DeleteRexxMsg( rexxmessage );
147 struct RexxMsg *CreateRexxCommand( struct RexxHost *host, char *buff, BPTR fh )
149 struct RexxMsg *rexx_command_message;
151 if( (rexx_command_message = CreateRexxMsg( host->port,
152 rexx_extension, host->port->mp_Node.ln_Name)) == NULL )
154 return( NULL );
157 if( (rexx_command_message->rm_Args[0] =
158 CreateArgstring(buff,strlen(buff))) == NULL )
160 DeleteRexxMsg(rexx_command_message);
161 return( NULL );
164 rexx_command_message->rm_Action = RXCOMM | RXFF_RESULT;
165 rexx_command_message->rm_Stdin = fh;
166 rexx_command_message->rm_Stdout = fh;
168 return( rexx_command_message );
172 struct RexxMsg *CommandToRexx( struct RexxHost *host, struct RexxMsg *rexx_command_message )
174 struct MsgPort *rexxport;
176 Forbid();
178 if( (rexxport = FindPort(RXSDIR)) == NULL )
180 Permit();
181 return( NULL );
184 PutMsg( rexxport, &rexx_command_message->rm_Node );
186 Permit();
188 ++host->replies;
189 return( rexx_command_message );
193 struct RexxMsg *SendRexxCommand( struct RexxHost *host, char *buff, BPTR fh )
195 struct RexxMsg *rcm;
197 if( rcm = CreateRexxCommand(host, buff, fh) )
198 return CommandToRexx( host, rcm );
199 else
200 return NULL;
204 void CloseDownARexxHost( struct RexxHost *host )
206 struct RexxMsg *rexxmsg;
208 if( host->port )
210 /* Port abmelden */
211 RemPort( host->port );
213 /* Auf noch ausstehende Replies warten */
214 while( host->replies > 0 )
216 WaitPort( host->port );
218 while( rexxmsg = (struct RexxMsg *) GetMsg(host->port) )
220 if( rexxmsg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG )
222 if( !rexxmsg->rm_Args[15] )
224 /* Reply zu einem SendRexxCommand()-Call */
225 if( ARexxResultHook )
226 ARexxResultHook( host, rexxmsg );
229 FreeRexxCommand( rexxmsg );
230 --host->replies;
232 else
233 ReplyRexxCommand( rexxmsg, -20, (long) "Host closing down", NULL );
237 /* MsgPort leeren */
238 while( rexxmsg = (struct RexxMsg *) GetMsg(host->port) )
239 ReplyRexxCommand( rexxmsg, -20, (long) "Host closing down", NULL );
241 if( !(host->flags & ARB_HF_USRMSGPORT) )
242 DeleteMsgPort( host->port );
245 if( host->rdargs ) FreeDosObject( DOS_RDARGS, host->rdargs );
246 FreeVec( host );
250 struct RexxHost *SetupARexxHost( char *basename, struct MsgPort *usrport )
252 struct RexxHost *host;
253 int ext = 0;
255 if( !basename )
256 basename = RexxPortBaseName;
257 else if( !*basename )
258 basename = RexxPortBaseName;
260 if( !(host = AllocVec(sizeof *host, MEMF_CLEAR)) )
261 return NULL;
263 strcpy( host->portname, basename );
265 if( usrport )
267 host->port = usrport;
268 host->flags |= ARB_HF_USRMSGPORT;
270 else if( !(host->port = CreateMsgPort()) )
272 FreeVec( host );
273 return NULL;
275 else
277 host->port->mp_Node.ln_Pri = 0;
280 Forbid();
282 while( FindPort(host->portname) )
283 sprintf( host->portname, "%s.%d", basename, ++ext );
285 host->port->mp_Node.ln_Name = host->portname;
286 AddPort( host->port );
288 Permit();
290 if( !(host->rdargs = AllocDosObject(DOS_RDARGS, NULL)) )
292 RemPort( host->port );
293 if( !usrport ) DeleteMsgPort( host->port );
294 FreeVec( host );
295 return NULL;
298 host->rdargs->RDA_Flags = RDAF_NOPROMPT;
300 return( host );
304 /* StateMachine für FindRXCommand() */
306 static inline char *scmp( char *inp, char *str )
308 while( *str && *inp )
309 if( *inp++ != *str++ )
310 return NULL;
312 /* Reststring zurückgeben */
313 return inp;
316 static int find( char *input )
318 struct arb_p_state *st = arb_p_state;
319 struct arb_p_link *ad;
320 char *ni, tmp[36], *s;
322 ni = tmp;
323 while( *input && ni-tmp < 32 )
324 *ni++ = toupper( *input++ );
325 *ni = 0;
326 input = tmp;
328 while( *input )
330 /* Terminalzustand erreicht? */
331 if( !st->pa )
333 if( *input )
334 return -1;
335 else
336 return st->cmd;
339 /* Wo geht's weiter? */
340 ni = 0;
341 for( ad = st->pa; s = ad->str; ad++ )
343 /* die Links sind absteigend sortiert */
344 if( *input > *s )
345 break;
347 if( *input == *s )
348 if( ni = scmp(input+1, s+1) )
349 break;
352 /* Nirgends... */
353 if( !ni )
354 return -1;
356 /* Zustandsüberführung */
357 st = arb_p_state + ad->dst;
358 input = ni;
361 return st->cmd;
364 struct rxs_command *FindRXCommand( char *com )
366 int cmd;
368 cmd = find( com );
370 if( cmd == -1 )
371 return NULL;
372 else
373 return( rxs_commandlist + cmd );
377 static struct rxs_command *ParseRXCommand( char **arg )
379 char com[256], *s, *t;
381 s = *arg;
382 t = com;
384 while( *s && *s != ' ' && *s != '\n' )
385 *t++ = *s++;
387 *t = '\0';
388 while( *s == ' ' ) ++s;
389 *arg = s;
391 return( FindRXCommand( com ) );
395 static char *CreateVAR( struct rxs_stemnode *stem )
397 char *var;
398 struct rxs_stemnode *s;
399 long size = 0;
401 if( !stem || stem == (struct rxs_stemnode *) -1L )
402 return( (char *) stem );
404 for( s = stem; s; s = s->succ )
405 size += strlen( s->value ) + 1;
407 if( !(var = AllocVec( size + 1, MEMF_ANY )) )
408 return( (char *) -1 );
410 *var = '\0';
412 for( s = stem; s; s = s->succ )
414 strcat( var, s->value );
415 if( s->succ )
416 strcat( var, " " );
419 return( var );
423 static struct rxs_stemnode *new_stemnode( struct rxs_stemnode **first, struct rxs_stemnode **old )
425 struct rxs_stemnode *new;
427 if( !(new = AllocVec(sizeof(struct rxs_stemnode), MEMF_CLEAR)) )
429 return( NULL );
431 else
433 if( *old )
435 (*old)->succ = new;
436 (*old) = new;
438 else
440 *first = *old = new;
444 return( new );
448 static void free_stemlist( struct rxs_stemnode *first )
450 struct rxs_stemnode *next;
452 if( (long) first == -1 )
453 return;
455 for( ; first; first = next )
457 next = first->succ;
458 if( first->name ) FreeVec( first->name );
459 if( first->value ) FreeVec( first->value );
460 FreeVec( first );
465 char *StrDup( char *s )
467 char *t = AllocVec( strlen(s)+1, MEMF_ANY );
468 if( t ) strcpy( t, s );
469 return t;
473 static struct rxs_stemnode *CreateSTEM( struct rxs_command *rxc, LONG *resarray, char *stembase )
475 struct rxs_stemnode *first = NULL, *old = NULL, *new;
476 char resb[512], *rs, *rb;
477 char longbuff[16];
479 rb = resb;
480 if( stembase )
482 while( *stembase )
483 *rb++ = toupper( *stembase++ );
485 *rb = '\0';
487 rb = resb + strlen(resb);
488 rs = rxc->results;
490 while( *rs )
492 char *t = rb;
493 BOOL optn = FALSE, optm = FALSE;
495 while( *rs && *rs != ',' )
497 if( *rs == '/' )
499 ++rs;
500 if( *rs == 'N' ) optn = TRUE;
501 else if( *rs == 'M' ) optm = TRUE;
503 else
504 *t++ = *rs;
506 ++rs;
509 if( *rs == ',' ) ++rs;
510 *t = '\0';
513 * Resultat(e) erzeugen
516 if( !*resarray )
518 ++resarray;
519 continue;
522 if( optm )
524 long *r, index = 0;
525 LONG **subarray = (LONG **) *resarray++;
526 struct rxs_stemnode *countnd;
528 /* Anzahl der Elemente */
530 if( !(new = new_stemnode(&first, &old)) )
532 free_stemlist( first );
533 return( (struct rxs_stemnode *) -1L );
535 countnd = new;
537 /* Die Elemente selbst */
539 while( r = *subarray++ )
541 if( !(new = new_stemnode(&first, &old)) )
543 free_stemlist( first );
544 return( (struct rxs_stemnode *) -1L );
547 sprintf( t, ".%ld", index++ );
548 new->name = StrDup( resb );
550 if( optn )
552 sprintf( longbuff, "%ld", *r );
553 new->value = StrDup( longbuff );
555 else
557 new->value = StrDup( (char *) r );
561 /* Die Count-Node */
563 strcpy( t, ".COUNT" );
564 countnd->name = StrDup( resb );
566 sprintf( longbuff, "%ld", index );
567 countnd->value = StrDup( longbuff );
569 else
571 /* Neue Node anlegen */
572 if( !(new = new_stemnode(&first, &old)) )
574 free_stemlist( first );
575 return( (struct rxs_stemnode *) -1L );
578 new->name = StrDup( resb );
580 if( optn )
582 sprintf( longbuff, "%ld", *((long *) *resarray) );
583 new->value = StrDup( longbuff );
584 ++resarray;
586 else
588 new->value = StrDup( (char *) (*resarray++) );
593 return( first );
597 static void DoRXCommand( struct RexxHost *host, struct RexxMsg *rexxmsg )
599 struct rxs_command *rxc;
600 char *argb, *arg;
602 LONG *array = NULL;
603 LONG *argarray;
604 LONG *resarray;
606 char *cargstr = NULL;
607 long rc=20, rc2;
608 char *result = NULL;
610 if( !(argb = AllocVec(strlen((char *) ARG0(rexxmsg)) + 2, MEMF_ANY)) )
612 rc2 = ERROR_NO_FREE_STORE;
613 goto drc_cleanup;
616 /* welches Kommando? */
618 strcpy( argb, (char *) ARG0(rexxmsg) );
619 strcat( argb, "\n" );
620 arg = argb;
622 if( !( rxc = ParseRXCommand( &arg ) ) )
624 if( arg = ExpandRXCommand( host, (char *) ARG0(rexxmsg) ) )
626 FreeVec( argb );
627 if( !(argb = AllocVec( strlen(arg) + 2, MEMF_ANY )) )
629 rc2 = ERROR_NO_FREE_STORE;
630 goto drc_cleanup;
633 strcpy( argb, arg );
634 strcat( argb, "\n" );
635 FreeVec( arg );
636 arg = argb;
638 rxc = ParseRXCommand( &arg );
642 if( !rxc )
644 /* Msg an ARexx schicken, vielleicht existiert ein Skript */
645 struct RexxMsg *rm;
647 if( rm = CreateRexxCommand(host, (char *) ARG0(rexxmsg), NULL) )
649 /* Original-Msg merken */
650 rm->rm_Args[15] = (STRPTR) rexxmsg;
652 if( CommandToRexx(host, rm) )
654 /* Reply wird später vom Dispatcher gemacht */
655 if( argb ) FreeVec( argb );
656 return;
658 else
659 rc2 = ERROR_NOT_IMPLEMENTED;
661 else
662 rc2 = ERROR_NO_FREE_STORE;
664 goto drc_cleanup;
667 if( !(rxc->flags & ARB_CF_ENABLED) )
669 rc = -10;
670 rc2 = (long) "Command disabled";
671 goto drc_cleanup;
674 /* Speicher für Argumente etc. holen */
676 (rxc->function)( host, (void **) &array, RXIF_INIT, rexxmsg );
677 cargstr = AllocVec( rxc->args ? 15+strlen(rxc->args) : 15, MEMF_ANY );
679 if( !array || !cargstr )
681 rc2 = ERROR_NO_FREE_STORE;
682 goto drc_cleanup;
685 argarray = array + 2;
686 resarray = array + rxc->resindex;
688 /* Argumente parsen */
690 if( rxc->results )
691 strcpy( cargstr, "VAR/K,STEM/K" );
692 else
693 *cargstr = '\0';
695 if( rxc->args )
697 if( *cargstr )
698 strcat( cargstr, "," );
699 strcat( cargstr, rxc->args );
702 if( *cargstr )
704 host->rdargs->RDA_Source.CS_Buffer = arg;
705 host->rdargs->RDA_Source.CS_Length = strlen(arg);
706 host->rdargs->RDA_Source.CS_CurChr = 0;
707 host->rdargs->RDA_DAList = NULL;
708 host->rdargs->RDA_Buffer = NULL;
710 if( !ReadArgs(cargstr, argarray, host->rdargs) )
712 rc = 10;
713 rc2 = IoErr();
714 goto drc_cleanup;
718 /* Funktion aufrufen */
720 (rxc->function)( host, (void **) &array, RXIF_ACTION, rexxmsg );
722 rc = array[0];
723 rc2 = array[1];
725 /* Resultat(e) auswerten */
727 if( rxc->results && rc==0 &&
728 (rexxmsg->rm_Action & RXFF_RESULT) )
730 struct rxs_stemnode *stem, *s;
732 stem = CreateSTEM( rxc, resarray, (char *)argarray[1] );
733 result = CreateVAR( stem );
735 if( result )
737 if( argarray[0] )
739 /* VAR */
740 if( (long) result == -1 )
742 rc = 20;
743 rc2 = ERROR_NO_FREE_STORE;
745 else
747 char *rb;
749 for( rb = (char *) argarray[0]; *rb; ++rb )
750 *rb = toupper( *rb );
752 if( SetRexxVar( (struct Message *) rexxmsg,
753 *((char *)argarray[0]) ? (char *)argarray[0] : "RESULT",
754 result, strlen(result) ) )
756 rc = -10;
757 rc2 = (long) "Unable to set Rexx variable";
760 FreeVec( result );
763 result = NULL;
766 if( !rc && argarray[1] )
768 /* STEM */
769 if( (long) stem == -1 )
771 rc = 20;
772 rc2 = ERROR_NO_FREE_STORE;
774 else
776 for( s = stem; s; s = s->succ )
777 rc |= SetRexxVar( (struct Message *) rexxmsg, s->name, s->value, strlen(s->value) );
779 if( rc )
781 rc = -10;
782 rc2 = (long) "Unable to set Rexx variable";
785 if( result && (long) result != -1 )
786 FreeVec( result );
789 result = NULL;
792 /* Normales Resultat: Möglich? */
794 if( (long) result == -1 )
796 /* Nein */
797 rc = 20;
798 rc2 = ERROR_NO_FREE_STORE;
799 result = NULL;
803 free_stemlist( stem );
806 drc_cleanup:
808 /* Nur RESULT, wenn weder VAR noch STEM */
810 ReplyRexxCommand( rexxmsg, rc, rc2, result );
812 /* benutzten Speicher freigeben */
814 if( result ) FreeVec( result );
815 FreeArgs( host->rdargs );
816 if( cargstr ) FreeVec( cargstr );
817 if( array ) (rxc->function)( host, (void **) &array, RXIF_FREE, rexxmsg );
818 if( argb ) FreeVec( argb );
822 void ARexxDispatch( struct RexxHost *host )
824 struct RexxMsg *rexxmsg;
826 while( rexxmsg = (struct RexxMsg *) GetMsg(host->port) )
828 if( (rexxmsg->rm_Action & RXCODEMASK) != RXCOMM )
830 /* Keine Rexx-Message */
831 ReplyMsg( (struct Message *) rexxmsg );
833 else if( rexxmsg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG )
835 struct RexxMsg *org = (struct RexxMsg *) rexxmsg->rm_Args[15];
837 if( org )
839 /* Reply zu durchgereichter Msg */
840 if( rexxmsg->rm_Result1 != 0 )
842 /* Befehl unbekannt */
843 ReplyRexxCommand( org, 20, ERROR_NOT_IMPLEMENTED, NULL );
845 else
847 ReplyRexxCommand( org, 0, 0, (char *) rexxmsg->rm_Result2 );
850 else
852 /* Reply zu einem SendRexxCommand()-Call */
853 if( ARexxResultHook )
854 ARexxResultHook( host, rexxmsg );
857 FreeRexxCommand( rexxmsg );
858 --host->replies;
860 else if( ARG0(rexxmsg) )
862 DoRXCommand( host, rexxmsg );
864 else
866 ReplyMsg( (struct Message *) rexxmsg );