int pdtlib__ManageArgs (CMDLINE* CmdLine, int (*Callback)(int Status), void (*SwitchFunc)(char Sign), const char* OptList, ...)
?
typedef struct CMDLINE { int argc; const char** argv; int argit; } CMDLINE; const char* pdtlib__GetCurrentArgPtr (CMDLINE* CmdLine) { return CmdLine->argv[CmdLine->argit]; }
pdtlib__0002: move.l 4(%sp),%a0 move.w 6(%a0),%d0 ext.l %d0 move.l 2(%a0),%a0 lsl.l #2,%d0 move.l (%a0,%d0.l),%a0 rts
pdtlib__0002: move.l 4(%sp),%a0 move.w 6(%a0),%d0 - ext.l %d0 | inutile, un word suffit, et d0 représente un int de toute façon, deux octets sur TI... move.l 2(%a0),%a0 - lsl.l #2,%d0 + add.w %d0,%d0 | plus rapide + add.w %d0,%d0 - move.l (%a0,%d0.l),%a0 + move.l (%a0,%d0.w),%a0 rts
#ifndef __HAVE_DEREFSMALL #define __HAVE_DEREFSMALL //! Dereferences a pointer: DEREFSMALL(\a p,\a i) does the same as <code>p[i]</code>, but in a faster and smaller way. // Doing the same thing using inline assembly saved ~100 bytes on an internal, buggy version of tthdex. // Credits go to Kevin Kofler for its generic definition and the &* trick. // 2.00 Beta 5: added ifndef/define pair so as to minimize incompatibility chances with the (same) // definition that could be added to TIGCC some day. #define DEREFSMALL(__p, __i) (*((typeof(&*(__p)))((unsigned char*)(__p)+(long)(short)((short)(__i)*sizeof(*(__p)))))) #endif
\RegTable: ; WARNING: will fail using functions > lib@00FF (should use word sized offsets) moveq.l #0,d0 \RegLoop: move.b (a1)+,d0 bne.s \Continue tst.b (a1) bne.s \Continue ; End of table: dc.b 0,0 rts \Continue: pea (a4) RAMC RAM_kernel::LibsPtr addq.l #4,sp moveq.l #0,d0 ; PreOS bug: LibsPtr destroys d0 move.b (a2)+,d0 move.w #$4EF9,0(a6,d0.w) move.l a0,2(a6,d0.w) bra.s \RegLoop
ButillibCallsTable: dc.b BUTILLIB_InitCmdLine dc.b BUTILLIB_GetCurrentArgPtr dc.b BUTILLIB_GetNextArgPtr dc.b BUTILLIB_IsArgSwitch dc.b BUTILLIB_IsNextArg dc.b BUTILLIB_GetFilePtr dc.b BUTILLIB_CheckFileType dc.b BUTILLIB_ExecSwitchRoutine dc.b BUTILLIB_SkipDummyLines dc.b BUTILLIB_SkipSpaces dc.b BUTILLIB_SkipLine dc.b BUTILLIB_GetFileHandle dc.b BUTILLIB_GetPrevArgPtr dc.b BUTILLIB_AdvanceToChar dc.b 0,0 ButillibCallsOffsets: dc.b INIT_CMDLINE dc.b GET_CURRENT_ARG_PTR dc.b GET_NEXT_ARG_PTR dc.b IS_ARG_SWITCH dc.b IS_NEXT_ARG dc.b GET_FILE_PTR dc.b CHECK_FILE_TYPE dc.b EXEC_SWITCH_ROUTINE dc.b SKIP_DUMMY_LINES dc.b SKIP_SPACES dc.b SKIP_LINE dc.b GET_FILE_HANDLE dc.b GET_PREV_ARG_PTR dc.b ADVANCE_TO_CHAR PedroMCallsTable: dc.b PEDROM_stdin dc.b PEDROM_printf dc.b PEDROM_fprintf dc.b 0,0 PedroMCallsOffsets: dc.b STDERR dc.b PRINTF dc.b FPRINTF
lea CMDLINE(a6),a0 ; Get CMDLINE* jsr GET_NEXT_ARG_PTR(a6) ; Skip current arg lea CMDLINE(a6),a0 ; Get CMDLINE* jsr IS_ARG_SWITCH(a6) ; Check if the arg is an switch
Lionel Debroux (./75) :
Si tu passes un jour à un langage où il n'y a pas de préprocesseur, tu verras que tu regretteras ce bon vieux préprocesseur
Data.InitCmdline = kernel_LibsPtr(Data.pdtlib, PDTLIB__INIT_CMDLINE); // void (*func)() kernel_LibsPtr (Descriptor, #Function); Data.ManageArgs = kernel_LibsPtr(Data.pdtlib, PDTLIB__MANAGE_ARGS); Data.GetCurrentArgPtr = kernel_LibsPtr(Data.pdtlib, PDTLIB__GET_CURRENT_ARG_PTR); Data.SkipArgs = kernel_LibsPtr(Data.pdtlib, PDTLIB__SKIP_ARGS);
const short PdtLibOffsets[] = {(unsigned long)&Data.InitCmdline - (unsigned long)&Data, (unsigned long)&Data.ManageArgs - (unsigned long)&Data, (unsigned long)&Data.GetCurrentArgPtr - (unsigned long)&Data, (unsigned long)&Data.SkipArgs - (unsigned long)&Data};
ou du 95B
Kevin Kofler (./86) :
Tu peux allouer de la place sur la pile par exemple avec alloca, copier ces trucs là-dedans et appeler le code en le transtypant vers le bon pointeur de fonction, mais!