2 * Amiga REXX functions for regina
3 * Copyright © 2002, Staf Verhaegen
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free
17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 /* This files contains functions that are implemented in ARexx
21 * but that are not standard REXX functions. This file contains
22 * the functions that are only to be used on amiga or compatibles.
23 * arxfuncs.c contains the ARexx functions that are usable on all
34 #include <exec/lists.h>
35 #include <exec/ports.h>
36 #include <exec/memory.h>
37 #include <exec/execbase.h>
38 #include <rexx/rxslib.h>
39 #include <rexx/storage.h>
40 #include <rexx/errors.h>
41 #include <rexx/rexxcall.h>
43 #include <proto/alib.h>
44 #include <proto/dos.h>
45 #include <proto/exec.h>
46 #include <proto/rexxsyslib.h>
50 /* We can't use AROS_LC1NR, since 'offset'
53 #define CallRsrcFunc(libbase, offset, rsrc) \
55 int _offset=abs(offset)/6; \
56 AROS_LVO_CALL1NR(VOID, \
57 AROS_LCA(struct RexxRsrc *, rsrc, A0), \
58 struct Library *, libbase, _offset, rexxcall); \
66 typedef struct _amiga_tsd_t
{
67 struct amiga_envir portenvir
;
68 struct RxsLib
*rexxsysbase
;
70 struct List resources
; /* List to store resources to clean up at the end */
71 struct MsgPort
*listenport
, *replyport
;
72 BYTE maintasksignal
, subtasksignal
;
73 struct Task
*parent
, *child
;
74 UBYTE
*value
; /* Here a temporary argstring will be stored for RXGETVAR */
78 GLOBAL_PROTECTION_VAR(createtask
)
81 #define RexxSysBase (((amiga_tsd_t *)TSD->ami_tsd)->rexxsysbase)
83 /* On AROS delete the allocated resources that are not recycled by the
84 * normal C exit handling
86 static void exit_amigaf( int dummy
, void *ptr
)
88 amiga_tsd_t
*atsd
= (amiga_tsd_t
*)ptr
;
89 struct RexxRsrc
*rsrc
;
91 ForeachNode( &atsd
->resources
, rsrc
)
92 CallRsrcFunc( rsrc
->rr_Base
, rsrc
->rr_Func
, rsrc
);
94 DeleteMsgPort( atsd
->replyport
);
95 Signal( atsd
->child
, 1<<atsd
->subtasksignal
);
96 if ( atsd
->rexxsysbase
!= NULL
)
97 CloseLibrary( (struct Library
*)atsd
->rexxsysbase
);
98 UnLock( CurrentDir( atsd
->startlock
) );
103 streng
*createstreng( tsd_t
*TSD
, char *value
, int length
)
108 retval
= TSD
->MTMalloc( TSD
, sizeof(streng
) );
109 if ( retval
!= NULL
)
111 retval
->value
= TSD
->MTMalloc( TSD
, length
);
112 if ( retval
->value
== NULL
)
114 TSD
->MTFree( retval
);
118 memcpy( retval
->value
, value
, length
);
121 retval
= TSD
->MTMalloc( TSD
, sizeof(streng
)-4*sizeof(char)+length
);
122 if ( retval
!= NULL
)
123 memcpy( retval
->value
, value
, length
);
125 retval
->len
= length
;
126 retval
->max
= length
;
131 /* ReginaHandleMessages will be executed in a subtask and will be
132 * able to handle messages send to it asynchronously
134 void ReginaHandleMessages(void)
136 tsd_t
*TSD
= subtask_tsd
;
137 amiga_tsd_t
*atsd
= (amiga_tsd_t
*)TSD
->ami_tsd
;
141 struct MsgPort
*listenport
;
143 listenport
= CreateMsgPort();
144 atsd
->listenport
= listenport
;
145 if ( listenport
== NULL
)
148 atsd
->subtasksignal
= AllocSignal( -1 );
149 Signal( atsd
->parent
, 1<<atsd
->maintasksignal
);
151 mask
= 1<<atsd
->subtasksignal
| 1<<atsd
->listenport
->mp_SigBit
;
152 done
= listenport
== NULL
;
155 signals
= Wait( mask
);
157 done
= (signals
& 1<<atsd
->subtasksignal
) != 0;
159 while ( (msg
= (struct RexxMsg
*)GetMsg( atsd
->listenport
)) != NULL
)
161 if ( IsRexxMsg( msg
) )
162 switch ( msg
->rm_Action
& RXCODEMASK
)
165 AddTail( &atsd
->resources
, (struct Node
*)ARG0( msg
) );
166 msg
->rm_Result1
= RC_OK
;
170 Remove( (struct Node
*)ARG0( msg
) );
171 msg
->rm_Result1
= RC_OK
;
176 if ( ( msg
->rm_Action
& RXARGMASK
) != 2 )
178 msg
->rm_Result1
= RC_ERROR
;
179 msg
->rm_Result2
= (IPTR
)ERR10_017
;
183 streng
*name
, *value
;
185 /* Using own allocation so I can get a NULL return value when allocation
186 * and not Exiterror is called
188 name
= createstreng( TSD
, (char *)msg
->rm_Args
[0], LengthArgstring( (UBYTE
*)msg
->rm_Args
[0] ) );
189 value
= createstreng( TSD
, (UBYTE
*)msg
->rm_Args
[1], LengthArgstring( (UBYTE
*)msg
->rm_Args
[1] ) );
191 if ( name
== NULL
|| value
== NULL
)
193 if ( name
!= NULL
) Free_stringTSD( name
);
194 if ( value
!= NULL
) Free_stringTSD( value
);
195 msg
->rm_Result1
= RC_ERROR
;
196 msg
->rm_Result2
= ERR10_003
;
200 setvalue( TSD
, name
, value
);
201 Free_stringTSD( name
);
202 msg
->rm_Result1
= RC_OK
;
203 msg
->rm_Result2
= (IPTR
)NULL
;
211 if ( ( msg
->rm_Action
& RXARGMASK
) != 1 )
213 msg
->rm_Result1
= RC_ERROR
;
214 msg
->rm_Result2
= (IPTR
)ERR10_017
;
218 amiga_tsd_t
*atsd
= (amiga_tsd_t
*)TSD
->ami_tsd
;
222 name
= createstreng( TSD
, (char *)msg
->rm_Args
[0], LengthArgstring( (UBYTE
*)msg
->rm_Args
[0] ) );
225 msg
->rm_Result1
= RC_ERROR
;
226 msg
->rm_Result2
= (IPTR
)ERR10_003
;
230 value
= isvariable( TSD
, name
);
231 Free_stringTSD( name
);
235 if ( atsd
->value
!= NULL
) DeleteArgstring( (UBYTE
*)atsd
->value
);
236 atsd
->value
= CreateArgstring( (STRPTR
)value
->value
, value
->len
);
238 msg
->rm_Result1
= RC_OK
;
239 msg
->rm_Result2
= (IPTR
)atsd
->value
;
243 msg
->rm_Result1
= RC_ERROR
;
244 msg
->rm_Result2
= (IPTR
)ERR10_039
;
252 msg
->rm_Result1
= RC_ERROR
;
253 msg
->rm_Result2
= ERR10_010
;
256 ReplyMsg( (struct Message
*)msg
);
260 FreeSignal(atsd
->subtasksignal
);
261 if ( listenport
!= NULL
)
262 DeletePort( listenport
);
265 /* Init amiga specific thread data, this function is called during initialisation
266 * of the thread specific data
268 int init_amigaf ( tsd_t
*TSD
)
270 amiga_tsd_t
*atsd
= (amiga_tsd_t
*)malloc( sizeof(amiga_tsd_t
) );
273 if (atsd
==NULL
) return 0;
275 TSD
->ami_tsd
= (void *)atsd
;
277 atsd
->portenvir
.envir
.e
.name
= NULL
;
278 atsd
->portenvir
.envir
.type
= ENVIR_AMIGA
;
279 atsd
->rexxsysbase
= (struct RxsLib
*)OpenLibrary( "rexxsyslib.library", 44 );
280 if ( atsd
->rexxsysbase
== NULL
)
282 old
= CurrentDir(NULL
);
283 atsd
->startlock
= DupLock( old
);
285 if (on_exit( exit_amigaf
, atsd
) == -1)
287 NewList( &atsd
->resources
);
288 atsd
->replyport
= CreatePort( NULL
, 0 );
289 atsd
->maintasksignal
= AllocSignal( -1 );
290 atsd
->parent
= FindTask( NULL
);
294 THREAD_PROTECT(createtask
)
296 atsd
->child
= CreateTask( "Regina Helper", 0, (APTR
)ReginaHandleMessages
, 8192 );
297 if ( atsd
->child
!= NULL
)
298 Wait(1<<atsd
->maintasksignal
);
299 THREAD_UNPROTECT(createtask
)
300 FreeSignal(atsd
->maintasksignal
);
302 if ( atsd
->child
== NULL
)
310 * Support function for exec lists
312 static streng
*getlistnames( tsd_t
*TSD
, struct List
*list
, const streng
*sep
)
316 streng
*retval
, *tmpstr
;
318 retval
= Str_cre_TSD( TSD
, "" );
319 ForeachNode( list
, ln
)
323 tmpstr
= Str_cat_TSD( TSD
, retval
, sep
);
324 if ( tmpstr
!= retval
)
326 Free_string_TSD( TSD
, retval
);
334 tmpstr
= Str_catstr_TSD( TSD
, retval
, ln
->ln_Name
);
335 if ( tmpstr
!= retval
)
337 Free_string_TSD( TSD
, retval
);
347 * SHOW a function the names available in different resource lists
349 streng
*amiga_show( tsd_t
*TSD
, cparamboxptr parm1
)
351 cparamboxptr parm2
= NULL
, parm3
= NULL
;
352 streng
*name
= NULL
, *sep
, *retval
;
354 checkparam( parm1
, 1, 3, "SHOW" );
359 if ( parm2
!= NULL
&& parm2
->value
!= NULL
&& parm2
->value
->len
!= 0 )
362 if ( parm3
== NULL
|| parm3
->value
== NULL
|| parm3
->value
->len
== 0 )
363 sep
= Str_cre_TSD( TSD
, " " );
365 sep
= Str_dup_TSD( TSD
, parm3
->value
);
367 switch( getoptionchar( TSD
, parm1
->value
, "SHOW", 1, "", "CFLP" ) )
370 retval
= arexx_show( TSD
, parm1
);
376 retval
= getlistnames( TSD
, &RexxSysBase
->rl_ClipList
, sep
);
379 char *s
= str_of( TSD
, name
);
380 struct Node
*ln
= FindName( &RexxSysBase
->rl_ClipList
, s
);
381 retval
= int_to_streng( TSD
, ln
!= NULL
);
390 retval
= getlistnames( TSD
, &RexxSysBase
->rl_LibList
, sep
);
393 char *s
= str_of( TSD
, name
);
394 struct Node
*ln
= FindName( &RexxSysBase
->rl_LibList
, s
);
395 retval
= int_to_streng( TSD
, ln
!= NULL
);
404 retval
= getlistnames( TSD
, &SysBase
->PortList
, sep
);
407 char *s
= str_of( TSD
, name
);
408 struct Node
*ln
= FindName( &SysBase
->PortList
, s
);
409 retval
= int_to_streng( TSD
, ln
!= NULL
);
415 Free_string_TSD( TSD
, sep
);
421 /* amiga_find_envir will try to find the port with the given and
422 * create an envir function for that
424 struct envir
*amiga_find_envir( const tsd_t
*TSD
, const streng
*name
)
426 amiga_tsd_t
*atsd
= (amiga_tsd_t
*)TSD
->ami_tsd
;
428 struct MsgPort
*port
;
430 s
= str_of( TSD
, name
);
431 port
= FindPort( s
);
437 if ( atsd
->portenvir
.envir
.e
.name
!= NULL
)
438 Free_stringTSD( atsd
->portenvir
.envir
.e
.name
);
440 atsd
->portenvir
.envir
.e
.name
= Str_dupTSD( name
);
441 atsd
->portenvir
.port
= port
;
443 return (struct envir
*)&(atsd
->portenvir
);
446 /* createreginamessage will create a RexxMsg filled with the necessary fields
447 * for regina specific things
449 struct RexxMsg
*createreginamessage( const tsd_t
*TSD
)
451 amiga_tsd_t
*atsd
= (amiga_tsd_t
*)TSD
->ami_tsd
;
454 msg
= CreateRexxMsg( atsd
->replyport
, NULL
, NULL
);
457 msg
->rm_Private1
= (IPTR
)atsd
->listenport
;
458 msg
->rm_Private2
= (IPTR
)TSD
;
463 /* The function sendandwait will send a rexx message to a certain
464 * port and wait till it returns. It the mean time also other
465 * message (like variable can be handled
466 * The replyport of the msg has to be atsd->listenport
468 void sendandwait( const tsd_t
*TSD
, struct MsgPort
*port
, struct RexxMsg
*msg
)
470 amiga_tsd_t
*atsd
= (amiga_tsd_t
*)TSD
->ami_tsd
;
471 struct RexxMsg
*msg2
;
473 PutMsg( port
, (struct Message
*)msg
);
476 while ( msg2
!= msg
)
478 WaitPort( atsd
->replyport
);
479 msg2
= (struct RexxMsg
*)GetMsg( atsd
->replyport
);
481 ReplyMsg( (struct Message
*)msg2
);
487 streng
*AmigaSubCom( const tsd_t
*TSD
, const streng
*command
, struct envir
*envir
, int *rc
)
490 struct MsgPort
*port
= ((struct amiga_envir
*)envir
)->port
;
491 streng
*retval
= NULL
;
493 msg
= createreginamessage( TSD
);
494 msg
->rm_Action
= RXCOMM
;
495 msg
->rm_Args
[0] = (IPTR
)CreateArgstring( (STRPTR
)command
->value
, command
->len
);
497 msg
->rm_Stdin
= Input();
498 msg
->rm_Stdout
= Output();
500 sendandwait( TSD
, port
, msg
);
502 *rc
= msg
->rm_Result1
;
503 if (msg
->rm_Result1
== 0)
505 if (msg
->rm_Result2
== NULL
)
506 retval
= Str_crestrTSD( "" );
509 retval
= Str_ncre_TSD( TSD
, (UBYTE
*)msg
->rm_Result2
, LengthArgstring( (UBYTE
*)msg
->rm_Result2
) );
510 DeleteArgstring( (UBYTE
*)msg
->rm_Result2
);
514 retval
= Str_crestrTSD( "" );
516 DeleteArgstring( (UBYTE
*)msg
->rm_Args
[0]);
517 DeleteRexxMsg( msg
);
524 * Here follows now the support function for ARexx style function hosts and libraries:
526 * Also here the try_func_amiga is defined which is called when a function is called
527 * in an ARexx script.
530 /* When addlib is called with two arguments the first argument is considered as a function
531 * host name. When it is called with three or four arguments a function library is assumed
533 streng
*amiga_addlib( tsd_t
*TSD
, cparamboxptr parm1
)
535 cparamboxptr parm2
= NULL
, parm3
= NULL
, parm4
= NULL
;
536 struct MsgPort
*rexxport
;
538 int pri
, offset
, version
, error
, count
;
542 checkparam( parm1
, 2, 4, "ADDLIB" );
544 pri
= streng_to_int( TSD
, parm2
->value
, &error
);
545 if (error
|| abs(pri
) > 100 )
546 exiterror( ERR_INCORRECT_CALL
, 11, "ADDLIB", 2, tmpstr_of( TSD
, parm2
->value
) );
549 if ( parm3
!= NULL
&& parm3
->value
!= NULL
&& parm3
->value
->len
== 0 )
550 exiterror( ERR_INCORRECT_CALL
, 21, "ADDLIB", 3 );
551 if ( parm3
== NULL
|| parm3
->value
== NULL
)
555 offset
= streng_to_int( TSD
, parm3
->value
, &error
);
556 if ( error
|| offset
>= 0 )
557 exiterror( ERR_INCORRECT_CALL
, 11, "ADDLIB", 3, tmpstr_of( TSD
, parm3
->value
) );
562 if ( parm4
== NULL
|| parm4
->value
== NULL
|| parm4
->value
->len
== 0 )
566 version
= streng_to_int( TSD
, parm4
->value
, &error
);
568 exiterror( ERR_INCORRECT_CALL
, 11, "ADDLIB", 4, tmpstr_of( TSD
, parm4
->value
) );
570 exiterror( ERR_INCORRECT_CALL
, 13, "ADDLIB", 4, tmpstr_of( TSD
, parm4
->value
) );
573 name
= str_of( TSD
, parm1
->value
);
574 msg
= createreginamessage( TSD
);
577 Free_TSD( TSD
, name
);
578 exiterror( ERR_STORAGE_EXHAUSTED
, 0 );
580 if ( parm3
== NULL
|| parm3
->value
== NULL
|| parm3
->value
->len
== 0 )
582 msg
->rm_Action
= RXADDFH
;
583 msg
->rm_Args
[0] = (IPTR
)name
;
584 msg
->rm_Args
[1] = (IPTR
)pri
;
586 if ( !FillRexxMsg( msg
, 2, 1<<1 ) )
588 Free_TSD( TSD
, name
);
589 DeleteRexxMsg( msg
);
590 exiterror( ERR_STORAGE_EXHAUSTED
, 0 );
595 msg
->rm_Action
= RXADDLIB
;
596 msg
->rm_Args
[0] = (IPTR
)name
;
597 msg
->rm_Args
[1] = (IPTR
)pri
;
598 msg
->rm_Args
[2] = (IPTR
)offset
;
599 msg
->rm_Args
[3] = (IPTR
)version
;
601 if ( !FillRexxMsg( msg
, 4, 1<<1 | 1<<2 | 1<<3 ) )
603 Free_TSD( TSD
, name
);
604 DeleteRexxMsg( msg
);
605 exiterror( ERR_STORAGE_EXHAUSTED
, 0 );
609 rexxport
= FindPort( "REXX" );
610 if (rexxport
== NULL
)
612 Free_TSD( TSD
, name
);
613 DeleteRexxMsg( msg
);
614 exiterror( ERR_EXTERNAL_QUEUE
, 0 );
616 sendandwait( TSD
, rexxport
, msg
);
618 Free_TSD( TSD
, name
);
619 ClearRexxMsg( msg
, count
);
621 retval
= ( msg
->rm_Result1
== 0 ) ? Str_cre_TSD( TSD
, "1" ) : Str_cre_TSD( TSD
, "0" );
623 DeleteRexxMsg( msg
);
628 streng
*amiga_remlib( tsd_t
*TSD
, cparamboxptr parm1
)
630 struct MsgPort
*rexxport
;
634 checkparam( parm1
, 1, 1, "REMLIB" );
636 msg
= createreginamessage( TSD
);
638 exiterror( ERR_STORAGE_EXHAUSTED
, 0 );
640 msg
->rm_Action
= RXREMLIB
;
641 msg
->rm_Args
[0] = (IPTR
)CreateArgstring( parm1
->value
->value
, parm1
->value
->len
);
643 rexxport
= FindPort( "REXX" );
644 if (rexxport
== NULL
)
646 DeleteArgstring( (UBYTE
*)msg
->rm_Args
[0] );
647 DeleteRexxMsg( msg
);
648 exiterror( ERR_EXTERNAL_QUEUE
, 0 );
650 sendandwait( TSD
, rexxport
, msg
);
652 retval
= ( msg
->rm_Result1
== 0 ) ? Str_cre_TSD( TSD
, "1" ) : Str_cre_TSD( TSD
, "0" );
654 DeleteArgstring( (UBYTE
*)msg
->rm_Args
[0] );
655 DeleteRexxMsg( msg
);
660 streng
*try_func_amiga( tsd_t
*TSD
, const streng
*name
, cparamboxptr parms
, char called
)
662 struct MsgPort
*port
;
664 struct RexxRsrc
*rsrc
;
669 unsigned int parmcount
;
673 msg
= createreginamessage( TSD
);
675 exiterror( ERR_STORAGE_EXHAUSTED
, 0 );
677 msg
->rm_Action
= RXFUNC
| RXFF_RESULT
;
678 msg
->rm_Args
[0] = (IPTR
)CreateArgstring( (char *)name
->value
, name
->len
);
680 for (parmit
= parms
, parmcount
= 0; parmit
!= NULL
; parmit
= parmit
->next
)
682 if ( parmit
->value
!= NULL
&& parmit
->value
->len
> 0 )
685 msg
->rm_Args
[parmcount
] = (IPTR
)CreateArgstring( parmit
->value
->value
, parmit
->value
->len
);
688 msg
->rm_Action
|= parmcount
;
689 msg
->rm_Stdin
= Input( );
690 msg
->rm_Stdout
= Output( );
694 for (rsrc
= (struct RexxRsrc
*)GetHead(&RexxSysBase
->rl_LibList
), result1
= 1;
695 rsrc
!= NULL
&& result1
== 1;
696 rsrc
= (struct RexxRsrc
*)GetSucc(rsrc
))
698 switch (rsrc
->rr_Node
.ln_Type
)
701 lib
= OpenLibrary(rsrc
->rr_Node
.ln_Name
, rsrc
->rr_Arg2
);
705 ClearRexxMsg( msg
, parmcount
+ 1 );
706 DeleteRexxMsg( msg
);
707 exiterror( ERR_EXTERNAL_QUEUE
, 0 );
709 /* Can not pass &result2 directly because on systems where
710 * sizeof(IPTR)>sizeof(UBYTE *) this goes wrong
712 result1
= RexxCallQueryLibFunc(msg
, lib
, rsrc
->rr_Arg1
, &retstring
);
714 result2
= (IPTR
)retstring
;
718 port
= FindPort(rsrc
->rr_Node
.ln_Name
);
722 ClearRexxMsg( msg
, parmcount
+ 1 );
723 DeleteRexxMsg( msg
);
724 exiterror( ERR_EXTERNAL_QUEUE
, 0 );
726 sendandwait( TSD
, port
, msg
);
728 result1
= (ULONG
)msg
->rm_Result1
;
729 result2
= msg
->rm_Result2
;
737 ClearRexxMsg( msg
, parmcount
+ 1 );
738 DeleteRexxMsg( msg
);
742 if ( (UBYTE
*)result2
== NULL
)
743 retval
= nullstringptr();
746 retval
= Str_ncre_TSD( TSD
, (const char *)result2
, LengthArgstring( (UBYTE
*)result2
) );
747 DeleteArgstring( (UBYTE
*)result2
);
750 else if ( result1
== 1 )
753 exiterror( ERR_EXTERNAL_QUEUE
, 0 );
760 /* The clip handling functions for AROS/amiga: setclip, getclip */
762 streng
*amiga_setclip( tsd_t
*TSD
, cparamboxptr parm1
)
765 struct MsgPort
*rexxport
;
769 checkparam( parm1
, 1, 2, "SETCLIP" );
772 msg
= createreginamessage( TSD
);
774 exiterror( ERR_STORAGE_EXHAUSTED
, 0 );
776 if ( parm2
== NULL
|| parm2
->value
== NULL
|| parm2
->value
->len
== 0 )
778 msg
->rm_Action
= RXREMCON
;
779 msg
->rm_Args
[0] = (IPTR
)str_of( TSD
, parm1
->value
);
783 msg
->rm_Action
= RXADDCON
;
784 msg
->rm_Args
[0] = (IPTR
)str_of( TSD
, parm1
->value
);
785 msg
->rm_Args
[1] = (IPTR
)parm2
->value
->value
;
786 msg
->rm_Args
[2] = (IPTR
)parm2
->value
->len
;
789 rexxport
= FindPort( "REXX" );
790 if ( rexxport
== NULL
)
792 Free_TSD( TSD
, (void *)msg
->rm_Args
[0] );
793 DeleteRexxMsg( msg
);
794 exiterror( ERR_EXTERNAL_QUEUE
, 0 );
796 sendandwait( TSD
, rexxport
, msg
);
798 Free_TSD( TSD
, (void *)msg
->rm_Args
[0] );
800 retval
= ( msg
->rm_Result1
== 0 ) ? Str_cre_TSD( TSD
, "1" ) : Str_cre_TSD( TSD
, "0" );
801 DeleteRexxMsg( msg
);
806 streng
*amiga_getclip( tsd_t
*TSD
, cparamboxptr parm1
)
808 struct RexxRsrc
*rsrc
;
811 checkparam( parm1
, 1, 1, "GETCLIP" );
813 name
= str_of( TSD
, parm1
->value
);
816 rsrc
= (struct RexxRsrc
*)FindName( &RexxSysBase
->rl_ClipList
, name
);
819 Free_TSD( TSD
, name
);
822 return nullstringptr();
824 return Str_ncre_TSD( TSD
, (const char *)rsrc
->rr_Arg1
, LengthArgstring( (UBYTE
*)rsrc
->rr_Arg1
) );
827 streng
*amiga_pragma( tsd_t
*TSD
, cparamboxptr parm1
)
831 static char buf
[1024];
833 checkparam( parm1
, 1, 2, "PRAGMA" );
836 switch( getoptionchar( TSD
, parm1
->value
, "PRAGMA", 1, "", "DPIS" ) )
840 BPTR lock
= CurrentDir( NULL
);
842 NameFromLock( lock
, buf
, 1023 );
844 retval
= Str_cre_TSD( TSD
, buf
);
845 if ( parm2
!= NULL
&& parm2
->value
!= NULL
&& parm2
->value
->len
!= 0 )
847 struct FileInfoBlock
*fib
;
848 char *name
= str_of( TSD
, parm2
->value
);
850 lock
= Lock( name
, ACCESS_READ
);
852 Free_TSD( TSD
, name
);
854 fib
= AllocDosObject( DOS_FIB
, NULL
);
858 UnLock( (BPTR
)lock
);
859 exiterror( ERR_STORAGE_EXHAUSTED
, 0 );
863 Examine( lock
, fib
);
865 if ( lock
== NULL
|| fib
->fib_DirEntryType
<= 0 )
867 FreeDosObject( DOS_FIB
, fib
);
868 Free_string_TSD( TSD
, retval
);
869 retval
= nullstringptr();
873 UnLock( CurrentDir( lock
) );
874 FreeDosObject( DOS_FIB
, fib
);
882 struct Task
*task
= FindTask( NULL
);
883 retval
= int_to_streng( TSD
, (int)task
->tc_Node
.ln_Pri
);
884 if ( parm2
!= NULL
&& parm2
->value
!= NULL
&& parm2
->value
->len
!= 0 )
887 pri
= streng_to_int( TSD
, parm2
->value
, &error
);
889 exiterror( ERR_INCORRECT_CALL
, 11, "PRAGMA", 2, tmpstr_of( TSD
, parm2
->value
) );
890 if ( abs(pri
) > 127 )
891 exiterror( ERR_INCORRECT_CALL
, 0 );
892 SetTaskPri( task
, pri
);
900 sprintf(s
, "%8X", (int)FindTask( NULL
) );
901 if ( parm2
!= NULL
&& parm2
->value
!= NULL
)
902 exiterror( ERR_INCORRECT_CALL
, 4, "PRAGMA", 1 );
903 retval
= Str_cre_TSD( TSD
, s
);
909 struct Process
*process
= (struct Process
*)FindTask( NULL
);
910 ULONG size
= (ULONG
)((char *)process
->pr_Task
.tc_SPUpper
- (char *)process
->pr_Task
.tc_SPLower
);
911 retval
= int_to_streng( TSD
, size
);
912 #warning second argument ignored because stack size increase is not implemented