int main(int argc,char *argv[]) { extern int amx_ConsoleInit(AMX *amx); extern int amx_ConsoleCleanup(AMX *amx); extern int amx_CoreInit(AMX *amx); extern int amx_CoredCleanp(AMX *amx); size_t memsize; void *program; AMX amx; int index, err; cell amx_addr, *phys_addr; char output[128]; if (argc != 4) PrintUsage(argv[0]); if ((memsize = aux_ProgramSize(argv[1])) == 0) PrintUsage(argv[0]); program = malloc(memsize); if (program == NULL) ErrorExit(NULL, AMX_ERR_MEMORY); err = aux_LoadProgram(&amx, argv[1], program); if (err) ErrorExit(&amx, err); amx_ConsoleInit(amx); err = amx_CoreInit(amx); if (err) ErrorExit(&amx, err); err = amx_FindPublic(&amx, argv[2], &index); if (err) ErrorExit(&amx, err); err = amx_Allot(&amx, strlen(argv[3]) + 1, &amx_addr, &phys_addr); if (err) ErrorExit(&amx, err); amx_SetString(phys_addr, argv[3], 0); err = amx_Exec(&amx, NULL, index, 1, amx_addr); if (err) ErrorExit(&amx, err); amx_GetString(output, phys_addr); amx_Release(&amx, amx_addr); printf("%s returns %s\n", argv[1], output); amx_ConsoleCleanup(&amx); amx_CoreCleanup(&amx); amx_Cleanup(&amx); free(program); return 0; }
int initialize_pawn_machine (pawn_machine *machine, const char* fname) { int err; size_t memsize; void* buffer; machine->initialized = 0; memsize = aux_ProgramSize (fname); if (memsize == 0) { log_error ("Unable to determine memory size for Pawn file %s", fname); return 0; } buffer = malloc (memsize); if (buffer == NULL) { log_error ("unable to allocate memory for Pawn file %s", fname); return 0; } err = aux_LoadProgram (&(machine->amx), fname, buffer); if (err != AMX_ERR_NONE) { free (buffer); log_error ("unable to load Pawn file %s", fname); return 0; } // The amx_*Init functions return an error when not all natives // used in the amx script are defined, so we only need to check // the last Init (when we have defined our entire library). amx_ConsoleInit (&(machine->amx)); amx_FloatInit (&(machine->amx)); amx_StringInit (&(machine->amx)); err = amx_ElInit (&(machine->amx)); if (err != AMX_ERR_NONE) { free (buffer); log_error ("Unable to initialize all native functions for Pawn file %s", fname); return 0; } machine->buf_size = memsize; machine->buffer = buffer; machine->initialized = 1; return 1; }
int main(int argc,char *argv[]) { AMX amx; cell ret = 0; int err; clock_t start,end; if (argc != 2) PrintUsage(argv[0]); /* function "usage" aborts the program */ if ((err = aux_LoadProgram(&amx, argv[1])) == AMX_ERR_NOTFOUND) { /* try adding an extension */ char filename[_MAX_PATH]; strcpy(filename, argv[1]); strcat(filename, ".amx"); err = aux_LoadProgram(&amx, filename); } /* if */ ExitOnError(&amx, err); amx_ConsoleInit(&amx); err = amx_CoreInit(&amx); ExitOnError(&amx, err); start=clock(); err = amx_Exec(&amx, &ret, AMX_EXEC_MAIN); while (err == AMX_ERR_SLEEP) err = amx_Exec(&amx, &ret, AMX_EXEC_CONT); end=clock(); ExitOnError(&amx, err); aux_FreeProgram(&amx); if (ret!=0) printf("\nReturn value: %ld\n", (long)ret); printf("\nRun time: %.2f seconds\n",(double)(end-start)/CLOCKS_PER_SEC); return 0; }
int main(int argc,char *argv[]) { AMX amx; cell ret = 0; int err, i; clock_t start,end; STACKINFO stackinfo = { 0 }; AMX_IDLE idlefunc; if (argc < 2) PrintUsage(argv[0]); /* function "usage" aborts the program */ #if !defined AMX_NODYNALOAD && defined ENABLE_BINRELOC && (defined __LINUX__ || defined __FreeBSD__ || defined __OpenBSD__) /* see www.autopackage.org for the BinReloc module */ if (br_init(NULL)) { char *libroot=br_find_exe_dir(""); setenv("AMXLIB",libroot,0); free(libroot); } /* if */ #endif /* Load the program and initialize the abstract machine. */ err = aux_LoadProgram(&amx, argv[1]); if (err != AMX_ERR_NONE) { /* try adding an extension */ char filename[_MAX_PATH]; strcpy(filename, argv[1]); strcat(filename, ".amx"); err = aux_LoadProgram(&amx, filename); if (err != AMX_ERR_NONE) PrintUsage(argv[0]); } /* if */ /* To install the debug hook "just-in-time", the signal function needs * a pointer to the abstract machine(s) to abort. There are various ways * to implement this; here I have done so with a simple global variable. */ global_amx = &amx; signal(SIGINT, sigabort); /* Initialize two core extension modules (more extension modules may be * loaded & initialized automatically as DLLs or shared libraries. */ amx_ConsoleInit(&amx); err = amx_CoreInit(&amx); ExitOnError(&amx, err); /* save the idle function, if set by any of the extension modules */ if (amx_GetUserData(&amx, AMX_USERTAG('I','d','l','e'), (void**)&idlefunc) != AMX_ERR_NONE) idlefunc = NULL; for (i = 2; i < argc; i++) { if (strcmp(argv[i],"-stack") == 0) { uint16_t flags; amx_Flags(&amx, &flags); if ((flags & AMX_FLAG_NOCHECKS) != 0) printf("This script was compiled with debug information removed.\n" "Stack monitoring is disfunctional\n\n"); /* Set "user data" with which the debug monitor can monitor stack usage * per abstract machine (in this example, though, there is only one abstract * machine, so a global variable would have sufficed). */ memset(&stackinfo, 0, sizeof stackinfo); err = amx_SetUserData(&amx, AMX_USERTAG('S','t','c','k'), &stackinfo); ExitOnError(&amx, err); /* Install the debug hook, so that we can start monitoring the stack/heap * usage right from the beginning of the script. */ amx_SetDebugHook(&amx, prun_Monitor); } /* if */ } /* for */ start=clock(); /* Run the compiled script and time it. The "sleep" instruction causes the * abstract machine to return in a "restartable" state (it restarts from * the point that it stopped. This allows for a kind of light-weight * cooperative multi-tasking. As native functions (or the debug hook) can * also force an abstract machine to "sleep", you can also use it to create * "latent functions": functions that allow the host application to continue * processing, and/or other abstract machines to run, while they wait for * some resource. */ err = amx_Exec(&amx, &ret, AMX_EXEC_MAIN); while (err == AMX_ERR_SLEEP) { if (idlefunc != NULL) { /* If the abstract machine was put to sleep, we can handle events during * that time. To save the "restart point", we must make a copy of the AMX * (keeping the stack, frame, instruction pointer and other vital * registers), but without cloning the entire abstract machine. * There should be some criterion on when the abstract machine must be * "woken up". In this example run-time, the parameter of the sleep * instruction is taken to be a delay in milliseconds. In your own host * application, you can choose to wait on a resource/semaphore or other. */ AMX nested_amx = amx; clock_t stamp = clock(); while (((clock() - stamp)*1000)/CLOCKS_PER_SEC < amx.pri && (err = idlefunc(&nested_amx,amx_Exec)) == AMX_ERR_NONE) /* nothing */; ExitOnError(&nested_amx, err); } /* if */ err = amx_Exec(&amx, &ret, AMX_EXEC_CONT); } /* while */ if (idlefunc == NULL || err != AMX_ERR_INDEX) ExitOnError(&amx, err); /* event-driven programs may not have main() */ /* For event-driven programs, we also need to loop over the idle/monitor * function that some extension module installed (this could be the console * module, for example). We did this if the main program was put to "sleep", * but we do that here too. */ if (idlefunc != NULL) { while ((err = idlefunc(&amx,amx_Exec)) == AMX_ERR_NONE) /* nothing */; ExitOnError(&amx, err); } /* if */ end=clock(); /* Free the compiled script and resources. This also unloads and DLLs or * shared libraries that were registered automatically by amx_Init(). */ aux_FreeProgram(&amx); /* Print the return code of the compiled script (often not very useful), * its run time, and its stack usage. */ if (ret!=0) printf("\nReturn value: %ld\n", (long)ret); printf("\nRun time: %.2f seconds\n",(double)(end-start)/CLOCKS_PER_SEC); if (stackinfo.maxstack != 0 || stackinfo.maxheap != 0) { printf("Stack usage: %ld cells (%ld bytes)\n", stackinfo.maxstack / sizeof(cell), stackinfo.maxstack); printf("Heap usage: %ld cells (%ld bytes)\n", stackinfo.maxheap / sizeof(cell), stackinfo.maxheap); } /* if */ #if defined AMX_TERMINAL /* This is likely a graphical terminal, which should not be closed * automatically */ { extern int amx_termctl(int,int); while (amx_termctl(4,0)) /* nothing */; } #endif return 0; }
int main(int argc,char *argv[]) { AMX amx; cell ret = 0; int err; if (argc != 2) PrintUsage(argv[0]); /* function "usage" aborts the program */ /* Load the program and initialize the abstract machine. */ err = aux_LoadProgram(&amx, argv[1], NULL, srun_Monitor); if (err != AMX_ERR_NONE) { /* try adding an extension */ char filename[_MAX_PATH]; strcpy(filename, argv[1]); strcat(filename, ".amx"); err = aux_LoadProgram(&amx, filename, NULL, srun_Monitor); if (err != AMX_ERR_NONE) PrintUsage(argv[0]); } /* if */ /* Initialize two core extension modules (more extension modules may be * loaded & initialized automatically as DLLs or shared libraries. */ amx_ConsoleInit(&amx); amx_CoreInit(&amx); /* register functions for the bstring library */ err = amx_Register(&amx, bstring_Natives, -1); ExitOnError(&amx, err); /* Initialize the garbage collector, start with a small table. */ gc_setcallback((GC_FREE)bdestroy); err = gc_settable(7, GC_AUTOGROW); ExitOnError(&amx, err); /* Run the compiled script and time it. The "sleep" instruction causes the * abstract machine to return in a "restartable" state (it restarts from * the point that it stopped. This enables for a kind of light-weight * cooperative multi-tasking. As native functions (or the debug hook) can * also force an abstract machine to "sleep", you can also use it to create * "latent functions": functions that allow the host application to continue * processing, and/or other abstract machines to run, while they wait for * some resource. * In this example, there are no other abstract machines (there is just one) * and this "host" program has nothing else to do than run the abstract * machine. So if it detects a "sleep" it just restarts the abstract machine * immediately. */ err = amx_Exec(&amx, &ret, AMX_EXEC_MAIN, 0); while (err == AMX_ERR_SLEEP) err = amx_Exec(&amx, &ret, AMX_EXEC_CONT, 0); ExitOnError(&amx, err); /* Free the compiled script and resources. This also unloads and DLLs or * shared libraries that were registered automatically by amx_Init(). */ aux_FreeProgram(&amx); /* Free the garbarge collector data and tables. */ gc_settable(0); /* Print the return code of the compiled script (often not very useful). */ if (ret!=0) printf("\nReturn value: %ld\n", (long)ret); #if defined AMX_TERMINAL /* This is likely a graphical terminal, which should not be closed * automatically */ { extern int amx_termctl(int,int); while (amx_termctl(4,0)) /* nothing */; } #endif return 0; }