123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- /* A68k compatibility wrapper for GNU as.
- * Copyright (C) 2005 Kevin Kofler
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #ifdef __WIN32__
- #include <windows.h>
- #undef IGNORE
- #endif
- #define fatal(s) ({fprintf(stderr,(s)); return 1;})
- #ifdef __WIN32__
- static int run_cmdline(const char *cmdline)
- {
- long exitcode;
- STARTUPINFO startupinfo={.cb=sizeof(startupinfo)};
- PROCESS_INFORMATION processinfo;
- if (!CreateProcess(NULL,(char *)cmdline,NULL,NULL,FALSE,0,NULL,NULL,
- &startupinfo,&processinfo)) return 1;
- if (WaitForSingleObject(processinfo.hProcess,INFINITE)==WAIT_FAILED) return 1;
- if (!GetExitCodeProcess(processinfo.hProcess,&exitcode)) return 1;
- CloseHandle(processinfo.hProcess);
- CloseHandle(processinfo.hThread);
- return exitcode;
- }
- #else
- #define run_cmdline system
- #endif
- __attribute__((noreturn)) static void outofmem(void)
- {
- fprintf(stderr,"Fatal error: not enough free memory\n");
- exit(1);
- }
- static char *dynstrcat(char *s, const char *t)
- {
- char *p;
- size_t l = strlen(s) + strlen(t) + 1;
- p = realloc(s,l);
- if (p) {
- strcat(p,t);
- return p;
- } else {
- free(s);
- outofmem();
- }
- }
- #ifndef __WIN32__
- static inline void escape_arg(char *escaped_arg, const char *unescaped_arg)
- {
- char *p;
- strcpy(escaped_arg,unescaped_arg);
- for (p=escaped_arg; *p; p++) {
- switch(*p) {
- /* The following characters are shell characters and need to be escaped! */
- case ' ':
- case '\\':
- case '\"':
- case '\'':
- case '$':
- case '!':
- case '^':
- case '&':
- case '*':
- case '(':
- case ')':
- case '~':
- case '[':
- case ']':
- case '|':
- case '{':
- case '}':
- case ';':
- case '<':
- case '>':
- case '?':
- memmove(p+1,p,strlen(p)+1);
- *(p++)='\\';
- default:
- break;
- }
- }
- }
- #endif
- static char *dynargcat(char *s, const char *t)
- {
- char *p;
- #ifdef __WIN32__
- size_t l = strlen(s)+strlen(t)+3;
- #else
- size_t l = strlen(s)+2*strlen(t)+1;
- #endif
- p = realloc(s,l);
- if (p) {
- #ifdef __WIN32__
- strcat(p,"\"");
- strcat(p,t);
- strcat(p,"\"");
- #else
- escape_arg(p+strlen(p),t);
- char *q = realloc(p,strlen(p)+1);
- if (q) p=q;
- #endif
- return p;
- } else {
- free(s);
- outofmem();
- }
- }
- int main(int argc, char *argv[])
- {
- /* Find GNU as */
- #ifdef __WIN32__
- HMODULE module_h = GetModuleHandle("a68k.exe");
- if (!module_h) fatal("Fatal error: Can't obtain module handle.");
- char path_to_as[MAX_PATH];
- if (!GetModuleFileName(module_h,path_to_as,MAX_PATH)) fatal("Fatal error: GetModuleFileName failed.");
- char *p=strrchr(path_to_as,'\\');
- if (!p) fatal("Fatal error: No backslash in module file name.");
- strcpy(p+1,"as.exe");
- #else
- const char *tigcc_base=getenv("TIGCC");
- if (!tigcc_base) fatal("Fatal error: $TIGCC not defined in the environment.\n");
- char path_to_as[strlen(tigcc_base)+8];
- sprintf(path_to_as,"%s/bin/as",tigcc_base);
- #endif
- /* Allocate argument string */
- char *argstr=calloc(1,1);
- argstr=dynargcat(argstr,path_to_as);
- argstr=dynstrcat(argstr," --a68k");
- /* Translate arguments */
- int i, ogiven=0, filearg=0, quiet=0;
- for (i=1; i<argc; i++) {
- #define IGNORE(a) if (!strncmp(argv[i],(a),2)) continue;
- #define FAIL(a) if (!strncmp(argv[i],a,2)) {free(argstr);fatal("switch " a " not supported");}
- #define CONVERT(a,b) if (!strcmp(argv[i],(a))) argstr=dynstrcat(argstr,(b)); else
- #define PARSE(a) else if (!strncmp(argv[i],(a),2)) {char *arg=argv[i]+2;
- IGNORE("-e")
- IGNORE("-f")
- IGNORE("-g")
- IGNORE("-n")
- IGNORE("-p")
- IGNORE("-q")
- IGNORE("-r")
- IGNORE("-s")
- IGNORE("-t")
- IGNORE("-w")
- IGNORE("-z")
- if (!strcmp(argv[i],"-q")) {quiet=1; continue;}
- FAIL("-h");
- FAIL("-m");
- argstr=dynstrcat(argstr," ");
- CONVERT("-a","--all-relocs")
- CONVERT("-k","-Z")
- CONVERT("-u","--unaligned")
- CONVERT("-y","--statistics")
- if (!strncmp(argv[i],"-d",2)) argstr=dynstrcat(argstr,"-L");
- PARSE("-i")
- const char *incpath=strtok(arg,",;");
- argstr=dynstrcat(argstr,"-I ");
- argstr=dynargcat(argstr,incpath);
- while ((incpath=strtok(NULL,",;"))) {
- argstr=dynstrcat(argstr," -I ");
- argstr=dynargcat(argstr,incpath);
- }
- }
- PARSE("-o")
- ogiven=1;
- argstr=dynstrcat(argstr,"-o ");
- argstr=dynargcat(argstr,arg);
- }
- PARSE("-l")
- argstr=dynstrcat(argstr,"-ahl=");
- argstr=dynargcat(argstr,arg);
- }
- PARSE("-x")
- argstr=dynstrcat(argstr,"-a=");
- argstr=dynargcat(argstr,arg);
- }
- PARSE("-v")
- char *p;
- argstr=dynstrcat(argstr,"--defsym ");
- if ((p=strchr(arg,','))) *p='=';
- if ((p=strchr(arg,';'))) *p='=';
- argstr=dynargcat(argstr,arg);
- } else {
- if (filearg) {free(argstr); fatal("too many file names");}
- filearg=i;
- argstr=dynargcat(argstr,argv[i]);
- }
- }
- /* Name a default output file */
- if (!ogiven && filearg) {
- char ofile[strlen(argv[filearg])+1];
- strcpy(ofile,argv[filearg]);
- char *p=strrchr(ofile,'.');
- if (!p || !p[1]) {free(argstr); fatal("invalid file name");}
- strcpy(p+1,"o");
- argstr=dynstrcat(argstr," -o ");
- argstr=dynargcat(argstr,ofile);
- }
-
- /* Run GNU as */
- if (!quiet) printf("A68k compatibility wrapper Copyright 2005 Kevin Kofler\n\nAssembling ...\n");
- int exitcode=run_cmdline(argstr);
- free(argstr);
- return exitcode;
- }
|