Francois Gouget : cmd: Introduce a WCMD_strsubstW() function to simplify string substitutions.
Alexandre Julliard
julliard at winehq.org
Mon Jun 15 07:59:08 CDT 2009
Module: wine
Branch: master
Commit: c48e5e048f776466b8e55a50ce28a73a6ba89f68
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c48e5e048f776466b8e55a50ce28a73a6ba89f68
Author: Francois Gouget <fgouget at free.fr>
Date: Mon Jun 15 10:59:31 2009 +0200
cmd: Introduce a WCMD_strsubstW() function to simplify string substitutions.
---
programs/cmd/batch.c | 5 +--
programs/cmd/wcmd.h | 1 +
programs/cmd/wcmdmain.c | 75 +++++++++++++++++++++-------------------------
3 files changed, 36 insertions(+), 45 deletions(-)
diff --git a/programs/cmd/batch.c b/programs/cmd/batch.c
index 0044f70..4c089ca 100644
--- a/programs/cmd/batch.c
+++ b/programs/cmd/batch.c
@@ -571,10 +571,7 @@ void WCMD_HandleTildaModifiers(WCHAR **start, WCHAR *forVariable, WCHAR *forValu
if (!doneModifier) strcpyW(finaloutput, outputparam);
/* Finish by inserting the replacement into the string */
- pos = WCMD_strdupW(lastModifier+1);
- strcpyW(*start, finaloutput);
- strcatW(*start, pos);
- free(pos);
+ WCMD_strsubstW(*start, lastModifier+1, finaloutput, -1);
}
/*******************************************************************
diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h
index 67aab42..4d3bab6 100644
--- a/programs/cmd/wcmd.h
+++ b/programs/cmd/wcmd.h
@@ -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);
WCHAR *WCMD_LoadMessage(UINT id);
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,
LPDWORD charsRead, const LPOVERLAPPED unused);
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c
index c58077b..7d3e526 100644
--- a/programs/cmd/wcmdmain.c
+++ b/programs/cmd/wcmdmain.c
@@ -422,6 +422,22 @@ WCHAR *WCMD_strdupW(WCHAR *input) {
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
*
@@ -493,9 +509,7 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) {
/* In batch program, missing terminator for % and no following
':' just removes the '%' */
if (context) {
- s = WCMD_strdupW(start + 1);
- strcpyW (start, s);
- free(s);
+ WCMD_strsubstW(start, start + 1, NULL, 0);
return start;
} else {
@@ -608,24 +622,20 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) {
/* Command line - just ignore this */
if (context == NULL) return endOfVar+1;
- s = WCMD_strdupW(endOfVar + 1);
/* Batch - replace unknown env var with nothing */
if (colonpos == NULL) {
- strcpyW (start, s);
-
+ WCMD_strsubstW(start, endOfVar + 1, NULL, 0);
} else {
len = strlenW(thisVar);
thisVar[len-1] = 0x00;
/* If %:...% supplied, : is retained */
if (colonpos == thisVar+1) {
- strcpyW (start, colonpos);
+ WCMD_strsubstW(start, endOfVar + 1, colonpos, -1);
} else {
- strcpyW (start, colonpos+1);
+ WCMD_strsubstW(start, endOfVar + 1, colonpos + 1, -1);
}
- strcatW (start, s);
}
- free (s);
return start;
}
@@ -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
then our work here is done */
if (colonpos == NULL) {
- s = WCMD_strdupW(endOfVar + 1);
- strcpyW (start, thisVarContents);
- strcatW (start, s);
- free(s);
+ WCMD_strsubstW(start, endOfVar + 1, thisVarContents, -1);
return start;
}
@@ -664,8 +671,6 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) {
substrposition = atolW(colonpos+2);
if (commapos) substrlength = atolW(commapos+1);
- s = WCMD_strdupW(endOfVar + 1);
-
/* Check bounds */
if (substrposition >= 0) {
startCopy = &thisVarContents[min(substrposition, len)];
@@ -674,21 +679,18 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) {
}
if (commapos == NULL) {
- strcpyW (start, startCopy); /* Copy the lot */
+ /* Copy the lot */
+ WCMD_strsubstW(start, endOfVar + 1, startCopy, -1);
} else if (substrlength < 0) {
int copybytes = (len+substrlength-1)-(startCopy-thisVarContents);
if (copybytes > len) copybytes = len;
else if (copybytes < 0) copybytes = 0;
- memcpy (start, startCopy, copybytes * sizeof(WCHAR)); /* Copy the lot */
- start[copybytes] = 0x00;
+ WCMD_strsubstW(start, endOfVar + 1, startCopy, copybytes);
} else {
- memcpy (start, startCopy, substrlength * sizeof(WCHAR)); /* Copy the lot */
- start[substrlength] = 0x00;
+ WCMD_strsubstW(start, endOfVar + 1, startCopy, substrlength);
}
- strcatW (start, s);
- free(s);
return start;
/* search and replace manipulation */
@@ -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, s);
} else {
- /* Copy as it */
+ /* Copy as is */
strcpyW(start, thisVarContents);
strcatW(start, s);
}
@@ -772,7 +774,7 @@ static void handleExpansion(WCHAR *cmd, BOOL justFors, WCHAR *forVariable, WCHAR
/* manual expansion of environment variables here */
WCHAR *p = cmd;
- WCHAR *s, *t;
+ WCHAR *t;
int i;
while ((p = strchrW(p, '%'))) {
@@ -784,9 +786,7 @@ static void handleExpansion(WCHAR *cmd, BOOL justFors, WCHAR *forVariable, WCHAR
/* Don't touch %% unless its in Batch */
if (!justFors && *(p+1) == '%') {
if (context) {
- s = WCMD_strdupW(p+1);
- strcpyW (p, s);
- free (s);
+ WCMD_strsubstW(p, p+1, NULL, 0);
}
p+=1;
@@ -797,21 +797,17 @@ static void handleExpansion(WCHAR *cmd, BOOL justFors, WCHAR *forVariable, WCHAR
/* Replace use of %0...%9 if in batch program*/
} else if (!justFors && context && (i >= 0) && (i <= 9)) {
- s = WCMD_strdupW(p+2);
t = WCMD_parameter (context -> command, i + context -> shift_count[i], NULL);
- strcpyW (p, t);
- strcatW (p, s);
- free (s);
+ WCMD_strsubstW(p, p+2, t, -1);
/* Replace use of %* if in batch program*/
} else if (!justFors && context && *(p+1)=='*') {
WCHAR *startOfParms = NULL;
- s = WCMD_strdupW(p+2);
t = WCMD_parameter (context -> command, 1, &startOfParms);
- if (startOfParms != NULL) strcpyW (p, startOfParms);
- else *p = 0x00;
- strcatW (p, s);
- free (s);
+ if (startOfParms != NULL)
+ WCMD_strsubstW(p, p+2, startOfParms, -1);
+ else
+ WCMD_strsubstW(p, p+2, NULL, 0);
} else if (forVariable &&
(CompareString (LOCALE_USER_DEFAULT,
@@ -819,10 +815,7 @@ static void handleExpansion(WCHAR *cmd, BOOL justFors, WCHAR *forVariable, WCHAR
p,
strlenW(forVariable),
forVariable, -1) == 2)) {
- s = WCMD_strdupW(p + strlenW(forVariable));
- strcpyW(p, forValue);
- strcatW(p, s);
- free(s);
+ WCMD_strsubstW(p, p + strlenW(forVariable), forValue, -1);
} else if (!justFors) {
p = WCMD_expand_envvar(p, forVariable, forValue);
More information about the wine-cvs
mailing list