Пакетные параметры командной строки Windows (cmd.exe) и манипуляции со строками - PullRequest
4 голосов
/ 30 января 2012

Давайте рассмотрим этот цикл FOR в пакетном скрипте Windows:

D:\MiLu\Dev\C++\temp :: type string.bat
@ECHO OFF
FOR %%a IN (%*) DO ECHO %%a

Это повторяет все аргументы, один за другим. Действительно?

D:\MiLu\Dev\C++\temp :: string.bat foo.obj bar.obj CPPFLAGS=/EHsc
foo.obj
bar.obj
CPPFLAGS
/EHsc

Он разбивает аргументы командной строки не только на пробелы (хорошо), но и на = (не хорошо). Как я могу предотвратить это?

То, чего я хочу добиться - это просто: обертка вокруг NMAKE.exe, которая указывает /nologo для nmake, а также - и это проблема - для компилятора через переменные окружения CFLAGS и CPPFLAGS, в то время как в то же самое время время , включая любые настройки для CFLAGS и CPPFLAGS, указанные в командной строке.

Другими словами, я хочу, чтобы скрипт добавил /nologo к вводу командной строки для CFLAGS и CPPFLAGS, даже если их нет. Всегда /nologo! Не раздражайте меня своим логотипом, товарищ компилятор!

Обновление

Вот что я придумал, основываясь на ответе Майка:

@ECHO OFF
SETLOCAL
SETLOCAL ENABLEDELAYEDEXPANSION

FOR %%a IN (%*) DO (
    SET var1=%%a
    ECHO %%a - !var1! - !var1:~0,1!
    IF "!var1:~0,1!" EQU "/" (
        ECHO gefunden: %%a !var1!
    )
)

Завтра продолжим ...

Обновление 2

Ладно, учитывая, что завтра уже здесь, я мог бы также продолжить ... так что вот рабочее решение, с гордостью представленное. Не стесняйтесь комментировать, как улучшить его.

@ECHO OFF
SETLOCAL
SETLOCAL ENABLEDELAYEDEXPANSION

SET files=
SET   CFLAGS=/nologo %CFLAGS%
SET CPPFLAGS=/nologo %CPPFLAGS%

SET state=normal
FOR %%a IN (%*) DO (
    SET curarg=%%a
    REM ECHO %%a - !curarg! - !curarg:~0,1!
    IF /I "%%a" EQU "CFLAGS" (
        SET state=expecting_cflags
    ) ELSE IF /I "%%a" EQU "CPPFLAGS" (
        SET state=expecting_cppflags
    ) ELSE (
        IF "!curarg:~0,1!" EQU "/" (
            REM ECHO gefunden: %%a !curarg!
            IF "!state!" EQU "expecting_cflags" (
                REM ECHO expecting_cflags
                SET CFLAGS=!CFLAGS! !curarg!
            ) ELSE IF "!state!" EQU "expecting_cppflags" (
                REM ECHO expecting_cppflags
                SET CPPFLAGS=!CPPFLAGS! !curarg!
            ) ELSE (
                ECHO Logikfehler >&2
            )
        ) ELSE (
            SET files=!files! !curarg!
        )
        SET state=normal
    )
)
ECHO Dateien:  !files! >&2
ECHO CFLAGS:   !CFLAGS! >&2
ECHO CPPFLAGS: !CPPFLAGS! >&2
:: ECHO ON
nmake /nologo %files% CFLAGS="%CFLAGS%" CPPFLAGS="%CPPFLAGS%"
ENDLOCAL

Ответы [ 3 ]

2 голосов
/ 30 января 2012

Один из способов обойти эту проблему - указать «CPPFLAGS = / EHsc», а затем в цикле использовать %% ~ a, чтобы избавиться от двойных кавычек.

Еще один способ обойти эту проблему - проверить первый символ %% a, а если это /, то добавить к нему =. Для этого вам нужно setlocal enabledelayedexpansion, присвоить %% a переменной, а затем использовать запись% variable: ~ 1,1%, чтобы извлечь первый символ, чтобы вы могли сравнить его с /. Для получения дополнительной информации об этой записи введите help set.

Обновление (после обновления ОП)

Следующий фрагмент работает, он немного проще соответствующего фрагмента в вашем решении и не содержит жестко заданных имен аргументов, поэтому он более универсален:

SET allargs=
FOR %%a IN (%*) DO (
    SET curarg=%%a
    IF "!curarg:~0,1!" EQU "/" (
        SET allargs=!allargs!=!curarg!
    ) ELSE (
        SET allargs=!allargs! !curarg!
    )
)
ECHO !allargs!
2 голосов
/ 30 января 2012

Вы можете использовать for /f в цикле для принудительного разделения списка аргументов по пробелам, а не по знаку равенства.Попробуйте что-то вроде этого:

@echo off
setlocal enabledelayedexpansion

set params=%*

:loop
for /f "usebackq tokens=1,*" %%A in ('!params!') do (
  echo %%A
  set params=%%B
)
if not "!params!"=="" goto loop

endlocal
2 голосов
/ 30 января 2012

Вы пробовали следующее?

string.bat foo.obj bar.obj "CPPFLAGS=/EHsc"

Если вы добавляете аргумент CPPFLAGS самостоятельно, попробуйте заключить его в кавычки.

Ссылка: http://www.robvanderwoude.com/parameters.php

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...