home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / SAWK.ZIP / SAWKCPS.DOC < prev    next >
Text File  |  1993-04-13  |  37KB  |  1,100 lines

  1.  
  2. Sandeep Dutta
  3. 11 Huntington Circle, Apt # 10
  4. Naperville IL 60540
  5. Compuserve Id [ 71172,2525 ]
  6. Phone No. (708)-717-7928 .
  7.  
  8. I had developed this sometime ago ( I had some time ). Any problems/suggestions
  9. please feel free to contact me. If you like it send $20.00 to the above address
  10. will be sent to charity . AWK is a great tool ....... hope you like it. 
  11.  
  12. ══════════════════════════════════════════════════════════════════════════════
  13.  
  14. Introduction
  15. ────────────
  16.  
  17.          SAWK, is the DOS & OS/2 equivalent for the UNIX utility AWK.
  18.     It  has  almost  all  the features that the standard UNIX awk has
  19.     (some  of the more advanced features like user function defintion
  20.     etc.  have  not  been provided). It has a limited set of built in
  21.     functions (will add more functions in future depending on the use
  22.     of  the tool). The source code is provided as part of the package
  23.     for  those  interested. My thanks to Mr. John Q. Walker , without
  24.     his  'JQFLEX'  &  'JQYACC',  it  would  have  been  impossible to
  25.     develope this utility.
  26.  
  27.          For those unfamiliar with 'awk' here is brief description of
  28.     the  utility  . A very simple way of describing 'awk' would be to
  29.     say , that it scans each line of an input file for user specified
  30.     patterns  and  perfoms  user  specified actions when it is found.
  31.     Patterns  and Actions are discussed in greater detail later on in
  32.     this  documentation.  When  processing  an  input line 'awk' also
  33.     breaks  it  up  into logical fields. The field seperator is white
  34.     space (tab/space) by default but can also be user specified. SAWK
  35.     seperates  these logical fields into the variables $1, $2 ,$3 ...
  36.     and so on, variable NF gives the count of the fields, $0 contains
  37.     the whole input line.
  38.  
  39. ══════════════════════════════════════════════════════════════════════════════
  40.  
  41. Usage
  42. ─────
  43.  
  44.     sawk   [-Fchar]       [-w nnnn]           [-f prog-file]
  45.            ["'pattern { action } '"] file1 [, file2 [, file3 ..] ] ]
  46.  
  47.  
  48.     -Fchar        -  Field seperating character .
  49.  
  50.     -f  prog-file -  Patterns  and  actions can be specified on the
  51.                      command   line   SAWK  can also read it from a
  52.                      file. -f parameter is used to specify the name
  53.                      of the program file.
  54.  
  55.  
  56.     -w nnnnn      -  Can be used to specify  the amount of work area
  57.                      SAWK is  going to use. By default it uses 30720
  58.                      bytes. This option can be used to increase work
  59.                      space when  an "AWKMEM01E..."  error message is
  60.                      issued by SAWK. Or can be used to decrease work
  61.                      space when "AWKALL01E .... "  error  message is
  62.                      issued.
  63.  
  64.                      NOTE . SAWK requires a minimum of 20480 of
  65.                             workspace.
  66.  
  67.  
  68.     pattern       -  Is a regular expression  specified  within '/'.
  69.                      eg. /RE/  will look for the string ' RE' in the
  70.                      input line.  Regular  expressions  supported by
  71.                      SAWK are discussed in a later section.
  72.  
  73.     action        -  Tells  SAWK   what  to  do   when   the pattern
  74.                      associated with it  is found in the input line.
  75.                      The  actions  are  also  described  in  a later
  76.                      section.
  77.                      (Note: IMPORTANT.  When   specifing  the
  78.                             patter-action  in  the  command line it
  79.                             MUST start    with "' and  end with '".
  80.                             This restriction has  been  put down by
  81.                             DOS and  Microsoft  C. Sorry about this
  82.                             deviation from the standard.
  83.                      )
  84.  
  85.     files         -  Files to be used by SAWK  as  input data files.
  86.                      All wildcards allowed by DOS & Os/2 are allowed
  87.                      (i.e.  '*',  '?'  etc. ). A  '-' means  use the
  88.                      stdin for input.
  89.  
  90. ══════════════════════════════════════════════════════════════════════════════
  91.  
  92. Patterns
  93. ────────
  94.  
  95.          The the following regular expressions are suppored by SAWK .
  96.     The regular expressions MUST always be specified within '/'s.
  97.  
  98.     r*        -        Zero or more occurence of r.
  99.  
  100.     r+        -        One or more occurence of  r.
  101.  
  102.     r?        -        Zero or one occurence of  r.
  103.  
  104.     \c        -        Take away special  meaning (if any) of
  105.                        character c.
  106.  
  107.     [..]      -        Matches a  Range of characters. Ranges like
  108.                        a-z are also  allowed. eg. [a-b0-9] matches
  109.                        are lower case character or a digit.
  110.  
  111.     .        -        Matches any character .
  112.  
  113.     $        -        End-of-line.
  114.  
  115.     ^        -        Beginning  of  line.  It  also  means  NOT when
  116.                       given in a range. eg. [^0-9] means NOT a digit.
  117.  
  118.  
  119.          Some  expamples  of Regular expressions and the strings they
  120.     match.
  121.  
  122.     /SAWK/                    -    "SAWK"
  123.  
  124.     /[Ss][Aa][Ww][Kk]/        -     Case insensitive match. Will
  125.                                     match all the following :
  126.                                     "Sawk" , "sAwk" ....... etc.
  127.  
  128.     /^$/                      -     NULL line.
  129.  
  130.     /[0-9]*\.[0-9]+/          -     Decimal number like 0.99 , .99 ,
  131.                                     123.88 ... etc.
  132.  
  133.  
  134. Pattern Ranges :-
  135. ─────────────────
  136.  
  137.     This is best illustrated with an example.
  138.  
  139.     /start/,/end/   { <action> }
  140.  
  141.          The  above  example  will  first  find  the  line containing
  142.     "start" and will perform the "<action>" till it encounters a line
  143.     with and "end", both lines inclusive.
  144.  
  145.          NOTE  -  When SAWK is performing the action specified by the
  146.                   range all other patterns-actions are ignored.
  147.  
  148.          Patters can also be logical expressions like the following .
  149.  
  150.     $3 > 1024 && $1 ~ /C/
  151.  
  152.          NOTE  -   SAWK  uses  what  is  called  a 'greedy' algorithm
  153.                    for pattern  matching,  which   essentially  means
  154.                    it will try to match  the  largest  string  in the
  155.                    input   with  the  pattern, so  be  careful   when
  156.                    specifing   patterns  like  '.*'  which will match
  157.                    an entire line.
  158.  
  159. Special patterns :
  160. ──────────────────
  161.  
  162.          Two special patterns are recognized by SAWK , they are BEGIN
  163.     and  END.  The  actions  associated  with  the  BEGIN pattern are
  164.     executed  'once' before any line is read from the input datafile.
  165.     The actions for END is executed when an end-of-file is sensed for
  166.     the input datafile, or when an 'exit' statemnt is encountered.
  167.  
  168.          If no pattern is specified for an action, then the action is
  169.     performed for all input lines.
  170.  
  171. ══════════════════════════════════════════════════════════════════════════════
  172.  
  173. Actions
  174. ───────
  175.  
  176.          SAWK  actions  are small programs which follow the C syntax.
  177.     An  action  can  consist of an unlimited number of instructions (
  178.     memory restrictions apply) . SAWK allows the use of variables and
  179.     except for the field values represnted by $0, $1 , $2 ...$n , the
  180.     variable  names  MUST  start  with a '_' or letter (upper case or
  181.     lowercase) followed by digits or letters.
  182.  
  183.  
  184.          Multiple  statements  can  be  grouped together with '{' and
  185.     '}'.
  186.  
  187.          If more than one  statement  is  specified  on one line then
  188.     they should be seperated by ';'s.
  189.  
  190.  Literals
  191.  ────────
  192.          Numeric   and  string  literals  are  also  allowed.  String
  193.     literals  must  be  enclosed  withins  quotes,  both "STRING" and
  194.     'STRING'  are  valid  string literals in SAWK. All numeric values
  195.     are internally stored as 'float'.
  196.  
  197.  Arrays.
  198.  ───────
  199.          SAWK  also  allows the use of arrays. eg. sum [expr], 'expr'
  200.     can   be   a  number  or  a  string.  SAWK  maintains  arrays  as
  201.     associations,  thus  there  is  no concept of an array limit ( as
  202.     long as the memory allows) .A special form of the 'for' statement
  203.     can used to lopp through all the elements in an array .
  204.  
  205.                 for ( variable in array )
  206.                         statement
  207.  
  208.          The statment is executed with variable set to each different
  209.     subscript in turn.
  210.  
  211.          To  check  if  a  subscript occurs in an array the following
  212.     expression can be used.
  213.  
  214.                 if ( subscript in array )
  215.                         statement
  216.  
  217.          This  will  check  the  existence  of subscript in the array
  218.     without creating a fresh array element as the following will.
  219.  
  220.                 if ( pop["Africa"] != 0 )
  221.                         ...
  222.  
  223.          SAWK  allows  multi-dimensional array but the array elements
  224.     indexes  are  seperated  using  SUBSPEC  and  atored  as a single
  225.     dimensional array . By default the value of SUBSPEC is '@'.
  226.  
  227.     e.g.
  228.                 pop["Asia","India"] = "very high"
  229.  
  230.     is the same as
  231.  
  232.                 pop["Asia@India"] = "very high"
  233.  
  234.     but  this gives the additional flexibility in accessing the array
  235.     elements.
  236.     e.g.
  237.             {
  238.                 ...
  239.                 country = 'India' ; continent = 'Asia' ;
  240.                 popc = pop[continent,coutry] ;
  241.                 ...
  242.             }
  243.  
  244.     after the previous statements the value of 'popc' will be
  245.     'very high'.
  246.  
  247.  
  248. Assignment statement :
  249. ──────────────────────
  250.  
  251.     Syntax :
  252.  
  253.     var = expr
  254.  
  255.          Assigns  a  the  value  of the 'expr' to 'var', 'var' can be
  256.     user  defined  scalar  or  array  variables.  NOTE  .  Assignment
  257.     expressions  are terminated with a newline, if the 'expr' exceeds
  258.     a line a '\' is required at the end of the previous line.
  259.  
  260.     eg.
  261.  
  262.     var = expr + expr * \
  263.       expr - expr
  264.  
  265. if statement :
  266. ──────────────
  267.  
  268.     Syntax I :
  269.  
  270.     if ( expr ) statement1
  271.     [else statement2]
  272.  
  273.          If  'expr' evaluates to non-zero then 'statement1' is
  274.     executed , else 'statement2' is executed.
  275.  
  276.     Syntax II :
  277.  
  278.     if ( expr in array_name )
  279.         statement
  280.  
  281.         This will check if subscript occurs in the array_name without
  282.     creating a fresh elemnt in array_name.
  283.  
  284. while statement :
  285. ─────────────────
  286.  
  287.     Syntax I:
  288.  
  289.     while ( expr )
  290.         statement
  291.  
  292.          'statement'  is  executed  repeatedly  ,  as  long as 'expr'
  293.     evaluates to a non-zero.
  294.  
  295.     Syntax II :
  296.  
  297.     while ( expr in array_name )
  298.         statement
  299.  
  300.          The  statements  will  be  executed  as  long  as  expr is a
  301.     subscript in array_name.
  302.  
  303. for statement :
  304. ───────────────
  305.  
  306.  
  307.  
  308.     Syntax I :
  309.  
  310.     for ( expr1 ; expr2; expr3 )
  311.         statement
  312.  
  313.          'expr1'  is  evaluated  at  initialization  time, 'expr3' is
  314.     evaluated  after each iteration , 'statement' is executed as long
  315.     as 'expr2' evaluates to a non-zero value.
  316.  
  317.  
  318.     Syntax II :
  319.  
  320.     for ( var in array_name )
  321.         statement
  322.  
  323.          This loop is executed as many times as there are elements in
  324.     the  one  dimensional  array 'array_name'. For each iteration the
  325.     value of the next index of 'array_name' is assigned to 'var'.
  326.  
  327.     eg.
  328.     ...
  329.     ...
  330.     {
  331.         mday["jan"] = 31
  332.         mday["feb"] = 28
  333.         mday["mar"] = 31
  334.         mday["apr"] = 30
  335.  
  336.         for ( m in mday )
  337.         print m , "has" , mday[m], "days"
  338.     }
  339.     ...
  340.     ...
  341.  
  342.          The above program will result in the following output.
  343.  
  344.     jan has 31 days
  345.     feb has 28 days
  346.     mar has 31 days
  347.     apr has 30 days
  348.  
  349.  
  350. Break statement
  351. ───────────────
  352.  
  353.     Syntax :
  354.  
  355.     break
  356.  
  357.          Will  terminate  a  'while'  or 'for' loop, and will cary on
  358.     execution  with  the  statement  following  the  'while' or 'for'
  359.     statement.
  360.  
  361.  
  362. Continue statement
  363. ──────────────────
  364.  
  365.     Syntax :
  366.  
  367.     continue
  368.  
  369.          In  case  of  a  'for'  loop  ,  this  statement  will cause
  370.     execution to continue with the next iteration. In case of 'while'
  371.     loops  this  statement  will  cause  the  'while-condition' to be
  372.     evaluated  and  if non-zero will continue execution at the top of
  373.     the loop.
  374.  
  375. Next statement :
  376. ────────────────
  377.  
  378.     Syntax :
  379.  
  380.     next
  381.  
  382.          Processing   of   remainder  of  the  current  statement  is
  383.     terminated   and   all  pattern-actions  following  are  ignored,
  384.     processing continues normally with the next input line.
  385.  
  386. Exit statement :
  387. ────────────────
  388.  
  389.     Syntax :
  390.  
  391.     exit
  392.  
  393.          Processing  of input line and the SAWK program is terminated
  394.     ,  the  control  is  passed  the  action  associated with the END
  395.     pattern ( if any ).
  396.  
  397.  
  398. Print statement :
  399. ─────────────────
  400.  
  401.     Syntax :
  402.  
  403.     print [ expr [ , expr [ , expr .. ] ] ] [ > expr ]
  404.  
  405.          Each 'expr' is evaluated and printed on the standard output.
  406.     If  no  operands  are  specified  then  the  whole  input line is
  407.     printed.  If  the print statement spans more than a line , then a
  408.     back-slash  ('\') should be placed at the end of each line except
  409.     the  last  line.   The  output  of  any  print  statement  can be
  410.     redirected  to a file,  using '>';  the 'expr' following '>' must
  411.     evaluate  to  a  valid file-name for DOS or OS/2 .
  412.  
  413.     e.g. print "File name  is  ",  \
  414.                 filename  , " Size " , \
  415.                 size
  416.  
  417.                 # output from the following  will  be  writen to file
  418.                 # 'awkfiles'
  419.  
  420.                 print "Filename ", filename > 'awkfiles'
  421.  
  422. Printf statement :
  423. ──────────────────
  424.  
  425.     Syntax :
  426.  
  427.     printf format-control [, expr [, expr ... ] ] [> expr]
  428.  
  429.  
  430.          The   'expr's   are  printed  in  the  format  specified  by
  431.     'format-control'.  The  formatting  is done exactly as the printf
  432.     function  in  C. If the printf statement spans more than one line
  433.     then  a back-slash it required at the end of each line except the
  434.     last  line.  The output of any printf statement can be redirected
  435.     to a file, using '>' ;the 'expr' following '>' must evaluate to a
  436.     valid  file-name  for  DOS  or OS/2
  437.  
  438.     e.g. printf "Filename = %s , Size in kilobytes = %dK", \
  439.                 filename , size/1024
  440.  
  441. Comments:
  442. ─────────
  443.  
  444.     Syntax :
  445.  
  446.     # comments .
  447.  
  448.          When an '#' is encountered, all characters following it upto
  449.     a newline are treated as comments.
  450.  
  451. ══════════════════════════════════════════════════════════════════════════════
  452.  
  453. Expressions & Operators :
  454. ─────────────────────────
  455.  
  456.     Operators in SAWK have the same meaning as in C.
  457.  
  458.     Arithmetic operators :
  459.  
  460.     +        Addition
  461.     -        Subtraction
  462.     /        Division
  463.     *        Multiplication
  464.     %        Modulus
  465.     space    Concatenation
  466.  
  467.     Bit-wise operators :
  468.  
  469.     &        Bit-wise AND
  470.     |        Bit-wise OR
  471.     ^        Exclusive OR
  472.  
  473.     Unary Operators :
  474.  
  475.     ++       Increment
  476.     --       Decrement
  477.  
  478.     Logical Operators :
  479.  
  480.     !        Not.
  481.     ~        Match.
  482.     ==       Equal to.
  483.     !=       Not equal to.
  484.     !~       Not match.
  485.     >        Greater than.
  486.     <        Less than.
  487.     >=       Greater Than Equal
  488.     <=       Less Than equal.
  489.     &&       Logical AND.
  490.     ||       Logical OR.
  491.  
  492.     Assignment Operators :
  493.  
  494.     =        Equal to.
  495.     +=       Plus equal.
  496.     -=       Minus Equal.
  497.     *=       Times equal.
  498.     /=       Divide equal.
  499.     %=       Modulus Equal.
  500.     &=       Bit-wise AND equal.
  501.     |=       Bit-wise OR  equal.
  502.  
  503.          Expressions follow the same syntax as C. Unlike the standard
  504.     'awk',  SAWK  allows  the  use of Logical operators in assignment
  505.     statements.  (i.e.  a  = 100 > 10 , is a valid statement in SAWK,
  506.     this will assign the value of 1. to the variable 'a'.)
  507.  
  508.          Recursive assignments are also allowed in SAWK. ( i.e. a = b
  509.     = c is valid).
  510.  
  511. ══════════════════════════════════════════════════════════════════════════════
  512.  
  513. Built-in Variables :
  514. ────────────────────
  515.  
  516.          The following variables are predefined in SAWK, their values
  517.     can be changed by the user.
  518.  
  519.     FS          -   Field seperator character, this can be changed by
  520.                     the -F  option in the command line, by default it
  521.                     is  white space i.e.  tab &  space.  If more that
  522.                     one  character  is  given as field seperater SAWK
  523.                     seperates fields with an OR logic.
  524.                     e.g. BEGIN { FS=":| \t" }
  525.  
  526.  
  527.                     if input line is -->
  528.                     'abcd:awk|good tool'
  529.  
  530.                     the fields will be
  531.                     $0 --> 'abcd:awk|good tool'
  532.                     $1 --> 'abcd'
  533.                     $2 --> 'awk'
  534.                     $3 --> 'good'
  535.                     $4 --> 'tool'
  536.  
  537.  
  538.     FILENAME    -   Name  of  the  current  file  being  processed or
  539.                     "CON" if '-' was specified as input.
  540.  
  541.     NF          -   Number of fields in the current input  line being
  542.                     processed.
  543.  
  544.     NR          -   Number of the record being processed.
  545.  
  546.     FNR         -   Number of the record in the current file being
  547.                     processed.
  548.  
  549.     OFMT        -   The format used to print numbers, by default this
  550.                     is '%f'.
  551.  
  552.     OFS         -   Output field  seperator,  this  is  the character
  553.                     that SAWK  prints when it   encounters a COMMA in
  554.                     the print statement, by default this is space (' ').
  555.  
  556.     RS          -   Input   record   seperator.  If  more  than  one
  557.                     character is given as record seperator then SAWK
  558.                     uses or logic to seperate records like FS. If RS
  559.                     is assigned to NULL (i.e. RS = '' ) then  multi-
  560.                     line records can be processed  and  a blank line
  561.                     will be treated as the record seperator.
  562.                     NOTE . Maximum record length can be 2048 bytes.
  563.  
  564.     ORS         -   Output   record  seperator,  this  character  is
  565.                     printed by the 'print' statement after each line
  566.                     is written.
  567.  
  568.     RSTART      -   See Built-in function match.
  569.  
  570.     RLENGTH     -   See Built-in function match.
  571.  
  572.  
  573. ══════════════════════════════════════════════════════════════════════════════
  574.  
  575. Built-in functions :
  576. ────────────────────
  577.  
  578.          The following built in functions are supported by SAWK.
  579.  
  580. length ([exp])       -   Length   in   characters   of   the  string
  581.                          represented  by 'exp'. If no parameters are
  582.                          given then the length of the  input line is
  583.                          returned.
  584.  
  585. split  (s,a,[,d])    -   Splits  the  string  s  into  elements  of a
  586.                          single  dimensional  array 'a' starting with
  587.                          1. It uses  the  first  character  of string
  588.                         'd' as the delimiting  character or uses 'FS'
  589.                          if  'd'  is  not   specified.  Return  value
  590.                          is the number of fields split.
  591.  
  592.                          e.g.  split  ( "06/26/92", date,"/")  will
  593.                          result in the following assignement with a
  594.                          return value of 3.
  595.  
  596.                          date[1] = 6
  597.                          date[2] = 26
  598.                          date[3] = 92
  599.  
  600. substr (s, m, [,n])  -   Returns a sub-string of 's', starting from
  601.                          the 'm'th character and 'n' characters in
  602.                          length, if 'n' is not specified then till
  603.                          the end of the string 's'.
  604.  
  605. index (s1,s2)        -   Returns the starting position of string 's2'
  606.                          in string 's1'.
  607.  
  608. int (expr)            -  Returns the integer part of 'expr'.
  609.  
  610. cos (expr)            -  Returns the cosine of 'expr'.
  611.  
  612. log (expr)            -  Returns log of 'expr'.
  613.  
  614. expr (expr)           -  Returns exponent of 'expr'.
  615.  
  616. sin (expr)            -  Returns sine of 'expr'.
  617.  
  618. getline()             -  Reads  the  next  line  from  the input data
  619.                          file, updates $0 , $1 , $2 .. etc. Returns 0
  620.                          if end-of-file has been reached else returns
  621.                          1.
  622.  
  623. system(cmd)           -  Allows "operating system commands" to be
  624.                          executed from the SAWK program. Returns the
  625.                          exit code returned from the operating
  626.                          system.
  627.  
  628. sub(r,t[,s])          -  This function will  return a string with the
  629.                          first  occurence  of  the regular expression
  630.                          'r' substituted by 't' in the string 's', if
  631.                          's' is not given the entire line is used.
  632.  
  633.                          e.g.
  634.                sub (/[Aa][Ww][Kk]/,"sawk", "awk is a powerful tool").
  635.                will return the string "sawk is a powerful tool"
  636.  
  637. gsub(r,t[,s])          - This works the same as 'sub' expect that it
  638.                          subtitues   all   occurences   of   regular
  639.                          expression 'r'  by  't' in string 's', uses
  640.                          entire line if 's' not given.
  641.                          e.g.
  642.             gsub (/[0-9]/,"n","abcd1234abcd") --> "abcdnnnnabcd"
  643.  
  644. match (s,r)            - Returns   position   in  string  's'  where
  645.                          regular expression 'r' occurs, returns 0 if
  646.                          'r' is  not  in 's'. The built-in variables
  647.                          RSTART & RLENGTH  are  set  to  the start &
  648.                          length respectively of the matched string.
  649.  
  650. ══════════════════════════════════════════════════════════════════════════════
  651.  
  652. Some small examples :
  653. ─────────────────────
  654.  
  655.          a. Find out files greater than 10K in size.
  656.  
  657.          C:\>dir    |   sawk   "'$3   >   10240   {   print   }'"   -
  658.     ──────────────────────────────────────────────────────────────────────────────
  659.  
  660.          b. Print only the last field .
  661.  
  662.          C:\>dir   |   sawk   "'   /AWK/   {   print  $(NF)  }  '"  -
  663.     ──────────────────────────────────────────────────────────────────────────────
  664.  
  665.          c. Printing filename & size in KB, for files having "AWK" in
  666.             their names.
  667.  
  668.          C:\>dir | sawk -f fn.prg -
  669.  
  670.          fn.prg :-
  671.  
  672.          /AWK/   { filename = $1 "." $2
  673.                    printf "Filename = %13s , Size = %3dK \n", \
  674.                           filename , $3/1024
  675.                  }
  676.  
  677. ──────────────────────────────────────────────────────────────────────────────
  678.  
  679.          d.  Find average file size for file with "AWK" in their file
  680.              name.
  681.  
  682.          C:\>dir | sawk -f avg.prg -
  683.  
  684.        avg.prg :-
  685.  
  686.        /AWK/    {
  687.             fsize += $3 ; nofiles++
  688.             }
  689.        END        {
  690.             print "Average = " , fsize / nofiles
  691.             }
  692. ──────────────────────────────────────────────────────────────────────────────
  693.  
  694.          e.  Find  the  word "awk" (case insensitive) in a document &
  695.     print the word previous to it & following it , print '^' if it is
  696.     the  first  word  &  print '$' if it is the last word, also print
  697.     name of document at the beginning.
  698.  
  699.        C:\>sawk -f awkwrd.prg sawk.doc
  700.  
  701.        awkwrd.prg :-
  702.  
  703.        BEGIN   {
  704.             # print name of document
  705.             print FILENAME
  706.             }
  707.         /^$/    {    next    } # skip thru blank lines
  708.         /[Aa][Ww][Kk]/ # case insensitive
  709.             {
  710.             # Note :- i starts from 1 , since $0 contains
  711.             #      the entire line.
  712.             for ( i = 1 ; i <= NF ; i++ )
  713.             {
  714.                 if ( $i ~ /[Aa][Ww][Kk]/ )
  715.                 {
  716.                 # if it is the first field
  717.                 if ( i == 1 )
  718.                     printf "^ %s ", $i
  719.                 else
  720.                     printf "%s %s", $(i-1) , $i
  721.  
  722.                 # if it is the last field
  723.                 if ( i== NF )
  724.                     print "$"
  725.                 else
  726.                     print $(i+1)
  727.  
  728.                 } # end of if
  729.             } # end of for
  730.             }
  731. ──────────────────────────────────────────────────────────────────────────────
  732.  
  733.          f.  Generating  ordinals for an OS/2 linker definition file.
  734.              Example provided by Graham Perks (IBM UK).
  735.  
  736.        awk program file DEF.AWK
  737.  
  738.  
  739.            # AWK program to add ordinals to .DEF files.
  740.  
  741.            # Initialisation, these keep track of the current ordinal number.
  742.            BEGIN { imp_ord = 0
  743.                    exp_ord = 0
  744.                  }
  745.  
  746.            # Skip comments (lines starting with semi-colons).
  747.            /^;.*/    {
  748.                     print ; next
  749.                      }
  750.            # Skip blanks
  751.            /^$/ {
  752.                     print ; next
  753.                 }
  754.  
  755.            /IMPORTS/       { imp_ord = 1
  756.                              exp_ord = 0
  757.                              print $0
  758.                              next
  759.                             }
  760.            /EXPORTS/       { exp_ord = 1
  761.                              imp_ord = 0
  762.                              print $0
  763.                              next
  764.                            }
  765.  
  766.            # If we have ords, write out line with them, otherwise just 
  767.            # copy line.
  768.            {
  769.          if (exp_ord > 0)
  770.                {
  771.                 printf "   %s @%.0f\n", $1, exp_ord
  772.                 exp_ord++
  773.          }
  774.              else
  775.              print $0
  776.        }
  777.         
  778.  
  779.     INPUT DATAFILE :- (RA.DEF)
  780.  
  781.     NAME    RA WINDOWAPI
  782.  
  783. DESCRIPTION 'XYZ Program'
  784. STUB    'os2stub.exe'
  785. CODE    MOVEABLE
  786. DATA    MOVEABLE MULTIPLE
  787.  
  788. HEAPSIZE   1000
  789. STACKSIZE  53000
  790.  
  791. PROTMODE
  792.  
  793. IMPORTS
  794. ;        PROGRESS.PROGRESSDLGPROC
  795.         SECA.SECA
  796.         SECB.SECB
  797.         SECC.SECC
  798.         SECD.SECD
  799.  
  800. ; Exports
  801. EXPORTS
  802.    FRED
  803.    BOB
  804.    ANGELA
  805.  
  806.     SAWK OUTPUT :- (RAA.DEF)
  807.  
  808. NAME    RA WINDOWAPI 
  809.  
  810. DESCRIPTION 'XYZ Program'
  811. STUB    'os2stub.exe' 
  812. CODE    MOVEABLE 
  813. DATA    MOVEABLE MULTIPLE 
  814.  
  815. HEAPSIZE   1000 
  816. STACKSIZE  53000 
  817.  
  818. PROTMODE 
  819.  
  820. IMPORTS 
  821. ;        PROGRESS.PROGRESSDLGPROC 
  822.    SECA.SECA
  823.    SECB.SECB
  824.    SECC.SECC
  825.    SECD.SECD
  826.  
  827. ; Exports 
  828. EXPORTS 
  829.    FRED @1
  830.    BOB @2
  831.    ANGELA @3
  832.  
  833.  
  834. ══════════════════════════════════════════════════════════════════════════════
  835. Difference Between SAWK & UNIX SYSTEM V AWK.
  836. ────────────────────────────────────────────
  837.  
  838.          1. User function definitions not allowed in SAWK.
  839.  
  840.          2. Predifined variables ARGC, ARGV & SUBSEP not available in
  841.             SAWK.
  842.  
  843.          3. Pattern grouping using '()' not allowed in SAWK.
  844.  
  845.          4.  Using  '|' to specify OR whithin a regular expression is
  846.              not allowed.
  847.  
  848.          5. Using regular expressions for FS & RS not allowed.
  849.  
  850.          6. Built-in function 'sprintf' not yet implemented.
  851.  
  852.          7. Multiple index arrays are not allowed in SAWK.
  853.  
  854.          8.  NO  DEFAULT  action is assumed in SAWK (unlike UNIX AWK,
  855.              which assumes a default action of 'print').
  856.  
  857.          9 . When SYSTEM V awk encounters a '&&' or '||' operation it
  858.              evaluates  from  the  left, in case of '&&' operation it
  859.              stops after at the first zero expression the expressions
  860.              following them  are  not  evluated,  similarly  for '||'
  861.              operation SYSTEM V  awk  evaluates to the first non-zero
  862.              expression expressions  to  the  right are not evlauted.
  863.              But SAWK   when    processing   a  '&&'/'||'   statement
  864.              evaluates  all   the   expressions   and   then does the
  865.              operation on them.
  866.  
  867.              e.g.  if ( (s=0) && (d=1))
  868.              { ... }
  869.  
  870.              After executing in SYSTEM V awk variable 'd' maynot have
  871.              the  value  '1'.  But   after executing in SAWK 'd' WILL
  872.              have the value '1'.
  873.  
  874.          10.  Enclosing  pattern-action  pair  whithin  braces is not
  875.               allowed. eg.
  876.  
  877.               { /ERR/ {
  878.                        ...
  879.                        ...
  880.                      }
  881.              }
  882.  
  883.              Is  valid  in  some UNIX awks. Invalid for SAWK, SAWK
  884.              maynot generate a syntax error but will behave
  885.              erratically.
  886.  
  887.         11.  In SYSTEM V awk built-in functions when called without
  888.              parameters  need not have the empty () after them e.g.
  889.  
  890.                 {
  891.                    ...
  892.                    x = length
  893.                    ...
  894.                 }
  895.  
  896.              Is valid in SYSTEM V awk & will assign the length of the
  897.              current line to x. But in SAWK the empty () is required.
  898.              e.g.
  899.  
  900.                 {
  901.                   ...
  902.                   x = length()
  903.                   ...
  904.                 }
  905.  
  906.  
  907. ══════════════════════════════════════════════════════════════════════════════
  908.  
  909. Files in the package :
  910. ──────────────────────
  911.  
  912.     File name        Description    
  913.     ---------        -----------
  914.     awk.y            Input File to YACC contains grammer for SAWK
  915.     ytab.c           Output file of YACC.
  916.     ytab.h           Output file of YACC containing #defines
  917.     awk.lex          Input for LEX contains token definitions.
  918.     lexyy.c          Output file of LEX.
  919.     awk.h            Header file contains 'extern's & structs.
  920.     awk.c            Source,contains parser support functions &
  921.                      initializing functions.
  922.  
  923.     awke.c           Source contains routines to do the file i/o and
  924.                      splitting into fields & the opcode interpreter.
  925.  
  926.     awka.c           Source, contains  the  execution routines. Also
  927.                      contains most of the internal functio code.
  928.  
  929.     regexp.c         Source, has all routines for regular expression
  930.                      search & compile etc.
  931.  
  932.     sawk.doc         Documentation file.
  933.     sawkos2.exe      Executable file for OS/2.
  934.     sawk.exe         Executable file for DOS.
  935.     awk.             Make file for DOS.
  936.     awk.mak          NMAKE file for both DOS & OS/2
  937.     awk.lnk          LINK response file for OS/2 (SAWKOS2.EXE)
  938.     awklnk.dos       LINK response file for DOS (SAWK.EXE)
  939.     sawkflow.lst     Output of C-HIER. Function calling sequence.
  940.     sawkused.lst     Output of C-USED. Function definitions.i.e.
  941.                      where each function has been defined.
  942.  
  943. ══════════════════════════════════════════════════════════════════════════════
  944.  
  945. Modifications Summary :
  946. ───────────────────────
  947.  
  948. 07/14/92 -  Version 1.60 .
  949.  
  950.         The following Modifications were made.
  951.  
  952.          1.  The '$' variable was not being cleared after processing,
  953.              the old values were retained, this has been fixed.
  954.  
  955.          2   The  compare  functions  '>', '<' , '<=' & '>='returned
  956.              invalid  return  codes  if  any  of  the  operands were
  957.              non-numeric,  now  they  return  false  if  any  of the
  958.              operands are non-numeric.
  959.  
  960.          3.  Memory  required previuosly was 335K this was reduced to
  961.              147K,  by  eliminating  static  arrays.  The size of the
  962.              work space was  increased from 10K to 30K  since all the
  963.              allocations will now be done from here.
  964.  
  965.         4.   Datastructure initializing routines were added to make
  966.              the program OS/2 compatible.
  967.  
  968.          5.  New option  -w added for command line to give user some
  969.              flexibility for memory.
  970.  
  971.         6.   OS/2 support added.
  972.  
  973. 07/17/92 - Version 1.63
  974.  
  975.          1. Range   patterns   (see   Patters  Section)  have  been
  976.             implemented.
  977.  
  978.          2. Internal variables FNR & RS have been added.
  979.  
  980.          3. Internal  functions  'system',  'sub' , 'gsub' & 'match'
  981.             have been added.
  982.  
  983.          4. Small bug fix. Fixed nesting of functions problem.
  984.  
  985. 07/24/92 - Version 1.65
  986.  
  987.          1. Documentaion updates.
  988.  
  989.          2.   Error   message   issued   when   '\n'  when  multiline
  990.               'print','printf'  or  assignment  statements  are given
  991.               without '\' at the end of line.
  992.  
  993.          3.  Fixed  bug  for temp file deletion under OS/2. Temporary
  994.              file  '$$temp$$.$$$'  was  not being deleted under OS/2,
  995.              problem now fixed.
  996.  
  997. 07/30/92  - Version 1.67
  998.  
  999.          1.  Bug-fix.  Blank  lines did not match the pattern /^$/ if
  1000.              they   had   only  a '\n' but matched  blank lines which
  1001.              had atleast one   space  or  tab in them.  This  bug has
  1002.              been  fixed. This  also  solves  another  potential  bug
  1003.              where-in  for  OS/2  the  program might terminate with a
  1004.              SEGMENTAION VIOLATION when  processing  lines  with only
  1005.              '\n' in them.
  1006.  
  1007.  
  1008.          2.  'print' statement prints '0.000000' when a 'print $0' is
  1009.              given  for  lines  having  only '\n'. This was caused
  1010.              because the function used to check if a field is
  1011.              numeric returned TRUE for strings ehich have only '\0'.
  1012.              This has been fixed.
  1013.  
  1014.  
  1015. 07/31/92   - Version 1.68
  1016.  
  1017.          1. printf statement could recognize only a few of the format
  1018.             type  . Included   all   format   types   supported under
  1019.             ANSI-C. i.e 'd', 'i', 'u', 'o', 'x', 'X', 'f', 'e', 'E',
  1020.             'g', 'G', 'c', & 's'.
  1021.  
  1022. 08/03/92  -  Version  1.70
  1023.  
  1024.          1.  Bit  operations 'and' (&) and 'or' (|) were not working.
  1025.              Error  in  the  opcode  interpreter  (exec_inst), it was
  1026.              pointing to wrong function. Problem fixed.
  1027.  
  1028.          2.  I/O  Redirection  ('>')  feature  added  for  'print'  &
  1029.              'printf'  statements.  For  more  details  see 'print' &
  1030.              'printf' statements  above.
  1031.  
  1032. 08/10/92  -  Version  1.71
  1033.  
  1034.          1.  MAX_BUFFER increased to 2048 (2 KiloBytes) & MAX_TOK_LEN
  1035.              increased to the same size as MAX_BUFFER since one line
  1036.              can one field.
  1037.  
  1038.          2.   Also   made  modifications  in  routine  'get_line'  to
  1039.               accomodate   multi-line   records.  This can be done by
  1040.               assigning  RS to ''  (null), this will match only blank
  1041.               lines ,   so   in  effect   the  blank   lines   become
  1042.               delimiters.   By   assigning  FS to '\n' it is possible
  1043.               to have     each     line     as     a    field.
  1044.  
  1045. 08/14/92  -   Version 1.74
  1046.  
  1047.          1.   Modified the grammar to accept ';' as a statement ender
  1048.               if multiple statements are specified on one line.
  1049.  
  1050.          2.   Fixed 'printf' bug. Printf statement did not allow only
  1051.               a string to be printed .i.e. printf 'hello world\n' was
  1052.               not allowed. This bug has been fixed.
  1053.  
  1054.          3.   Changed grammer (awk.y) to allow ';' after 'continue' &
  1055.               'next' & 'break' statements.
  1056.  
  1057. 08/18/92  -   Version 1.76
  1058.  
  1059.          1.   After  introducing  ';'  the grammar did not accept any
  1060.               print statement that did not end with a ';' or  newline
  1061.               so  the  statements  like  '{print}'  generated 'syntax
  1062.               error. The  grammar  has  been  changed to take care of
  1063.               this.
  1064.  
  1065.          2.   If a '$' field  was  referenced and if NF was less than
  1066.               it . e.g.  $3  was  referenced  with  NF  <  3  then it
  1067.               generated an  index mismatch error. This has been fixed.
  1068.  
  1069. 08/19/92  -   Version 1.79
  1070.  
  1071.          1.   Added the special  expression 'subscript in array'.This
  1072.               can  be  used  in  'if' statements & 'while' statements
  1073.               only.
  1074.  
  1075. 09/20/92  -   Version 2.02
  1076.  
  1077.          1.   Added multidimensional array support .
  1078.  
  1079.          2.   Negative  number  problem  resolved.  When  a  negative
  1080.               number  was  generated  as   a   result  of an arimetic
  1081.               operation  it  could   not  be  used  for  any  furthur
  1082.               computation. This  was because the  routine  'isnumstr'
  1083.               did not accept leading signs. This has been modified.
  1084.  
  1085.          3.   The  character '.' was  internally being treated like a
  1086.               numeric field. This was again a problem with 'isnumstr'
  1087.               it has been fixed.
  1088.  
  1089. 12/16/92  -   Version 2.04
  1090.  
  1091.          1.   Regular expression related problems removed. Problem I
  1092.               '-' could not speficied within range specs ([..]). Bug
  1093.               found in routine 'compile'. Problem II match failed if
  1094.               compiled string larger than source string even  though
  1095.               rest of compiled string was not required.
  1096.  
  1097.          2.   Printed '0.000000' if $0 had only one numeric field.
  1098.  
  1099. ==============================================================================
  1100.