diff options
Diffstat (limited to 'misc')
| -rw-r--r-- | misc/launcher.c | 358 | ||||
| -rw-r--r-- | misc/yosys.proto | 12 | 
2 files changed, 364 insertions, 6 deletions
| diff --git a/misc/launcher.c b/misc/launcher.c new file mode 100644 index 000000000..157d68cf3 --- /dev/null +++ b/misc/launcher.c @@ -0,0 +1,358 @@ +/* This file comes from the PyPA Setuptools repository, commit 16e452a: +https://github.com/pypa/setuptools +Modifications include this comment and inline inclusion of the LICENSE text. */ + +/* Copyright (C) 2016 Jason R Coombs <jaraco@jaraco.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. */ + +/*  Setuptools Script Launcher for Windows + +    This is a stub executable for Windows that functions somewhat like +    Effbot's "exemaker", in that it runs a script with the same name but +    a .py extension, using information from a #! line.  It differs in that +    it spawns the actual Python executable, rather than attempting to +    hook into the Python DLL.  This means that the script will run with +    sys.executable set to the Python executable, where exemaker ends up with +    sys.executable pointing to itself.  (Which means it won't work if you try +    to run another Python process using sys.executable.) + +    To build/rebuild with mingw32, do this in the setuptools project directory: + +       gcc -DGUI=0           -mno-cygwin -O -s -o setuptools/cli.exe launcher.c +       gcc -DGUI=1 -mwindows -mno-cygwin -O -s -o setuptools/gui.exe launcher.c + +    To build for Windows RT, install both Visual Studio Express for Windows 8 +    and for Windows Desktop (both freeware), create "win32" application using +    "Windows Desktop" version, create new "ARM" target via +    "Configuration Manager" menu and modify ".vcxproj" file by adding +    "<WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport>" tag +    as child of "PropertyGroup" tags that has "Debug|ARM" and "Release|ARM" +    properties. + +    It links to msvcrt.dll, but this shouldn't be a problem since it doesn't +    actually run Python in the same process.  Note that using 'exec' instead +    of 'spawn' doesn't work, because on Windows this leads to the Python +    executable running in the *background*, attached to the same console +    window, meaning you get a command prompt back *before* Python even finishes +    starting.  So, we have to use spawnv() and wait for Python to exit before +    continuing.  :( +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <windows.h> +#include <tchar.h> +#include <fcntl.h> + +int child_pid=0; + +int fail(char *format, char *data) { +    /* Print error message to stderr and return 2 */ +    fprintf(stderr, format, data); +    return 2; +} + +char *quoted(char *data) { +    int i, ln = strlen(data), nb; + +    /* We allocate twice as much space as needed to deal with worse-case +       of having to escape everything. */ +    char *result = calloc(ln*2+3, sizeof(char)); +    char *presult = result; + +    *presult++ = '"'; +    for (nb=0, i=0; i < ln; i++) +      { +        if (data[i] == '\\') +          nb += 1; +        else if (data[i] == '"') +          { +            for (; nb > 0; nb--) +              *presult++ = '\\'; +            *presult++ = '\\'; +          } +        else +          nb = 0; +        *presult++ = data[i]; +      } + +    for (; nb > 0; nb--)        /* Deal w trailing slashes */ +      *presult++ = '\\'; + +    *presult++ = '"'; +    *presult++ = 0; +    return result; +} + + + + + + + + + + +char *loadable_exe(char *exename) { +    /* HINSTANCE hPython;  DLL handle for python executable */ +    char *result; + +    /* hPython = LoadLibraryEx(exename, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); +    if (!hPython) return NULL; */ + +    /* Return the absolute filename for spawnv */ +    result = calloc(MAX_PATH, sizeof(char)); +    strncpy(result, exename, MAX_PATH); +    /*if (result) GetModuleFileNameA(hPython, result, MAX_PATH); + +    FreeLibrary(hPython); */ +    return result; +} + + +char *find_exe(char *exename, char *script) { +    char drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT]; +    char path[_MAX_PATH], c, *result; + +    /* convert slashes to backslashes for uniform search below */ +    result = exename; +    while (c = *result++) if (c=='/') result[-1] = '\\'; + +    _splitpath(exename, drive, dir, fname, ext); +    if (drive[0] || dir[0]=='\\') { +        return loadable_exe(exename);   /* absolute path, use directly */ +    } +    /* Use the script's parent directory, which should be the Python home +       (This should only be used for bdist_wininst-installed scripts, because +        easy_install-ed scripts use the absolute path to python[w].exe +    */ +    _splitpath(script, drive, dir, fname, ext); +    result = dir + strlen(dir) -1; +    if (*result == '\\') result--; +    while (*result != '\\' && result>=dir) *result-- = 0; +    _makepath(path, drive, dir, exename, NULL); +    return loadable_exe(path); +} + + +char **parse_argv(char *cmdline, int *argc) +{ +    /* Parse a command line in-place using MS C rules */ + +    char **result = calloc(strlen(cmdline), sizeof(char *)); +    char *output = cmdline; +    char c; +    int nb = 0; +    int iq = 0; +    *argc = 0; + +    result[0] = output; +    while (isspace(*cmdline)) cmdline++;   /* skip leading spaces */ + +    do { +        c = *cmdline++; +        if (!c || (isspace(c) && !iq)) { +            while (nb) {*output++ = '\\'; nb--; } +            *output++ = 0; +            result[++*argc] = output; +            if (!c) return result; +            while (isspace(*cmdline)) cmdline++;  /* skip leading spaces */ +            if (!*cmdline) return result;  /* avoid empty arg if trailing ws */ +            continue; +        } +        if (c == '\\') +            ++nb;   /* count \'s */ +        else { +            if (c == '"') { +                if (!(nb & 1)) { iq = !iq; c = 0; }  /* skip " unless odd # of \ */ +                nb = nb >> 1;   /* cut \'s in half */ +            } +            while (nb) {*output++ = '\\'; nb--; } +            if (c) *output++ = c; +        } +    } while (1); +} + +void pass_control_to_child(DWORD control_type) { +    /* +     * distribute-issue207 +     * passes the control event to child process (Python) +     */ +    if (!child_pid) { +        return; +    } +    GenerateConsoleCtrlEvent(child_pid,0); +} + +BOOL control_handler(DWORD control_type) { +    /* +     * distribute-issue207 +     * control event handler callback function +     */ +    switch (control_type) { +        case CTRL_C_EVENT: +            pass_control_to_child(0); +            break; +    } +    return TRUE; +} + +int create_and_wait_for_subprocess(char* command) { +    /* +     * distribute-issue207 +     * launches child process (Python) +     */ +    DWORD return_value = 0; +    LPSTR commandline = command; +    STARTUPINFOA s_info; +    PROCESS_INFORMATION p_info; +    ZeroMemory(&p_info, sizeof(p_info)); +    ZeroMemory(&s_info, sizeof(s_info)); +    s_info.cb = sizeof(STARTUPINFO); +    // set-up control handler callback funciotn +    SetConsoleCtrlHandler((PHANDLER_ROUTINE) control_handler, TRUE); +    if (!CreateProcessA(NULL, commandline, NULL, NULL, TRUE, 0, NULL, NULL, &s_info, &p_info)) { +        fprintf(stderr, "failed to create process.\n"); +        return 0; +    } +    child_pid = p_info.dwProcessId; +    // wait for Python to exit +    WaitForSingleObject(p_info.hProcess, INFINITE); +    if (!GetExitCodeProcess(p_info.hProcess, &return_value)) { +        fprintf(stderr, "failed to get exit code from process.\n"); +        return 0; +    } +    return return_value; +} + +char* join_executable_and_args(char *executable, char **args, int argc) +{ +    /* +     * distribute-issue207 +     * CreateProcess needs a long string of the executable and command-line arguments, +     * so we need to convert it from the args that was built +     */ +    int len,counter; +    char* cmdline; + +    len=strlen(executable)+2; +    for (counter=1; counter<argc; counter++) { +        len+=strlen(args[counter])+1; +    } + +    cmdline = (char*)calloc(len, sizeof(char)); +    sprintf(cmdline, "%s", executable); +    len=strlen(executable); +    for (counter=1; counter<argc; counter++) { +        sprintf(cmdline+len, " %s", args[counter]); +        len+=strlen(args[counter])+1; +    } +    return cmdline; +} + +int run(int argc, char **argv, int is_gui) { + +    char python[256];   /* python executable's filename*/ +    char *pyopt;        /* Python option */ +    char script[256];   /* the script's filename */ + +    int scriptf;        /* file descriptor for script file */ + +    char **newargs, **newargsp, **parsedargs; /* argument array for exec */ +    char *ptr, *end;    /* working pointers for string manipulation */ +    char *cmdline; +    int i, parsedargc;              /* loop counter */ + +    /* compute script name from our .exe name*/ +    GetModuleFileNameA(NULL, script, sizeof(script)); +    end = script + strlen(script); +    while( end>script && *end != '.') +        *end-- = '\0'; +    *end-- = '\0'; +    strcat(script, (GUI ? "-script.pyw" : "-script.py")); + +    /* figure out the target python executable */ + +    scriptf = open(script, O_RDONLY); +    if (scriptf == -1) { +        return fail("Cannot open %s\n", script); +    } +    end = python + read(scriptf, python, sizeof(python)); +    close(scriptf); + +    ptr = python-1; +    while(++ptr < end && *ptr && *ptr!='\n' && *ptr!='\r') {;} + +    *ptr-- = '\0'; + +    if (strncmp(python, "#!", 2)) { +        /* default to python.exe if no #! header */ +        strcpy(python, "#!python.exe"); +    } + +    parsedargs = parse_argv(python+2, &parsedargc); + +    /* Using spawnv() can fail strangely if you e.g. find the Cygwin +       Python, so we'll make sure Windows can find and load it */ + +    ptr = find_exe(parsedargs[0], script); +    if (!ptr) { +        return fail("Cannot find Python executable %s\n", parsedargs[0]); +    } + +    /* printf("Python executable: %s\n", ptr); */ + +    /* Argument array needs to be +       parsedargc + argc, plus 1 for null sentinel */ + +    newargs = (char **)calloc(parsedargc + argc + 1, sizeof(char *)); +    newargsp = newargs; + +    *newargsp++ = quoted(ptr); +    for (i = 1; i<parsedargc; i++) *newargsp++ = quoted(parsedargs[i]); + +    *newargsp++ = quoted(script); +    for (i = 1; i < argc; i++)     *newargsp++ = quoted(argv[i]); + +    *newargsp++ = NULL; + +    /* printf("args 0: %s\nargs 1: %s\n", newargs[0], newargs[1]); */ + +    if (is_gui) { +        /* Use exec, we don't need to wait for the GUI to finish */ +        execv(ptr, (const char * const *)(newargs)); +        return fail("Could not exec %s", ptr);   /* shouldn't get here! */ +    } + +    /* +     * distribute-issue207: using CreateProcessA instead of spawnv +     */ +    cmdline = join_executable_and_args(ptr, newargs, parsedargc + argc); +    return create_and_wait_for_subprocess(cmdline); +} + +int WINAPI WinMain(HINSTANCE hI, HINSTANCE hP, LPSTR lpCmd, int nShow) { +    return run(__argc, __argv, GUI); +} + +int main(int argc, char** argv) { +    return run(argc, argv, GUI); +} diff --git a/misc/yosys.proto b/misc/yosys.proto index 2870176cb..a583e6265 100644 --- a/misc/yosys.proto +++ b/misc/yosys.proto @@ -1,12 +1,12 @@  //  // yosys -- Yosys Open SYnthesis Suite -//  +//  // Copyright (C) 2018  Serge Bazanski <q3k@symbioticeda.com> -//  +//  // Permission to use, copy, modify, and/or distribute this software for any  // purpose with or without fee is hereby granted, provided that the above  // copyright notice and this permission notice appear in all copies. -//  +//  // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES  // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF  // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR @@ -73,7 +73,7 @@ message Module {          BitVector bits = 2;      }      map<string, Port> port = 2; -     +      // Named cells in this module.      message Cell {          // Set to true when the name of this cell is automatically created and @@ -129,7 +129,7 @@ message Model {              TYPE_FALSE = 6;          };          Type type = 1; -     +          message Port {              // Name of port.              string portname = 1; @@ -148,7 +148,7 @@ message Model {              // Set for AND, NAND.              Gate gate = 3;          } -     +          // Set when the node drives given output port(s).          message OutPort {              // Name of port. | 
