Windows 7 Forums
Welcome to Windows 7 Forums. Our forum is dedicated to helping you find support and solutions for any problems regarding your Windows 7 PC be it Dell, HP, Acer, Asus or a custom build. We also provide an extensive Windows 7 tutorial section that covers a wide range of tips and tricks.


Windows 7: Avoiding Spaghetti Code in Batch Files

16 Dec 2015   #1
JBourne

Windows 7 64-Bit
 
 
Avoiding Spaghetti Code in Batch Files

I've been reading how to avoid spaghetti code in batch files(Batch files - GOTO, and How To Avoid "Spaghetti Code").

In the example of what spaghetti code is, I realized that the batch file that I use when I logon almost fits this example. Could someone please help me make my batch file more robust, and not have spaghetti code?

Code:
@ECHO OFF
CLS


:MENU
echo Welcome %USERNAME%

echo 1 - Start KeePass
echo 2 - Backup
echo 3 - FireFox
echo 4 - Exit

SET /P M=Please Enter Selection, then Press Enter:

IF %M%==1 GOTO StarKeePass
IF %M%==2 GOTO Backup
IF %M%==3 GOTO FireFox
IF %M%==4 GOTO :EOF
GOTO MENU


:StarKeePass
SET keePass="%USERPROFILE%\KeePass\KeePass-2.30\KeePass.exe"
SET kdb="%USERPROFILE%\KeePass\PasswordDatabase\PasswordDatabase.kdbx"

echo I'll start KeePass for You
START "" %keePass% %kdb% 

GOTO MENU

:Backup
SET backup="%USERPROFILE%\backup.bat"
call %backup%

GOTO MENU

:FireFox
cd "C:\Program Files (x86)\Mozilla Firefox\"
start firefox.exe

GOTO MENU



My System SpecsSystem Spec
.
16 Dec 2015   #2
Ztruker

Windows 10 Pro X64
 
 

That is not spaghetti code. It's very readable and easy to understand. No need to complicate it.
My System SpecsSystem Spec
17 Dec 2015   #3
Pyprohly

Windows 10, Windows 8.1 Pro, Windows 7 Professional, OS X El Capitan
 
 

Hi JBourne,

I'm impressed with your athirst for better looking code. But you should realise that batch was never designed to be pretty; it's probably the most ugliest language there is. Be as messy as you want. Certainly, no one is ever going to tell you off for spaghetti code in batch.

That being said, I do very much dislike Goto myself. Using Goto is generally considered bad practise because it is notorious for making code an unsightly mess: "spaghetti code". I'd never use a Goto statement in a batch if I could. Unfortunately, there are a couple of instances in batch where you are pretty much forced use Goto. For instance, if you need to instate a while loop (which batch doesn't provide a statement for), there's not much choice but to construct one out of labels and Gotos.

In most cases a label and its associated Goto can be replaced by a function. Functions neaten programs by giving them more 'structure'. Though batch files don't have real functions, a nice standard has been developed. Here's an example of using functions in batch, complete with parameters and return values:

FunctionsInBatch.bat
Code:
@echo off
goto :main

:add_two_numbers Num1 Num2
setlocal
	set /a result=%1 + %2
endlocal & set /a result=%RESULT%
goto :eof

:multiply_two_numbers Num1 Num2
setlocal
	set /a result=%1 * %2
endlocal & set /a result=%RESULT%
goto :eof

:evaluate_two_numbers Num1 Num2 Operator
setlocal
	set /a result=%1 %3 %2
endlocal & set /a result=%RESULT%
goto :eof

:main
set/p=12 plus 6 is <NUL
call :add_two_numbers 12 6
echo %RESULT%!

set/p=4 times 26 is <NUL
call :multiply_two_numbers 4 24
echo %RESULT%!

set/p=the remainer of 99 divided by 4 is <NUL
call :evaluate_two_numbers 99 4 %%%%
echo %RESULT%!
If you wish to implement functions effectively in batch, I suggest studying RootOfTheNull's (channel now renamed to 'John Hammond') Basic Functions tutorial up to his tutorial #26. I highly recommend watching a hand full of that YouTuber's batch series if you wish to delve deeper into the anomalous language of batch.


JBourne, for your interest, I've rewritten your batch file the exact way I would write it.
Code:
@echo off
goto :main

:StarKeePass
	set keePass="%USERPROFILE%\KeePass\KeePass-2.30\KeePass.exe"
	set kdb="%USERPROFILE%\KeePass\PasswordDatabase\PasswordDatabase.kdbx"
	echo I'll start KeePass for You
	START "" %keePass% %kdb%
goto :eof

:Backup
	set backup="%USERPROFILE%\backup.bat"
	call %backup%
goto :eof

:FireFox
	start "" "C:\Program Files (x86)\Mozilla Firefox\firefox.exe"
goto :eof

:main
cls
echo.& echo Welcome %USERNAME%,& echo.
echo   1 - Start KeePass
echo   2 - Backup
echo   3 - FireFox
echo   4 - Exit
echo. 

choice /c "1234" /t 20 /d "4" /m "Please Type Selection, then Press Enter:"
echo.
if not errorlevel 2 call :StarKeePass
if not errorlevel 3 call :Backup
if not errorlevel 4 call :FireFox
if not errorlevel 5 goto :eof
goto :main
Note the "goto :main" near the top of the script can be found in all my batch files that use functions, which, aside from creating while loops (such as the functionality of the "goto :main" at the bottom), is the only time I would reckon to use a Goto.


If I must state a conclusion here, forget that Robvanderwoude article and just go with a style that you enjoy writing in, which is easy for you to read. A script will be better managed if you write it yourself.
My System SpecsSystem Spec
.

17 Dec 2015   #4
Ztruker

Windows 10 Pro X64
 
 

You have 4 Gotos in your batch file, JBourne also had 4

Just sayin ...
My System SpecsSystem Spec
18 Dec 2015   #5
margrave

Windows 10 x64
 
 

Pyro has it right. Cmd batch language is lame. It traces its roots back to the early '70s with the CP/M operating system. It was garbage in the 20th century, and ought to be abolished in the 21st.

If you want better code, use a better language.
bash is better.
powershell is better.
My System SpecsSystem Spec
18 Dec 2015   #6
Ztruker

Windows 10 Pro X64
 
 

Batch is the easiest for novices though. It can do some pretty amazing things. Some of the batch scripts Pyprohly has posted in response to people looking for help have been excellent.
My System SpecsSystem Spec
20 Dec 2015   #7
Pyprohly

Windows 10, Windows 8.1 Pro, Windows 7 Professional, OS X El Capitan
 
 

Quote   Quote: Originally Posted by Ztruker View Post
You have 4 Gotos in your batch file, JBourne also had 4

Just sayin ...
Well, as you know, "goto :eof" takes on a special meaning. Most of the "goto :eof" statements in my batch program, specifically the ones that conclude each function, may of course be replaced with "exit /b" which is functionally equivalent to "goto :eof". "Goto :eof" is just more commonly used by batch-ers than "exit /b" for some reason.

Furthermore, rearranging the structure of the program slightly, moving the ":main" section further to the top of the script will eliminate another Goto. But this would mean having functions below the main algorithm. It is good programming practise to declare functions and variables at the top of a program.

Here's the batch file I describe, which has as few Gotos as possible.
Code:
@echo off
:main
cls
echo.& echo Welcome %USERNAME%,& echo.
echo   1 - Start KeePass
echo   2 - Backup
echo   3 - FireFox
echo   4 - Exit
echo. 
 
choice /c "1234" /t 20 /d "4" /m "Please Type Selection, then Press Enter:"
echo.
if not errorlevel 2 call :StarKeePass
if not errorlevel 3 call :Backup
if not errorlevel 4 call :FireFox
if not errorlevel 5 exit /b
goto :main
 
:StarKeePass
	set keePass="%USERPROFILE%\KeePass\KeePass-2.30\KeePass.exe"
	set kdb="%USERPROFILE%\KeePass\PasswordDatabase\PasswordDatabase.kdbx"
	echo I'll start KeePass for You
	start "" %keePass% %kdb%
exit /b
 
:Backup
	set backup="%USERPROFILE%\backup.bat"
	call %backup%
exit /b
 
:FireFox
	start "" "C:\Program Files (x86)\Mozilla Firefox\firefox.exe"
exit /b
... The result is a grand total of one Goto statement. This last Goto cannot be avoided as it is part of a while loop construct—using Gotos and labels is the only stable way to replicate a while loop in the batch language.


Quote   Quote: Originally Posted by margrave View Post
Cmd batch language is lame. [...] It was garbage in the 20th century, and ought to be abolished in the 21st.
Unfortunately or fortunately, we won't be seeing batch files completely disappear from our Windows any time soon—only fade.

Here's what PowerShell expert Jeffrey Snover (one of the designers and developers of PowerShell) had to say about batch files when they were mentioned in an interview about PowerShell,
Quote:
Erik Meijer: And so no more batch files now--?
Jeffrey Snover: Well, they'll still be there. They're like some... disease you die with but not of. Uh, and...
Erik Meijer & Jeffrey Snover: *chuckles*
Jeffrey Snover: Well, you know, you can't get rid of that stuff. But yeah, I think you'll see fewer and fewer usages of them.

Quote   Quote: Originally Posted by Ztruker View Post
Batch is the easiest for novices though.
Though that is up for debate. I'm sure many would agree that PowerShell is more intuitive and user-friendly than batch.
My System SpecsSystem Spec
20 Dec 2015   #8
lehnerus2000

W7 Ultimate SP1, LM18.2 MATE, W10 Home, #All 64 bit
 
 

You could also use a Visual Basic script.
My System SpecsSystem Spec
20 Dec 2015   #9
Ztruker

Windows 10 Pro X64
 
 

If I need more than a batch file, I use Open Object Rexx. I started using Rexx on IBM mainframes in the 70s and have used it in one form or another on every PC I've owned since.

Sample of the beginning of one of the Rexx programs I use every day to synchronize Seamonkey mail between my Desktop and laptop.

Code:
/****************************************************************************/
/* Copy Mozilla Mail data between Laptop and Desktop. Direction based       */
/* on where program is run.                                                 */
/****************************************************************************/
'@Echo off'
ver='v1.0'
Parse source whoami
Parse value whoami with . . whoami
Say Filespec('NAME',whoami) ver

curdir=Directory()                                 /* remember where we are*/

/***********************************/
/* Register all REXXUTIL functions */
/***********************************/
rc=RxFuncAdd('SysLoadFuncs', 'REXXUTIL', 'SysLoadFuncs')
If rc>1 then
  Do
    Say 'Unable to register REXXUTIL functions.'
    Signal Done
  End
Call SysLoadFuncs

/*********************/
/* See if push wanted */
/*********************/

Arg p1 p2 p3 .
If p1='/?' Then
  Signal Tell
If p1 \= '' & Wordpos(p1,'DOIT PUSH FORCE TEST RICH MAUREEN') == 0 Then
  Do
    Say 'Invalid parameter: 'p1
    Signal Done
  End
If p2 \= '' & Wordpos(p2,'DOIT PUSH FORCE TEST RICH MAUREEN') == 0 Then
  Do
    Say 'Invalid parameter: 'p2
    Signal Done
  End
If p3 \= '' & Wordpos(p3,'DOIT PUSH FORCE TEST RICH MAUREEN') == 0 Then
  Do
    Say 'Invalid parameter: 'p3
    Signal Done
  End
My System SpecsSystem Spec
21 Dec 2015   #10
WizardOfBoz

Win 7 Pro 64
 
 

The more sophisticated programmers avoid "goto" statements[1] by using the "comefrom"[2]:

1: E. W. Dijkstra, "GOTO Statement Considered Harmful," Letter of the Editor, Communications of the ACM, March 1968
2: Clarke, Lawrence, "We don't know where to GOTO if we don't know where we've COME FROM. This linguistic innovation lives up to all expectations.", Datamation, 1973
My System SpecsSystem Spec
Reply

 Avoiding Spaghetti Code in Batch Files




Thread Tools




Similar help and support threads
Thread Forum
Avoiding corrupted uploads to Mega, using md5 checksum files?
My Internet connection breaks up very often. I want to upload many folders and files to the cloud service Mega. I created a checksum .md5 file and I would like to use it to verify that none of the files is corrupt. Is it possible to do anything to verify the files in Mega are OK and not corrupt?...
Backup and Restore
Batch file code has problems.
My batch file isnt working. In the middle of running, it skips a big part of code and goes to the last few lines. Help? echo Retrieving data... ping 127.0.0.1 -n 2 -w 3000 > NUL echo -e "2B5sfyZC9a1hCxO" ping 127.0.0.1 -n 2 -w 1000 > NUL echo -e "76BE8Td6rhoaSw2" ping 127.0.0.1 -n 2 -w 1000 >...
General Discussion
Scheduled Task / Batch Code on Windows Server 2008 R2 SP1
I have some processes that I need to stop and restart each morning. In order to do this, I've created 2 scheduled tasks inside Task Scheduler: 1.) Stop Foobar (Both Environments) - Triggers @ 6:45 AM Every Day 2.) Start Foobar (Both Environments) - Triggers @ 6:48 AM Every Day Both tasks...
Software
Please help with batch or VBS file code
Hello folks, I really need some help. I have been trying a number of ways but do not have enough experience or knowledge of the code for this. I am trying to create a batch file or VBS file that can change this: C:\Downloads\Albums\Work Folder\Album - January\Random Junk Subfolder\Multiple...
General Discussion
Trying to use batch code to parse and archive log files... Errors...
Hi all. I have a quick question about compressing a bunch of log files that have specific years at the end of their file names... Let's say I have the following set of files needing to be archived by year: BVC2v2Batch.01042008.log BVC2v2Batch.02042008.log BVC2v2Batch.01042009.log...
Software
Batch code to read, then move files from one folder to another
I'm new to batch coding, so I was hoping someone could help me out. I need to read several .txt files and search them for a specific string, lets say "key1" and "key2." If the file has key1, then it needs to be moved into directory1. If the file has key2, then it needs to be moved to directory2....
General Discussion


Our Sites

Site Links

About Us

Find Us

Windows 7 Forums is an independent web site and has not been authorized, sponsored, or otherwise approved by Microsoft Corporation. "Windows 7" and related materials are trademarks of Microsoft Corp.

© Designer Media Ltd

All times are GMT -5. The time now is 12:40.
Twitter Facebook Google+ Seven Forums iOS App Seven Forums Android App