home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 11 Util
/
11-Util.zip
/
SAWK.ZIP
/
SAWKCPS.DOC
< prev
next >
Wrap
Text File
|
1993-04-13
|
37KB
|
1,100 lines
Sandeep Dutta
11 Huntington Circle, Apt # 10
Naperville IL 60540
Compuserve Id [ 71172,2525 ]
Phone No. (708)-717-7928 .
I had developed this sometime ago ( I had some time ). Any problems/suggestions
please feel free to contact me. If you like it send $20.00 to the above address
will be sent to charity . AWK is a great tool ....... hope you like it.
══════════════════════════════════════════════════════════════════════════════
Introduction
────────────
SAWK, is the DOS & OS/2 equivalent for the UNIX utility AWK.
It has almost all the features that the standard UNIX awk has
(some of the more advanced features like user function defintion
etc. have not been provided). It has a limited set of built in
functions (will add more functions in future depending on the use
of the tool). The source code is provided as part of the package
for those interested. My thanks to Mr. John Q. Walker , without
his 'JQFLEX' & 'JQYACC', it would have been impossible to
develope this utility.
For those unfamiliar with 'awk' here is brief description of
the utility . A very simple way of describing 'awk' would be to
say , that it scans each line of an input file for user specified
patterns and perfoms user specified actions when it is found.
Patterns and Actions are discussed in greater detail later on in
this documentation. When processing an input line 'awk' also
breaks it up into logical fields. The field seperator is white
space (tab/space) by default but can also be user specified. SAWK
seperates these logical fields into the variables $1, $2 ,$3 ...
and so on, variable NF gives the count of the fields, $0 contains
the whole input line.
══════════════════════════════════════════════════════════════════════════════
Usage
─────
sawk [-Fchar] [-w nnnn] [-f prog-file]
["'pattern { action } '"] file1 [, file2 [, file3 ..] ] ]
-Fchar - Field seperating character .
-f prog-file - Patterns and actions can be specified on the
command line SAWK can also read it from a
file. -f parameter is used to specify the name
of the program file.
-w nnnnn - Can be used to specify the amount of work area
SAWK is going to use. By default it uses 30720
bytes. This option can be used to increase work
space when an "AWKMEM01E..." error message is
issued by SAWK. Or can be used to decrease work
space when "AWKALL01E .... " error message is
issued.
NOTE . SAWK requires a minimum of 20480 of
workspace.
pattern - Is a regular expression specified within '/'.
eg. /RE/ will look for the string ' RE' in the
input line. Regular expressions supported by
SAWK are discussed in a later section.
action - Tells SAWK what to do when the pattern
associated with it is found in the input line.
The actions are also described in a later
section.
(Note: IMPORTANT. When specifing the
patter-action in the command line it
MUST start with "' and end with '".
This restriction has been put down by
DOS and Microsoft C. Sorry about this
deviation from the standard.
)
files - Files to be used by SAWK as input data files.
All wildcards allowed by DOS & Os/2 are allowed
(i.e. '*', '?' etc. ). A '-' means use the
stdin for input.
══════════════════════════════════════════════════════════════════════════════
Patterns
────────
The the following regular expressions are suppored by SAWK .
The regular expressions MUST always be specified within '/'s.
r* - Zero or more occurence of r.
r+ - One or more occurence of r.
r? - Zero or one occurence of r.
\c - Take away special meaning (if any) of
character c.
[..] - Matches a Range of characters. Ranges like
a-z are also allowed. eg. [a-b0-9] matches
are lower case character or a digit.
. - Matches any character .
$ - End-of-line.
^ - Beginning of line. It also means NOT when
given in a range. eg. [^0-9] means NOT a digit.
Some expamples of Regular expressions and the strings they
match.
/SAWK/ - "SAWK"
/[Ss][Aa][Ww][Kk]/ - Case insensitive match. Will
match all the following :
"Sawk" , "sAwk" ....... etc.
/^$/ - NULL line.
/[0-9]*\.[0-9]+/ - Decimal number like 0.99 , .99 ,
123.88 ... etc.
Pattern Ranges :-
─────────────────
This is best illustrated with an example.
/start/,/end/ { <action> }
The above example will first find the line containing
"start" and will perform the "<action>" till it encounters a line
with and "end", both lines inclusive.
NOTE - When SAWK is performing the action specified by the
range all other patterns-actions are ignored.
Patters can also be logical expressions like the following .
$3 > 1024 && $1 ~ /C/
NOTE - SAWK uses what is called a 'greedy' algorithm
for pattern matching, which essentially means
it will try to match the largest string in the
input with the pattern, so be careful when
specifing patterns like '.*' which will match
an entire line.
Special patterns :
──────────────────
Two special patterns are recognized by SAWK , they are BEGIN
and END. The actions associated with the BEGIN pattern are
executed 'once' before any line is read from the input datafile.
The actions for END is executed when an end-of-file is sensed for
the input datafile, or when an 'exit' statemnt is encountered.
If no pattern is specified for an action, then the action is
performed for all input lines.
══════════════════════════════════════════════════════════════════════════════
Actions
───────
SAWK actions are small programs which follow the C syntax.
An action can consist of an unlimited number of instructions (
memory restrictions apply) . SAWK allows the use of variables and
except for the field values represnted by $0, $1 , $2 ...$n , the
variable names MUST start with a '_' or letter (upper case or
lowercase) followed by digits or letters.
Multiple statements can be grouped together with '{' and
'}'.
If more than one statement is specified on one line then
they should be seperated by ';'s.
Literals
────────
Numeric and string literals are also allowed. String
literals must be enclosed withins quotes, both "STRING" and
'STRING' are valid string literals in SAWK. All numeric values
are internally stored as 'float'.
Arrays.
───────
SAWK also allows the use of arrays. eg. sum [expr], 'expr'
can be a number or a string. SAWK maintains arrays as
associations, thus there is no concept of an array limit ( as
long as the memory allows) .A special form of the 'for' statement
can used to lopp through all the elements in an array .
for ( variable in array )
statement
The statment is executed with variable set to each different
subscript in turn.
To check if a subscript occurs in an array the following
expression can be used.
if ( subscript in array )
statement
This will check the existence of subscript in the array
without creating a fresh array element as the following will.
if ( pop["Africa"] != 0 )
...
SAWK allows multi-dimensional array but the array elements
indexes are seperated using SUBSPEC and atored as a single
dimensional array . By default the value of SUBSPEC is '@'.
e.g.
pop["Asia","India"] = "very high"
is the same as
pop["Asia@India"] = "very high"
but this gives the additional flexibility in accessing the array
elements.
e.g.
{
...
country = 'India' ; continent = 'Asia' ;
popc = pop[continent,coutry] ;
...
}
after the previous statements the value of 'popc' will be
'very high'.
Assignment statement :
──────────────────────
Syntax :
var = expr
Assigns a the value of the 'expr' to 'var', 'var' can be
user defined scalar or array variables. NOTE . Assignment
expressions are terminated with a newline, if the 'expr' exceeds
a line a '\' is required at the end of the previous line.
eg.
var = expr + expr * \
expr - expr
if statement :
──────────────
Syntax I :
if ( expr ) statement1
[else statement2]
If 'expr' evaluates to non-zero then 'statement1' is
executed , else 'statement2' is executed.
Syntax II :
if ( expr in array_name )
statement
This will check if subscript occurs in the array_name without
creating a fresh elemnt in array_name.
while statement :
─────────────────
Syntax I:
while ( expr )
statement
'statement' is executed repeatedly , as long as 'expr'
evaluates to a non-zero.
Syntax II :
while ( expr in array_name )
statement
The statements will be executed as long as expr is a
subscript in array_name.
for statement :
───────────────
Syntax I :
for ( expr1 ; expr2; expr3 )
statement
'expr1' is evaluated at initialization time, 'expr3' is
evaluated after each iteration , 'statement' is executed as long
as 'expr2' evaluates to a non-zero value.
Syntax II :
for ( var in array_name )
statement
This loop is executed as many times as there are elements in
the one dimensional array 'array_name'. For each iteration the
value of the next index of 'array_name' is assigned to 'var'.
eg.
...
...
{
mday["jan"] = 31
mday["feb"] = 28
mday["mar"] = 31
mday["apr"] = 30
for ( m in mday )
print m , "has" , mday[m], "days"
}
...
...
The above program will result in the following output.
jan has 31 days
feb has 28 days
mar has 31 days
apr has 30 days
Break statement
───────────────
Syntax :
break
Will terminate a 'while' or 'for' loop, and will cary on
execution with the statement following the 'while' or 'for'
statement.
Continue statement
──────────────────
Syntax :
continue
In case of a 'for' loop , this statement will cause
execution to continue with the next iteration. In case of 'while'
loops this statement will cause the 'while-condition' to be
evaluated and if non-zero will continue execution at the top of
the loop.
Next statement :
────────────────
Syntax :
next
Processing of remainder of the current statement is
terminated and all pattern-actions following are ignored,
processing continues normally with the next input line.
Exit statement :
────────────────
Syntax :
exit
Processing of input line and the SAWK program is terminated
, the control is passed the action associated with the END
pattern ( if any ).
Print statement :
─────────────────
Syntax :
print [ expr [ , expr [ , expr .. ] ] ] [ > expr ]
Each 'expr' is evaluated and printed on the standard output.
If no operands are specified then the whole input line is
printed. If the print statement spans more than a line , then a
back-slash ('\') should be placed at the end of each line except
the last line. The output of any print statement can be
redirected to a file, using '>'; the 'expr' following '>' must
evaluate to a valid file-name for DOS or OS/2 .
e.g. print "File name is ", \
filename , " Size " , \
size
# output from the following will be writen to file
# 'awkfiles'
print "Filename ", filename > 'awkfiles'
Printf statement :
──────────────────
Syntax :
printf format-control [, expr [, expr ... ] ] [> expr]
The 'expr's are printed in the format specified by
'format-control'. The formatting is done exactly as the printf
function in C. If the printf statement spans more than one line
then a back-slash it required at the end of each line except the
last line. The output of any printf statement can be redirected
to a file, using '>' ;the 'expr' following '>' must evaluate to a
valid file-name for DOS or OS/2
e.g. printf "Filename = %s , Size in kilobytes = %dK", \
filename , size/1024
Comments:
─────────
Syntax :
# comments .
When an '#' is encountered, all characters following it upto
a newline are treated as comments.
══════════════════════════════════════════════════════════════════════════════
Expressions & Operators :
─────────────────────────
Operators in SAWK have the same meaning as in C.
Arithmetic operators :
+ Addition
- Subtraction
/ Division
* Multiplication
% Modulus
space Concatenation
Bit-wise operators :
& Bit-wise AND
| Bit-wise OR
^ Exclusive OR
Unary Operators :
++ Increment
-- Decrement
Logical Operators :
! Not.
~ Match.
== Equal to.
!= Not equal to.
!~ Not match.
> Greater than.
< Less than.
>= Greater Than Equal
<= Less Than equal.
&& Logical AND.
|| Logical OR.
Assignment Operators :
= Equal to.
+= Plus equal.
-= Minus Equal.
*= Times equal.
/= Divide equal.
%= Modulus Equal.
&= Bit-wise AND equal.
|= Bit-wise OR equal.
Expressions follow the same syntax as C. Unlike the standard
'awk', SAWK allows the use of Logical operators in assignment
statements. (i.e. a = 100 > 10 , is a valid statement in SAWK,
this will assign the value of 1. to the variable 'a'.)
Recursive assignments are also allowed in SAWK. ( i.e. a = b
= c is valid).
══════════════════════════════════════════════════════════════════════════════
Built-in Variables :
────────────────────
The following variables are predefined in SAWK, their values
can be changed by the user.
FS - Field seperator character, this can be changed by
the -F option in the command line, by default it
is white space i.e. tab & space. If more that
one character is given as field seperater SAWK
seperates fields with an OR logic.
e.g. BEGIN { FS=":| \t" }
if input line is -->
'abcd:awk|good tool'
the fields will be
$0 --> 'abcd:awk|good tool'
$1 --> 'abcd'
$2 --> 'awk'
$3 --> 'good'
$4 --> 'tool'
FILENAME - Name of the current file being processed or
"CON" if '-' was specified as input.
NF - Number of fields in the current input line being
processed.
NR - Number of the record being processed.
FNR - Number of the record in the current file being
processed.
OFMT - The format used to print numbers, by default this
is '%f'.
OFS - Output field seperator, this is the character
that SAWK prints when it encounters a COMMA in
the print statement, by default this is space (' ').
RS - Input record seperator. If more than one
character is given as record seperator then SAWK
uses or logic to seperate records like FS. If RS
is assigned to NULL (i.e. RS = '' ) then multi-
line records can be processed and a blank line
will be treated as the record seperator.
NOTE . Maximum record length can be 2048 bytes.
ORS - Output record seperator, this character is
printed by the 'print' statement after each line
is written.
RSTART - See Built-in function match.
RLENGTH - See Built-in function match.
══════════════════════════════════════════════════════════════════════════════
Built-in functions :
────────────────────
The following built in functions are supported by SAWK.
length ([exp]) - Length in characters of the string
represented by 'exp'. If no parameters are
given then the length of the input line is
returned.
split (s,a,[,d]) - Splits the string s into elements of a
single dimensional array 'a' starting with
1. It uses the first character of string
'd' as the delimiting character or uses 'FS'
if 'd' is not specified. Return value
is the number of fields split.
e.g. split ( "06/26/92", date,"/") will
result in the following assignement with a
return value of 3.
date[1] = 6
date[2] = 26
date[3] = 92
substr (s, m, [,n]) - Returns a sub-string of 's', starting from
the 'm'th character and 'n' characters in
length, if 'n' is not specified then till
the end of the string 's'.
index (s1,s2) - Returns the starting position of string 's2'
in string 's1'.
int (expr) - Returns the integer part of 'expr'.
cos (expr) - Returns the cosine of 'expr'.
log (expr) - Returns log of 'expr'.
expr (expr) - Returns exponent of 'expr'.
sin (expr) - Returns sine of 'expr'.
getline() - Reads the next line from the input data
file, updates $0 , $1 , $2 .. etc. Returns 0
if end-of-file has been reached else returns
1.
system(cmd) - Allows "operating system commands" to be
executed from the SAWK program. Returns the
exit code returned from the operating
system.
sub(r,t[,s]) - This function will return a string with the
first occurence of the regular expression
'r' substituted by 't' in the string 's', if
's' is not given the entire line is used.
e.g.
sub (/[Aa][Ww][Kk]/,"sawk", "awk is a powerful tool").
will return the string "sawk is a powerful tool"
gsub(r,t[,s]) - This works the same as 'sub' expect that it
subtitues all occurences of regular
expression 'r' by 't' in string 's', uses
entire line if 's' not given.
e.g.
gsub (/[0-9]/,"n","abcd1234abcd") --> "abcdnnnnabcd"
match (s,r) - Returns position in string 's' where
regular expression 'r' occurs, returns 0 if
'r' is not in 's'. The built-in variables
RSTART & RLENGTH are set to the start &
length respectively of the matched string.
══════════════════════════════════════════════════════════════════════════════
Some small examples :
─────────────────────
a. Find out files greater than 10K in size.
C:\>dir | sawk "'$3 > 10240 { print }'" -
──────────────────────────────────────────────────────────────────────────────
b. Print only the last field .
C:\>dir | sawk "' /AWK/ { print $(NF) } '" -
──────────────────────────────────────────────────────────────────────────────
c. Printing filename & size in KB, for files having "AWK" in
their names.
C:\>dir | sawk -f fn.prg -
fn.prg :-
/AWK/ { filename = $1 "." $2
printf "Filename = %13s , Size = %3dK \n", \
filename , $3/1024
}
──────────────────────────────────────────────────────────────────────────────
d. Find average file size for file with "AWK" in their file
name.
C:\>dir | sawk -f avg.prg -
avg.prg :-
/AWK/ {
fsize += $3 ; nofiles++
}
END {
print "Average = " , fsize / nofiles
}
──────────────────────────────────────────────────────────────────────────────
e. Find the word "awk" (case insensitive) in a document &
print the word previous to it & following it , print '^' if it is
the first word & print '$' if it is the last word, also print
name of document at the beginning.
C:\>sawk -f awkwrd.prg sawk.doc
awkwrd.prg :-
BEGIN {
# print name of document
print FILENAME
}
/^$/ { next } # skip thru blank lines
/[Aa][Ww][Kk]/ # case insensitive
{
# Note :- i starts from 1 , since $0 contains
# the entire line.
for ( i = 1 ; i <= NF ; i++ )
{
if ( $i ~ /[Aa][Ww][Kk]/ )
{
# if it is the first field
if ( i == 1 )
printf "^ %s ", $i
else
printf "%s %s", $(i-1) , $i
# if it is the last field
if ( i== NF )
print "$"
else
print $(i+1)
} # end of if
} # end of for
}
──────────────────────────────────────────────────────────────────────────────
f. Generating ordinals for an OS/2 linker definition file.
Example provided by Graham Perks (IBM UK).
awk program file DEF.AWK
# AWK program to add ordinals to .DEF files.
# Initialisation, these keep track of the current ordinal number.
BEGIN { imp_ord = 0
exp_ord = 0
}
# Skip comments (lines starting with semi-colons).
/^;.*/ {
print ; next
}
# Skip blanks
/^$/ {
print ; next
}
/IMPORTS/ { imp_ord = 1
exp_ord = 0
print $0
next
}
/EXPORTS/ { exp_ord = 1
imp_ord = 0
print $0
next
}
# If we have ords, write out line with them, otherwise just
# copy line.
{
if (exp_ord > 0)
{
printf " %s @%.0f\n", $1, exp_ord
exp_ord++
}
else
print $0
}
INPUT DATAFILE :- (RA.DEF)
NAME RA WINDOWAPI
DESCRIPTION 'XYZ Program'
STUB 'os2stub.exe'
CODE MOVEABLE
DATA MOVEABLE MULTIPLE
HEAPSIZE 1000
STACKSIZE 53000
PROTMODE
IMPORTS
; PROGRESS.PROGRESSDLGPROC
SECA.SECA
SECB.SECB
SECC.SECC
SECD.SECD
; Exports
EXPORTS
FRED
BOB
ANGELA
SAWK OUTPUT :- (RAA.DEF)
NAME RA WINDOWAPI
DESCRIPTION 'XYZ Program'
STUB 'os2stub.exe'
CODE MOVEABLE
DATA MOVEABLE MULTIPLE
HEAPSIZE 1000
STACKSIZE 53000
PROTMODE
IMPORTS
; PROGRESS.PROGRESSDLGPROC
SECA.SECA
SECB.SECB
SECC.SECC
SECD.SECD
; Exports
EXPORTS
FRED @1
BOB @2
ANGELA @3
══════════════════════════════════════════════════════════════════════════════
Difference Between SAWK & UNIX SYSTEM V AWK.
────────────────────────────────────────────
1. User function definitions not allowed in SAWK.
2. Predifined variables ARGC, ARGV & SUBSEP not available in
SAWK.
3. Pattern grouping using '()' not allowed in SAWK.
4. Using '|' to specify OR whithin a regular expression is
not allowed.
5. Using regular expressions for FS & RS not allowed.
6. Built-in function 'sprintf' not yet implemented.
7. Multiple index arrays are not allowed in SAWK.
8. NO DEFAULT action is assumed in SAWK (unlike UNIX AWK,
which assumes a default action of 'print').
9 . When SYSTEM V awk encounters a '&&' or '||' operation it
evaluates from the left, in case of '&&' operation it
stops after at the first zero expression the expressions
following them are not evluated, similarly for '||'
operation SYSTEM V awk evaluates to the first non-zero
expression expressions to the right are not evlauted.
But SAWK when processing a '&&'/'||' statement
evaluates all the expressions and then does the
operation on them.
e.g. if ( (s=0) && (d=1))
{ ... }
After executing in SYSTEM V awk variable 'd' maynot have
the value '1'. But after executing in SAWK 'd' WILL
have the value '1'.
10. Enclosing pattern-action pair whithin braces is not
allowed. eg.
{ /ERR/ {
...
...
}
}
Is valid in some UNIX awks. Invalid for SAWK, SAWK
maynot generate a syntax error but will behave
erratically.
11. In SYSTEM V awk built-in functions when called without
parameters need not have the empty () after them e.g.
{
...
x = length
...
}
Is valid in SYSTEM V awk & will assign the length of the
current line to x. But in SAWK the empty () is required.
e.g.
{
...
x = length()
...
}
══════════════════════════════════════════════════════════════════════════════
Files in the package :
──────────────────────
File name Description
--------- -----------
awk.y Input File to YACC contains grammer for SAWK
ytab.c Output file of YACC.
ytab.h Output file of YACC containing #defines
awk.lex Input for LEX contains token definitions.
lexyy.c Output file of LEX.
awk.h Header file contains 'extern's & structs.
awk.c Source,contains parser support functions &
initializing functions.
awke.c Source contains routines to do the file i/o and
splitting into fields & the opcode interpreter.
awka.c Source, contains the execution routines. Also
contains most of the internal functio code.
regexp.c Source, has all routines for regular expression
search & compile etc.
sawk.doc Documentation file.
sawkos2.exe Executable file for OS/2.
sawk.exe Executable file for DOS.
awk. Make file for DOS.
awk.mak NMAKE file for both DOS & OS/2
awk.lnk LINK response file for OS/2 (SAWKOS2.EXE)
awklnk.dos LINK response file for DOS (SAWK.EXE)
sawkflow.lst Output of C-HIER. Function calling sequence.
sawkused.lst Output of C-USED. Function definitions.i.e.
where each function has been defined.
══════════════════════════════════════════════════════════════════════════════
Modifications Summary :
───────────────────────
07/14/92 - Version 1.60 .
The following Modifications were made.
1. The '$' variable was not being cleared after processing,
the old values were retained, this has been fixed.
2 The compare functions '>', '<' , '<=' & '>='returned
invalid return codes if any of the operands were
non-numeric, now they return false if any of the
operands are non-numeric.
3. Memory required previuosly was 335K this was reduced to
147K, by eliminating static arrays. The size of the
work space was increased from 10K to 30K since all the
allocations will now be done from here.
4. Datastructure initializing routines were added to make
the program OS/2 compatible.
5. New option -w added for command line to give user some
flexibility for memory.
6. OS/2 support added.
07/17/92 - Version 1.63
1. Range patterns (see Patters Section) have been
implemented.
2. Internal variables FNR & RS have been added.
3. Internal functions 'system', 'sub' , 'gsub' & 'match'
have been added.
4. Small bug fix. Fixed nesting of functions problem.
07/24/92 - Version 1.65
1. Documentaion updates.
2. Error message issued when '\n' when multiline
'print','printf' or assignment statements are given
without '\' at the end of line.
3. Fixed bug for temp file deletion under OS/2. Temporary
file '$$temp$$.$$$' was not being deleted under OS/2,
problem now fixed.
07/30/92 - Version 1.67
1. Bug-fix. Blank lines did not match the pattern /^$/ if
they had only a '\n' but matched blank lines which
had atleast one space or tab in them. This bug has
been fixed. This also solves another potential bug
where-in for OS/2 the program might terminate with a
SEGMENTAION VIOLATION when processing lines with only
'\n' in them.
2. 'print' statement prints '0.000000' when a 'print $0' is
given for lines having only '\n'. This was caused
because the function used to check if a field is
numeric returned TRUE for strings ehich have only '\0'.
This has been fixed.
07/31/92 - Version 1.68
1. printf statement could recognize only a few of the format
type . Included all format types supported under
ANSI-C. i.e 'd', 'i', 'u', 'o', 'x', 'X', 'f', 'e', 'E',
'g', 'G', 'c', & 's'.
08/03/92 - Version 1.70
1. Bit operations 'and' (&) and 'or' (|) were not working.
Error in the opcode interpreter (exec_inst), it was
pointing to wrong function. Problem fixed.
2. I/O Redirection ('>') feature added for 'print' &
'printf' statements. For more details see 'print' &
'printf' statements above.
08/10/92 - Version 1.71
1. MAX_BUFFER increased to 2048 (2 KiloBytes) & MAX_TOK_LEN
increased to the same size as MAX_BUFFER since one line
can one field.
2. Also made modifications in routine 'get_line' to
accomodate multi-line records. This can be done by
assigning RS to '' (null), this will match only blank
lines , so in effect the blank lines become
delimiters. By assigning FS to '\n' it is possible
to have each line as a field.
08/14/92 - Version 1.74
1. Modified the grammar to accept ';' as a statement ender
if multiple statements are specified on one line.
2. Fixed 'printf' bug. Printf statement did not allow only
a string to be printed .i.e. printf 'hello world\n' was
not allowed. This bug has been fixed.
3. Changed grammer (awk.y) to allow ';' after 'continue' &
'next' & 'break' statements.
08/18/92 - Version 1.76
1. After introducing ';' the grammar did not accept any
print statement that did not end with a ';' or newline
so the statements like '{print}' generated 'syntax
error. The grammar has been changed to take care of
this.
2. If a '$' field was referenced and if NF was less than
it . e.g. $3 was referenced with NF < 3 then it
generated an index mismatch error. This has been fixed.
08/19/92 - Version 1.79
1. Added the special expression 'subscript in array'.This
can be used in 'if' statements & 'while' statements
only.
09/20/92 - Version 2.02
1. Added multidimensional array support .
2. Negative number problem resolved. When a negative
number was generated as a result of an arimetic
operation it could not be used for any furthur
computation. This was because the routine 'isnumstr'
did not accept leading signs. This has been modified.
3. The character '.' was internally being treated like a
numeric field. This was again a problem with 'isnumstr'
it has been fixed.
12/16/92 - Version 2.04
1. Regular expression related problems removed. Problem I
'-' could not speficied within range specs ([..]). Bug
found in routine 'compile'. Problem II match failed if
compiled string larger than source string even though
rest of compiled string was not required.
2. Printed '0.000000' if $0 had only one numeric field.
==============================================================================