| 
						 
							
							
							
						 
					 | 
				
			
			 | 
			 | 
			
				@ -1,5 +1,5 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				QSEAWK Language {#awk-lang}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				===============
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				QSEAWK Language                                                      {#awk-lang}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				================================================================================
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				QSEAWK implements the language described in the 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				[The AWK Programming Language][awkbook] with extensions.
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -63,14 +63,24 @@ represents the value of 0.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				A string is enclosed in a pair of double quotes or single quotes.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				A character in a string encosed in the double-quotes can be preceeded with 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				a back-slash to change the meaning of the character.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				A character in a string encosed in the double-quotes, when preceded with 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				a back-slash, changes the meaning.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				\\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				\a
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				\b
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				\uXXXX
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				\UXXXXXXXX
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 - \\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 - \a
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 - \b
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 - \uXXXX
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 - \UXXXXXXXX
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				You can use \\u and \\U in a string to specify a character by unicode if  
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				[Character Type](@ref installation) chosen for building is the wide character
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				type.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    BEGIN { 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        print "\uC720\uB2C8\uCF54\uB4DC \U00007D71\U00004E00\U000078BC"; 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				This program should print 유니코드 統一碼.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				There are no escaping sequences supported for a string enclosed in the single
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				quotes. For that reason, you can't specify the single quote itself within
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -99,7 +109,7 @@ Each language element requires the option in the second column to be on.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				<table>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				<tr><th>Element                    </th><th>Option             </th></tr>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				<tr><td>Comment                    </td><td>                   </td></tr>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				<tr><td>Global variable declaration</td><td>#QSE_AWK_EXPLICIT  </td></tr>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				<tr><td>Global variable declaration</td><td>                   </td></tr>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				<tr><td>Pattern-action block       </td><td>#QSE_AWK_PABLOCK   </td></tr>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				<tr><td>User-defined function      </td><td>                   </td></tr>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				<tr><td>\@include                  </td><td>#QSE_AWK_INCLUDE   </td></tr>
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -120,7 +130,7 @@ A pattern-action block, and a user-defined function can have the following eleme
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				<table>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				<tr><th>Element                    </th><th>Option            </th></tr>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				<tr><td>Local variable declaration</td><td>#QSE_AWK_EXPLICIT  </td></tr>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				<tr><td>Local variable declaration</td><td>                   </td></tr>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				<tr><td>Statement                 </td><td>                   </td></tr>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				<tr><td>getline                   </td><td>#QSE_AWK_RIO       </td></tr>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				<tr><td>print                     </td><td>#QSE_AWK_RIO       </td></tr>
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -218,116 +228,74 @@ BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				The !== operator is a negated form of the === operator.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@subsection awk_ext_vardecl VARIABLE DECLARATION
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				### Variable Declaration ###
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#QSE_AWK_EXPLICIT enables variable declaration. Variables declared are accessed
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				directly bypassing the global named map that stores undeclared variables.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				The keyword @b global introduces a global variable and the keyword @b local 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				introduces local variable. Local variable declaraion in a block must be 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				located before an expression or a statement appears.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				Variables declared are accessed directly bypassing the global named map 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				that stores undeclared variables. The keyword \@global introduces a global
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				variable and the keyword \@local introduces local variable. Local variable
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				declaraion in a block must be located before an expression or a statement 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				appears.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@code
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				global g1, g2; #declares two global variables g1 and g2
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    @global g1, g2; #declares two global variables g1 and g2
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        @local a1, a2, a3; # declares three local variables 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        g1 = 300; a1 = 200;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				             @local a1; # a1 here hides the a1 at the outer scope
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				             @local g1; # g1 here hides the global g1
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				             a1 = 10; g1 = 5;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				             print a1, g1; # it prints 10 and 5
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        print a1, g1; # it prints 200 and 300
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					local a1, a2, a3; # declares three local variables 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					g1 = 300; a1 = 200;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						local a1; # a1 here hides the a1 at the outer scope
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						local g1; # g1 here hides the global g1
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						a1 = 10; g1 = 5;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						print a1, g1; # it prints 10 and 5
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					print a1, g1; # it prints 200 and 300
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				However, turning on #QSE_AWK_EXPLICIT does not disable named variables.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				To disable named variables, you must turn off #QSE_AWK_IMPLICIT.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@subsection awk_ext_include INCLUDE
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				### \@include ###
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				The \@include directive inserts the contents of the object specified in the
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				following string, typically a file name, as if they appeared in the source
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				stream being processed. The directive can only be used at the outmost scope 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				where global variable declarations, @b BEGIN, @b END, and/or pattern-action 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				blocks appear. To use \@include, you must turn on #QSE_AWK_INCLUDE.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				where global variable declarations, *BEGIN*, *END*, and/or pattern-action 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				blocks appear. 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@code
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@include "abc.awk"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				BEGIN { func_in_abc (); }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    @include "abc.awk"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    BEGIN { func_in_abc (); }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				A semicolon is optional after the included file name. The following is the 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				same as the sample above.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@code
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@include "abc.awk";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				BEGIN { func_in_abc(); }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    @include "abc.awk";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    BEGIN { func_in_abc(); }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				If #QSE_AWK_NEWLINE is off, the semicolon is required.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				### Function Call ###
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@subsection awk_ext_funcall FUNCTIONC CALL
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    name(1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				name(1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				if there is no space between 'name' and the left parenthesis, the 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				name is treated as a function name.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				name (1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    name (1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				If there is a space, the name is treated as a function name if the 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				name has been declared as the function or if #QSE_AWK_IMPLICIT is on,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				it may be 'name' concatenated with the expression in the parentheses.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				The following is a valid program.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@code
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@pragma implicit off
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				BEGIN { name (1); }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				function name(a) { print a; }'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     BEGIN { name (1); }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     function name(a) { print a; }'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				However, in this program, the first 'name' becomes a named global variable.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				so the function declaration with 'name' triggers the variable redefinition 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				error.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@pragma implicit on
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				BEGIN { name (1); }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				function name(a) { print a; }'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@subsection awk_ext_print EXTENDED PRINT/PRINTF
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				When #QSE_AWK_TOLERANT is on, print and printf are treated as if
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				they are function calls.  In this mode, they return a negative number
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				on failure and a zero on success and any I/O failure doesn't abort
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				a running program. 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    BEGIN { name (1); }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    function name(a) { print a; }'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@code
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					a = print "hello, world" > "/dev/null";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					print a;	
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					a = print ("hello, world") > "/dev/null";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					print a;	
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				Since print and printf are like function calls, you can use them
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				in any context where a normal expression is allowed. For example,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				printf is used as a conditional expression in an 'if' statement 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				in the sample code below.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@code
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if ((printf "hello, world\n" || "tcp://127.0.0.1:9999") <= -1)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						print "FAILURE";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						print "SUCCESS";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@subsection awk_ext_exprgroup GROUPED EXPRESSION
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				### GROUPED EXPRESSION ###
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				When #QSE_AWK_TOLERANT is on, you can use a grouped expression without
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				the 'in' operator. A grouped expression is a parentheses-enclosed list
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				of expressions separated with a comma. Each expression in the group is
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -344,153 +312,19 @@ BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@subsection awk_ext_rwpipe TWO-WAY PIPE
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				The two-way pipe indicated by @b || is supproted, in addition to the one-way 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				pipe indicated by @b |. Turn on #QSE_AWK_RWPIPE to enable the two-way pipe.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@code
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					print "15" || "sort";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					print "14" || "sort";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					print "13" || "sort";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					print "12" || "sort";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					print "11" || "sort";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					# close the input side of the pipe as 'sort' starts emitting result 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					# once the input is closed.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					close ("sort", "r");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					while (("sort" || getline x) > 0) print "xx:", x; 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				This two-way pipe can create a TCP or UDP connection if the pipe command
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				string is prefixed with one of the followings:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				- tcp:// - establishes a TCP connection to a specified IP address/port.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				- udp:// - establishes a TCP connection to a specified IP address/port.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				- tcpd:// - binds a TCP socket to a specified IP address/port and waits for the first connection.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				- udpd:// - binds a TCP socket to a specified IP address/port and waits for the first sender.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@code
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				BEGIN { 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					# it binds a TCP socket to the IPv6 address :: and the port number 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					# 9999 and waits for the first coming connection. It repeats writing
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					# "hello world" to the first connected peer and reading a line from
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					# it until the session is torn down.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					do { 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						print "hello world" || "tcpd://[::]:9999"; 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (("tcpd://[::]:9999" || getline x) <= 0) break; 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						print x; 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					} 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					while(1);  
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				You can specify TCP or UDP timeouts for connection, accepting, reading, and 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				writing with setioattr (pipe-name, timeout-name, timeout-value). timeout-name 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				should be one of "ctimeout", "atimeout", "rtimeout", and "wtimeout". 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				timeout-value is a number specifying the actual timeout in milliseconds. 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				A negative value indicates no timeout. 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				You can call getioattr (pipe-name, timeout-name) to get the current 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				timeout-value set.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				See the example below.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@code
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				BEGIN { 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					setioattr ("tcp://127.0.0.1:9999", "ctimeout", 3000);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					setioattr ("tcp://127.0.0.1:9999", "rtimeout", 5000);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					print "hello world" || "tcp://127.0.0.1:9999"; 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					"tcp://127.0.0.1:9999" || getline x; 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					print x;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				Here is a more interesting example adopting Michael Sanders'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				AWK web server, modified for QSEAWK.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@code
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				# 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				# Michael Sanders' AWK web server for QSEAWK.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				# Orginal code in http://awk.info/?tools/server
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				# qseawk --tolerant=on --rwpipe=on webserver.awk
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  x        = 1                         # script exits if x < 1 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  port     = 8080                      # port number 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  host     = "tcpd://0.0.0.0:" port    # host string 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  url      = "http://localhost:" port  # server url 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  status   = 200                       # 200 == OK 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  reason   = "OK"                      # server response 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  RS = ORS = "\r\n"                    # header line terminators 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  doc      = Setup()                   # html document 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  len      = length(doc) + length(ORS) # length of document 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  while (x) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     if ($1 == "GET") RunApp(substr($2, 2))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     if (! x) break
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     print "HTTP/1.0", status, reason || host
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     print "Connection: Close"        || host
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     print "Pragma: no-cache"         || host
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     print "Content-length:", len     || host
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     print ORS doc                    || host
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     close(host)     # close client connection 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     host || getline # wait for new client request 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  # server terminated... 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  doc = Bye()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  len = length(doc) + length(ORS)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  print "HTTP/1.0", status, reason || host
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  print "Connection: Close"        || host
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  print "Pragma: no-cache"         || host
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  print "Content-length:", len     || host
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  print ORS doc                    || host
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  close(host)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				function Setup() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  tmp = "<html>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  <head><title>Simple gawk server</title></head>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  <body>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  <p><a href=" url "/xterm>xterm</a>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  <p><a href=" url "/xcalc>xcalc</a>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  <p><a href=" url "/xload>xload</a>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  <p><a href=" url "/exit>terminate script</a>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  </body>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  </html>"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return tmp
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				function Bye() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  tmp = "<html>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  <head><title>Simple gawk server</title></head>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  <body><p>Script Terminated...</body>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  </html>"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return tmp
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				function RunApp(app) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (app == "xterm")  {system("xterm&"); return}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (app == "xcalc" ) {system("xcalc&"); return}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (app == "xload" ) {system("xload&"); return}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (app == "exit")   {x = 0}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@subsection awk_ext_return RETURN
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				### RETURN ###
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				The return statement is valid in pattern-action blocks as well as in functions.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				The execution of a calling block is aborted once the return statement is executed.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@code
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				$ qseawk 'BEGIN { return 20; }' ; echo $?
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				20
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				If #QSE_AWK_MAPTOVAR is on, you can return an arrayed value from a function.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@code
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				function getarray() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					local a;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@local a;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					a["one"] = 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					a["two"] = 2;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					a["three"] = 3;
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -498,14 +332,14 @@ function getarray() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					local x;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@local x;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					x = getarray();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					for (i in x) print i, x[i];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@subsection awk_ext_reset RESET
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				### RESET ###
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				The reset statement resets an array variable back to the initial state.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				After that, the array variable can also be used as a scalar variable again.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				You must have #QSE_AWK_RESET on to be able to be able to use this 
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -520,7 +354,7 @@ BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@subsection awk_ext_abort ABORT
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				### ABORT ###
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				The abort statment is similar to the exit statement except that
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				it skips executing the END block. You must have #QSE_AWK_ABORT on to be
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				able to use this statement.
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -535,10 +369,7 @@ END {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@subsection awk_ext_comment COMMENT
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				You can use the C-style comment as well as the pound comment.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@subsection awk_ext_fnc EXTENDED FUNCTIONS
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				### EXTENDED FUNCTIONS ###
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				index() and match() can accept the third parameter indicating the position 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				where the search begins. A negative value indicates a position from the back.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -557,7 +388,7 @@ BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@subsection awk_ext_fs EXTENDED FS
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				### EXTENDED FS ###
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				If the value for FS begins with a question mark followed by 4 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				additional letters, QSEAWK can split a record with quoted fields 
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -599,84 +430,6 @@ $3: a b c
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@subsection awk_ext_binnum BINARY NUMBER
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				Use 0b to begin a binary number sequence.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@code 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				$ qseawk 'BEGIN { printf ("%b %o %d %x\n", 0b1101, 0b1101, 0b1101, 0b1101); }'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				1101 15 13 d
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@subsection awk_ext_unicode UNICODE ESCAPE SEQUENCE 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				If QSE is compiled for #QSE_CHAR_IS_WCHAR, you can use \\u and \\U in a 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				string to specify a character by unicode.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@code
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				$ qseawk 'BEGIN { print "\uC720\uB2C8\uCF54\uB4DC \U00007D71\U00004E00\U000078BC"; }'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				유니코드 統一碼
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@subsection awk_ext_ioenc I/O ENCODING
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				You can call setioattr() to set the character encoding of a stream resource 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				like a pipe or a file. See qse_findcmgr() for a list of supported encoding names.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				Let's say you run this simple echoing script on a WIN32 platform that has
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				the active code page of 949 and is reachable at the IP address 192.168.2.8.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@code
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				C:\> chcp
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				Active code page: 949
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				C:\> type s.awk
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    sock = "tcpd://0.0.0.0:9999";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    setioattr (sock, "codepage", "cp949"); # this is not needed since the active
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                           # code page is already 949.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    do {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				         if ((sock || getline x) <= 0) break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				         print "PEER: " x;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				         print x || sock;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    while(1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				C:\> qseawk --rwpipe=on -f r.awk
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				PEER: 안녕
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				PEER: ?好!
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				Now you run the following script on a UTF-8 console of a Linux box.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@code
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				$ echo $LANG
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				en_US.UTF-8
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				$ cat  c.awk
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     peer = "tcp://192.168.2.8:9999";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     setioattr (peer, "codepage", "cp949");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     do
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          printf "> ";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          if ((getline x) <= 0) break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          print x || peer;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          if ((peer || getline line) <= -1) break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          print "PEER: " line;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     while (1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				$ qseawk --rwpipe=on -f c.awk
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				> 안녕
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				PEER: 안녕
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				> 你好!
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				PEER: ?好!
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@endcode
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				Note that 你 has been converted to a question mark since the letter is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				not supported by cp949.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				## Built-in I/O ##
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				QSEAWK comes with built-in I/O commands and functions in addition to the 
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -687,11 +440,16 @@ is available only if QSEAWK is set with #QSE_AWK_RIO.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				The *getline* command has multiple forms of usage. It can be used with or 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				without a variable name and can also be associated with a pipe or a file 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				redirection. Basically, it reads a record from an input stream associated 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				and stores it.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				redirection. The default association is the console when no pipe and file 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				redirection is specified. In principle, it reads a record from the associated
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				input stream and updates $0 or a variable with the record. If it managed to
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				perform this successfully, it return 1; it if detected EOF, it returns 0; it
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				return -1 on failure.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				*getline* without a following variable reads a record from an associated
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				input stream and updates $0 with the value. It also updates *NF*, *FNR*, *NR*.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				input stream, updates $0 with the value and increments *FNR*, *NR*. Updating
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				$0 also causes changes in *NF* and fields from $1 to $NF.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				The sample below reads records from the console and prints them. 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    BEGIN {
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -711,19 +469,112 @@ and updates the variable with the value. It updates *FNR* and *NR*, too.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        while (getline line > 0) print line;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				*getline* is associated with the console by default. you can change it
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				to a file or a pipe by using |, ||, <.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				You can change the stream association to a pipe or a file. If *getline* or
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				*getline variable* is followed by a input redirection operator(<) and 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				an expression, the evaluation result of the expression becomes the name of
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				the file to read records from. The file is opened at the first occurrence
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				and can be closed with the *close* function.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				The *getline* command acts like a function in that it returns a value: 1 on 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				success, 0 on EOF, -1 on error. But you can't place an empty parentheses
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				when no variable name is specified nor can you parenthesize the optional 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				variable name. For example, *getline(a)* is different from *getline a* and 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				means the concatenation of the return value of *getline* and the variable *a*.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				         filename = "/etc/passwd";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				         while ((getline line < filename) > 0) print line;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				         close (filename);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				When *getline* or *getline variable* is preceded with an expression and a pipe
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				operator(|), the evaluation result of the expression becomes the name of 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				the external command to execute. The command is executed at the first occurrence
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				and can be terminated with the *close* function. The example below reads
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				the output of the *ls -laF* command and prints it to the console.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        procname = "ls -laF";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        while ((procname | getline line) > 0) print line;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        close (procname);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				The two-way pipe operator(||) can also be used to read records from an 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				external command. There is no visible chanages to the end-user in case
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				of the example above if you switch the operator.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        procname = "ls -laF";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        while ((procname || getline line) > 0) print line;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        close (procname);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				The *getline* command acts like a function in that it returns a value.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				But you can't place an empty parentheses when no variable name is specified 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				nor can you parenthesize the optional variable name. For example, *getline(a)*
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				is different from *getline a* and means the concatenation of the return value 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				of *getline* and the variable *a*. Besides, it is not clear if 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    getline a < b  
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    (getline a) < b 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				or 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    (getline) (a < b)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				For this reason, you are advised to parenthesize *getline* and its related 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				components to avoid confusion whenever necessary. The example reading into 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				the variable *line* can be made clearer with parenthesization.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        while ((getline line) > 0) print line;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				### print ###
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				**TODO**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				### printf ###
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				When #QSE_AWK_TOLERANT is on, print and printf are treated as if
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				they are function calls.  In this mode, they return a negative number
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				on failure and a zero on success and any I/O failure doesn't abort
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				a running program. 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        a = print "hello, world" > "/dev/null";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        print a;	
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        a = print ("hello, world") > "/dev/null";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        print a;	
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				Since print and printf are like function calls, you can use them
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				in any context where a normal expression is allowed. For example,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				printf is used as a conditional expression in an 'if' statement 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				in the sample code below.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if ((printf "hello, world\n" || "tcp://127.0.0.1:9999") <= -1)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            print "FAILURE";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            print "SUCCESS";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				### close (io-name, what) ###
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				The *close* function closes a stream indicated by the name *io-name*. It takes
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				an optional parameter *what* indicating whether input or output should be
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				closed. 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				If *io-name* is a file, it closes the file handle associated;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				If *io-name* is a command, it may kill the running process from the command,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				reclaims other sytstem resources, and closes the pipe handles;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				If *io-name* is a network stream, it tears down connections to the network
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				peer and closes the socket handles.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				The optional paramenter *what* must be one of *r* or *w* when used is useful
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				when *io-name* is a command invoked for the two-way operator. The value of
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				*r* causes the function to close the read-end of the pipe and the value of
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				*w* causes the function to close the write-end of the pipe.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				The function returns 0 on success and -1 on failure.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				### setioattr (io-name, attr-name, attr-value) ###
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				The *setioattr* function changes the I/O attribute of the name *attr-name* to 
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -762,4 +613,181 @@ failure.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        else print "codepage: " codepage;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				### Two-way Pipe ###
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				The two-way pipe is indicated by the two-way pipe operator(||) and QSEAWK
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				must be set with #QSE_AWK_RWPIPE to be able to use the two-way pipe.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				The example redirects the output of *print* to the external *sort* command
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				and reads back the output. 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        print "15" || "sort";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        print "14" || "sort";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        print "13" || "sort";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        print "12" || "sort";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        print "11" || "sort";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        # close the input side of the pipe as 'sort' starts emitting result 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        # once the input is closed.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        close ("sort", "r");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        while (("sort" || getline x) > 0) print x; 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				This two-way pipe can create a TCP or UDP connection if the pipe command
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				string is prefixed with one of the followings:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 - tcp:// - establishes a TCP connection to a specified IP address/port.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 - udp:// - establishes a TCP connection to a specified IP address/port.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 - tcpd:// - binds a TCP socket to a specified IP address/port and waits for the first connection.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 - udpd:// - binds a TCP socket to a specified IP address/port and waits for the first sender.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				See this example.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    BEGIN { 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        # it binds a TCP socket to the IPv6 address :: and the port number 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        # 9999 and waits for the first coming connection. It repeats writing
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        # "hello world" to the first connected peer and reading a line from
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        # it until the session is torn down.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        do { 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            print "hello world" || "tcpd://[::]:9999"; 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (("tcpd://[::]:9999" || getline x) <= 0) break; 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            print x; 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        } 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        while(1);  
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				You can manipulate TCP or UDP timeouts for connection, accepting, reading, and 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				writing with the *setioattr* function and the *getioattr* function.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				See the example below.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    BEGIN { 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        setioattr ("tcp://127.0.0.1:9999", "ctimeout", 3);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        setioattr ("tcp://127.0.0.1:9999", "rtimeout", 5.5);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        print "hello world" || "tcp://127.0.0.1:9999"; 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        "tcp://127.0.0.1:9999" || getline x; 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        print x;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				Here is an interesting example adopting Michael Sanders' AWK web server, 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				modified for QSEAWK.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    # 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    # Michael Sanders' AWK web server for QSEAWK.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    # Orginal code in http://awk.info/?tools/server
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    #
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    # qseawk --tolerant=on --rwpipe=on webserver.awk
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    #
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      x        = 1                         # script exits if x < 1 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      port     = 8080                      # port number 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      host     = "tcpd://0.0.0.0:" port    # host string 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      url      = "http://localhost:" port  # server url 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      status   = 200                       # 200 == OK 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      reason   = "OK"                      # server response 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      RS = ORS = "\r\n"                    # header line terminators 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      doc      = Setup()                   # html document 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      len      = length(doc) + length(ORS) # length of document 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      while (x) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				         if ($1 == "GET") RunApp(substr($2, 2))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				         if (! x) break
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				         print "HTTP/1.0", status, reason || host
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				         print "Connection: Close"        || host
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				         print "Pragma: no-cache"         || host
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				         print "Content-length:", len     || host
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				         print ORS doc                    || host
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				         close(host)     # close client connection 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				         host || getline # wait for new client request 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      # server terminated... 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      doc = Bye()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      len = length(doc) + length(ORS)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      print "HTTP/1.0", status, reason || host
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      print "Connection: Close"        || host
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      print "Pragma: no-cache"         || host
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      print "Content-length:", len     || host
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      print ORS doc                    || host
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      close(host)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    function Setup() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      tmp = "<html>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      <head><title>Simple gawk server</title></head>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      <body>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      <p><a href=" url "/xterm>xterm</a>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      <p><a href=" url "/xcalc>xcalc</a>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      <p><a href=" url "/xload>xload</a>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      <p><a href=" url "/exit>terminate script</a>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      </body>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      </html>"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      return tmp
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    function Bye() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      tmp = "<html>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      <head><title>Simple gawk server</title></head>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      <body><p>Script Terminated...</body>\
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      </html>"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      return tmp
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    function RunApp(app) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if (app == "xterm")  {system("xterm&"); return}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if (app == "xcalc" ) {system("xcalc&"); return}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if (app == "xload" ) {system("xload&"); return}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if (app == "exit")   {x = 0}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				### I/O Character Encoding ###
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				You can change the character encoding encoding of a stream. See qse_findcmgr()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				for a list of supported encoding names.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				Let's say you run this simple echoing script on a WIN32 platform that has
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				the active code page of 949 and is reachable at the IP address 192.168.2.8.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    C:\> chcp
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Active code page: 949
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    C:\> type s.awk
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        sock = "tcpd://0.0.0.0:9999";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        setioattr (sock, "codepage", "cp949"); 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        do {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if ((sock || getline x) <= 0) break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            print "PEER: " x;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            print x || sock;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        while(1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    C:\> qseawk -f r.awk
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    PEER: 안녕
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    PEER: ?好!
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				Now you run the following script on a UTF-8 console of a Linux box.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    $ echo $LANG
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    en_US.UTF-8
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    $ cat  c.awk
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    BEGIN {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        peer = "tcp://192.168.2.8:9999";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        setioattr (peer, "codepage", "cp949");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        do
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            printf "> ";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if ((getline x) <= 0) break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            print x || peer;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if ((peer || getline line) <= -1) break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            print "PEER: " line;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        while (1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    $ qseawk --rwpipe=on -f c.awk
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    > 안녕
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    PEER: 안녕
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    > 你好!
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    PEER: ?好!
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				Note that 你 has been converted to a question mark since the letter is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				not supported by cp949.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				[awkbook]: http://cm.bell-labs.com/cm/cs/awkbook/ 
 | 
			
		
		
	
	
		
			
				
					
					| 
						 
							
							
							
						 
					 | 
				
			
			 | 
			 | 
			
				
 
 |