Compatibilidad CMD y CMDebug / TCC-RT, Parte 2
Después de mi solicitud de archivos por lotes CMD que no funcionaron CMDebug or TCC, un usuario me envió un archivo por lotes con un uso curioso de la sintaxis de expansión variable retardada de CMD.
CMD soporta la !var! sintaxis para retrasar la expansión de variables en el momento de la ejecución de un comando, en lugar de cuando se lee la declaración. Por ejemplo, supongamos que desea crear una lista de todos los archivos en un directorio. Tu primer intento podría ser algo como esto:
establecer ARCHIVOS = para %f en (*) establezca FILES=%FILES% %f
Ahora, esto funcionará en CMDebug y TCC, pero será no trabajar en CMD. La razón es que CMD en realidad termina ejecutando esto:
[código]para %f en (*) establezca ARCHIVOS= %f[/código]
y terminará con una lista que contiene solo el último archivo del directorio.
Entonces Microsoft agregó la opción de retrasar la expansión de variables en CMD (configurable al inicio o con el comando SETLOCAL). No es necesario en TCC archivos por lotes, pero es compatible con TCC y CMDebug en aras de la compatibilidad.
Así que desde TCC ya apoyaba esto, cual era la incompatibilidad? El problema estaba en esta línea:
establecer "regVal=!regVal:%%=?!"
y un correspondiente:
establezca "regVal=!regVal:?=%%!"
¿Cuál es el propósito aquí? El código está sustituyendo un ? para cada % en la variable, y posteriormente revertir la sustitución. ¿Por qué utilizar la expansión de variable retrasada, ya que esta no es una declaración IF o FOR o un grupo de comandos, y el valor no va a cambiar entre el momento en que se leyó la línea y el momento en que se ejecutó?
Porque CMD no puede manejar algo como esto:
establecer "regVal=%regVal:%%=?%"
Terminará el argumento en la primera coincidencia. %, entonces terminas con esto:
establecer "regVal=%regVal:%"
Bien, entonces ¿por qué no simplemente escapar del % ¿Personaje que quieres sustituir?
establecer "regVal=%regVal:^%=?%"
Esto funciona bien en TCC y CMDebug, pero falla en CMD. (Podría ser un error o simplemente un comportamiento no compatible; la documentación de CMD no lo menciona). Entonces, el desarrollador utilizó la expansión variable retrasada para evitar la % que se interprete como si encierra el nombre de la variable. Cuando CMD evaluó la línea, encontró un doble %, que convirtió en un único %, y la línea se ejecutó como:
establecer "regVal=!regVal:%=?!"
Entonces, ¿por qué esto no funcionó con TCC? Porque TCC No esperaba encontrar un lugar sin escape. % Carácter dentro de una cadena de sustitución en una variable de expansión retrasada. Porque, ¿por qué harías eso? Sin motivo, a menos que quieras sustituirlo % personajes en CMD, y no pudiste hacerlo de ninguna de las formas esperadas. (Hay varias maneras de hacer esto en TCC, todos ellos más comprensibles que esta sintaxis torturada.)
He agregado soporte para esta sintaxis CMD a las versiones actuales de TCC, TCC-RT, y CMDebug.
¡Sigue enviando esos extravagantes archivos por lotes CMD!