• No results found

Batch File Programing

N/A
N/A
Protected

Academic year: 2021

Share "Batch File Programing"

Copied!
14
0
0

Loading.... (view fulltext now)

Full text

(1)

Living with DOS: Living with DOS:

(( Intermediate BATch Tutorial )) (( Intermediate BATch Tutorial ))

by

by Barry Barry SimonSimon

Copyright (c) 1986, Capital PC User Group Inc. Copyright (c) 1986, Capital PC User Group Inc.

This material may be republished only for internal use This material may be republished only for internal use by other not-for-profit user groups.

by other not-for-profit user groups.

Additional material copyright (c) 1986, Barry Simon Additional material copyright (c) 1986, Barry Simon Posted on

Posted on Compuserve with Compuserve with permission of permission of CPCUG. CPCUG. May May not benot be reproduced without including the above copyright notice. reproduced without including the above copyright notice.

Published in the November 1986 issue of the Capital PC Monitor. Published in the November 1986 issue of the Capital PC Monitor.

Introduction Introduction

One of the tools that most distinguishes the experienced DOS user One of the tools that most distinguishes the experienced DOS user from others

from others is the is the effective use of effective use of BATch files. BATch files. In this In this article, Iarticle, I will discuss some of the more advanced features of BATch files and will discuss some of the more advanced features of BATch files and their commands.

their commands. I I call call this tutorial this tutorial "intermediate" because "intermediate" because I I havehave tried to write in a manner accessible to those with only a little tried to write in a manner accessible to those with only a little experience writing BATch files.

experience writing BATch files.

Simple BATch files Simple BATch files

To begin with, a BATch file is a set of DOS commands which you To begin with, a BATch file is a set of DOS commands which you place together and which you can issue by just typing the name of place together and which you can issue by just typing the name of the batch

the batch file. file. The classic The classic example is example is the batch the batch file whichfile which

changes to the directory containing Lotus' 123 and then runs 123. changes to the directory containing Lotus' 123 and then runs 123.

The same idea can be carried much further; for example, when I execute The same idea can be carried much further; for example, when I execute my word processor with a batch file, it

my word processor with a batch file, it o

o loads the loads the proper set proper set of macros of macros in by in by keyboard macro program;keyboard macro program; o

o makes makes a a mark mark using using Kokkennen's MARK/RELEASE Kokkennen's MARK/RELEASE package;package; o

o loads loads my my thesaurus;thesaurus; o

o loads loads the the appropriate mouse appropriate mouse menu menu program;program; o

o runs runs the the words words processor; processor; andand o

o after I after I am finished am finished with the with the word processor, clears word processor, clears the macros the macros andand runs RELEASE to boot the thesaurus and mouse menu from memory.

runs RELEASE to boot the thesaurus and mouse menu from memory. BATch files must be pure ASCII text files with separate commands BATch files must be pure ASCII text files with separate commands

(2)

on distinct lines separated by carriage return/line feed pairs. on distinct lines separated by carriage return/line feed pairs.

To create your BATch files, you can use EDLIN, a text editor, or any To create your BATch files, you can use EDLIN, a text editor, or any word processor that produces straight ASCII text files.

word processor that produces straight ASCII text files.

BATch programs can contain DOS commands, application program commands, BATch programs can contain DOS commands, application program commands, or a variety of specialized programming features that are known as or a variety of specialized programming features that are known as BATch commands.

BATch commands.

BATch Commands and Features BATch Commands and Features Parameters

Parameters

Your editor may allow you to specify a text file to use as a Your editor may allow you to specify a text file to use as a parameter on

parameter on the command the command line loading line loading it. it. You would You would like tolike to

specify the file name as a parameter on the command line calling a specify the file name as a parameter on the command line calling a BATch file to start your editor and have this file name passed on BATch file to start your editor and have this file name passed on to

to the the editor editor when when it it is is loaded. loaded. This This is is quite quite easy. easy. If If youryour editor is called EDITOR.EXE and you load it via a BATch file editor is called EDITOR.EXE and you load it via a BATch file called foo.bat, you need only make the line calling the editor called foo.bat, you need only make the line calling the editor say:

say:

editor %1 editor %1

and then call up the BATch file as and then call up the BATch file as

foo filename foo filename

When the BATch processor comes to the %1, it looks for the first When the BATch processor comes to the %1, it looks for the first parameter following "foo" and replaces %1 by that parameter, in parameter following "foo" and replaces %1 by that parameter, in this case by filename.

this case by filename.

To be more precise, DOS parses the command line calling the BATch To be more precise, DOS parses the command line calling the BATch file into distinct "words" separated by one of four delimiters: file into distinct "words" separated by one of four delimiters:

<space> , ; = <space> , ; =

That is, it looks for strings of allowed characters separated by That is, it looks for strings of allowed characters separated by one or

one or more of more of these special these special four. four. Any of Any of the 256 the 256 ASCIIASCII characters are

characters are allowed in allowed in the strings the strings except for except for these these fourfour

delimiters, the three redirection characters (<,>,|) and the ASCII delimiters, the three redirection characters (<,>,|) and the ASCII nul.

nul. The first The first word on word on the command the command line is line is assigned the value assigned the value %0,%0, the next

the next %1, etc. %1, etc. Normally, %0 Normally, %0 is just is just the name the name of the of the BATch fileBATch file but since "." is not a delimiter in parsing the line but is a

but since "." is not a delimiter in parsing the line but is a delimiter in ending file names, if you have a BATch file foo.bat delimiter in ending file names, if you have a BATch file foo.bat and type in

and type in

foo.cpcugisgreat foo.cpcugisgreat

foo.bat will be run and %0 will have the full 17 character string foo.bat will be run and %0 will have the full 17 character string assigned to

assigned to it. it. Similarly, since Similarly, since DOS knows DOS knows that file that file names are names are nono more than 8 characters, the BATch file 12345678.bat will be run if more than 8 characters, the BATch file 12345678.bat will be run if you type in

you type in

12345678ABCDEFGHIJ 12345678ABCDEFGHIJ but %0

but %0 will have will have an 18 an 18 character string. character string. These are These are admittedlyadmittedly curiosities but DOS curiosities have a knack of being useful curiosities but DOS curiosities have a knack of being useful

(3)

sometimes.

sometimes. In a In a real sense, real sense, DOS assigns DOS assigns as many as many parameters asparameters as there are words on the command line, but initially you can only there are words on the command line, but initially you can only access the

access the first ten first ten as %0 as %0 through %9. through %9. Any place Any place that %1 that %1 appearsappears in the BATch file except as %%1, it will be replaced by the first in the BATch file except as %%1, it will be replaced by the first word after

word after the filename the filename even if even if that word that word is the is the empty word. empty word. AnyAny other time that the symbol % appears in the BATch file DOS will other time that the symbol % appears in the BATch file DOS will strip the %-sign away except that %% is replaced by a single strip the %-sign away except that %% is replaced by a single percent and %%1 becomes %1 so if foo.bat has the single line: percent and %%1 becomes %1 so if foo.bat has the single line:

echo %%1 has the value %1 echo %%1 has the value %1 then typing

then typing foo junk foo junk

will issue the message will issue the message

%1 has the value junk %1 has the value junk

There is no limit on the size of any individual parameter other There is no limit on the size of any individual parameter other than the overall limitation that the entire DOS command line can than the overall limitation that the entire DOS command line can contain no more than a total of 128 characters.

contain no more than a total of 128 characters.

To summarize, any time %i (for i=0,1,...,9) occurs in the file To summarize, any time %i (for i=0,1,...,9) occurs in the file except as a %%i, it will be replaced by the ith string in the except as a %%i, it will be replaced by the ith string in the command line.

command line.

The real limitation of BATch file parameters is that they are not The real limitation of BATch file parameters is that they are not variables.

variables. You cannot You cannot manipulate them manipulate them by by parsing them parsing them and and cannotcannot change their values.

change their values.

Labels Labels

As a preparation for discussing BATch file GOTO commands, I need As a preparation for discussing BATch file GOTO commands, I need to discuss

to discuss labels. labels. Any line Any line beginning with beginning with the character the character ":" will":" will be skipped

be skipped by the by the BATch processor when BATch processor when it gets it gets to it. to it. This meansThis means that you can use such lines as remark lines which will not appear that you can use such lines as remark lines which will not appear on the screen even if echo is on (in which case lines beginning on the screen even if echo is on (in which case lines beginning with rem

with rem do do appear). appear). You You can also can also place the place the redirectionredirection characters <,>,| on such a line (but you cannot place such characters <,>,| on such a line (but you cannot place such characters on

characters on a "rem" a "rem" line). line). And % And % signs are signs are not treatednot treated specially on such lines.

specially on such lines.

While DOS ignores such lines, the string following the : becomes a While DOS ignores such lines, the string following the : becomes a label for

label for the GOTO the GOTO command which I'll command which I'll discuss next. discuss next. The first The first word orword or the first eight characters of the first word become the name of that the first eight characters of the first word become the name of that label.

label. You can You can also place also place comments after a comments after a label name label name if you if you separateseparate these comments with a space.

these comments with a space.

GOTO GOTO

The most significant way in which BATch files go beyond the DOS The most significant way in which BATch files go beyond the DOS command line concerns two logical control structures, the GOTO and command line concerns two logical control structures, the GOTO and the

the IF IF commands. commands. The The lineline goto <label>

(4)

will send the BATch file to the line immediately following the will send the BATch file to the line immediately following the line on

line on which the which the label appears. label appears. If the If the label appears label appears more thanmore than once, its

once, its first appearance in first appearance in the file the file is used. is used. If the If the label doeslabel does not appear, the processing of the BATch file is abruptly ended not appear, the processing of the BATch file is abruptly ended with the message "label not found".

with the message "label not found".

GOTO's can be used for either branching or some rather crude GOTO's can be used for either branching or some rather crude looping.

looping. Here Here is is a a simple simple example example of of branching. branching. Suppose Suppose that that youyou wish to send control codes to your printer easily from the DOS wish to send control codes to your printer easily from the DOS command line.

command line. You You might might prepare little prepare little files files like like ff.txtff.txt

containing a formfeed (control-L), or boldon.txt with the codes containing a formfeed (control-L), or boldon.txt with the codes for turning

for turning bold face bold face on, etc. on, etc. Then you Then you could write could write a print.bata print.bat file which began:

file which began: goto %1 goto %1 :ff :ff copy ff.txt prn copy ff.txt prn goto end goto end :boldon :boldon copy boldon.txt prn copy boldon.txt prn ETC ETC

with a label ":end" as the last line of the file. with a label ":end" as the last line of the file.

One problem with the limited logic allowed by BATch files is the One problem with the limited logic allowed by BATch files is the difficulty of

difficulty of error checking. error checking. With the With the above, if above, if you forget you forget toto put in a parameter or put in an illegal value, you would get the put in a parameter or put in an illegal value, you would get the rather

rather inelegant inelegant "label "label not not found" found" message. message. Alternatively, youAlternatively, you could replace the "goto %1" with separate lines such as:

could replace the "goto %1" with separate lines such as: if %1 == ff, goto ff

if %1 == ff, goto ff

and then place an error message, hardly a neat solution. and then place an error message, hardly a neat solution.

PAUSE PAUSE

The next BATch command that I'll discuss, PAUSE, unlike GOTO and The next BATch command that I'll discuss, PAUSE, unlike GOTO and parameters makes

parameters makes sense at sense at the DOS the DOS command line. command line. For straight For straight DOSDOS usage, this is pointless but for environments like CED or TallScreen usage, this is pointless but for environments like CED or TallScreen which allow

which allow multiple commands on multiple commands on one line, one line, it can it can be useful. be useful. WhatWhat PAUSE does is display the message:

PAUSE does is display the message: Strike a key when ready . . . Strike a key when ready . . .

and pause the processing of the BATch file until a key is struck. and pause the processing of the BATch file until a key is struck. Before the message is displayed, the keyboard buffer is flushed to Before the message is displayed, the keyboard buffer is flushed to prevent any stray keystrokes left over from previous operations prevent any stray keystrokes left over from previous operations from bypassing the effect of the PAUSE command.

from bypassing the effect of the PAUSE command. There are

There are three rather three rather distinct uses distinct uses of the of the PAUSE command. PAUSE command. TheThe most well known is to allow the user to take an action like most well known is to allow the user to take an action like inserting a diskette

inserting a diskette into a into a drive. drive. Often, you Often, you will want will want to echo to echo aa message to the screen before the PAUSE command such as:

message to the screen before the PAUSE command such as: echo Place a diskette into drive B: and ...

echo Place a diskette into drive B: and ... pause

(5)

A second use is to allow the user to see the output of some A second use is to allow the user to see the output of some program before

program before the the BATch file BATch file continues. continues. Without the Without the PAUSE, thePAUSE, the output might

output might disappear too disappear too quickly to quickly to absorb. absorb. A third A third use thatuse that we'll see later is as an extremely crude device for user input. we'll see later is as an extremely crude device for user input.

The IF command The IF command

The second and last element of flow control provided by DOS is the The second and last element of flow control provided by DOS is the IF command.

IF command. Like pause, Like pause, it also it also makes sense makes sense at the at the DOS commandDOS command line.

line. The The syntax syntax isis

IF (not) <comparison> <consequence> IF (not) <comparison> <consequence> The not

The not is an is an optional part optional part which we'll which we'll explain later. explain later. ComparisonComparison is limited to three types:

is limited to three types: o

o A A test for test for the equality the equality of of two two strings;strings; o

o A A test for test for the existence the existence of a of a file; andfile; and o

o A A test test of of the the "error "error level".level".

If the comparison is true, then the command in "consequence" will If the comparison is true, then the command in "consequence" will get carried

get carried out. out. If the If the word "not" word "not" is included, is included, thenthen <consequence> is

<consequence> is carried out carried out only if only if the the comparison fails. comparison fails. WhileWhile consequence is typically a GOTO statement, any acceptable DOS or consequence is typically a GOTO statement, any acceptable DOS or BATch command

BATch command is allowed. is allowed. You can You can even have even have the consequence the consequence be abe a second if statement as in

second if statement as in

if not %1 == ff if not %1 == boldon goto error if not %1 == ff if not %1 == boldon goto error

As the last line shows, the syntax for checking strings is to use As the last line shows, the syntax for checking strings is to use two equal

two equal signs. signs. Strings are Strings are sequences of sequences of characters notcharacters not including the standard delimiters (space, comma, semicolon or including the standard delimiters (space, comma, semicolon or equal) or

equal) or redirection signs. redirection signs. These These redirection signs redirection signs but but notnot delimiters can appear if the string or part of the string is delimiters can appear if the string or part of the string is surrounded by single or double quotes. If an illegal string is surrounded by single or double quotes. If an illegal string is used, DOS

used, DOS will reward will reward you with you with "bad command "bad command or filename". or filename". ThereThere is a standard problem faced by users first exposed to BATch files. is a standard problem faced by users first exposed to BATch files. Often, you will want to test for an empty string, for example to Often, you will want to test for an empty string, for example to give an error message if the user failed to provide a necessary give an error message if the user failed to provide a necessary parameter.

parameter. Empty strings Empty strings are not are not allowed so allowed so that that the linethe line if

if %1 %1 == == echo echo whoopswhoops

will yield "syntax error" if %1 is empty, and "bad command or will yield "syntax error" if %1 is empty, and "bad command or filename" if %1 has the value "echo" unless of course you have a filename" if %1 has the value "echo" unless of course you have a program named "whoops".

program named "whoops". The way The way out of out of this problem this problem is to is to use theuse the fact that %1 is replaced where ever it is and add a dummy

fact that %1 is replaced where ever it is and add a dummy parameter as in

parameter as in

if a%1 == a echo whoops if a%1 == a echo whoops

The possibility of looking for a file provides essential error The possibility of looking for a file provides essential error checking.

checking. A common A common example of example of its use its use is to is to fix the fix the deadly movedeadly move BATch file:

(6)

copy %1 %2\%1 copy %1 %2\%1 erase %1

erase %1

This may seem like a great way of moving a file from one directory This may seem like a great way of moving a file from one directory to another so that

to another so that

move foo.txt C:\junk move foo.txt C:\junk will move

will move foo.txt from foo.txt from the current the current directory to directory to junk. junk. But if But if thethe directory junk doesn't exist, the first line will give the error directory junk doesn't exist, the first line will give the error message "Invalid directory" and the second line will erase the message "Invalid directory" and the second line will erase the file which

file which has NOT has NOT been copied. been copied. Thus, as Thus, as a a protection one protection one shouldshould add before the "erase %1" line

add before the "erase %1" line if not exist %2\%1 goto end if not exist %2\%1 goto end with an

with an appropriate label appropriate label and error and error message. message. There are There are many othermany other places where such error checking can be invaluable.

places where such error checking can be invaluable.

Unfortunately, "if exist" works with path names only in DOS 3.x Unfortunately, "if exist" works with path names only in DOS 3.x and not in DOS 2.x.

and not in DOS 2.x.

The final if comparison, "if errorlevel", is useless within the The final if comparison, "if errorlevel", is useless within the context of pure DOS commands since no DOS command (before DOS 3.2) context of pure DOS commands since no DOS command (before DOS 3.2) sets errorlevel.

sets errorlevel. But the But the DOS technical DOS technical reference describes reference describes how how aa program can set this parameter and if you have a program that sets program can set this parameter and if you have a program that sets it, this comparison is useful.

it, this comparison is useful.

But I must warn you that the comparison But I must warn you that the comparison

if errorlevel 2 if errorlevel 2

is TRUE not only if the value of errorlevel is 2 but if it is 2 or is TRUE not only if the value of errorlevel is 2 but if it is 2 or greater.

greater. Beginning with Beginning with DOS DOS 3.2, 3.2, several external several external DOS DOS commandscommands such as BACKUP, RESTORE, and FORMAT set what the DOS manual calls such as BACKUP, RESTORE, and FORMAT set what the DOS manual calls "exit codes" which can be tested with "if errorlevel".

"exit codes" which can be tested with "if errorlevel".

Nested and Chained BATch files Nested and Chained BATch files

It is possible to make rather elaborate collections of BATch files It is possible to make rather elaborate collections of BATch files which call

which call one another. one another. The simplest The simplest is the is the equivalent of equivalent of a a GOTO.GOTO. If the name of another file appears as a line in one BATch file, If the name of another file appears as a line in one BATch file, the new BATch file will begin and you will NOT return to the first the new BATch file will begin and you will NOT return to the first BATch file when the second one ends.

BATch file when the second one ends.

Particularly since the BATch control structures (GOTO and IF) do Particularly since the BATch control structures (GOTO and IF) do not include CALL/RETURN processing of subroutines, one would like not include CALL/RETURN processing of subroutines, one would like to be able to call a second BATch file as a subroutine and return to be able to call a second BATch file as a subroutine and return to the

to the first BATch first BATch file when file when the second the second one finished. one finished. Many books,Many books, especially the older ones, will tell you that this is not

especially the older ones, will tell you that this is not possible.

possible. However, in However, in DOS 2.x DOS 2.x and later, and later, there is there is a method a method ofof doing precisely

doing precisely this kind this kind of subroutine of subroutine call. call. This is This is an examplean example of something which is not undocumented but rather so badly

of something which is not undocumented but rather so badly

documented that many experts did not realize its potential until documented that many experts did not realize its potential until some time

some time had passed. had passed. The reason The reason that an that an ordinary call to ordinary call to aa second BATch file does not return you to the first is that second BATch file does not return you to the first is that command.com is only

(7)

solution is to load a secondary copy of command.com to process the solution is to load a secondary copy of command.com to process the second

second BATch BATch file. file. The The correct correct syntax syntax isis command/c foo

command/c foo to call

to call foo.bat from foo.bat from another BATch another BATch file. file. When When foo ends,foo ends,

processing of the first BATch file will continue on the next line. processing of the first BATch file will continue on the next line. Several warnings

Several warnings are in are in order concerning order concerning this command. this command. As you As you maymay know, DOS has both internal commands like COPY and external

know, DOS has both internal commands like COPY and external commands like

commands like FORMAT. FORMAT. That is, That is, once command.com once command.com is is loaded duringloaded during initial bootup, COPY becomes an available command while FORMAT is initial bootup, COPY becomes an available command while FORMAT is a stand alone program, which provided separately on the DOS disk, a stand alone program, which provided separately on the DOS disk, which must reside in the default directory or in the path to be which must reside in the default directory or in the path to be available to

available to the user. the user. You might You might think that think that COMMAND was COMMAND was anan internal command but

internal command but it is it is external. external. That is, That is, in order in order for a for a lineline like

like

command/c foo command/c foo

to work, COMMAND.COM must be available in the default directory or to work, COMMAND.COM must be available in the default directory or in the

in the path. path. In addition In addition if you if you leave an leave an old version old version ofof

COMMAND.COM somewhere on your hard disk and that happens to be the COMMAND.COM somewhere on your hard disk and that happens to be the one first found when this line is processed, you will get a

one first found when this line is processed, you will get a message "incompatible

message "incompatible DOS DOS versions". versions". Finally, there Finally, there is is a a warningwarning about the SET command discussed in the section below on global about the SET command discussed in the section below on global variables.

variables.

FOR...IN...DO FOR...IN...DO

FOR...IN...DO is one of DOS' most powerful and least appreciated FOR...IN...DO is one of DOS' most powerful and least appreciated commands.

commands. It can It can be used be used at the at the DOS command DOS command line or line or in a in a BATchBATch file with

file with slightly different slightly different syntax. syntax. The syntax The syntax at at the DOSthe DOS command line is

command line is

for %a in (<list>) do expression(%a) for %a in (<list>) do expression(%a)

The use of a in %a is not important; you can use any letter or The use of a in %a is not important; you can use any letter or number or even extended ASCII code so long as it appears in all number or even extended ASCII code so long as it appears in all places.

places. The % The % is important is important and since and since %'s get %'s get stripped from stripped from BATchBATch files, the

files, the syntax in syntax in a BATch a BATch file must file must be "for be "for %%a...". %%a...". TheThe

keyword "do" must appear or you will get a "syntax error" message. keyword "do" must appear or you will get a "syntax error" message. Within the () can appear a list of ASCII strings separated by the Within the () can appear a list of ASCII strings separated by the standard delimiters.

standard delimiters. Following the Following the keyword keyword "do" "do" can can be be anyany

command with %a as a parameter which will be successively replaced command with %a as a parameter which will be successively replaced by

by the the values values listed within listed within (). (). For For exampleexample for %a in (file1 file2 file3) do copy %a prn for %a in (file1 file2 file3) do copy %a prn

will issue three separate commands copying the three files to prn. will issue three separate commands copying the three files to prn. The power of the FOR...IN...DO construction comes because you can The power of the FOR...IN...DO construction comes because you can include wildcards and DOS will substitute in turn each filename include wildcards and DOS will substitute in turn each filename satisfying the wildcard, so for example,

satisfying the wildcard, so for example, for %a in (file?) do copy %a prn

(8)

would do the same thing as the above command if there were no would do the same thing as the above command if there were no other files

other files with the with the name file?. name file?. Therefore, the Therefore, the greatest use greatest use ofof FOR...IN...DO is to force programs which don't understand wild FOR...IN...DO is to force programs which don't understand wild cards

cards to to understand them understand them none-the-less! none-the-less! For For example, when example, when II discussed file viewers, I talked about both LIST and FILEVIEW. discussed file viewers, I talked about both LIST and FILEVIEW. LIST allows you to give wildcard filenames so "list *.doc" would LIST allows you to give wildcard filenames so "list *.doc" would successively view

successively view all files all files with a with a doc extension. doc extension. FILEVIEW doesFILEVIEW does not have this built in but you can do it yourself: rename fv.exe not have this built in but you can do it yourself: rename fv.exe [email protected] and make a one line BATch file called fv.bat saying

[email protected] and make a one line BATch file called fv.bat saying for %%a in (%1) do fv@ %%a

for %%a in (%1) do fv@ %%a

and suddenly FILEVIEW also has this capability. and suddenly FILEVIEW also has this capability.

You can also force commands which don't treat wildcards "properly" You can also force commands which don't treat wildcards "properly" to do

to do so. so. For example, For example, if you if you want to want to change the change the date/time stampdate/time stamp on a file foo.txt to the current date and time, the command

on a file foo.txt to the current date and time, the command copy/b foo.txt+,,

copy/b foo.txt+,, will do

will do precisely that. precisely that. If one If one replaces "foo.txt" in replaces "foo.txt" in the abovethe above command by *.*, DOS will create one file which is the combination command by *.*, DOS will create one file which is the combination of each file in the current directory, probably not what you

of each file in the current directory, probably not what you intended.

intended. To To change the change the date/time of date/time of all files all files useuse for %a in (*.*) do copy/b %a+,,

for %a in (*.*) do copy/b %a+,,

You can combine multiple commands and wildcards as in You can combine multiple commands and wildcards as in

for %a in (*.pas *.com) do copy %a A: for %a in (*.pas *.com) do copy %a A:

If you want to stop such a command before it has run its course, If you want to stop such a command before it has run its course, Ctrl-C will

Ctrl-C will give you give you the opportunity the opportunity to break to break the loop. the loop. InIn addition you should be warned that a FOR...IN...DO loop is addition you should be warned that a FOR...IN...DO loop is

like a BATch file: if the expression called after the keyword "do" like a BATch file: if the expression called after the keyword "do" involves a BATch file, processing will not return to the

involves a BATch file, processing will not return to the FOR...IN...DO loop.

FOR...IN...DO loop. It will It will only be only be processed one processed one time even time even ifif you have

you have several possibilities in several possibilities in your list. your list. As happens As happens for BATchfor BATch files, placing command/c will prevent the chain breaking so

files, placing command/c will prevent the chain breaking so for %a in (*.*) do command/c foo %a

for %a in (*.*) do command/c foo %a

issued at the DOS command line would run the BATch file foo.bat issued at the DOS command line would run the BATch file foo.bat successively with each file in the default directory as a

successively with each file in the default directory as a parameter.

parameter. The BATch

The BATch processor is processor is rather inefficient. rather inefficient. It reads It reads only one only one lineline of the file into memory at a time (try including a line like

of the file into memory at a time (try including a line like "erase foo.bat" in a BATch file to see what happens) although it "erase foo.bat" in a BATch file to see what happens) although it keeps its place by counting the byte offset (try using your editor keeps its place by counting the byte offset (try using your editor on foo.bat

on foo.bat as a as a line in line in foo.bat to foo.bat to explore this). explore this). By using By using thethe FOR...IN...DO command to reduce the number of lines in a BATch FOR...IN...DO command to reduce the number of lines in a BATch file, you can speed up processing by a noticeable although not file, you can speed up processing by a noticeable although not spectacular amount (perhaps

spectacular amount (perhaps by 10%). by 10%). For example, For example, if you if you have ahave a large RAM disk and routinely copy several directories to it during large RAM disk and routinely copy several directories to it during bootup try (the "\*.*" isn't needed; I include it for emphasis). bootup try (the "\*.*" isn't needed; I include it for emphasis).

for %%a in (path1 path2) do copy %%a\*.* D: >nul for %%a in (path1 path2) do copy %%a\*.* D: >nul

(9)

Two warnings about this procedure: you cannot include a command Two warnings about this procedure: you cannot include a command with its own parameters in the list since DOS processes the list with its own parameters in the list since DOS processes the list in ()

in () one word one word at a at a time. time. Second, for Second, for technical reasons, Itechnical reasons, I strongly recommend against loading resident programs in such a strongly recommend against loading resident programs in such a statement.

statement.

SHIFT SHIFT

As I described above, when DOS parses the input command line to a As I described above, when DOS parses the input command line to a BATch file, only the first 10 words are available as %0 to %9. BATch file, only the first 10 words are available as %0 to %9. However DOS keeps

However DOS keeps a record a record of the of the entire line. entire line. One of One of the thingsthe things that the SHIFT command does is provide you with access to the that the SHIFT command does is provide you with access to the other parameters.

other parameters. A line A line with the with the single command single command SHIFT drops SHIFT drops %0%0 changes %1 to %0,..., %9 to %8 and makes what was the eleventh changes %1 to %0,..., %9 to %8 and makes what was the eleventh word on

word on the original the original command line command line into the into the new %9. new %9. AdditionalAdditional calls to SHIFT repeat this process.

calls to SHIFT repeat this process.

If SHIFT were only good for accessing parameters beyond the initial If SHIFT were only good for accessing parameters beyond the initial ten, it

ten, it would be would be of limited of limited use. use. I cannot I cannot find any find any interestinginteresting use of

use of this aspect this aspect of the of the command. command. Its real Its real use lies use lies in thein the possibility of

possibility of having a having a real loop real loop within a within a DOS BATch DOS BATch file. file. HereHere is a sample "touch.bat" expanding the one line procedure for is a sample "touch.bat" expanding the one line procedure for updating the date/time stamp of a file:

updating the date/time stamp of a file: :top

:top

if %1x=x goto end if %1x=x goto end

for %%a in (%1) do copy %%a+,, for %%a in (%1) do copy %%a+,, shift shift goto top goto top :end :end

With this BATch file, you can issue the command touch followed by With this BATch file, you can issue the command touch followed by several parameters,

several parameters, each each with with wildcards. wildcards. The The basic basic operation isoperation is applied to each file meeting any of the filespecs listed as

applied to each file meeting any of the filespecs listed as parameters.

parameters. Of course Of course one could one could probably do probably do just as just as well with well with thethe single line

single line

for %%a in (%1 %2 %3 %4 %5) do copy %%a+,, for %%a in (%1 %2 %3 %4 %5) do copy %%a+,,

While I can develop considerable enthusiasm for the FOR...IN...DO While I can develop considerable enthusiasm for the FOR...IN...DO command, SHIFT does not evoke much excitement!

command, SHIFT does not evoke much excitement!

ECHO ECHO

Next, I turn to the issue of displaying information on the screen, Next, I turn to the issue of displaying information on the screen, the primary method of communication between the writer of a BATch the primary method of communication between the writer of a BATch file and

file and the user. the user. Even if Even if you are you are writing BATch writing BATch files forfiles for yourself, it pays to expend some effort in making attractive, yourself, it pays to expend some effort in making attractive, instructive displays.

instructive displays. By By default, every default, every line in line in the the BATch fileBATch file appears on

appears on the screen. the screen. While this While this has the has the potential advantage ofpotential advantage of showing the user what is going on, usually the display is so fast showing the user what is going on, usually the display is so fast that it

that it is more is more distracting than useful. distracting than useful. You can You can turn off turn off thethe automatic display of commands to the screen with the command automatic display of commands to the screen with the command

echo off echo off

(10)

When echo is off, you can display messages by preceding the When echo is off, you can display messages by preceding the desired communication

desired communication with with the the keyword ECHO. keyword ECHO. The The default fordefault for BATch file should be echo off and there are patches for

BATch file should be echo off and there are patches for COMMAND.COM to

COMMAND.COM to make that make that the default. the default. I have I have avoided this avoided this patchpatch because such a patch is not immediately available for new versions because such a patch is not immediately available for new versions of DOS.

of DOS. Unless you Unless you make this make this patch, most patch, most of your of your BATch filesBATch files should begin with

should begin with echo off

echo off cls

cls

It is not necessary to turn echo on before exiting a BATch file; It is not necessary to turn echo on before exiting a BATch file; it is

it is turned back turned back on automatically. on automatically. You can You can suppress the suppress the promptprompt on a DOS command line by typing "echo off" at the DOS prompt and on a DOS command line by typing "echo off" at the DOS prompt and then "echo on" is necessary to restore the default.

then "echo on" is necessary to restore the default. ECHO can

ECHO can be a be a useful command. useful command. It's message It's message is sent is sent to standardto standard output which means that you can redirect it and so use it to send output which means that you can redirect it and so use it to send codes to

codes to your printer. your printer. But be But be warned that warned that a CR/LF a CR/LF pair is pair is alwaysalways appended to an echo line so

appended to an echo line so echo ^L >prn

echo ^L >prn

(where ^L means control-L the form feed character) will not send (where ^L means control-L the form feed character) will not send only a

only a form feed form feed to your to your printer. printer. It will It will send an send an extra lineextra line feed.

feed. Also, you Also, you will not will not be able be able to send to send escape codes escape codes to yourto your screen or

screen or printer directly printer directly from the from the DOS command DOS command line. line. DOS reactsDOS reacts to your <Esc> key by aborting the current command instead of

to your <Esc> key by aborting the current command instead of placing an

placing an escape character escape character at the at the cursor. cursor. With many With many editors youeditors you can put escape characters into a file and so write BATch files to can put escape characters into a file and so write BATch files to send escape codes to the screen or printer.

send escape codes to the screen or printer.

One character you may want to use is ^G (Control-G entered by One character you may want to use is ^G (Control-G entered by depressing the

depressing the control key control key and hitting and hitting g). g). This is This is the "BEL"the "BEL" character and

character and will beep will beep when sent when sent to the to the screen. screen. SoSo echo ^GYou made an error

echo ^GYou made an error will

will catch catch the the user's user's attention. attention. But But please control please control yourself:yourself: avoid

avoid putting several putting several ^G's ^G's together. together. And And with with most most printersprinters echo ^G >prn

echo ^G >prn

will beep the printer. will beep the printer. A famous

A famous problem is problem is how to how to use ECHO use ECHO to make to make blank lines. blank lines. A BATchA BATch file command line with the single word "echo" will not work as file command line with the single word "echo" will not work as this will

this will get the get the response "echo is response "echo is on" or on" or "echo is "echo is off". off". DOS 2.xDOS 2.x had

had a a celebrated celebrated undocumented feature: undocumented feature: "echo<space>" did "echo<space>" did produceproduce a blank line but relying on this undocumented feature caused grief a blank line but relying on this undocumented feature caused grief when DOS

when DOS 3.x gave 3.x gave the "echo the "echo is on/off" is on/off" response. response. Some versions Some versions ofof DOS have had

DOS have had echo . echo .

(note the period) produce blank lines but this has not always been (note the period) produce blank lines but this has not always been true and has led to some rather fancy programs with installation true and has led to some rather fancy programs with installation

(11)

files showing

files showing bunches of bunches of dots on dots on the screen. the screen. There is There is a rathera rather simple solution.

simple solution. To To get get a a blank blank line line trytry echo <char 255>

echo <char 255>

where <char 255> means including the character with ASCII code where <char 255> means including the character with ASCII code 255.

255. You can't You can't enter this enter this in all in all editors but editors but in many in many (e.g.(e.g.

EDLIN), you can by holding down the <Alt> key and hitting 2 5 5 on EDLIN), you can by holding down the <Alt> key and hitting 2 5 5 on the numeric

the numeric keypad. keypad. Lest you Lest you be wary be wary of using of using an undocumentedan undocumented feature of DOS, this trick merely relies on the documented feature feature of DOS, this trick merely relies on the documented feature of "echo" to send any character even those with codes above 128 to of "echo" to send any character even those with codes above 128 to the screen:

the screen: <char 255> <char 255> is a is a blank character. blank character. You can You can also use also use oneone of these characters to anchor down a message that you don't want of these characters to anchor down a message that you don't want to start in column one.

to start in column one.

Even if echo is off, the last line in the BATch file will appear Even if echo is off, the last line in the BATch file will appear on the screen if that line does not end in a carriage return /line on the screen if that line does not end in a carriage return /line feed pair.

feed pair. For this For this reason, you reason, you will probably will probably want to want to be surebe sure that the last lines in your BATch files have such a CR/LF pair at that the last lines in your BATch files have such a CR/LF pair at the

the end. end. The The exception exception is is if if the the last last line line is is "cls". "cls". In In thisthis case the echo to the screen is unimportant and adding a CR/LF will case the echo to the screen is unimportant and adding a CR/LF will sometimes place the prompt on line three instead of line two.

sometimes place the prompt on line three instead of line two.

Using ANSI.SYS Using ANSI.SYS

If you are writing for a "mass market", you cannot assume that the If you are writing for a "mass market", you cannot assume that the user of your BATch files has ANSI.SYS installed but if you are user of your BATch files has ANSI.SYS installed but if you are writing for yourself or for a colleague, you can be sure it is writing for yourself or for a colleague, you can be sure it is installed.

installed. ANSI.SYS provides ANSI.SYS provides a a simple way simple way of of controlling colorscontrolling colors and, to get really attractive screens, the location of messages. and, to get really attractive screens, the location of messages. You should consult your DOS manual (or the DOS technical reference You should consult your DOS manual (or the DOS technical reference for DOS

for DOS 3.x) to 3.x) to learn how learn how to move to move the cursor. the cursor. For example, if For example, if youyou want to start with echo off and then only erase the line "echo want to start with echo off and then only erase the line "echo off" without clearing the whole screen, try:

off" without clearing the whole screen, try: echo off

echo off

echo <esc>[A<esc>[K echo <esc>[A<esc>[K

Input the Inelegant Way Input the Inelegant Way

One of the weaknesses of the DOS BATch processor is its inability One of the weaknesses of the DOS BATch processor is its inability to accept

to accept input from input from the user. the user. This is This is of importance not of importance not onlyonly when writing for

when writing for others. others. You might You might want a want a BATch file BATch file to run to run aa program and then

program and then ask if ask if you wanted you wanted to make to make a backup. a backup. Of course,Of course, if you knew the answer to this backup question in advance you if you knew the answer to this backup question in advance you could write the BATch file to get such input as a parameter when could write the BATch file to get such input as a parameter when the BATch file was loaded but there is no simple way to get input the BATch file was loaded but there is no simple way to get input once the

once the BATch file BATch file is running. is running. The best The best way to way to overcome thisovercome this lack is to use one of the programs I'll be discussing in later lack is to use one of the programs I'll be discussing in later articles in

articles in this miniseries. this miniseries. Lacking that, Lacking that, I know I know of two of two methodsmethods to get

to get user user input just input just using DOS's using DOS's tools. tools. First, Control-BreakFirst, Control-Break (or Control-C) will stop a BATch file (or rather give you the (or Control-C) will stop a BATch file (or rather give you the message "Terminate Batch file(y/n)?") and so you can point out to message "Terminate Batch file(y/n)?") and so you can point out to the user

the user the option the option that is that is always available always available any ways. any ways. ForFor example, if backing up is all that is left you could put in the example, if backing up is all that is left you could put in the lines:

(12)

echo To prevent backup hit Control-Break; otherwise echo To prevent backup hit Control-Break; otherwise Pause

Pause

Since you can accidentally brush a key, this is hardly an ideal Since you can accidentally brush a key, this is hardly an ideal solution.

solution.

Also, you can end a BATch file by displaying a menu with choices Also, you can end a BATch file by displaying a menu with choices labelled "a,b,c" and have BATch files called a.bat, b.bat, c.bat labelled "a,b,c" and have BATch files called a.bat, b.bat, c.bat to run depending on the user's response.

to run depending on the user's response.

Global variables Global variables

If one chains or nests BATch files, it is easy to pass parameters If one chains or nests BATch files, it is easy to pass parameters between them by putting the parameters in the command line calling between them by putting the parameters in the command line calling the second

the second BATch file. BATch file. But what But what about BATch about BATch files called files called atat different times.

different times. For example, For example, you you may have may have noticed that noticed that thethe

a.bat,... procedure above seems to have the disadvantage that you a.bat,... procedure above seems to have the disadvantage that you can only use it for one menu unless you use different directories can only use it for one menu unless you use different directories or different

or different letter choices. letter choices. Wouldn't it Wouldn't it be better be better if there if there werewere a place to put "global variables" so you could set menuchoice=1 a place to put "global variables" so you could set menuchoice=1 before displaying a menu and have a.bat do different things before displaying a menu and have a.bat do different things depending on

depending on the the value of value of "menuchoice". "menuchoice". Well, DOS Well, DOS has has preciselyprecisely such global variables although a part of the procedure is

such global variables although a part of the procedure is undocumented.

undocumented.

When COMMAND.COM is initially loaded, it sets aside a region of When COMMAND.COM is initially loaded, it sets aside a region of memory as

memory as "the environment" "the environment" which by which by default is default is 160 bytes. 160 bytes. MyMy article in last November's monitor lists patches to increase this article in last November's monitor lists patches to increase this size by patching command.com and DOS 3.1 and 3.2 have a mechanism size by patching command.com and DOS 3.1 and 3.2 have a mechanism of increasing environment size by a command in your config.sys of increasing environment size by a command in your config.sys file.

file. This SHELL This SHELL command option command option is documented is documented in DOS in DOS 3.2 but3.2 but undocumented (and slightly different syntax) in DOS 3.1.

undocumented (and slightly different syntax) in DOS 3.1.

The environment is intended primarily to store the location of The environment is intended primarily to store the location of COMMAND.COM when its transient portion needs to be loaded, your COMMAND.COM when its transient portion needs to be loaded, your path and prompt and information that the user can provide various path and prompt and information that the user can provide various programs.

programs. However, you However, you can also can also use it use it to store to store global variablesglobal variables for communication between your BATch files.

for communication between your BATch files.

Placing information into the environment is a documented DOS Placing information into the environment is a documented DOS command.

command. You You use use SET. SET. ThusThus SET name=string

SET name=string

will define a global variable "name" to have the value "string". will define a global variable "name" to have the value "string". As usual, "name" doesn't distinguish between lower and upper case; As usual, "name" doesn't distinguish between lower and upper case; if you look at the environment by typing "SET" with no parameters, if you look at the environment by typing "SET" with no parameters, the variable will appear as

the variable will appear as NAME=string

NAME=string Upper and

Upper and lower case lower case are are distinguished in distinguished in strings. strings. Notice alsoNotice also that spaces count so that the command

that spaces count so that the command SET name = string

(13)

will define another variable "NAME "(note the space). will define another variable "NAME "(note the space).

Getting the value of a global variable is easy from within a Getting the value of a global variable is easy from within a BATch file.

BATch file. If a If a name appears name appears between percent between percent signs, then signs, then DOSDOS will replace

will replace the string the string %name% by %name% by its environmental its environmental value. value. Thus ifThus if you issued "set foo=fun" and later have a line like

you issued "set foo=fun" and later have a line like if %foo%=fun goto success

if %foo%=fun goto success then the

then the BATch file BATch file will go will go to the to the label success. label success. If foo If foo has nohas no current value,

current value, %foo% is %foo% is replaced by replaced by the the empty string. empty string. SeveralSeveral warnings are

warnings are in in order. order. First, this First, this procedure is procedure is undocumented.undocumented. However, it has been constant from DOS 2.0 through 3.2 and is so However, it has been constant from DOS 2.0 through 3.2 and is so close to a documented procedure available to programs that it is close to a documented procedure available to programs that it is as likely to remain in DOS as anything that is not documented. as likely to remain in DOS as anything that is not documented. Second, while you can use the SET command to define variables Second, while you can use the SET command to define variables whose names have spaces in them or whose name begins with a whose names have spaces in them or whose name begins with a numeral, you cannot use %name% to access such variables. numeral, you cannot use %name% to access such variables. A final

A final warning. warning. If you If you use command/c to use command/c to nest a nest a BATch file, BATch file, DOSDOS makes a copy of the environment for the new shell that runs the makes a copy of the environment for the new shell that runs the nested BATch

nested BATch file. file. Anything in Anything in the original the original environment is environment is in thein the new one so global variables are available to the new shell.

new one so global variables are available to the new shell.

However, any changes made in the environment by the nested BATch However, any changes made in the environment by the nested BATch file via a SET command are only saved in the secondary environment file via a SET command are only saved in the secondary environment and will be lost when you return to the original BATch file.

and will be lost when you return to the original BATch file.

What are global variables good for? I have placed today's date in What are global variables good for? I have placed today's date in English (that is January 1, 1980 rather than 1-1-80) in my

English (that is January 1, 1980 rather than 1-1-80) in my

environment at bootup and then I have a letter.bat which makes a environment at bootup and then I have a letter.bat which makes a copy of a template with my address and my word processor's

copy of a template with my address and my word processor's formatting command and I append to this copy via

formatting command and I append to this copy via echo

echo (char (char 255) 255) %date% %date% >>%1>>%1

Key Stacking Key Stacking

Wouldn't you like to call up TURBO PASCAL in a BATch file which Wouldn't you like to call up TURBO PASCAL in a BATch file which automatically answered

automatically answered Y Y to to the the opening question, opening question, hits hits W,W,

supplies the name of a file that you passed to the BATch file as a supplies the name of a file that you passed to the BATch file as a parameter and then

parameter and then hit E hit E for edit? for edit? Or wouldn't Or wouldn't you like you like to have to have aa key struck automatically in response to the IBM logo and "hit any key struck automatically in response to the IBM logo and "hit any key to

key to continue" at continue" at the start the start of so of so many IBM many IBM programs? programs? BATchBATch files need a command that lets you prestack some convenient files need a command that lets you prestack some convenient strokes in the keyboard buffer.

strokes in the keyboard buffer.

However, there is one crude way of providing keyboard input with However, there is one crude way of providing keyboard input with DOS tools if you can provide all the required input in advance. DOS tools if you can provide all the required input in advance. For example, if you want an "erase *.*" command in a BATch file For example, if you want an "erase *.*" command in a BATch file and would like to avoid having to answer "Are you sure(Y/N)?", and would like to avoid having to answer "Are you sure(Y/N)?", prepare a file, "yes.txt" with the single line "Y" (and including prepare a file, "yes.txt" with the single line "Y" (and including a CR/LF) and place the line

a CR/LF) and place the line erase *.* < yes.txt erase *.* < yes.txt in

in the the BATch BATch file. file. Two Two warnings warnings are are in in order order here. here. Be Be sure sure youyou have a complete set of responses or else your system will hang. have a complete set of responses or else your system will hang.

(14)

In response to the "Are you sure", you must respond Y followed by In response to the "Are you sure", you must respond Y followed by <Enter> so if you left the CR/LF out of yes.txt, "erase" would <Enter> so if you left the CR/LF out of yes.txt, "erase" would patiently wait for the <Enter> and wouldn't take it from the patiently wait for the <Enter> and wouldn't take it from the keyboard since you told it to only take input from yes.txt. keyboard since you told it to only take input from yes.txt.

Second, you cannot redirect input and output to a BATch file as a Second, you cannot redirect input and output to a BATch file as a whole but you can redirect input or output of individual commands whole but you can redirect input or output of individual commands if the

if the commands use commands use standard I/O. standard I/O. Thus, you Thus, you cannot make cannot make a file,a file, 2yes.txt, with two yes lines and a foo.bat with two lines saying 2yes.txt, with two yes lines and a foo.bat with two lines saying "erase *.*"

"erase *.*" and use and use "foo<2yes.txt". "foo<2yes.txt". Foo Foo will still will still insist oninsist on input from you.

input from you.

Summary Summary

BATch commands provide the end user with a powerful set of programming BATch commands provide the end user with a powerful set of programming tools to develop custom and innovative solutions for everyday computer tools to develop custom and innovative solutions for everyday computer needs.

needs.

In future articles, I will describe some programs that can be used to In future articles, I will describe some programs that can be used to enhance the BATch commands and further extend and improve this

enhance the BATch commands and further extend and improve this convenient programming tool.

convenient programming tool.

Some remarks added after the publication of the article: Some remarks added after the publication of the article: 1.

1. The The feature of feature of placing several placing several filespecs with filespecs with wildcards inwildcards in for..in..do is

for..in..do is only available only available in DOS in DOS 3.x. 3.x. DOS 2.x DOS 2.x allows eitherallows either several elements OR one wildcarded specification.

several elements OR one wildcarded specification. 2.

2. You can You can place ONE place ONE parameter after a parameter after a command name command name in ain a for...in...do command if you separate the parameter from the for...in...do command if you separate the parameter from the command by

command by a :. a :. For...in...do interprets the For...in...do interprets the : as : as a connectora connector while DOS interprets it as a separator between the command and while DOS interprets it as a separator between the command and it's parameters.

it's parameters. Whether you Whether you can can pass more pass more than one than one parameterparameter in this manner will depend on how the command parses it's command in this manner will depend on how the command parses it's command line

line parameters. parameters. For For exampleexample

for %%a in (ctrlalt;tb+ emmcahce;36) for %%a in (ctrlalt;tb+ emmcahce;36) would be interpreted as if the two lines would be interpreted as if the two lines

ctrlalt tb+ ctrlalt tb+ emmcache 36 emmcache 36 were issued. were issued. 3.

3. Better than Better than erase *.* erase *.* <yes.txt would be <yes.txt would be to use to use piping andpiping and echo Y|erase *.*

echo Y|erase *.* 4.

4. Despite what Despite what I say I say above, one above, one can redirect can redirect ALL the ALL the output in output in aa BATch file, foo.bat by using

BATch file, foo.bat by using command/c foo >somefile.out command/c foo >somefile.out

However, somefile.out will include all output including the prompt However, somefile.out will include all output including the prompt for any lines issued with echo on such as the first "echo off" for any lines issued with echo on such as the first "echo off" line.

line. This This is is probably probably not not what what you you want!want!

///////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ///////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ////////////////// Remember where you saw this file first : \\\\\\\\\\\\\\\\\\ ////////////////// Remember where you saw this file first : \\\\\\\\\\\\\\\\\\ ITRIS, the International Technology Research Institute ITRIS, the International Technology Research Institute ---\\\\\\\\\

\\\\\\\\\ http://www.fortunhttp://www.fortunecity.com/skyscrapecity.com/skyscraper/data/567/index.er/data/567/index.html html ////////////////// \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\///////////////////////////////////// \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////////

References

Related documents