[ros-diffs] [jmorlan] 40191: Implement %~$PATH:var variable substitution

jmorlan at svn.reactos.org jmorlan at svn.reactos.org
Mon Mar 23 20:54:53 CET 2009


Author: jmorlan
Date: Mon Mar 23 22:54:52 2009
New Revision: 40191

URL: http://svn.reactos.org/svn/reactos?rev=40191&view=rev
Log:
Implement %~$PATH:var variable substitution

Modified:
    trunk/reactos/base/shell/cmd/cmd.c

Modified: trunk/reactos/base/shell/cmd/cmd.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/cmd.c?rev=40191&r1=40190&r2=40191&view=diff
==============================================================================
--- trunk/reactos/base/shell/cmd/cmd.c [iso-8859-1] (original)
+++ trunk/reactos/base/shell/cmd/cmd.c [iso-8859-1] Mon Mar 23 22:54:52 2009
@@ -891,8 +891,8 @@
 }
 #define GrowIfNecessary(x, y, z) GrowIfNecessary_dbg(x, y, z, __FILE__, __LINE__)
 
-LPCTSTR
-GetEnvVarOrSpecial ( LPCTSTR varName )
+LPTSTR
+GetEnvVar(LPCTSTR varName)
 {
 	static LPTSTR ret = NULL;
 	static UINT retlen = 0;
@@ -907,20 +907,23 @@
 	}
 	if ( size )
 		return ret;
+	return NULL;
+}
+
+LPCTSTR
+GetEnvVarOrSpecial(LPCTSTR varName)
+{
+	static TCHAR ret[MAX_PATH];
+
+	LPTSTR var = GetEnvVar(varName);
+	if (var)
+		return var;
 
 	/* env var doesn't exist, look for a "special" one */
 	/* %CD% */
 	if (_tcsicmp(varName,_T("cd")) ==0)
 	{
-		size = GetCurrentDirectory ( retlen, ret );
-		if ( size > retlen )
-		{
-			if ( !GrowIfNecessary ( size, &ret, &retlen ) )
-				return NULL;
-			size = GetCurrentDirectory ( retlen, ret );
-		}
-		if ( !size )
-			return NULL;
+		GetCurrentDirectory(MAX_PATH, ret);
 		return ret;
 	}
 	/* %TIME% */
@@ -937,8 +940,6 @@
 	/* %RANDOM% */
 	else if (_tcsicmp(varName,_T("random")) ==0)
 	{
-		if ( !GrowIfNecessary ( MAX_PATH, &ret, &retlen ) )
-			return NULL;
 		/* Get random number */
 		_itot(rand(),ret,10);
 		return ret;
@@ -953,8 +954,6 @@
 	/* %CMDEXTVERSION% */
 	else if (_tcsicmp(varName,_T("cmdextversion")) ==0)
 	{
-		if ( !GrowIfNecessary ( MAX_PATH, &ret, &retlen ) )
-			return NULL;
 		/* Set version number to 2 */
 		_itot(2,ret,10);
 		return ret;
@@ -963,8 +962,6 @@
 	/* %ERRORLEVEL% */
 	else if (_tcsicmp(varName,_T("errorlevel")) ==0)
 	{
-		if ( !GrowIfNecessary ( MAX_PATH, &ret, &retlen ) )
-			return NULL;
 		_itot(nErrorLevel,ret,10);
 		return ret;
 	}
@@ -990,6 +987,7 @@
 	} Modifiers = 0;
 
 	TCHAR *Format, *FormatEnd;
+	TCHAR *PathVarName = NULL;
 	LPTSTR Variable;
 	TCHAR *VarEnd;
 	BOOL VariableIsParam0;
@@ -1011,17 +1009,31 @@
 	while (*FormatEnd && _tcschr(ModifierTable, _totlower(*FormatEnd)))
 		FormatEnd++;
 
-	/* TODO: check for $PATH: syntax */
-
-	/* Now backtrack if necessary to get a variable name match */
-	while (!(Variable = GetVar(*FormatEnd, &VariableIsParam0)))
-	{
-		if (FormatEnd == Format)
+	if (*FormatEnd == _T('$'))
+	{
+		/* $PATH: syntax */
+		PathVarName = FormatEnd + 1;
+		FormatEnd = _tcschr(PathVarName, _T(':'));
+		if (!FormatEnd)
 			return NULL;
-		FormatEnd--;
-	}
-
-	for (; Format < FormatEnd; Format++)
+
+		/* Must be immediately followed by the variable */
+		Variable = GetVar(*++FormatEnd, &VariableIsParam0);
+		if (!Variable)
+			return NULL;
+	}
+	else
+	{
+		/* Backtrack if necessary to get a variable name match */
+		while (!(Variable = GetVar(*FormatEnd, &VariableIsParam0)))
+		{
+			if (FormatEnd == Format)
+				return NULL;
+			FormatEnd--;
+		}
+	}
+
+	for (; Format < FormatEnd && *Format != _T('$'); Format++)
 		Modifiers |= 1 << (_tcschr(ModifierTable, _totlower(*Format)) - ModifierTable);
 
 	*pFormat = FormatEnd + 1;
@@ -1040,11 +1052,26 @@
 	memcpy(Result, Variable, (char *)VarEnd - (char *)Variable);
 	Result[VarEnd - Variable] = _T('\0');
 
-	/* For plain %~var with no modifiers, just return the variable without quotes */
-	if (Modifiers == 0)
+	if (PathVarName)
+	{
+		/* $PATH: syntax - search the directories listed in the
+		 * specified environment variable for the file */
+		LPTSTR PathVar;
+		FormatEnd[-1] = _T('\0');
+		PathVar = GetEnvVar(PathVarName);
+		FormatEnd[-1] = _T(':');
+		if (!PathVar ||
+		    !SearchPath(PathVar, Result, NULL, MAX_PATH, FullPath, NULL))
+		{
+			return _T("");
+		}
+	}
+	else if (Modifiers == 0)
+	{
+		/* For plain %~var with no modifiers, just return the variable without quotes */
 		return Result;
-
-	if (VariableIsParam0)
+	}
+	else if (VariableIsParam0)
 	{
 		/* Special case: If the variable is %0 and modifier characters are present,
 		 * use the batch file's path (which includes the .bat/.cmd extension)
@@ -1141,6 +1168,7 @@
 			Out += FormatDate(Out, &st, TRUE);
 			*Out++ = _T(' ');
 			Out += FormatTime(Out, &st);
+			*Out++ = _T(' ');
 		}
 		if (Modifiers & M_SIZE)
 		{
@@ -1151,25 +1179,32 @@
 		}
 	}
 
+	/* When using the path-searching syntax or the S modifier,
+	 * at least part of the file path is always included.
+	 * If none of the DPNX modifiers are present, include the full path */
+	if (PathVarName || (Modifiers & M_SHORT))
+		if ((Modifiers & (M_DRIVE | M_PATH | M_NAME | M_EXT)) == 0)
+			Modifiers |= M_FULL;
+
 	/* Now add the requested parts of the name.
-	 * With the F or S modifiers, add all parts to form the full path. */
+	 * With the F modifier, add all parts to form the full path. */
 	Extension = _tcsrchr(Filename, _T('.'));
-	if (Modifiers & (M_DRIVE | M_FULL | M_SHORT))
+	if (Modifiers & (M_DRIVE | M_FULL))
 	{
 		*Out++ = FixedPath[0];
 		*Out++ = FixedPath[1];
 	}
-	if (Modifiers & (M_PATH | M_FULL | M_SHORT))
+	if (Modifiers & (M_PATH | M_FULL))
 	{
 		memcpy(Out, &FixedPath[2], (char *)Filename - (char *)&FixedPath[2]);
 		Out += Filename - &FixedPath[2];
 	}
-	if (Modifiers & (M_NAME | M_FULL | M_SHORT))
+	if (Modifiers & (M_NAME | M_FULL))
 	{
 		while (*Filename && Filename != Extension)
 			*Out++ = *Filename++;
 	}
-	if (Modifiers & (M_EXT | M_FULL | M_SHORT))
+	if (Modifiers & (M_EXT | M_FULL))
 	{
 		if (Extension)
 			Out = _stpcpy(Out, Extension);



More information about the Ros-diffs mailing list