. . . .

Perl, Awk, Etc

 

updated:2018.05.11

Prev   Next   Site Map   Home  
Text Size
Please reload page for style change

Perl Translate Strings


#!perl
# File:     xlateEloStrings.pl
# ....................... notes .........................................
# STDIN is opened on input from strings.rc to support debugging under PerlIde,
# which doesn't afford a means of establishing input arguments. Under Eclipse
# this could be a debug argument by redirect, i.e. < strings.rc or other. From
# the command prompt, the file name is the first argument (without redirect),
# e.g getStrings.pl strings.rc.
#
# The value string can contain quoted components and does not have to begin or
# end on a quotation mark, for example:
# COMPANY " Touchscreen Control Panel"
# "Customizes touch settings and aligns your " COMPANY " touchmonitor."
# "EloToolTray"  COMPANY  (this is a frabricated example-- there are none of
# this type).
# This allows the script to support concatenated strings and CARDINALs of
# quoted strings, which are defined in some header file, which we don't have
# to see.
# Any amount of space, including blank lines may appear between the IDS_ name
# and its value but the value must occur on one line.
#
# Invocation Arguments:
# This can be invoked stand-alone, piped, or debug with (e.g. Eclipse-EPIC) or
# without (e.g. PerlIde) invocation argument control. The data output is
# STDOUT, which can be piped to another program, redirected to a data file, or
# observed in a debugger's console window. In order to support debuggers
# without argument control, if there are no arguments, the file strings.rc is
# used. This is required in order to support argument-less debuggers, but it
# precludes piped input, which is unlikely to be very useful anyway. The
# typical use cases are:
# Command line without piping: getEloStrings.pl EloStrings_XXX.rc > stringsXXX.
# Command line with piping: getEloStrings.pl EloStrings_XXX.rc | text processing program
# Debug without arguments: strings.rc is the input, console window the output.
# Debug with arguments: inputFile  > output file
# Debugger without arguments but specific input file, edit $defaultInputFile = "strings.rc";
# Typical procedure:
# getEloStrings.pl EloStrings_FRE.rc > stringsFre
# xlateEloStrings.pl stringsFre EloStrings_ENG.rc > EloStrings_FRE.rc
# or
# getEloStrings.pl EloStrings_FRE.rc | xlateEloStrings.pl EloStrings_ENG.rc > EloStrings_FRE.rc
#............................................................................
use  strict;
use warnings;

print STDERR "Begin xlateEloStrings.pl\n";

if( !defined( $ARGV[0] ))
{ $ARGV[0] = "stringsFre"; }
if( !defined( $ARGV[1] ))
{ $ARGV[1] = "EloStrings_ENG.rc"; }
if( !defined( $ARGV[2] ))
{ $ARGV[2] = "frenchRc"; }

#..............................................................................
# Debugger without invocation argument control might want these
# $ARGV[0] = "strings.rc";
# open STDOUT, ">stringList";
# ............................................................................

print STDERR "Merge " . $ARGV[0] . " and " . $ARGV[1] . " into " . $ARGV[2] . "\n";

# Build association list from line pairs in string file
my( %eloStrings, $key, $value );

sub showAssociationList
{
  while( ($key, $value) = each %eloStrings )
  { print $key , " = " , $value , "\n"; }
}

open ASSOCFILE, "<" . $ARGV[0];
while( <ASSOCFILE> )
{
    chomp;
    chomp( my $value = <ASSOCFILE> );
    $eloStrings{ $_ } = $value;
}
#&showAssociationList();
close ASSOCFILE;

open RCIN, "<" . $ARGV[1];
open RCOUT, ">" . $ARGV[2];

while( <RCIN> )
{
  if( /(IDS_\S+)(.*)/)
  {
    print RCOUT $1 . "\n";      # IDS_ cardinal
    $_ = $2;            # Get possible value. Could be just whitespace
# Remove leading and trailing space of the presumed value in $_ (default). If
# the result is empty or only space then read the next line of the file and
# repeat until a non-empty, non-space string results. This is the value.
# Note that $1 in the substitution expression refers to the first match
# memory, (.+), i.e. replace $_ with itself minus leading and trailing
# space.
    until( length( s/^\s*(.+)\s*$/$1/ ) != 0 && m/[^\s]+/ )
    {
        $_ = <RCIN>;
    }
    my $xstring = $eloStrings{ $1 };
    if( defined( $xstring )) {
      print RCOUT $xstring . "\n";
    }
    else {
      print RCOUT $_ . "  // << Missing translation\n";
    }
  }
  else
  {
    print RCOUT;
  }
}

close RCOUT;
close RCIN;

print STDERR "End xlateEloStrings.pl\n";


AWK SHOW INSTALLED PROGRAM DETAILS


# installed.awk
# Purpose:   Used in Windows to filter output from reg query uninstall keys to 
# find installed programs. DisplayName, Publisher, and InstallLocation value 
# data are displayed for each program that meets the filter criteria. Any 
# apparent program with a blank display name and all programs with "update" in 
# their DisplayName are ignored. 
#
# Non-existent Publisher and InstallLocation values are shown as "Unspecified" 
# but as "Blank" if the key exists but has no assigned data. If "filter" is 
# defined on the the command line and it appears in any of the three keys then 
# that program is displayed. Most often, the filter is the name of a program, 
# which will be matched by the DisplayName. However, if it is the name of a 
# Publisher, then all of that Publisher's installed programs will be displayed. 
# 
# Filter may be a path, for example "d:\wpgm" to find all programs installed 
# under this directory. In the case of path with \, the filter value must 
# substitute /, for example D:/Wpgm instead of D:\Wpgm. In the BEGIN action, 
# all / characters in filter are replaced by "\\\\". 
#
# Filter is case-insensitive and can be a fragment of whatever is being 
# searched for. It actually is a regular expression (which is why a single \ 
# character must be expressed by four of them) but there is little purpose in 
# trying to take advantage of this with some clever pattern.
#
# installed.bat provides a similar facility but can only show the DisplayName 
# because it simply invokes grep for every key it sees under the Uninstall key 
# and doesn't have any context capability.
#
# ......................... Invocation ..................................  
# This may be part of a direct command line, e.g:
# reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" /s | awk -f installed.awk
# reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" /s | awk -v filter=windows -f installed.awk
# reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" /s | awk -v filter=microsoft -f installed.awk
# However, it is intended for routine use through the installedx.bat, which 
# is essentially a super-charged version of installed.bat. It is:
# if "%1" == "" (
# reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" /s | awk -f %~dp0installed.awk
# echo ------------------------------
# reg query "HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" /s 2>nul | awk -f %~dp0installed.awk
# ) else (
# reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" /s | awk -v filter=%1 -f %~dp0installed.awk
# echo ------------------------------
# reg query "HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" /s 2>nul | awk -v filter=%1 -f %~dp0installed.awk
# )
# ........................... Environment ---------------------------------
# This uses environment variable conwidth 
# ................................. Notes .................................
#                                KEY DATA ORDER
# Every program is represented by the key:
# HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\someName
# Since reg query shows this first, it represents the end of the preceding and
# beginning of the next. Under this, the DisplayName is usually, but not always
# last value and Publisher and InstallLocation values may not exist (many are
# blank but this is not the same thing). Therefore, we can't simply collect the
# Publisher and InstallLocation while waiting for the DisplayName or trigger
# analysis when all three have been collected. Instead, we collect them until
# the next HKEY_LOCAL_MACHINE or end and then process whatever we have picked
# up.
#                           DATA WITH SPACES
# Every data line comprises space keyname REG_something space value. All of 
# these values may contain spaces, causing them to be parsed into fields, so we
# can't simply take $3 as the value. A loop could be used to concantentate 
# everything from $3 to $NF but this would unconditionally compress multiple 
# spaces and it is simpler to delete everything up to $3 in $0. In nearly all 
# cases, the value type is REG_SZ but one WinDvd had REG_EXPAND_SZ, so the 
# search expression uses REG_anything.
# ---------------------------------------------------------------------------

function initVals()
{
    vals[0] = "" ; vals[1] = "Unspecified" ; vals[2] = "Unspecified"
}

function showkey()
{
# gawk for windows blows up on return statement (in any context) so we have to use
# some stupid code like this.
    if( vals[0] == "" ) ; # Discard undefined display name cases
    #else if( filter == 0 && vals[0] ~ "update" ) ; # Skip updates if no filter.
    else if( vals[0] ~ "update" ) ; # Skip all items with update in their name.
    else if( filter != 0 && vals[0] !~ filter && vals[1] !~ filter && vals[2] !~ filter ) ;
    else
    {
    printf( "Name=%-32s", vals[0])
    len = length( vals[0])
    if( len < 32 ) len = 32
    if( len > 32 || len + length( vals[1]) > conwidth )
    {
        pos = length( vals[1]) > conwidth - 32 ? 16 : 37 
        printf( "\n%*s", pos, "" )
    }
    else
        pos = 32
    printf( " | Publisher=%s", vals[1] )
    pos += length( vals[1]) + 33
    if( length( vals[2]) + pos  > conwidth )
    {
        pos = length( vals[2]) > conwidth - 50 ? 16 : 37 
        printf( "\n%*s", pos, "" )
    }
    printf( " | Location=%s\n", vals[2] )
    }
}

BEGIN { 
    print args
    IGNORECASE=1
    "conwin 1" | getline conwidth
    if( filter != 0 ) 
    sub( "/", "\\\\", filter )
    initVals()
}

# ------------ For Each Line -------------
{   
    if( $0 ~ "HKEY_LOCAL_MACHINE" ) 
    { 
    showkey()
    initVals()
    next 
    }
    if( $1 == "DisplayName" ) idx = 0 
    else if( $1 == "Publisher" ) idx = 1 
    else if( $1 == "InstallLocation" ) idx = 2
    else next

    sub( /.*REG_[^ \t]+[ \t]+/, "" ) # Essentially convert $0 to $3 + all the rest.
    vals[ idx ] = length($0) == 0 ? "Blank" : $0
}

# If the last one matches, show it now, since it isn't followed by an HKEY.
END { showkey() } 


Awk Field Calculation


# east.awk
# Use: awk script. Invoke by awk -f east.awk < eastSwipes
# Purpose: Calculate angle error of stroke analysis methods applied to multiple
# east strokes. 
# The fields of eastSwipes are:
# 1=number of failures, 2=min angle, 3=max angle, 4=avg pos angle, 5=cnt, 6=avg neg angle, 
# 7=cnt, 8=method number, 9=method description.
# The angle error is calculated by adding the positive and negative average 
# angle errors times their respective count and dividing by the total (of non-
# failures). This prevents fails from skewing the actual errors. Fails are 
# worse than minor angle errors but better than major ones but there is no 
# precise formula for computing their effect on the quality of the method. 
#
# An average angle of 0 represents no error. A positive error is calculated by a 
# unique formula for each quadrant.
# For positive angles 0 to 180 error is angle. e.g. 15 -> 15, 165 -> 165.
# For negative angles 0 to -180 error is - angle. e.g. -15 -> 15, -165 -> 165.
#
# North and south traces automatically provide a count of outliers because
# positive angles are outliers for south and negative angles are outliers for
# north and the count of angles in the positive and negative averages is in
# the record. For east and west, we can tell only whether or not a method
# produced at least one or two outliers by checking minimum and maximum angles
# against -90 and 90.
# For east, if the minimum angle < -90 count one outlier. If the maximum is 
# > 90 count one outlier.
{ 
    err = 0
    outliers = 0
    if( $5 + $7 != 0 ) # Cheap way to skip comments
    {
    if( $5 != 0 ) # Any postive angles?
        err += $4 * $5
    if( $7 != 0 ) # Any negative angles?
        err -= $6 * $7
    if( $2 < -90 )
        ++outliers
    if( $3 > 90 )
        ++outliers
    printf( "Method %2d error=%4d uncomputables=%2d outliers=%2d\n", 
        $8, 100 * err / ( $5 + $7 ), $1, outliers  )
    }
}

For my differential capacitive pointing device, I had built into my demo/development program a facility to log the results of many algorithms applied to every flick made by a test person. I could have added the means for the program to open and read its own log to calculate statistics but it was faster to do this with AWK scripts. This one is specialized for calculating eastward flick statistics.




Prev   Next   Site Map   Home   Top   Valid HTML   Valid CSS