SIM_RC sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env) { SIM_CPU *cpu = STATE_CPU (sd, 0); SIM_ADDR addr; /* Set the PC. */ if (abfd != NULL) addr = bfd_get_start_address (abfd); else addr = 0; sim_pc_set (cpu, addr); /* Standalone mode (i.e. `bfin-...-run`) will take care of the argv for us in sim_open() -> sim_parse_args(). But in debug mode (i.e. 'target sim' with `bfin-...-gdb`), we need to handle it. */ if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG) { freeargv (STATE_PROG_ARGV (sd)); STATE_PROG_ARGV (sd) = dupargv (argv); } switch (STATE_ENVIRONMENT (sd)) { case USER_ENVIRONMENT: bfin_user_init (sd, cpu, abfd, (void *)argv, (void *)env); break; case OPERATING_ENVIRONMENT: bfin_os_init (sd, cpu, (void *)argv); break; default: bfin_virtual_init (sd, cpu); break; } return SIM_RC_OK; }
int run_tests (const char **test_data) { int argc_after, argc_before; char ** argv_before, ** argv_after; int i, j, k, fails, failed; i = j = fails = 0; /* Loop over all the tests */ while (test_data[j]) { /* Write test data */ writeout_test (i, test_data[j++]); /* Copy argv before */ argv_before = dupargv ((char **) &test_data[j]); /* Count argc before/after */ argc_before = 0; argc_after = 0; while (test_data[j + argc_before]) argc_before++; j += argc_before + 1; /* Skip null */ while (test_data[j + argc_after]) argc_after++; /* Copy argv after */ argv_after = dupargv ((char **) &test_data[j]); /* Run all possible replaces */ for (k = 0; k < argc_before; k++) run_replaces (argv_before[k]); for (k = 0; k < argc_after; k++) run_replaces (argv_after[k]); /* Run test: Expand arguments */ expandargv (&argc_before, &argv_before); failed = 0; /* Compare size first */ if (argc_before != argc_after) { printf ("FAIL: test-expandargv-%d. Number of arguments don't match.\n", i); failed++; } /* Compare each of the argv's ... */ else for (k = 0; k < argc_after; k++) if (strcmp (argv_before[k], argv_after[k]) != 0) { printf ("FAIL: test-expandargv-%d. Arguments don't match.\n", i); failed++; } if (!failed) printf ("PASS: test-expandargv-%d.\n", i); else fails++; freeargv (argv_before); freeargv (argv_after); /* Advance to next test */ j += argc_after + 1; /* Erase test file */ erase_test (i); i++; } return fails; }
void expandargv (int *argcp, char ***argvp) { /* The argument we are currently processing. */ int i = 0; /* Non-zero if ***argvp has been dynamically allocated. */ int argv_dynamic = 0; /* Limit the number of response files that we parse in order to prevent infinite recursion. */ unsigned int iteration_limit = 2000; /* Loop over the arguments, handling response files. We always skip ARGVP[0], as that is the name of the program being run. */ while (++i < *argcp) { /* The name of the response file. */ const char *filename; /* The response file. */ FILE *f; /* An upper bound on the number of characters in the response file. */ long pos; /* The number of characters in the response file, when actually read. */ size_t len; /* A dynamically allocated buffer used to hold options read from a response file. */ char *buffer; /* Dynamically allocated storage for the options read from the response file. */ char **file_argv; /* The number of options read from the response file, if any. */ size_t file_argc; /* We are only interested in options of the form "@file". */ filename = (*argvp)[i]; if (filename[0] != '@') continue; /* If we have iterated too many times then stop. */ if (-- iteration_limit == 0) { fprintf (stderr, "%s: error: too many @-files encountered\n", (*argvp)[0]); xexit (1); } /* Read the contents of the file. */ f = fopen (++filename, "r"); if (!f) continue; if (fseek (f, 0L, SEEK_END) == -1) goto error; pos = ftell (f); if (pos == -1) goto error; if (fseek (f, 0L, SEEK_SET) == -1) goto error; buffer = (char *) xmalloc (pos * sizeof (char) + 1); len = fread (buffer, sizeof (char), pos, f); if (len != (size_t) pos /* On Windows, fread may return a value smaller than POS, due to CR/LF->CR translation when reading text files. That does not in-and-of itself indicate failure. */ && ferror (f)) goto error; /* Add a NUL terminator. */ buffer[len] = '\0'; /* If the file is empty or contains only whitespace, buildargv would return a single empty argument. In this context we want no arguments, instead. */ if (only_whitespace (buffer)) { file_argv = (char **) xmalloc (sizeof (char *)); file_argv[0] = NULL; } else /* Parse the string. */ file_argv = buildargv (buffer); /* If *ARGVP is not already dynamically allocated, copy it. */ if (!argv_dynamic) *argvp = dupargv (*argvp); /* Count the number of arguments. */ file_argc = 0; while (file_argv[file_argc]) ++file_argc; /* Now, insert FILE_ARGV into ARGV. The "+1" below handles the NULL terminator at the end of ARGV. */ *argvp = ((char **) xrealloc (*argvp, (*argcp + file_argc + 1) * sizeof (char *))); memmove (*argvp + i + file_argc, *argvp + i + 1, (*argcp - i) * sizeof (char *)); memcpy (*argvp + i, file_argv, file_argc * sizeof (char *)); /* The original option has been replaced by all the new options. */ *argcp += file_argc - 1; /* Free up memory allocated to process the response file. We do not use freeargv because the individual options in FILE_ARGV are now in the main ARGV. */ free (file_argv); free (buffer); /* Rescan all of the arguments just read to support response files that include other response files. */ --i; error: /* We're all done with the file now. */ fclose (f); } }