#include #ifdef __linux__ #include #else #include #include #endif #include #include "zlib.h" #include "amx.h" #include "amxdbg.h" #include "amxxpc.h" void ReadFileIntoPl(abl *pl, FILE *fp); int main(int argc, char **argv) { struct abl pl32; struct abl pl64; #ifdef _DEBUG printf("debug clamp\n"); getchar(); #endif #ifdef __linux__ HINSTANCE lib = dlmount("./amxxpc32.so"); #else HINSTANCE lib = dlmount("amxxpc32.dll"); #endif if (!lib) { #ifdef __linux__ printf("32bit compiler failed to instantiate: %s\n", dlerror()); #else printf("32bit compiler failed to instantiate: %d\n", GetLastError()); #endif exit(0); } COMPILER sc32 = (COMPILER)dlsym(lib, "Compile32"); PRINTF pc_printf = (PRINTF)dlsym(lib, "pc_printf"); if (!sc32 || !pc_printf) { #ifdef __linux__ printf("32bit compiler failed to link: %p|%p.\n",sc32, sc_printf); #else printf("32bit compiler failed to link: %d.\n", GetLastError()); #endif exit(0); } pc_printf("Welcome to the AMX Mod X %s Compiler.\n", VERSION_STRING); pc_printf("Copyright (c) 1997-2005 ITB CompuPhase, AMX Mod X Team\n\n"); if (argc < 2) { pc_printf("Usage: [options]\n"); pc_printf("Use -? or --help to see full options\n\n"); getchar(); exit(0); } if (!strcmp(argv[1], "-?") || !strcmp(argv[1], "--help")) { show_help(); pc_printf("Press any key to continue.\n"); getchar(); exit(0); } sc32(argc, argv); char *file = FindFileName(argc, argv); if (file == NULL) { pc_printf("Could not locate the output file.\n"); exit(0); } else if (strstr(file, ".asm")) { pc_printf("Assembler output succeeded.\n"); exit(0); } else { FILE *fp = fopen(file, "rb"); if (fp == NULL) { pc_printf("Could not locate output file %s (compile failed).\n", file); exit(0); } ReadFileIntoPl(&pl32, fp); pl32.cellsize = 4; fclose(fp); } unlink(file); HINSTANCE lib64 = 0; #ifdef __linux__ lib64 = dlmount("./amxxpc64.so"); #else lib64 = dlmount("amxxpc64.dll"); #endif if (!lib64) { pc_printf("64bit compiler failed to instantiate.\n"); exit(0); } COMPILER sc64 = (COMPILER)dlsym(lib64, "Compile64"); if (!sc64) { #ifdef __linux__ pc_printf("64bit compiler failed to link: %s.\n", dlerror()); #else pc_printf("64bit compiler failed to link: %d.\n", GetLastError()); #endif exit(0); } sc64(argc, argv); dlclose(lib64); if (file == NULL) { pc_printf("Could not locate the output file on second pass.\n"); exit(0); } else { FILE *fp = fopen(file, "rb"); if (fp == NULL) { pc_printf("Could not locate output file on second pass (compile failed).\n"); exit(0); } ReadFileIntoPl(&pl64, fp); pl64.cellsize = 8; fclose(fp); } ///////////// // COMPRSSION ///////////// int err; pl32.cmpsize = compressBound(pl32.size); pl32.cmp = new char[pl32.cmpsize]; err = compress((Bytef *)pl32.cmp, (uLongf *)&(pl32.cmpsize), (const Bytef*)pl32.data, pl32.size); if (err != Z_OK) { pc_printf("internal error - compression failed on first pass: %d\n", err); exit(0); } pl64.cmpsize = compressBound(pl64.size); pl64.cmp = new char[pl64.cmpsize]; err = compress((Bytef *)pl64.cmp, (uLongf *)&(pl64.cmpsize), (const Bytef*)pl64.data, pl64.size); if (err != Z_OK) { pc_printf("internal error - compression failed on second pass: %d\n", err); exit(0); } char *newfile = new char[strlen(file)+3]; strcpy(newfile, file); if (!strstr(file, ".amxx") && !strstr(file, ".AMXX")) strcat(newfile, "x"); FILE *fp = fopen(newfile, "wb"); if (!fp) { pc_printf("Error trying to write file %s.\n", newfile); exit(0); } //magic + archn int hdrsize = sizeof(long) + sizeof(char); int entry = sizeof(long) + sizeof(long) + sizeof(char); int offset1 = hdrsize + (entry * 2); int offset2 = offset1 + pl32.cmpsize; int magic = MAGIC_HEADER; fwrite((void *)&magic, sizeof(int), 1, fp); char n = 2; fwrite((void *)&n, sizeof(char), 1, fp); fwrite((void *)&(pl32.cellsize), sizeof(char), 1, fp); fwrite((void *)&(pl32.stp), sizeof(long), 1, fp); fwrite((void *)&(offset1), sizeof(long), 1, fp); fwrite((void *)&(pl64.cellsize), sizeof(char), 1, fp); fwrite((void *)&(pl64.stp), sizeof(long), 1, fp); fwrite((void *)&(offset2), sizeof(long), 1, fp); fwrite(pl32.cmp, sizeof(char), pl32.cmpsize, fp); fwrite(pl64.cmp, sizeof(char), pl64.cmpsize, fp); fclose(fp); unlink(file); pc_printf("Done.\n"); dlclose(lib); exit(0); } //As of Small 3.0, there's extra debug info in the file we need to get out. //Sadly this is placed somewhere really inconvenient and I'm mad. void ReadFileIntoPl(abl *pl, FILE *fp) { AMX_HEADER hdr; AMX_DBG_HDR dbg; fread(&hdr, sizeof(hdr), 1, fp); amx_Align32((uint32_t *)&hdr.stp); amx_Align32((uint32_t *)&hdr.size); pl->stp = hdr.stp; int size = hdr.size; if (hdr.flags & AMX_FLAG_DEBUG) { fseek(fp, hdr.size, SEEK_SET); fread(&dbg, sizeof(dbg), 1, fp); size += dbg.size; } pl->size = size; pl->data = new char[size]; rewind(fp); fread(pl->data, 1, size, fp); } //we get the full name of the file here //our job is to a] switch the .sma extension to .amx // and to b] strip everything but the trailing name char *swiext(const char *file, const char *ext, int isO) { int i = 0, pos = -1, j = 0; int fileLen = strlen(file); int extLen = strlen(ext); int max = 0, odirFlag = -1; for (i=fileLen-1; i>=0; i--) { if (file[i] == '.' && pos == -1) { pos = i+1; } if ((file[i] == '/' || file[i] == '\\') && !isO) { odirFlag = i+1; //realign pos - we've just stripped fileLen-i chars pos -= i + 1; break; } } char *newbuffer = new char[fileLen+strlen(ext)+2]; fileLen += strlen(ext); if (odirFlag == -1) { strcpy(newbuffer, file); } else { strcpy(newbuffer, &(file[odirFlag])); } if (pos > -1) { for (i=pos; i0) { return swiext(argv[save], "amx", 0); } return NULL; } void show_help() { printf("Options:\n"); printf("\t-A alignment in bytes of the data segment and the stack\n"); printf("\t-a output assembler code\n"); printf("\t-C[+/-] compact encoding for output file (default=-)\n"); printf("\t-c codepage name or number; e.g. 1252 for Windows Latin-1\n"); printf("\t-Dpath active directory path\n"); printf("\t-d0 no symbolic information, no run-time checks\n"); printf("\t-d1 [default] run-time checks, no symbolic information\n"); printf("\t-d2 full debug information and dynamic checking\n"); printf("\t-d3 full debug information, dynamic checking, no optimization\n"); printf("\t-e set name of error file (quiet compile)\n"); printf("\t-H window handle to send a notification message on finish\n"); printf("\t-i path for include files\n"); printf("\t-l create list file (preprocess only)\n"); printf("\t-o set base name of output file\n"); printf("\t-p set name of \"prefix\" file\n"); printf("\t-r[name] write cross reference report to console or to specified file\n"); }