Commit c48e5e04 authored by Francois Gouget's avatar Francois Gouget Committed by Alexandre Julliard

cmd: Introduce a WCMD_strsubstW() function to simplify string substitutions.

parent d51d209b
...@@ -571,10 +571,7 @@ void WCMD_HandleTildaModifiers(WCHAR **start, WCHAR *forVariable, WCHAR *forValu ...@@ -571,10 +571,7 @@ void WCMD_HandleTildaModifiers(WCHAR **start, WCHAR *forVariable, WCHAR *forValu
if (!doneModifier) strcpyW(finaloutput, outputparam); if (!doneModifier) strcpyW(finaloutput, outputparam);
/* Finish by inserting the replacement into the string */ /* Finish by inserting the replacement into the string */
pos = WCMD_strdupW(lastModifier+1); WCMD_strsubstW(*start, lastModifier+1, finaloutput, -1);
strcpyW(*start, finaloutput);
strcatW(*start, pos);
free(pos);
} }
/******************************************************************* /*******************************************************************
......
...@@ -101,6 +101,7 @@ void WCMD_HandleTildaModifiers(WCHAR **start, WCHAR *forVariable, WCHAR *forValu ...@@ -101,6 +101,7 @@ void WCMD_HandleTildaModifiers(WCHAR **start, WCHAR *forVariable, WCHAR *forValu
void WCMD_splitpath(const WCHAR* path, WCHAR* drv, WCHAR* dir, WCHAR* name, WCHAR* ext); void WCMD_splitpath(const WCHAR* path, WCHAR* drv, WCHAR* dir, WCHAR* name, WCHAR* ext);
WCHAR *WCMD_LoadMessage(UINT id); WCHAR *WCMD_LoadMessage(UINT id);
WCHAR *WCMD_strdupW(WCHAR *input); WCHAR *WCMD_strdupW(WCHAR *input);
void WCMD_strsubstW(WCHAR *start, WCHAR* next, WCHAR* insert, int len);
BOOL WCMD_ReadFile(const HANDLE hIn, WCHAR *intoBuf, const DWORD maxChars, BOOL WCMD_ReadFile(const HANDLE hIn, WCHAR *intoBuf, const DWORD maxChars,
LPDWORD charsRead, const LPOVERLAPPED unused); LPDWORD charsRead, const LPOVERLAPPED unused);
......
...@@ -422,6 +422,22 @@ WCHAR *WCMD_strdupW(WCHAR *input) { ...@@ -422,6 +422,22 @@ WCHAR *WCMD_strdupW(WCHAR *input) {
return result; return result;
} }
/*************************************************************************
* WCMD_strsubstW
* Replaces a portion of a Unicode string with the specified string.
* It's up to the caller to ensure there is enough space in the
* destination buffer.
*/
void WCMD_strsubstW(WCHAR* start, WCHAR* next, WCHAR* insert, int len) {
if (len < 0)
len=insert ? lstrlenW(insert) : 0;
if (start+len != next)
memmove(start+len, next, (strlenW(next) + 1) * sizeof(*next));
if (insert)
memcpy(start, insert, len * sizeof(*insert));
}
/*************************************************************************** /***************************************************************************
* WCMD_strtrim_leading_spaces * WCMD_strtrim_leading_spaces
* *
...@@ -493,9 +509,7 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) { ...@@ -493,9 +509,7 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) {
/* In batch program, missing terminator for % and no following /* In batch program, missing terminator for % and no following
':' just removes the '%' */ ':' just removes the '%' */
if (context) { if (context) {
s = WCMD_strdupW(start + 1); WCMD_strsubstW(start, start + 1, NULL, 0);
strcpyW (start, s);
free(s);
return start; return start;
} else { } else {
...@@ -608,24 +622,20 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) { ...@@ -608,24 +622,20 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) {
/* Command line - just ignore this */ /* Command line - just ignore this */
if (context == NULL) return endOfVar+1; if (context == NULL) return endOfVar+1;
s = WCMD_strdupW(endOfVar + 1);
/* Batch - replace unknown env var with nothing */ /* Batch - replace unknown env var with nothing */
if (colonpos == NULL) { if (colonpos == NULL) {
strcpyW (start, s); WCMD_strsubstW(start, endOfVar + 1, NULL, 0);
} else { } else {
len = strlenW(thisVar); len = strlenW(thisVar);
thisVar[len-1] = 0x00; thisVar[len-1] = 0x00;
/* If %:...% supplied, : is retained */ /* If %:...% supplied, : is retained */
if (colonpos == thisVar+1) { if (colonpos == thisVar+1) {
strcpyW (start, colonpos); WCMD_strsubstW(start, endOfVar + 1, colonpos, -1);
} else { } else {
strcpyW (start, colonpos+1); WCMD_strsubstW(start, endOfVar + 1, colonpos + 1, -1);
} }
strcatW (start, s);
} }
free (s);
return start; return start;
} }
...@@ -633,10 +643,7 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) { ...@@ -633,10 +643,7 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) {
/* See if we need to do complex substitution (any ':'s), if not /* See if we need to do complex substitution (any ':'s), if not
then our work here is done */ then our work here is done */
if (colonpos == NULL) { if (colonpos == NULL) {
s = WCMD_strdupW(endOfVar + 1); WCMD_strsubstW(start, endOfVar + 1, thisVarContents, -1);
strcpyW (start, thisVarContents);
strcatW (start, s);
free(s);
return start; return start;
} }
...@@ -664,8 +671,6 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) { ...@@ -664,8 +671,6 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) {
substrposition = atolW(colonpos+2); substrposition = atolW(colonpos+2);
if (commapos) substrlength = atolW(commapos+1); if (commapos) substrlength = atolW(commapos+1);
s = WCMD_strdupW(endOfVar + 1);
/* Check bounds */ /* Check bounds */
if (substrposition >= 0) { if (substrposition >= 0) {
startCopy = &thisVarContents[min(substrposition, len)]; startCopy = &thisVarContents[min(substrposition, len)];
...@@ -674,21 +679,18 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) { ...@@ -674,21 +679,18 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) {
} }
if (commapos == NULL) { if (commapos == NULL) {
strcpyW (start, startCopy); /* Copy the lot */ /* Copy the lot */
WCMD_strsubstW(start, endOfVar + 1, startCopy, -1);
} else if (substrlength < 0) { } else if (substrlength < 0) {
int copybytes = (len+substrlength-1)-(startCopy-thisVarContents); int copybytes = (len+substrlength-1)-(startCopy-thisVarContents);
if (copybytes > len) copybytes = len; if (copybytes > len) copybytes = len;
else if (copybytes < 0) copybytes = 0; else if (copybytes < 0) copybytes = 0;
memcpy (start, startCopy, copybytes * sizeof(WCHAR)); /* Copy the lot */ WCMD_strsubstW(start, endOfVar + 1, startCopy, copybytes);
start[copybytes] = 0x00;
} else { } else {
memcpy (start, startCopy, substrlength * sizeof(WCHAR)); /* Copy the lot */ WCMD_strsubstW(start, endOfVar + 1, startCopy, substrlength);
start[substrlength] = 0x00;
} }
strcatW (start, s);
free(s);
return start; return start;
/* search and replace manipulation */ /* search and replace manipulation */
...@@ -723,7 +725,7 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) { ...@@ -723,7 +725,7 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) {
strcatW(start, thisVarContents + (found-searchIn) + strlenW(searchFor+1)); strcatW(start, thisVarContents + (found-searchIn) + strlenW(searchFor+1));
strcatW(start, s); strcatW(start, s);
} else { } else {
/* Copy as it */ /* Copy as is */
strcpyW(start, thisVarContents); strcpyW(start, thisVarContents);
strcatW(start, s); strcatW(start, s);
} }
...@@ -772,7 +774,7 @@ static void handleExpansion(WCHAR *cmd, BOOL justFors, WCHAR *forVariable, WCHAR ...@@ -772,7 +774,7 @@ static void handleExpansion(WCHAR *cmd, BOOL justFors, WCHAR *forVariable, WCHAR
/* manual expansion of environment variables here */ /* manual expansion of environment variables here */
WCHAR *p = cmd; WCHAR *p = cmd;
WCHAR *s, *t; WCHAR *t;
int i; int i;
while ((p = strchrW(p, '%'))) { while ((p = strchrW(p, '%'))) {
...@@ -784,9 +786,7 @@ static void handleExpansion(WCHAR *cmd, BOOL justFors, WCHAR *forVariable, WCHAR ...@@ -784,9 +786,7 @@ static void handleExpansion(WCHAR *cmd, BOOL justFors, WCHAR *forVariable, WCHAR
/* Don't touch %% unless its in Batch */ /* Don't touch %% unless its in Batch */
if (!justFors && *(p+1) == '%') { if (!justFors && *(p+1) == '%') {
if (context) { if (context) {
s = WCMD_strdupW(p+1); WCMD_strsubstW(p, p+1, NULL, 0);
strcpyW (p, s);
free (s);
} }
p+=1; p+=1;
...@@ -797,21 +797,17 @@ static void handleExpansion(WCHAR *cmd, BOOL justFors, WCHAR *forVariable, WCHAR ...@@ -797,21 +797,17 @@ static void handleExpansion(WCHAR *cmd, BOOL justFors, WCHAR *forVariable, WCHAR
/* Replace use of %0...%9 if in batch program*/ /* Replace use of %0...%9 if in batch program*/
} else if (!justFors && context && (i >= 0) && (i <= 9)) { } else if (!justFors && context && (i >= 0) && (i <= 9)) {
s = WCMD_strdupW(p+2);
t = WCMD_parameter (context -> command, i + context -> shift_count[i], NULL); t = WCMD_parameter (context -> command, i + context -> shift_count[i], NULL);
strcpyW (p, t); WCMD_strsubstW(p, p+2, t, -1);
strcatW (p, s);
free (s);
/* Replace use of %* if in batch program*/ /* Replace use of %* if in batch program*/
} else if (!justFors && context && *(p+1)=='*') { } else if (!justFors && context && *(p+1)=='*') {
WCHAR *startOfParms = NULL; WCHAR *startOfParms = NULL;
s = WCMD_strdupW(p+2);
t = WCMD_parameter (context -> command, 1, &startOfParms); t = WCMD_parameter (context -> command, 1, &startOfParms);
if (startOfParms != NULL) strcpyW (p, startOfParms); if (startOfParms != NULL)
else *p = 0x00; WCMD_strsubstW(p, p+2, startOfParms, -1);
strcatW (p, s); else
free (s); WCMD_strsubstW(p, p+2, NULL, 0);
} else if (forVariable && } else if (forVariable &&
(CompareString (LOCALE_USER_DEFAULT, (CompareString (LOCALE_USER_DEFAULT,
...@@ -819,10 +815,7 @@ static void handleExpansion(WCHAR *cmd, BOOL justFors, WCHAR *forVariable, WCHAR ...@@ -819,10 +815,7 @@ static void handleExpansion(WCHAR *cmd, BOOL justFors, WCHAR *forVariable, WCHAR
p, p,
strlenW(forVariable), strlenW(forVariable),
forVariable, -1) == 2)) { forVariable, -1) == 2)) {
s = WCMD_strdupW(p + strlenW(forVariable)); WCMD_strsubstW(p, p + strlenW(forVariable), forValue, -1);
strcpyW(p, forValue);
strcatW(p, s);
free(s);
} else if (!justFors) { } else if (!justFors) {
p = WCMD_expand_envvar(p, forVariable, forValue); p = WCMD_expand_envvar(p, forVariable, forValue);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment