Beispiel #1
0
/**
 *  Given the original argv stuff, the length of our target executable, and the
 *  filepath, build a suitable command line for CreateProcess.
 */
STATIC LPTSTR BuildCmdLine(int argc, TCHAR* argv[], SIZE_T szExecutable, LPTSTR lpExecutable)
{
	int i = 1;
	LPTSTR lpCmdLine = NULL;
	SIZE_T szCmdLine = szExecutable;
	TCHAR** lpNewArgs = (TCHAR**)calloc(argc, sizeof(TCHAR*));
	assert(lpNewArgs != NULL);
	
	// Quote the executable path if need be.
	XINFO(_T("Building command line.."));
	if(HasSpace(lpExecutable, szExecutable)) {
		lpNewArgs[0] = Quote(lpExecutable, &szCmdLine, FALSE);
	} else {
		lpNewArgs[0] = DupArg(lpExecutable, &szCmdLine, FALSE);
	}
	
	// Iterate through all args, quoting as necessary.
	for(; i < argc; i++) {
		SIZE_T szArg = (SIZE_T)_tcslen((const TCHAR*)argv[i]);
		if(HasSpace(argv[i], szArg)) {
			lpNewArgs[i] = Quote(argv[i], &szArg, TRUE);
		} else {
			lpNewArgs[i] = DupArg(argv[i], &szArg, TRUE);
		}
		// +1 for space + len(arg)
		szCmdLine += szArg;
	}
	
	// Allocate our cmdline buffer and begin adding the various parts.
	lpCmdLine = (LPTSTR)calloc(szCmdLine + 1, sizeof(TCHAR));
	assert(lpCmdLine != NULL);
	_tcscpy(lpCmdLine, lpNewArgs[0]);
	XINFO(_T("  [0] => \"%s\""), lpNewArgs[0]);
	
	// Cleanup allocated arg.
	xfree(lpNewArgs[0]);
	lpNewArgs[0] = NULL;
	
	for(i = 1; i < argc; i++) {
		XINFO(_T("  [%d] => \"%s\""), i, argv[i]);
		_tcscat(lpCmdLine, lpNewArgs[i]);
		xfree(lpNewArgs[i]);
		lpNewArgs[i] = NULL;
	}
	
	XINFO(_T("Finished building.."));
	XINFO(_T("CmdLine: %s"), lpCmdLine);
	xfree(lpNewArgs);
	return lpCmdLine;
}
Beispiel #2
0
char *ParseCompFlags(int nargs, char **args, int *BITS, ATL_arg_t **files,
                     ATL_arg_t **CMP, ATL_arg_t **ASM, ATL_arg_t **LNK,
                     int *CPPONLY)
{
   int i, nfiles=0, DOASM=1, DOLNK=1;
   ATL_arg_t *cmpb, *cp, *asmb, *ap, *lnkb, *lp, *filb, *fp, *an;
   char *outn=NULL;
   *CPPONLY = 0;
/*
 * Go through compiler flags and separate them into flags affecting
 * compilation, assembling, and linking
 */
   cmpb = cp = NewArg(MYGCC);
   asmb = ap = NewArg(MYASM);
   lnkb = lp = NewArg(MYLNK);
   filb = NULL;
   for (i=1; i < nargs; i++)
   {
      ATL_arg_t *at;
      at = NewArg(args[i]);
      if (at->arg[0] == '-')  /* flag */
      {
         switch (at->arg[1])
         {
         case 'o' :  /* -o : found name of output file */
/*
 *          If this is just -o, then actual name is given in the next arg
 */
            if (at->len == 2)
            {
               assert(++i < nargs);
               outn = args[i];
            }
/*
 *          is of form -o<name>
 */
            else
               outn = args[i]+2;
            break;
         case 'L' : /* -L/l args go only to linker  */
         case 'l' :
            if (at->len == 2)
            {
               assert(++i < nargs);
               lp->next = at;
               lp = at->next = NewArg(args[i]);
            }
            else
            {
               lp->next = at;
               lp = at;
            }
            break;
         case 'x' :  /* I only use -x asg-with-cpp, so pass to comp only */
            *CPPONLY = 1;
            cp->next = at;
            assert(++i < nargs);
            assert(!strcmp(args[i], "assembler-with-cpp"));
            cp = at->next = NewArg(args[i]);
            break;
         case 'c' :
            DOLNK = 0;
            break;
         case 'S' :
            DOASM = DOLNK = 0;
            break;
         case 'E':
         case 'X':
         case 'T':
         case 'u':
            fprintf(stderr, "FLAG '-%c' NOT HANDLED, DYING\n", at->arg[1]);
            assert(0); /* not implemented at moment */
         case 'W': /* possible linker/assembler pass-thru */
           if (at->len > 3)
           {
              if (at->arg[2] == 'a' && at->arg[3] == ',') /* asm pass-thru */
              {
                 ap->next = at;
                 ap = at;
              }
              else if (at->arg[2] == 'l' && at->arg[3] == ',') /* lnk pass */
              {
                 lp->next = at;
                 lp = at;
              }
           }
           /* else fall-thru to default */
         default:  /* everything else assumed to be a compiler-only flag */
/*
 *          In default, compare against all known linker options
 */
            if ( (at->len == 13 && !strcmp(at->arg, "-nostartfiles")) ||
                 (at->len == 14 && !strcmp(at->arg, "-nodefaultlibs")) ||
                 (at->len == 9 && !strcmp(at->arg, "-nostdlib")) ||
                 (at->len == 4 && !strcmp(at->arg, "-pie")) ||
                 (at->len == 9 && !strcmp(at->arg, "-rdynamic")) ||
                 (at->len == 2 && at->arg[1] == 's') ||
                 (at->len == 7 && !strcmp(at->arg, "-static")) ||
                 (at->len == 14 && !strcmp(at->arg, "-static-libgcc")) ||
                 (at->len == 9 && !strcmp(at->arg, "-symbolic"))
               )
            {
               lp->next = at;
               lp = at;
            }
            else if (at->len == 8 && !strcmp(at->arg, "-Xlinker"))
            {
               assert(++i < nargs);
               lp->next = at;
               lp = at->next = NewArg(args[i]);
            }
            else if (at->len == 11 && !strcmp(at->arg, "-Xassembler"))
            {
               assert(++i < nargs);
               ap->next = at;
               ap = at->next = NewArg(args[i]);
            }
/*
 *          -m64/32 args get passed to comp, asm & linker
 */
            else if (at->len == 4 &&
                     (!strcmp(at->arg, "-m64") || !strcmp(at->arg, "-mx32") ||
                      !strcmp(at->arg, "-m32")))
            {
               if (at->arg[2] == '6')
                  *BITS = 64;
               else
                  *BITS = 32;
               lp->next = DupArg(at);
               lp = lp->next;
               ap->next = DupArg(at);
               ap = ap->next;
               cp->next = at;
               cp = at;
            }
            else if (at->len == 9 && !strcmp(at->arg, "--version"))
            {
               char *sp;
               int i;
               i = strlen(MYGCC);
               sp = malloc(i + 12);
               strcpy(sp, MYGCC);
               strcpy(sp+i, " --version");
               system(sp);
               free(sp);
               #ifdef DEBUG
                  fclose(fplog);
               #endif
               exit(0);  /* ugly uncleaned-up exit; live with it */
            }
            else
            {
               cp->next = at;
               cp = at;
            }
         }
      }
      else  /* anything not beginning with - must be a filename */
      {
         char ch;
         int F90=0;
         int len = at->len;

         assert(len > 2);
         ch = at->arg[len-1];
         nfiles++;
         if (at->arg[len-2] == '.') /* .f or .F */
            assert(ch == 'f' || ch == 'F' || ch == 'o' || ch == 'a');
         else  /* .f90 */
         {
            F90 = 1;
            ch = at->arg[len-3];
            assert(len > 4)
            assert(at->arg[len-4] == '.' &&
                   (ch == 'f' || ch == 'F') ||
                   (at->arg[len-2] == '9'));
         }
/*
 *       If it isn't already an object file, add it to list of files to be
 *       renamed during compilation
 */
         if (ch != 'o' && ch != 'a')
         {
            if (!filb)
               filb = fp = at;
            else
            {
               fp->next = at;
               fp = at;
            }
/*
 *          Put empty node in linker options to indicate where to put in the
 *          generated file names
 */
            lp->next = NewArg(NULL);
            lp = lp->next;
         }
/*
 *       If it is a object/archive file, just add it to link line and forget it
 */
         else
         {
            lp->next = NewArg(at->arg);
            lp = lp->next;
         }
/*
 *       If the file is already an object file, add it to linker
 */
      }
   }
   if (outn)  /* must use particular output name */
   {
      ATL_arg_t *tp;
      tp = (DOLNK) ? lp : ap;
      tp->next = NewArg("-o");
      tp->next->next = NewArg(outn);
      tp = tp->next->next;
   }
   if (outn && !DOLNK)
      assert(nfiles == 1);
   else
      assert(nfiles > 0);
/*
 * If there are no files in filb, that means nothing need be compiled, so
 * the only thing we are doing is linking
 */
   if (!filb)
   {
      assert(DOLNK);
      if (cmpb)
         KillAllArgs(cmpb);
      if (asmb)
         KillAllArgs(asmb);
      *CMP = NULL;
      *ASM = NULL;
   }
   else
   {
      *CMP = cmpb;
      if (DOASM)
         *ASM = asmb;
      else
      {
         *ASM = NULL;
         KillAllArgs(asmb);
      }
   }
   if (DOLNK)
      *LNK = lnkb;
   else
   {
      *LNK = NULL;
      KillAllArgs(lnkb);
   }
   *files = filb;
   return(outn);
}