Last active
January 19, 2021 20:20
-
-
Save neocotic/1095029 to your computer and use it in GitHub Desktop.
INI File Utilities
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
:: INI File Utilities | |
:: | |
:: Copyright 2011, [neocotic](http://github.com/neocotic) | |
:: Released under the MIT License | |
:: http://en.wikipedia.org/wiki/MIT_License | |
@echo off | |
setLocal enableDelayedExpansion | |
:: Declares required constants | |
set TEMP_FILE="%TEMP%\ini-%RANDOM%.tmp" | |
:: To be returned when script ends | |
:: If an unexpected problem occurs, this will be changed to reflect the level of that problem | |
set returnCode=0 | |
if exist %TEMP_FILE% del /Q %TEMP_FILE% | |
set optClear=N | |
set optKeys=N | |
set optRemove=N | |
set optStrictMode=N | |
set optUsage=N | |
set optValues=N | |
:: Reads options one-by-one | |
:readOptions | |
set opt=%~1 | |
if "%opt:~0,1%"=="/" ( | |
:: Checks if usage descriptor should be printed | |
if "%opt:~1,1%"=="?" ( | |
set optUsage=Y | |
goto nextOption | |
) | |
:: Checks if key value should be cleared | |
if /i "%opt:~1,1%"=="C" ( | |
set optClear=Y | |
set optRemove=N | |
goto nextOption | |
) | |
:: Checks if only keys should be printed | |
if /i "%opt:~1,1%"=="K" ( | |
set optKeys=Y | |
set optValues=N | |
goto nextOption | |
) | |
:: Checks if key should be removed | |
if /i "%opt:~1,1%"=="R" ( | |
set optClear=N | |
set optRemove=Y | |
goto nextOption | |
) | |
:: Checks if an error should be thrown when accessing non-existant sections/keys | |
if /i "%opt:~1,1%"=="S" ( | |
set optStrictMode=Y | |
goto nextOption | |
) | |
:: Checks if only values should be printed | |
if /i "%opt:~1,1%"=="V" ( | |
set optKeys=N | |
set optValues=Y | |
goto nextOption | |
) | |
goto invalidOptionError | |
:nextOption | |
shift | |
goto readOptions | |
) | |
:: Determines if usage should be printed and whether or not to continue with process afterwards | |
if "%optUsage%"=="Y" goto printUsage | |
:process | |
:: Assigns parameter values to declared variables | |
set fileName=%~1 | |
set section=%~2 | |
set key=%~3 | |
set value=%~4 | |
:: Validates file name specified | |
if "%fileName%"=="" goto fileNotSpecifiedError | |
if not exist "%fileName%" goto fileNotFoundError | |
:: Determines what to print based on parameters provided | |
if "%section%"=="" goto printAll | |
if "%key%"=="" ( | |
if "%optClear%"=="Y" goto handleSection | |
if "%optRemove%"=="Y" goto handleSection | |
goto printAllSection | |
) | |
if "%value%"=="" ( | |
if "%optClear%"=="Y" goto handleKey | |
if "%optRemove%"=="Y" goto handleKey | |
goto printKeyValue | |
) | |
goto handleKey | |
:: Prints all sections contained within specified file, including their key=value pairs | |
:: Section headings only printed if neither /K /V options were specified | |
:: Keys only printed if /V option wasn't specified | |
:: Values only printed if /K option wasn't specified | |
:printAll | |
for /f "tokens=1,* delims==" %%A in (%fileName%) do ( | |
set line=%%A | |
if "!line:~0,1!"=="[" ( | |
set currentSection=!line! | |
if "%optKeys%"=="N" if "%optValues%"=="N" ( | |
echo. | |
echo.!currentSection! | |
) | |
) else ( | |
if not "!currentSection!"=="" ( | |
if "%optKeys%"=="Y" ( | |
echo.%%A | |
) else ( | |
if "%optValues%"=="Y" ( | |
echo.%%B | |
) else ( | |
echo.%%A=%%B | |
) | |
) | |
) | |
) | |
) | |
goto end | |
:: Prints key=value pairs of the speciifed section contained within specified file | |
:: Keys only printed if /V option wasn't specified | |
:: Values only printed if /K option wasn't specified | |
:printAllSection | |
set sectionFound=N | |
for /f "tokens=1,* delims==" %%A in (%fileName%) do ( | |
set line=%%A | |
if "!line:~0,1!"=="[" ( | |
set currentSection=!line! | |
if /i "!currentSection!"=="[%section%]" set sectionFound=Y | |
) else ( | |
if /i "!currentSection!"=="[%section%]" ( | |
if "%optKeys%"=="Y" ( | |
echo.%%A | |
) else ( | |
if "%optValues%"=="Y" ( | |
echo.%%B | |
) else ( | |
echo.%%A=%%B | |
) | |
) | |
) | |
) | |
) | |
if "%sectionFound%"=="N" if "%optStrictMode%"=="Y" goto sectionNotFoundError | |
goto end | |
:: Prints value of the key paired under the specified section contained within specified file | |
:printKeyValue | |
set sectionFound=N | |
for /f "tokens=1,* delims==" %%A in (%fileName%) do ( | |
set line=%%A | |
if "!line:~0,1!"=="[" ( | |
set currentSection=!line! | |
if /i "!currentSection!"=="[%section%]" set sectionFound=Y | |
) else ( | |
if /i "!currentSection!"=="[%section%]" ( | |
if /i "%%A"=="%key%" ( | |
echo.%%B | |
goto end | |
) | |
) | |
) | |
) | |
if "%optStrictMode%"=="Y" ( | |
if "%sectionFound%"=="N" goto sectionNotFoundError | |
goto keyNotFoundError | |
) else ( | |
echo. | |
) | |
goto end | |
:: Handles the key within the specified section contained within specified file | |
:handleKey | |
set keyAdded=N | |
set keyFound=N | |
set sectionFound=N | |
for /f "tokens=1,* delims==" %%A in (%fileName%) do ( | |
set line=%%A | |
if "!line:~0,1!"=="[" ( | |
if not "!currentSection!"=="" ( | |
(echo.)>>%TEMP_FILE% | |
if /i "!currentSection!"=="[%section%]" if "!keyFound!"=="N" if "%optRemove%"=="N" ( | |
set keyAdded=Y | |
if "%optClear%"=="Y" ( | |
(echo.%key%=)>>%TEMP_FILE% | |
) else ( | |
if not "%value%"=="" (echo.%key%=%value%)>>%TEMP_FILE% | |
) | |
) | |
) | |
set currentSection=!line! | |
if /i "!currentSection!"=="[%section%]" set sectionFound=Y | |
(echo.!currentSection!)>>%TEMP_FILE% | |
) else ( | |
if not "!currentSection!"=="" ( | |
if /i "!currentSection!"=="[%section%]" ( | |
if /i "%%A"=="%key%" ( | |
set keyFound=Y | |
if "%optRemove%"=="N" ( | |
if "%optClear%"=="Y" ( | |
(echo.%key%=)>>%TEMP_FILE% | |
) else ( | |
if not "%value%"=="" (echo.%key%=%value%)>>%TEMP_FILE% | |
) | |
) | |
) else ( | |
(echo.%%A=%%B)>>%TEMP_FILE% | |
) | |
) else ( | |
(echo.%%A=%%B)>>%TEMP_FILE% | |
) | |
) else ( | |
(echo.!line!)>>%TEMP_FILE% | |
) | |
) | |
) | |
if "%sectionFound%"=="N" if "%optRemove%"=="N" (echo [%section%])>>%TEMP_FILE% | |
if "%keyFound%"=="N" if "%keyAdded%"=="N" if "%optRemove%"=="N" ( | |
if "%optClear%"=="Y" ( | |
(echo.%key%=)>>%TEMP_FILE% | |
) else ( | |
if not "%value%"=="" (echo.%key%=%value%)>>%TEMP_FILE% | |
) | |
) | |
goto write | |
:: Handles the section contained within specified file | |
:handleSection | |
set sectionFound=N | |
for /f "tokens=1,* delims==" %%A in (%fileName%) do ( | |
set line=%%A | |
if "!line:~0,1!"=="[" ( | |
if not "!currentSection!"=="" (echo.)>>%TEMP_FILE% | |
set currentSection=!line! | |
if /i "!currentSection!"=="[%section%]" ( | |
set sectionFound=Y | |
if "%optRemove%"=="N" (echo.!currentSection!)>>%TEMP_FILE% | |
) else ( | |
(echo.!currentSection!)>>%TEMP_FILE% | |
) | |
) else ( | |
if not "!currentSection!"=="" ( | |
if /i not "!currentSection!"=="[%section%]" (echo.%%A=%%B)>>%TEMP_FILE% | |
) else ( | |
(echo.!line!)>>%TEMP_FILE% | |
) | |
) | |
) | |
if "%sectionFound%"=="N" if "%optStrictMode%"=="Y" goto sectionNotFoundError | |
goto write | |
:: Writes each line of the temporary file to the specified file | |
:write | |
set firstLine=Y | |
for /f "tokens=*" %%A in (%TEMP_FILE%) do ( | |
if "!firstLine!"=="Y" ( | |
set firstLine=N | |
(echo.%%A)>%fileName% | |
) else ( | |
(echo.%%A)>>%fileName% | |
) | |
) | |
goto end | |
:: Provides user feedback on any unexpected errors | |
:fileNotFoundError | |
(echo [ ERROR ] File not found: %fileName%)1>&2 | |
goto error | |
:fileNotSpecifiedError | |
(echo [WARNING] File not specified)1>&2 | |
goto warning | |
:invalidOptionError | |
(echo [ ERROR ] Invalid option: %opt%)1>&2 | |
goto error | |
:keyNotFoundError | |
(echo [ ERROR ] Key not found: %key%)1>&2 | |
goto error | |
:sectionNotFoundError | |
(echo [ ERROR ] Section not found: %section%)1>&2 | |
goto error | |
:: Handles exiting script correctly due to an unexcepted problem | |
:error | |
set returnCode=2 | |
goto end | |
:warning | |
set returnCode=1 | |
goto end | |
:: Prints usage descriptor for this command | |
:printUsage | |
echo Usage: ini [options] [file [section [key [value]]]] | |
echo Options: | |
echo /C clears specified key's value or section's keys | |
echo /K print keys only | |
echo /R removes specified key or section | |
echo /S enables strict mode | |
echo /V print values only | |
if not "%~1"=="" ( | |
echo. | |
goto process | |
) | |
:end | |
if exist %TEMP_FILE% del /Q %TEMP_FILE% | |
endLocal&exit /b %returnCode% |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment