Ejemplo n.º 1
0
Archivo: nvc.c Proyecto: jkone27/nvc
static int list_cmd(int argc, char **argv)
{
   static struct option long_options[] = {
      { 0, 0, 0, 0 }
   };

   const int next_cmd = scan_cmd(2, argc, argv);
   int c, index = 0;
   const char *spec = "";
   while ((c = getopt_long(next_cmd, argv, spec, long_options, &index)) != -1) {
      switch (c) {
      case 0:
         // Set a flag
         break;
      case '?':
         fatal("unrecognised list option %s", argv[optind - 1]);
      default:
         abort();
      }
   }

   lib_walk_index(lib_work(), list_walk_fn, NULL);

   argc -= next_cmd - 1;
   argv += next_cmd - 1;

   return argc > 1 ? process_command(argc, argv) : EXIT_SUCCESS;
}
Ejemplo n.º 2
0
Archivo: nvc.c Proyecto: jkone27/nvc
static int syntax_cmd(int argc, char **argv)
{
   static struct option long_options[] = {
      { 0, 0, 0, 0 }
   };

   const int next_cmd = scan_cmd(2, argc, argv);
   int c, index = 0;
   const char *spec = "";
   while ((c = getopt_long(next_cmd, argv, spec, long_options, &index)) != -1) {
      switch (c) {
      case 0:
         // Set a flag
         break;
      case '?':
         fatal("unrecognised syntax option %s", argv[optind - 1]);
      default:
         abort();
      }
   }

   for (int i = optind; i < next_cmd; i++) {
      input_from_file(argv[i]);
      (void)parse();
   }

   if (parse_errors() > 0)
      return EXIT_FAILURE;

   argc -= next_cmd - 1;
   argv += next_cmd - 1;

   return argc > 1 ? process_command(argc, argv) : EXIT_SUCCESS;
}
Ejemplo n.º 3
0
Archivo: nvc.c Proyecto: jkone27/nvc
static int dump_cmd(int argc, char **argv)
{
   static struct option long_options[] = {
      { "elab", no_argument, 0, 'E' },
      { "body", no_argument, 0, 'b' },
      { "nets", no_argument, 0, 'n' },
      { 0, 0, 0, 0 }
   };

   const int next_cmd = scan_cmd(2, argc, argv);
   bool add_elab = false, add_body = false, nets = false;
   int c, index = 0;
   const char *spec = "Eb";
   while ((c = getopt_long(argc, argv, spec, long_options, &index)) != -1) {
      switch (c) {
      case 0:
         // Set a flag
         break;
      case '?':
         fatal("unrecognised dump option %s", argv[optind - 1]);
      case 'E':
         add_elab = true;
         break;
      case 'b':
         add_body = true;
         break;
      case 'n':
         add_elab = true;
         nets = true;
         break;
      default:
         abort();
      }
   }

   if (optind == next_cmd)
      fatal("missing unit name");

   for (int i = optind; i < next_cmd; i++) {
      ident_t name = to_unit_name(argv[i]);
      if (add_elab)
         name = ident_prefix(name, ident_new("elab"), '.');
      else if (add_body)
         name = ident_prefix(name, ident_new("body"), '-');
      tree_t top = lib_get(lib_work(), name);
      if (top == NULL)
         fatal("%s not analysed", istr(name));
      (nets ? dump_nets : dump)(top);
   }

   argc -= next_cmd - 1;
   argv += next_cmd - 1;

   return argc > 1 ? process_command(argc, argv) : EXIT_SUCCESS;
}
Ejemplo n.º 4
0
Archivo: nvc.c Proyecto: jkone27/nvc
static int make_cmd(int argc, char **argv)
{
   static struct option long_options[] = {
      { "deps-only", no_argument, 0, 'd' },
      { "native",    no_argument, 0, 'n' },
      { "posix",     no_argument, 0, 'p' },
      { 0, 0, 0, 0 }
   };

   const int next_cmd = scan_cmd(2, argc, argv);
   int c, index = 0;
   const char *spec = "";
   while ((c = getopt_long(next_cmd, argv, spec, long_options, &index)) != -1) {
      switch (c) {
      case 0:
         // Set a flag
         break;
      case '?':
         fatal("unrecognised make option %s", argv[optind - 1]);
      case 'd':
         opt_set_int("make-deps-only", 1);
         break;
      case 'n':
         opt_set_int("native", 1);
         break;
      case 'p':
         opt_set_int("make-posix", 1);
         break;
      default:
         abort();
      }
   }

   const int count = next_cmd - optind;
   tree_t *targets = xmalloc(count * sizeof(tree_t));

   lib_t work = lib_work();

   for (int i = optind; i < next_cmd; i++) {
      ident_t name = to_unit_name(argv[i]);
      ident_t elab = ident_prefix(name, ident_new("elab"), '.');
      if ((targets[i - optind] = lib_get(work, elab)) == NULL) {
         if ((targets[i - optind] = lib_get(work, name)) == NULL)
            fatal("cannot find unit %s in library %s",
                  istr(name), istr(lib_name(work)));
      }
   }

   make(targets, count, stdout);

   argc -= next_cmd - 1;
   argv += next_cmd - 1;

   return argc > 1 ? process_command(argc, argv) : EXIT_SUCCESS;
}
Ejemplo n.º 5
0
Archivo: nvc.c Proyecto: jkone27/nvc
static int codegen(int argc, char **argv)
{
   static struct option long_options[] = {
      { 0, 0, 0, 0 }
   };

   const int next_cmd = scan_cmd(2, argc, argv);
   int c, index = 0;
   const char *spec = "";
   while ((c = getopt_long(next_cmd, argv, spec, long_options, &index)) != -1) {
      switch (c) {
      case 0:
         // Set a flag
         break;
      case '?':
         fatal("unrecognised codegen option %s", argv[optind - 1]);
      default:
         abort();
      }
   }

   set_top_level(argv, next_cmd);

   tree_t pack = lib_get(lib_work(), top_level);
   if (pack == NULL)
      fatal("cannot find unit %s in library %s",
            istr(top_level), istr(lib_name(lib_work())));

   if (tree_kind(pack) != T_PACKAGE)
      fatal("this command can only be used with packages");

   if (pack_needs_cgen(pack))
      link_package(pack);

   ident_t body_i = ident_prefix(top_level, ident_new("body"), '-');
   tree_t body = lib_get(lib_work(), body_i);
   if (body != NULL)
      link_package(body);

   argc -= next_cmd - 1;
   argv += next_cmd - 1;

   return argc > 1 ? process_command(argc, argv) : EXIT_SUCCESS;
}
Ejemplo n.º 6
0
/**
 * A redirecting test command handler.
 *
 * @param context    The Exit context.
 * @param address    The environment name.
 * @param command    The command name and arguments.
 * @param ioContext  The IO Redirector context.
 */
RexxObjectPtr RexxEntry ioCommandHandler(RexxExitContext *context, RexxStringObject address, RexxStringObject command, RexxIORedirectorContext *ioContext)
{
    int pid;
    int status;
    char* argv[MAX_COMMAND_ARGS + 1];
    // If SYSSHELLPATH could ever grow longer than 128 chars
    // then this array size will need to be increased.
    char shell[128 + 1 + 256 + 1]; // SYSSHELLPATH plus "/" plus environment name

    CSTRING environment = context->CString(address);
    CSTRING commandString = context->CString(command);

    if (Utilities::strCaselessCompare("path", environment) == 0)
    {   // For the no-shell "direct" environment we need to break the command
        // string into a command name and separate arguments each (we have no
        // shell to do this for us).
        if (!scan_cmd(commandString, argv))
        {   // too many arguments
            return ErrorFailure(context, commandString);
        }
        // posix_spawnp() will fault if argv[0] is NULL.  Fix this.
        if (argv[0] == NULL)
        {
            argv[0] = (char*)"";
            argv[1] = NULL;
        }
    }
    else
    {   // Set up the full path to the requested shell.
        strcpy(shell, SYSSHELLPATH);
        if (shell[strlen(shell) - 1] != '/')
        {   // append slash if we don't have one yet
            strcat(shell, "/");
        }
        if (strlen(environment) == 0 || Utilities::strCaselessCompare("command", environment) == 0)
        {   // for environments "" and "command" we use "sh" as shell
            strcat(shell, "sh");
        }
        else
        {   // for all other environment names we use this name in lower case
            strcat(shell, environment);
            Utilities::strlower(shell);
        }

        argv[0] = (char*)shell;
        argv[1] = (char*)"-c";
        argv[2] = (char*)commandString;
        argv[3] = NULL;
    }

    if (ioContext->IsRedirectionRequested())
    {
        InputWriterThread inputThread; // separate thread if we need to write INPUT
        ErrorReaderThread errorThread; // separate thread if we need to read ERROR
        bool need_to_write_input = false;
        bool need_to_read_output = false;
        bool need_to_read_error = false;
        int input[2], output[2], error[2];

        posix_spawn_file_actions_t action;
        posix_spawn_file_actions_init(&action);

        // ignore SIGPIPE so that we receive EPIPE for a write() operation on a
        // pipe which has closed its read end.
        if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
        {
            return ErrorRedirection(context, errno);
        }

        // Create stdin, stdout, and stderr pipes as requested.  pipe() returns
        // two file descriptors: [0] is the pipe read end, [1] is the pipe
        // write end.  The child process (i. e. the command to be run) will
        // inherit both the read and write end of all created pipes.  Of each
        // end *we* will only ever use one end, and the child the other end.
        // Therefore we and the child will close any unused ends.  In addition,
        // we also prepare any file actions that are to be be done by the child.
        // These actions are collected with posix_spawn_file_actions()

        // is stdin redirection requested?
        if (ioContext->IsInputRedirected())
        {
            if (pipe(input) != 0) // create stdin pipe
            {
                return ErrorRedirection(context, errno);
            }
            posix_spawn_file_actions_adddup2(&action, input[0], 0); // stdin reads from pipe
            posix_spawn_file_actions_addclose(&action, input[1]); // close unused write end in child
            need_to_write_input = true;
        }

        // is stdout redirection requested?
        if (ioContext->IsOutputRedirected())
        {
            if (pipe(output) != 0) // create stdout pipe
            {
                return ErrorRedirection(context, errno);
            }
            // do we want interleaved stdout and stderr redirection?
            // this is a special case .. we just redirect stderr to stdout upfront
            if (ioContext->AreOutputAndErrorSameTarget())
            {
                posix_spawn_file_actions_adddup2(&action, output[1], 2); //stderr writes to pipe
            }
            posix_spawn_file_actions_adddup2(&action, output[1], 1); //stdout writes to pipe
            posix_spawn_file_actions_addclose(&action, output[0]); // close unused read end in child
            need_to_read_output = true;
        }

        // now stderr redirection
        // if both stdout and stderr are to be redirected to the same object, then
        // everything was already set up in the previous stdout redirection step
        if (ioContext->IsErrorRedirected() && !ioContext->AreOutputAndErrorSameTarget())
        {
            if (pipe(error) != 0) // create stderr pipe
            {
                return ErrorRedirection(context, errno);
            }
            posix_spawn_file_actions_adddup2(&action, error[1], 2); // stderr writes to pipe
            posix_spawn_file_actions_addclose(&action, error[0]); // close unused read end in child
            need_to_read_error = true;
        }

        // ok, everything is set up accordingly, let's fork the redirected command
        if (posix_spawnp(&pid, argv[0], &action, NULL, argv, getEnvironment()) != 0)
            {
                return ErrorFailure(context, commandString);
            }

        // Close all unneeded read- and write ends
        if (need_to_write_input)
        {
            close(input[0]); // we close our unused stdout pipe write end
        }
        if (need_to_read_output)
        {
            close(output[1]); // we close our unused stdout pipe write end
        }
        if (need_to_read_error)
        {
            close(error[1]); // we close our unused stderr pipe write end
        }

        if (need_to_write_input)
        {
            ioContext->ReadInputBuffer(&inputThread.inputBuffer, &inputThread.bufferLength);
            // we start a separate thread to write INPUT data to the input pipe
            inputThread.start(input[1]);
        }
        if (need_to_read_error)
        {
            // we start a separate thread to read ERROR data from the error pipe
            errorThread.start(error[0]);
        }

        // do we need to read OUTPUT from the stdout pipe?
        // we run this in the main thread instead of starting another new thread
        // if we have stdout and sterr interleaved, we'll read both of them here
        if (need_to_read_output)
        {
            // According to POSIX.1 PIPE_BUF is at least 512 bytes; on Linux
            // it's 4096 bytes.
            char outputBuffer[PIPE_BUF];
            ssize_t outputLength;

            while ((outputLength = read(output[0], &outputBuffer, PIPE_BUF)) > 0)
            {
                ioContext->WriteOutputBuffer(outputBuffer, outputLength);
            }
            if (outputLength != 0) // 0 is EOF, success
            {
                return ErrorRedirection(context, errno);
            }
            close(output[0]);
        }

        // did we start an ERROR thrad?
        if (need_to_read_error)
        {
            // wait for the ERROR thread to finish
            errorThread.waitForTermination();
            if (errorThread.bufferLength > 0)
            {   // return what the ERROR thread read from its pipe
                ioContext->WriteErrorBuffer(errorThread.errorBuffer, errorThread.bufferLength);
            }
            // the ERROR thread may have encountered an error .. raise it now
            if (errorThread.error != 0)
            {
                return ErrorRedirection(context, errorThread.error);
            }
        }

        // if we started an INPUT thread, wait until it finishes
        if (need_to_write_input)
        {
            inputThread.waitForTermination();
            // the INPUT thread may have encountered an error .. raise it now
            if (inputThread.error != 0)
            {
                return ErrorRedirection(context, inputThread.error);
            }
        }

        posix_spawn_file_actions_destroy(&action);
    }
    else // no redirection requested
    {
        // try to handle special commands like 'cd' or 'export' internally
        RexxObjectPtr rc = NULLOBJECT;

        if (handleCommandInternally(context, (char*)commandString, rc))
        {   // the command was handled in this thread
            return rc;
        }
        else
        {   // to run the command we spawn another thread
            if (posix_spawnp(&pid, argv[0], NULL, NULL, argv, getEnvironment()) != 0)
            {
                return ErrorFailure(context, commandString);
            }
        }
    }

    // wait for our child, the forked command
    waitpid(pid, &status, 0);
    int rc;
    if (WIFEXITED(status)) // child process ended normal
    {
        rc = WEXITSTATUS(status); // set return code
    }
    else
    {   // child process died
        rc = -(WTERMSIG(status));
        if (rc == 1) // process was stopped
        {
            rc = -1;
        }
    }

    // unknown command code?
    // a FAILURE will be raised for any command returning 127
    if (rc == UNKNOWN_COMMAND)
    {
        return ErrorFailure(context, commandString);
    }
    else if (rc != 0)
    {
        // for any non-zero return code we raise an ERROR condition
        context->RaiseCondition("ERROR", context->String(commandString),
          NULL, context->WholeNumberToObject(rc));
        return NULLOBJECT;
    }
    return context->False(); // zero return code
}
RexxObjectPtr RexxEntry systemCommandHandler(RexxExitContext *context, RexxStringObject address, RexxStringObject command)
{
    const char *cmd = context->StringData(command);
    const char *envName = context->StringData(address);

    RexxObjectPtr rc = NULLOBJECT;

    /* check for redirection symbols, ignore them when enclosed in double quotes.
       escaped quotes are ignored. */
    bool noDirectInvoc = false;
    bool inQuotes = false;
    bool escape = false;
    size_t i;
    for (i = 0; i<strlen(cmd); i++)
    {
        if (escape)
        {
            escape = false;
        }
        else if (cmd[i] == '\\')
        {
            escape = true;
        }
        else if (cmd[i] == '"')
        {
            inQuotes = !inQuotes;
        }
        else
        {
            /* if we're in the unquoted part and the current character is one of */
            /* the redirection characters or the & for multiple commands then we */
            /* will no longer try to invoke the command directly                 */
            if (!inQuotes && (strchr("<>|&", cmd[i]) != NULL))
            {
                noDirectInvoc = true;
                break;
            }
        }
    }

    if (!noDirectInvoc)
    {
        /* execute 'cd' in the same process */
        size_t commandLen = strlen(cmd);

        if (strcmp(cmd, "cd") == 0)
        {
            if (sys_process_cd(context, cmd, rc))
            {
                return rc;
            }
        }
        else if (commandLen >= 3)
        {
            char tmp[16];
            strncpy(tmp, cmd, 3);
            tmp[3] = '\0';
            if (strcmp("cd ",tmp) == 0)
            {
                if (sys_process_cd(context, cmd, rc))
                {
                    return rc;
                }
            }
            strncpy(tmp, cmd, 4);
            tmp[4] = '\0';
            if (strcmp("set ",tmp) == 0)
            {
                if (sys_process_export(context, cmd, rc, SET_FLAG)) /*unset works fine for me*/
                {
                    return rc;
                }
            }
            strncpy(tmp, cmd, 6);
            tmp[6] = '\0';
            if (Utilities::strCaselessCompare("unset ", tmp) == 0)
            {
                if (sys_process_export(context, cmd, rc, UNSET_FLAG))
                {
                    return rc;
                }
            }
            strncpy(tmp, cmd, 7);
            tmp[7] = '\0';
            if (Utilities::strCaselessCompare("export ", tmp) == 0)
            {
                if (sys_process_export(context, cmd, rc, EXPORT_FLAG))
                {
                    return rc;
                }
            }
        }
    }


    /****************************************************************************/
    /* Invoke the system command handler to execute the command                 */
    /****************************************************************************/
    // if this is the null string, then use the default address environment
    // for the platform
    if (strlen(envName) == 0)
    {
        envName = SYSINITIALADDRESS;
    }

    int errCode = 0;

#ifdef LINUX

    if (Utilities::strCaselessCompare("bash", envName) == 0)
    {
        errCode = system( cmd );
        if ( errCode >= 256 )
        {
            errCode = errCode / 256;
        }
    }
    else
#endif
    {
        int pid = fork();
        int status;

        if (pid != 0)                         /* spawn a child process to run the  */
        {
            waitpid ( pid, &status, 0);          /* command and wait for it to finish */
            if (WIFEXITED(status))               /* If cmd process ended normal       */
            {
                                                 /* Give 'em the exit code            */
                errCode = WEXITSTATUS(status);
            }
            else                              /* Else process died ugly, so        */
            {
                errCode = -(WTERMSIG(status));
                if (errCode == 1)                    /* If process was stopped            */
                {
                    errCode = -1;                   /* Give 'em a -1.                    */
                }
            }
        }
        else
        {
        	/* run the command in the child      */
            if (Utilities::strCaselessCompare("sh", envName) == 0)
            {
				#ifdef ANDROID
            		execl("/system/bin/sh", "sh", "-c", cmd, NULL);
				#else
                    execl("/bin/sh", "sh", "-c", cmd, NULL);
				#endif
            }
            else if (Utilities::strCaselessCompare("ksh", envName) == 0)
            {
                execl("/bin/ksh", "ksh", "-c", cmd, NULL);
            }
            else if (Utilities::strCaselessCompare("bsh", envName) == 0)
            {
                execl("/bin/bsh", "bsh", "-c", cmd, NULL);
            }
            else if (Utilities::strCaselessCompare("csh", envName) == 0)
            {
                execl("/bin/csh", "csh", "-c", cmd, NULL);
            }
            else if (Utilities::strCaselessCompare("bash", envName) == 0)
            {
                execl("/bin/bash", "bash", "-c", cmd, NULL);
            }
            else if (Utilities::strCaselessCompare("cmd", envName) == 0)
            {
                char * args[MAX_COMMAND_ARGS+1];      /* Array for argument parsing */
                if (!scan_cmd(cmd, args))             /* Parse cmd into arguments  */
                {
                    exit(1);
                }
                execvp(args[0], args);           /* Invoke command directly   */
                exit(1);                         /* we couldn't run the       */
            }
            else
            {
                execl("/bin/sh", "sh", "-c", cmd, NULL);
            }
        }
    }
    // unknown command code?
    if (errCode == UNKNOWN_COMMAND)
    {
        // failure condition
        context->RaiseCondition("FAILURE", context->String(cmd), NULL, context->WholeNumberToObject(errCode));
    }
    else if (errCode != 0)
    {
        // non-zero is an error condition
        context->RaiseCondition("ERROR", context->String(cmd), NULL, context->WholeNumberToObject(errCode));
    }

    return context->False();      // zero return code
}
Ejemplo n.º 8
0
Archivo: nvc.c Proyecto: jkone27/nvc
int main(int argc, char **argv)
{
   term_init();
   set_default_opts();
   intern_strings();

   if (getenv("NVC_GDB") != NULL)
      register_gdb_signal_handlers();
   else
      register_trace_signal_handlers();

   if (is_debugger_running())
      atexit(tree_gc);

   atexit(fbuf_cleanup);

   static struct option long_options[] = {
      { "help",        no_argument,       0, 'h' },
      { "version",     no_argument,       0, 'v' },
      { "work",        required_argument, 0, 'w' },
      { "std",         required_argument, 0, 's' },
      { "messages",    required_argument, 0, 'M' },
      { "map",         required_argument, 0, 'p' },
      { "ignore-time", no_argument,       0, 'i' },
      { "force-init",  no_argument,       0, 'f' },
      { 0, 0, 0, 0 }
   };

   opterr = 0;

   const char *work_name = "work";
   const char *work_path = work_name;
   lib_t work = NULL;

   const int next_cmd = scan_cmd(1, argc, argv);
   int c, index = 0;
   const char *spec = "aehrvL:";
   while ((c = getopt_long(next_cmd, argv, spec, long_options, &index)) != -1) {
      switch (c) {
      case 0:
         // Set a flag
         break;
      case 'h':
         usage();
         exit(EXIT_SUCCESS);
      case 'v':
         printf("%s\n%s\n", version_string, copy_string);
         exit(EXIT_SUCCESS);
      case 'w':
         parse_work_name(optarg, &work_name, &work_path);
         break;
      case 'L':
         lib_add_search_path(optarg);
         break;
      case 's':
         set_standard(parse_standard(optarg));
         break;
      case 'M':
         set_message_style(parse_message_style(optarg));
         break;
      case 'p':
         parse_library_map(optarg);
         break;
      case 'i':
         opt_set_int("ignore-time", 1);
         break;
      case 'f':
         opt_set_int("force-init", 1);
         break;
      case '?':
         fatal("unrecognised global option %s", argv[optind - 1]);
      default:
         abort();
      }
   }

   work = lib_new(work_name, work_path);
   lib_set_work(work);

   argc -= next_cmd - 1;
   argv += next_cmd - 1;

   return process_command(argc, argv);
}
Ejemplo n.º 9
0
Archivo: nvc.c Proyecto: jkone27/nvc
static int run(int argc, char **argv)
{
   static struct option long_options[] = {
      { "trace",         no_argument,       0, 't' },
      { "batch",         no_argument,       0, 'b' },
      { "command",       no_argument,       0, 'c' },
      { "stop-time",     required_argument, 0, 's' },
      { "stats",         no_argument,       0, 'S' },
      { "wave",          optional_argument, 0, 'w' },
      { "stop-delta",    required_argument, 0, 'd' },
      { "format",        required_argument, 0, 'f' },
      { "include",       required_argument, 0, 'i' },
      { "exclude",       required_argument, 0, 'e' },
      { "exit-severity", required_argument, 0, 'x' },
#if ENABLE_VHPI
      { "load",          required_argument, 0, 'l' },
      { "vhpi-trace",    no_argument,       0, 'T' },
#endif
      { 0, 0, 0, 0 }
   };

   enum { BATCH, COMMAND } mode = BATCH;
   enum { LXT, FST, VCD} wave_fmt = FST;

   uint64_t stop_time = UINT64_MAX;
   const char *wave_fname = NULL;
   const char *vhpi_plugins = NULL;

   static bool have_run = false;
   if (have_run)
      fatal("multiple run commands are not supported");

   have_run = true;

   const int next_cmd = scan_cmd(2, argc, argv);

   int c, index = 0;
   const char *spec = "bcw::l:";
   while ((c = getopt_long(next_cmd, argv, spec, long_options, &index)) != -1) {
      switch (c) {
      case 0:
         // Set a flag
         break;
      case '?':
         fatal("unrecognised run option %s", argv[optind - 1]);
      case 't':
         opt_set_int("rt_trace_en", 1);
         break;
      case 'T':
         opt_set_int("vhpi_trace_en", 1);
         break;
      case 'b':
         mode = BATCH;
         break;
      case 'c':
         mode = COMMAND;
         break;
      case 's':
         stop_time = parse_time(optarg);
         break;
      case 'f':
         if (strcmp(optarg, "vcd") == 0)
            wave_fmt = VCD;
         else if (strcmp(optarg, "fst") == 0)
            wave_fmt = FST;
         else if (strcmp(optarg, "lxt") == 0)
            wave_fmt = LXT;
         else
            fatal("invalid waveform format: %s", optarg);
         break;
      case 'S':
         opt_set_int("rt-stats", 1);
         break;
      case 'w':
         if (optarg == NULL)
            wave_fname = "";
         else
            wave_fname = optarg;
         break;
      case 'd':
         opt_set_int("stop-delta", parse_int(optarg));
         break;
      case 'i':
         wave_include_glob(optarg);
         break;
      case 'e':
         wave_exclude_glob(optarg);
         break;
      case 'l':
         vhpi_plugins = optarg;
         break;
      case 'x':
         rt_set_exit_severity(parse_severity(optarg));
         break;
      default:
         abort();
      }
   }

   set_top_level(argv, next_cmd);

   ident_t ename = ident_prefix(top_level, ident_new("elab"), '.');
   tree_rd_ctx_t ctx;
   tree_t e = lib_get_ctx(lib_work(), ename, &ctx);
   if (e == NULL)
      fatal("%s not elaborated", istr(top_level));
   else if (tree_kind(e) != T_ELAB)
      fatal("%s not suitable top level", istr(top_level));

   if (wave_fname != NULL) {
      const char *name_map[] = { "LXT", "FST", "VCD" };
      const char *ext_map[]  = { "lxt", "fst", "vcd" };
      char *tmp LOCAL = NULL;

      if (*wave_fname == '\0') {
         tmp = xasprintf("%s.%s", argv[optind], ext_map[wave_fmt]);
         wave_fname = tmp;
         notef("writing %s waveform data to %s", name_map[wave_fmt], tmp);
      }

      wave_include_file(argv[optind]);

      switch (wave_fmt) {
      case LXT:
         lxt_init(wave_fname, e);
         break;
      case VCD:
         vcd_init(wave_fname, e);
         break;
      case FST:
         fst_init(wave_fname, e);
         break;
      }
   }

   rt_start_of_tool(e, ctx);

   if (vhpi_plugins != NULL)
      vhpi_load_plugins(e, vhpi_plugins);

   rt_restart(e);

   if (mode == COMMAND)
      shell_run(e, ctx);
   else
      rt_run_sim(stop_time);

   rt_end_of_tool(e);
   tree_read_end(ctx);

   argc -= next_cmd - 1;
   argv += next_cmd - 1;

   return argc > 1 ? process_command(argc, argv) : EXIT_SUCCESS;
}
Ejemplo n.º 10
0
Archivo: nvc.c Proyecto: jkone27/nvc
static int elaborate(int argc, char **argv)
{
   static struct option long_options[] = {
      { "disable-opt", no_argument,       0, 'o' },
      { "dump-llvm",   no_argument,       0, 'd' },
      { "dump-vcode",  optional_argument, 0, 'v' },
      { "native",      no_argument,       0, 'n' },
      { "cover",       no_argument,       0, 'c' },
      { "verbose",     no_argument,       0, 'V' },
      { 0, 0, 0, 0 }
   };

   const int next_cmd = scan_cmd(2, argc, argv);
   bool verbose = false;
   int c, index = 0;
   const char *spec = "Vg:";
   while ((c = getopt_long(next_cmd, argv, spec, long_options, &index)) != -1) {
      switch (c) {
      case 'o':
         opt_set_int("optimise", 0);
         break;
      case 'd':
         opt_set_int("dump-llvm", 1);
         break;
      case 'v':
         opt_set_str("dump-vcode", optarg ?: "");
         break;
      case 'n':
         opt_set_int("native", 1);
         break;
      case 'c':
         opt_set_int("cover", 1);
         break;
      case 'V':
         verbose = true;
         opt_set_int("verbose", 1);
         break;
      case 'g':
         parse_generic(optarg);
         break;
      case 0:
         // Set a flag
         break;
      case '?':
         fatal("unrecognised elaborate option %s", argv[optind - 1]);
      default:
         abort();
      }
   }

   set_top_level(argv, next_cmd);

   elab_verbose(verbose, "initialising");

   tree_t unit = lib_get(lib_work(), top_level);
   if (unit == NULL)
      fatal("cannot find unit %s in library %s",
            istr(top_level), istr(lib_name(lib_work())));

   elab_verbose(verbose, "loading top-level unit");

   tree_t e = elab(unit);
   if (e == NULL)
      return EXIT_FAILURE;

   elab_verbose(verbose, "elaborating design");

   opt(e);
   elab_verbose(verbose, "optimising design");

   group_nets(e);
   elab_verbose(verbose, "grouping nets");

   // Save the library now so the code generator can attach temporary
   // meta data to trees
   lib_save(lib_work());
   elab_verbose(verbose, "saving library");

   lower_unit(e);
   elab_verbose(verbose, "generating intermediate code");

   cgen(e);
   elab_verbose(verbose, "generating LLVM");

   link_bc(e);
   elab_verbose(verbose, "linking");

   argc -= next_cmd - 1;
   argv += next_cmd - 1;

   return argc > 1 ? process_command(argc, argv) : EXIT_SUCCESS;
}
Ejemplo n.º 11
0
Archivo: nvc.c Proyecto: jkone27/nvc
static int analyse(int argc, char **argv)
{
   static struct option long_options[] = {
      { "bootstrap",       no_argument,       0, 'b' },
      { "dump-llvm",       no_argument,       0, 'D' },
      { "dump-vcode",      optional_argument, 0, 'v' },
      { "prefer-explicit", no_argument,       0, 'p' },   // DEPRECATED
      { "relax",           required_argument, 0, 'R' },
      { 0, 0, 0, 0 }
   };

   const int next_cmd = scan_cmd(2, argc, argv);
   int c, index = 0;
   const char *spec = "";
   while ((c = getopt_long(next_cmd, argv, spec, long_options, &index)) != -1) {
      switch (c) {
      case 0:
         // Set a flag
         break;
      case '?':
         fatal("unrecognised analyse option %s", argv[optind - 1]);
      case 'b':
         opt_set_int("bootstrap", 1);
         break;
      case 'D':
         opt_set_int("dump-llvm", 1);
         break;
      case 'v':
         opt_set_str("dump-vcode", optarg ?: "");
         break;
      case 'p':
         warnf("the --prefer-explict option is deprecated: use "
               "--relax=prefer-explict instead");
         opt_set_int("relax", RELAX_PREFER_EXPLICT);
         break;
      case 'R':
         opt_set_int("relax", parse_relax(optarg));
         break;
      default:
         abort();
      }
   }

   size_t unit_list_sz = 32;
   tree_t *units LOCAL = xmalloc(sizeof(tree_t) * unit_list_sz);
   int n_units = 0;

   for (int i = optind; i < next_cmd; i++) {
      input_from_file(argv[i]);

      tree_t unit;
      while ((unit = parse()) && sem_check(unit))
         ARRAY_APPEND(units, unit, n_units, unit_list_sz);
   }

   for (int i = 0; i < n_units; i++) {
      simplify(units[i]);
      bounds_check(units[i]);
   }

   if (parse_errors() + sem_errors() + bounds_errors() > 0)
      return EXIT_FAILURE;

   for (int i = 0; i < n_units; i++) {
      tree_kind_t kind = tree_kind(units[i]);
      const bool need_cgen =
         (kind == T_PACK_BODY)
         || ((kind == T_PACKAGE) && pack_needs_cgen(units[i]));
      if (need_cgen)
         opt(units[i]);
      else
         units[i] = NULL;
   }

   lib_save(lib_work());

   for (int i = 0; i < n_units; i++) {
      if (units[i] != NULL) {
         lower_unit(units[i]);
         cgen(units[i]);
      }
   }

   argc -= next_cmd - 1;
   argv += next_cmd - 1;

   return argc > 1 ? process_command(argc, argv) : EXIT_SUCCESS;
}