* environ.c: Move code earlier to allow:
(_addenv): Call parse_options() when CYGWIN environment variable is being changed. (parse_options): Change parameter to 'const'.
This commit is contained in:
parent
e720cf09bd
commit
b9cf88ddba
|
@ -1,3 +1,10 @@
|
|||
2011-06-09 Christopher Faylor <me.cygwin2011@cgf.cx>
|
||||
|
||||
* environ.c: Move code earlier to allow:
|
||||
(_addenv): Call parse_options() when CYGWIN environment variable is
|
||||
being changed.
|
||||
(parse_options): Change parameter to 'const'.
|
||||
|
||||
2011-06-08 Christopher Faylor <me.cygwin2011@cgf.cx>
|
||||
|
||||
* environ.cc (tty_is_gone): Add missing space to message.
|
||||
|
|
|
@ -41,6 +41,184 @@ static bool create_upcaseenv = false;
|
|||
|
||||
static char **lastenviron;
|
||||
|
||||
/* Parse CYGWIN options */
|
||||
|
||||
static NO_COPY bool export_settings = false;
|
||||
|
||||
enum settings
|
||||
{
|
||||
justset,
|
||||
isfunc,
|
||||
setbit
|
||||
};
|
||||
|
||||
/* When BUF is:
|
||||
null or empty: disables globbing
|
||||
"ignorecase": enables case-insensitive globbing
|
||||
anything else: enables case-sensitive globbing */
|
||||
static void
|
||||
glob_init (const char *buf)
|
||||
{
|
||||
if (!buf || !*buf)
|
||||
{
|
||||
allow_glob = false;
|
||||
ignore_case_with_glob = false;
|
||||
}
|
||||
else if (ascii_strncasematch (buf, "ignorecase", 10))
|
||||
{
|
||||
allow_glob = true;
|
||||
ignore_case_with_glob = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
allow_glob = true;
|
||||
ignore_case_with_glob = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_proc_retry (const char *buf)
|
||||
{
|
||||
child_info::retry_count = strtoul (buf, NULL, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
tty_is_gone (const char *buf)
|
||||
{
|
||||
if (!user_shared->warned_notty)
|
||||
{
|
||||
small_printf ("\"tty\" option detected in CYGWIN environment variable.\n"
|
||||
"CYGWIN=tty is no longer supported. Please remove it from your\n"
|
||||
"CYGWIN environment variable and use a terminal emulator like mintty, "
|
||||
"xterm, or rxvt\n");
|
||||
user_shared->warned_notty = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* The structure below is used to set up an array which is used to
|
||||
parse the CYGWIN environment variable or, if enabled, options from
|
||||
the registry. */
|
||||
static struct parse_thing
|
||||
{
|
||||
const char *name;
|
||||
union parse_setting
|
||||
{
|
||||
bool *b;
|
||||
DWORD *x;
|
||||
int *i;
|
||||
void (*func)(const char *);
|
||||
} setting;
|
||||
|
||||
enum settings disposition;
|
||||
char *remember;
|
||||
union parse_values
|
||||
{
|
||||
DWORD i;
|
||||
const char *s;
|
||||
} values[2];
|
||||
} known[] NO_COPY =
|
||||
{
|
||||
{"dosfilewarning", {&dos_file_warning}, justset, NULL, {{false}, {true}}},
|
||||
{"envcache", {&envcache}, justset, NULL, {{true}, {false}}},
|
||||
{"error_start", {func: error_start_init}, isfunc, NULL, {{0}, {0}}},
|
||||
{"export", {&export_settings}, justset, NULL, {{false}, {true}}},
|
||||
{"glob", {func: glob_init}, isfunc, NULL, {{0}, {s: "normal"}}},
|
||||
{"proc_retry", {func: set_proc_retry}, isfunc, NULL, {{0}, {5}}},
|
||||
{"reset_com", {&reset_com}, justset, NULL, {{false}, {true}}},
|
||||
{"strip_title", {&strip_title_path}, justset, NULL, {{false}, {true}}},
|
||||
{"title", {&display_title}, justset, NULL, {{false}, {true}}},
|
||||
{"tty", {func: tty_is_gone}, isfunc, NULL, {{0}, {0}}},
|
||||
{"upcaseenv", {&create_upcaseenv}, justset, NULL, {{false}, {true}}},
|
||||
{"winsymlinks", {&allow_winsymlinks}, justset, NULL, {{false}, {true}}},
|
||||
{NULL, {0}, justset, 0, {{0}, {0}}}
|
||||
};
|
||||
|
||||
/* Parse a string of the form "something=stuff somethingelse=more-stuff",
|
||||
silently ignoring unknown "somethings". */
|
||||
static void __stdcall
|
||||
parse_options (const char *inbuf)
|
||||
{
|
||||
int istrue;
|
||||
char *p, *lasts;
|
||||
parse_thing *k;
|
||||
|
||||
if (inbuf == NULL)
|
||||
{
|
||||
tmp_pathbuf tp;
|
||||
char *newbuf = tp.c_get ();
|
||||
newbuf[0] = '\0';
|
||||
for (k = known; k->name != NULL; k++)
|
||||
if (k->remember)
|
||||
{
|
||||
strcat (strcat (newbuf, " "), k->remember);
|
||||
free (k->remember);
|
||||
k->remember = NULL;
|
||||
}
|
||||
|
||||
if (export_settings)
|
||||
{
|
||||
debug_printf ("%s", newbuf + 1);
|
||||
setenv ("CYGWIN", newbuf + 1, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
char *buf = strcpy ((char *) alloca (strlen (inbuf) + 1), inbuf);
|
||||
for (p = strtok_r (buf, " \t", &lasts);
|
||||
p != NULL;
|
||||
p = strtok_r (NULL, " \t", &lasts))
|
||||
{
|
||||
char *keyword_here = p;
|
||||
if (!(istrue = !ascii_strncasematch (p, "no", 2)))
|
||||
p += 2;
|
||||
else if (!(istrue = *p != '-'))
|
||||
p++;
|
||||
|
||||
char ch, *eq;
|
||||
if ((eq = strchr (p, '=')) != NULL || (eq = strchr (p, ':')) != NULL)
|
||||
ch = *eq, *eq++ = '\0';
|
||||
else
|
||||
ch = 0;
|
||||
|
||||
for (parse_thing *k = known; k->name != NULL; k++)
|
||||
if (ascii_strcasematch (p, k->name))
|
||||
{
|
||||
switch (k->disposition)
|
||||
{
|
||||
case isfunc:
|
||||
k->setting.func ((!eq || !istrue) ?
|
||||
k->values[istrue].s : eq);
|
||||
debug_printf ("%s (called func)", k->name);
|
||||
break;
|
||||
case justset:
|
||||
if (!istrue || !eq)
|
||||
*k->setting.x = k->values[istrue].i;
|
||||
else
|
||||
*k->setting.x = strtol (eq, NULL, 0);
|
||||
debug_printf ("%s %d", k->name, *k->setting.x);
|
||||
break;
|
||||
case setbit:
|
||||
*k->setting.x &= ~k->values[istrue].i;
|
||||
if (istrue || (eq && strtol (eq, NULL, 0)))
|
||||
*k->setting.x |= k->values[istrue].i;
|
||||
debug_printf ("%s %x", k->name, *k->setting.x);
|
||||
break;
|
||||
}
|
||||
|
||||
if (eq)
|
||||
*--eq = ch;
|
||||
|
||||
int n = eq - p;
|
||||
p = strdup (keyword_here);
|
||||
if (n > 0)
|
||||
p[n] = ':';
|
||||
k->remember = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
debug_printf ("returning");
|
||||
}
|
||||
|
||||
/* Helper functions for the below environment variables which have to
|
||||
be converted Win32<->POSIX. */
|
||||
extern "C" ssize_t env_PATH_to_posix (const void *, void *, size_t);
|
||||
|
@ -383,6 +561,8 @@ _addenv (const char *name, const char *value, int overwrite)
|
|||
win_env *spenv;
|
||||
if ((spenv = getwinenv (envhere)))
|
||||
spenv->add_cache (value);
|
||||
if (strcmp (name, "CYGWIN") == 0)
|
||||
parse_options (value);
|
||||
|
||||
MALLOC_CHECK;
|
||||
return 0;
|
||||
|
@ -522,184 +702,6 @@ ucenv (char *p, const char *eq)
|
|||
}
|
||||
}
|
||||
|
||||
/* Parse CYGWIN options */
|
||||
|
||||
static NO_COPY bool export_settings = false;
|
||||
|
||||
enum settings
|
||||
{
|
||||
justset,
|
||||
isfunc,
|
||||
setbit
|
||||
};
|
||||
|
||||
/* When BUF is:
|
||||
null or empty: disables globbing
|
||||
"ignorecase": enables case-insensitive globbing
|
||||
anything else: enables case-sensitive globbing */
|
||||
static void
|
||||
glob_init (const char *buf)
|
||||
{
|
||||
if (!buf || !*buf)
|
||||
{
|
||||
allow_glob = false;
|
||||
ignore_case_with_glob = false;
|
||||
}
|
||||
else if (ascii_strncasematch (buf, "ignorecase", 10))
|
||||
{
|
||||
allow_glob = true;
|
||||
ignore_case_with_glob = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
allow_glob = true;
|
||||
ignore_case_with_glob = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_proc_retry (const char *buf)
|
||||
{
|
||||
child_info::retry_count = strtoul (buf, NULL, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
tty_is_gone (const char *buf)
|
||||
{
|
||||
if (!user_shared->warned_notty)
|
||||
{
|
||||
small_printf ("\"tty\" option detected in CYGWIN environment variable.\n"
|
||||
"CYGWIN=tty is no longer supported. Please remove it from your\n"
|
||||
"CYGWIN environment variable and use a terminal emulator like mintty, "
|
||||
"xterm, or rxvt\n");
|
||||
user_shared->warned_notty = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* The structure below is used to set up an array which is used to
|
||||
parse the CYGWIN environment variable or, if enabled, options from
|
||||
the registry. */
|
||||
static struct parse_thing
|
||||
{
|
||||
const char *name;
|
||||
union parse_setting
|
||||
{
|
||||
bool *b;
|
||||
DWORD *x;
|
||||
int *i;
|
||||
void (*func)(const char *);
|
||||
} setting;
|
||||
|
||||
enum settings disposition;
|
||||
char *remember;
|
||||
union parse_values
|
||||
{
|
||||
DWORD i;
|
||||
const char *s;
|
||||
} values[2];
|
||||
} known[] NO_COPY =
|
||||
{
|
||||
{"dosfilewarning", {&dos_file_warning}, justset, NULL, {{false}, {true}}},
|
||||
{"envcache", {&envcache}, justset, NULL, {{true}, {false}}},
|
||||
{"error_start", {func: error_start_init}, isfunc, NULL, {{0}, {0}}},
|
||||
{"export", {&export_settings}, justset, NULL, {{false}, {true}}},
|
||||
{"glob", {func: glob_init}, isfunc, NULL, {{0}, {s: "normal"}}},
|
||||
{"proc_retry", {func: set_proc_retry}, isfunc, NULL, {{0}, {5}}},
|
||||
{"reset_com", {&reset_com}, justset, NULL, {{false}, {true}}},
|
||||
{"strip_title", {&strip_title_path}, justset, NULL, {{false}, {true}}},
|
||||
{"title", {&display_title}, justset, NULL, {{false}, {true}}},
|
||||
{"tty", {func: tty_is_gone}, isfunc, NULL, {{0}, {0}}},
|
||||
{"upcaseenv", {&create_upcaseenv}, justset, NULL, {{false}, {true}}},
|
||||
{"winsymlinks", {&allow_winsymlinks}, justset, NULL, {{false}, {true}}},
|
||||
{NULL, {0}, justset, 0, {{0}, {0}}}
|
||||
};
|
||||
|
||||
/* Parse a string of the form "something=stuff somethingelse=more-stuff",
|
||||
silently ignoring unknown "somethings". */
|
||||
static void __stdcall
|
||||
parse_options (char *buf)
|
||||
{
|
||||
int istrue;
|
||||
char *p, *lasts;
|
||||
parse_thing *k;
|
||||
|
||||
if (buf == NULL)
|
||||
{
|
||||
tmp_pathbuf tp;
|
||||
char *newbuf = tp.c_get ();
|
||||
newbuf[0] = '\0';
|
||||
for (k = known; k->name != NULL; k++)
|
||||
if (k->remember)
|
||||
{
|
||||
strcat (strcat (newbuf, " "), k->remember);
|
||||
free (k->remember);
|
||||
k->remember = NULL;
|
||||
}
|
||||
|
||||
if (export_settings)
|
||||
{
|
||||
debug_printf ("%s", newbuf + 1);
|
||||
setenv ("CYGWIN", newbuf + 1, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
buf = strcpy ((char *) alloca (strlen (buf) + 1), buf);
|
||||
for (p = strtok_r (buf, " \t", &lasts);
|
||||
p != NULL;
|
||||
p = strtok_r (NULL, " \t", &lasts))
|
||||
{
|
||||
char *keyword_here = p;
|
||||
if (!(istrue = !ascii_strncasematch (p, "no", 2)))
|
||||
p += 2;
|
||||
else if (!(istrue = *p != '-'))
|
||||
p++;
|
||||
|
||||
char ch, *eq;
|
||||
if ((eq = strchr (p, '=')) != NULL || (eq = strchr (p, ':')) != NULL)
|
||||
ch = *eq, *eq++ = '\0';
|
||||
else
|
||||
ch = 0;
|
||||
|
||||
for (parse_thing *k = known; k->name != NULL; k++)
|
||||
if (ascii_strcasematch (p, k->name))
|
||||
{
|
||||
switch (k->disposition)
|
||||
{
|
||||
case isfunc:
|
||||
k->setting.func ((!eq || !istrue) ?
|
||||
k->values[istrue].s : eq);
|
||||
debug_printf ("%s (called func)", k->name);
|
||||
break;
|
||||
case justset:
|
||||
if (!istrue || !eq)
|
||||
*k->setting.x = k->values[istrue].i;
|
||||
else
|
||||
*k->setting.x = strtol (eq, NULL, 0);
|
||||
debug_printf ("%s %d", k->name, *k->setting.x);
|
||||
break;
|
||||
case setbit:
|
||||
*k->setting.x &= ~k->values[istrue].i;
|
||||
if (istrue || (eq && strtol (eq, NULL, 0)))
|
||||
*k->setting.x |= k->values[istrue].i;
|
||||
debug_printf ("%s %x", k->name, *k->setting.x);
|
||||
break;
|
||||
}
|
||||
|
||||
if (eq)
|
||||
*--eq = ch;
|
||||
|
||||
int n = eq - p;
|
||||
p = strdup (keyword_here);
|
||||
if (n > 0)
|
||||
p[n] = ':';
|
||||
k->remember = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
debug_printf ("returning");
|
||||
}
|
||||
|
||||
/* Set options from the registry. */
|
||||
static bool __stdcall
|
||||
regopt (const WCHAR *name, char *buf)
|
||||
|
|
Loading…
Reference in New Issue