Back to index

plt-scheme  4.2.1
Defines | Functions | Variables
start.c File Reference
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <process.h>
#include <ctype.h>

Go to the source code of this file.

Defines

#define MZSTART
#define GOSUBDIR   L"\\"
#define GOEXE   L"mzscheme"
#define sGOEXE   "mzscheme"
#define WAITTILDONE   1
#define MAXCOMMANDLEN   1024
#define MAX_ARGS   100
#define MSC_IZE(x)   x
#define DUPLICATE_INPUT

Functions

static int wc_strlen (const wchar_t *ws)
static void wc_strcpy (wchar_t *dest, const wchar_t *src)
static void wc_strcat (wchar_t *dest, const wchar_t *src)
static wchar_t * protect (wchar_t *s)
static int parse_command_line (int count, wchar_t **command, wchar_t *buf, int maxargs)
static wchar_t * make_command_line (int argc, wchar_t **argv)
void WriteStr (HANDLE h, const char *s)
static wchar_t * copy_string (wchar_t *s)
int wmain (int argc_in, wchar_t **argv_in)

Variables

static wchar_t * input = "***************************************************************>"
static wchar_t * exedir = "********************************************>"
static wchar_t * variant = "<Executable Variant: Replace This>"

Define Documentation

#define DUPLICATE_INPUT

Definition at line 42 of file start.c.

#define GOEXE   L"mzscheme"

Definition at line 29 of file start.c.

#define GOSUBDIR   L"\\"

Definition at line 28 of file start.c.

#define MAX_ARGS   100

Definition at line 35 of file start.c.

#define MAXCOMMANDLEN   1024

Definition at line 34 of file start.c.

#define MSC_IZE (   x)    x

Definition at line 40 of file start.c.

#define MZSTART

Definition at line 16 of file start.c.

#define sGOEXE   "mzscheme"

Definition at line 30 of file start.c.

#define WAITTILDONE   1

Definition at line 31 of file start.c.


Function Documentation

static wchar_t* copy_string ( wchar_t *  s) [static]

Definition at line 241 of file start.c.

{
  int l = wc_strlen(s);
  wchar_t *d = (wchar_t *)malloc((l + 1) * sizeof(wchar_t));
  memcpy(d, s, (l + 1) * sizeof(wchar_t));
  return d;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static wchar_t* make_command_line ( int  argc,
wchar_t **  argv 
) [static]

Definition at line 212 of file start.c.

{
  int i, len = 0;
  wchar_t *r;

  for (i = 0; i < argc; i++) {
    len += wc_strlen(argv[i]) + 1;
  }
  r = (wchar_t *)malloc(len * sizeof(wchar_t));
  len = 0;
  for (i = 0; i < argc; i++) {
    int l = wc_strlen(argv[i]);
    if (len) r[len++] = ' ';
    memcpy(r + len, argv[i], l * sizeof(wchar_t));
    len += l;
  }

  r[len] = 0;
  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int parse_command_line ( int  count,
wchar_t **  command,
wchar_t *  buf,
int  maxargs 
) [static]

Definition at line 165 of file start.c.

{
  wchar_t *parse, *created, *write;
  int findquote = 0;
    
  parse = created = write = buf;
  while (*parse) {
    while (*parse && (*parse < 128) && isspace(*parse)) parse++;
    while (*parse && ((*parse > 128) || !isspace(*parse) || findquote))      {
      if (*parse== '"') {
       findquote = !findquote;
      } else if (*parse== '\\') {
       wchar_t *next;
       for (next = parse; *next == '\\'; next++);
       if (*next == '"') {
         /* Special handling: */
         int count = (next - parse), i;
         for (i = 1; i < count; i += 2)
           *(write++) = '\\';
         parse += (count - 1);
         if (count & 0x1) {
           *(write++) = '\"';
           parse++;
         }
       }      else
         *(write++) = *parse;
      } else
       *(write++) = *parse;
      parse++;
    }
    if (*parse)
      parse++;
    *(write++) = 0;
         
    if (*created) {
      command[count++] = created;
      if (count == maxargs)
       return count;
    }
    created = write;
  }

  return count;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static wchar_t* protect ( wchar_t *  s) [static]

Definition at line 115 of file start.c.

{
  wchar_t *naya;
  int has_space = 0, has_quote = 0, was_slash = 0;

  for (naya = s; *naya; naya++) {
    if (((*naya < 128) && isspace(*naya)) || (*naya == '\'')) {
      has_space = 1;
      was_slash = 0;
    } else if (*naya == '"') {
      has_quote += 1 + (2 * was_slash);
      was_slash = 0;
    } else if (*naya == '\\') {
      was_slash++;
    } else
      was_slash = 0;
  }

  if (has_space || has_quote) {
    wchar_t *p;
    int wrote_slash = 0;

    naya = (wchar_t *)malloc((wc_strlen(s) + 3 + 3*has_quote) * sizeof(wchar_t));
    naya[0] = '"';
    for (p = naya + 1; *s; s++) {
      if (*s == '"') {
       while (wrote_slash--)
         *(p++) = '\\';
       *(p++) = '"'; /* endquote */
       *(p++) = '\\';
       *(p++) = '"'; /* protected */
       *(p++) = '"'; /* start quote again */
       wrote_slash = 0;
      } else if (*s == '\\') {
       *(p++) = '\\';
       wrote_slash++;
      } else {
       *(p++) = *s;
       wrote_slash = 0;
      }
    }
    *(p++) = '"';
    *p = 0;

    return naya;
  }

  return s;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void wc_strcat ( wchar_t *  dest,
const wchar_t *  src 
) [static]

Definition at line 108 of file start.c.

{
  while (*dest)
    dest++;
  wc_strcpy(dest, src);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void wc_strcpy ( wchar_t *  dest,
const wchar_t *  src 
) [static]

Definition at line 98 of file start.c.

{
  while (*src) {
    *dest = *src;
    dest++;
    src++;
  }
  *dest = 0;
}

Here is the caller graph for this function:

static int wc_strlen ( const wchar_t *  ws) [static]

Definition at line 91 of file start.c.

{
  int l;
  for (l = 0; ws[l]; l++) { }
  return l;
}

Here is the caller graph for this function:

int wmain ( int  argc_in,
wchar_t **  argv_in 
)

Definition at line 254 of file start.c.

{
  wchar_t go[MAXCOMMANDLEN * 2];
  wchar_t *args[MAX_ARGS + 1];
  wchar_t *command_line; 
  int count, i, cl_len;
  struct MSC_IZE(stat) st;
  STARTUPINFOW si;
  PROCESS_INFORMATION pi;
#ifdef MZSTART
  HANDLE out;

  out = GetStdHandle(STD_OUTPUT_HANDLE);
#endif
 
#ifdef DUPLICATE_INPUT
  /* gcc: input is read-only */
  input = copy_string(input);
  exedir = copy_string(exedir);
#endif

  count = 1;
  count = parse_command_line(count, args, input, MAX_ARGS);
  
  /* exedir can be relative to the current executable */
  if ((exedir[0] == '\\')
      || ((((exedir[0] >= 'a') && (exedir[0] <= 'z'))
          ||  ((exedir[0] >= 'A') && (exedir[0] <= 'Z')))
         && (exedir[1] == ':'))) {
    /* Absolute path */
  } else {
    /* Make it absolute, relative to this executable */
    int plen;
    int mlen;
    wchar_t *s2, *path;

    path = (wchar_t *)malloc(1024 * sizeof(wchar_t));
    GetModuleFileNameW(NULL, path, 1024);

    plen = wc_strlen(exedir);
    mlen = wc_strlen(path);

    while (mlen && (path[mlen - 1] != '\\')) {
      mlen--;
    }
    s2 = (wchar_t *)malloc((mlen + plen + 1) * sizeof(wchar_t));
    memcpy(s2, path, mlen * sizeof(wchar_t));
    memcpy(s2 + mlen, exedir, (plen + 1) * sizeof(wchar_t));
    exedir = s2;
  }

  wc_strcpy(go, exedir);
  wc_strcat(go, GOSUBDIR);
  wc_strcat(go, GOEXE);
  wc_strcat(go, variant);
  wc_strcat(go, L".exe");

  if (_wstat(go, &st)) {
#ifdef MRSTART
    wchar_t errbuff[MAXCOMMANDLEN * 2];
    swprintf(errbuff,L"Can't find %s",go);
    MessageBoxW(NULL,errbuff,L"Error",MB_OK);
#else
    char errbuff[MAXCOMMANDLEN * 2];
    sprintf(errbuff,"Can't find %S\n",go);
    WriteStr(out,errbuff);
#endif
    exit(-1);
  }

  args[0] = go;

#ifdef MRSTART
  {
    wchar_t *buf;
    
    m_lpCmdLine = GetCommandLineW();

    buf = (wchar_t *)malloc((wc_strlen(m_lpCmdLine) + 1) * sizeof(wchar_t));
    memcpy(buf, m_lpCmdLine, (wc_strlen(m_lpCmdLine) + 1) * sizeof(wchar_t));
    count = parse_command_line(count, args, buf, MAX_ARGS);
  }
#else
  {
    int i;
    for (i = 1; i < argc_in; i++)
      args[count++] = argv_in[i];
  }
#endif
  
  args[count] = NULL;
  
  for (i = 0; i < count; i++) {
    args[i] = protect(args[i]);
    /* MessageBox(NULL, args[i], "Argument", MB_OK); */
  }
  
  memset(&si, 0, sizeof(si));
  si.cb = sizeof(si);
  
  command_line = make_command_line(count, args);

  cl_len = wc_strlen(command_line);
  if (cl_len > MAXCOMMANDLEN) {
#ifdef MRSTART
    wchar_t errbuff[MAXCOMMANDLEN * 2];
    swprintf(errbuff,L"Command line of %d characters exceeds %d characters: %.1024s",
            cl_len, MAXCOMMANDLEN,command_line);
    MessageBoxW(NULL,errbuff,L"Error",MB_OK);
#else
    char errbuff[MAXCOMMANDLEN * 2];
    sprintf(errbuff,"Command line of %d characters exceeds %d characters: %.1024S\n",
           cl_len, MAXCOMMANDLEN,command_line);
    WriteStr(out,errbuff);
#endif
    exit(-1);
  } 

  if (!CreateProcessW(go,
                    command_line,
                    NULL, NULL, TRUE,
                    0, NULL, NULL, &si, &pi)) {
    
#ifdef MRSTART
    MessageBoxW(NULL, L"Can't start " GOEXE, L"Error", MB_OK);
#else
    WriteStr(out, "Can't start " sGOEXE "\n");
#endif
    return -1;
  } else {
#if WAITTILDONE
    DWORD result;
    WaitForSingleObject(pi.hProcess, INFINITE);
    GetExitCodeProcess(pi.hProcess, &result);
    return result;
#else
    return 0;
#endif
  }
}

Here is the call graph for this function:

void WriteStr ( HANDLE  h,
const char *  s 
)

Definition at line 234 of file start.c.

                                       {
  DWORD done;
  WriteFile(h, s, strlen(s), &done, NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

wchar_t* exedir = "********************************************>" [static]

Definition at line 82 of file start.c.

wchar_t* input = "***************************************************************>" [static]

Definition at line 47 of file start.c.

wchar_t* variant = "<Executable Variant: Replace This>" [static]

Definition at line 89 of file start.c.