Author: jisom
Date: Sun Feb 18 23:40:12 2007
New Revision: 17053

Added:
   trunk/tools/util/pgegrep   (contents, props changed)
Modified:
   trunk/MANIFEST
   trunk/src/pmc/resizablestringarray.pmc
   trunk/t/pmc/resizablestringarray.t

Log:
Add splice to resizablestringarray.pmc
Add tests for it, change some tests to actually use resizablestringarray
instead of resizeablepmcarray, and comment out the call for one that
resizablestringarray can't do
Add pgegrep to tools/util(I don't know the best place)
MANIFEST housekeeping



Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST      (original)
+++ trunk/MANIFEST      Sun Feb 18 23:40:12 2007
@@ -2950,6 +2950,7 @@
 tools/docs/write_docs.pl                                    [devel]
 tools/util/ncidef2pasm.pl                                   []
 tools/util/perltidy.conf                                    []
+tools/util/pgegrep                                          []
 tools/util/pirtidy.pl                                       []
 tools/util/smartlinks.pl                                    []
 tools/util/smokeserv-README.pod                             []

Modified: trunk/src/pmc/resizablestringarray.pmc
==============================================================================
--- trunk/src/pmc/resizablestringarray.pmc      (original)
+++ trunk/src/pmc/resizablestringarray.pmc      Sun Feb 18 23:40:12 2007
@@ -538,6 +538,65 @@
             data[i] = data[i + 1];
         DYNSELF.set_integer_native(size - 1);
     }
+
+/*
+
+=item C<void splice(PMC* value, INTVAL offset, INTVAL count)>
+
+Replaces C<count> elements starting at C<offset> with the elements in
+C<value>.
+
+Note that the C<value> PMC can be of any of the various array types.
+
+Note that this implementation can be *VERY* inefficient as it manipulates
+everything via the VTABLE api.
+
+=cut
+
+*/
+
+    void splice(PMC* value, INTVAL offset, INTVAL count) {
+        if (value->vtable->base_type != SELF->vtable->base_type &&
+                value->vtable->base_type != enum_class_FixedStringArray)
+            real_exception(INTERP, NULL, E_TypeError,
+                    "ResizableStringArray: illegal type for splice!");
+
+        INTVAL length = VTABLE_elements(INTERP, SELF);
+        INTVAL elems  = VTABLE_elements(INTERP, value);
+        INTVAL shift  = elems - count;
+        INTVAL i;
+
+        /* start from end? */
+        if (offset < 0)
+            offset += length;
+        if (offset < 0)
+            internal_exception(OUT_OF_BOUNDS, "illegal splice offset\n");
+
+        /* shrink the array */
+        if (shift < 0) {
+            /* start at offset so we don't overwrite values we'll need */
+            for (i=offset+count; i<length; i++)
+                VTABLE_set_pmc_keyed_int(INTERP, SELF, i + shift,
+                    VTABLE_get_pmc_keyed_int(INTERP, SELF, i));
+
+            DYNSELF.set_integer_native(length + shift);
+        }
+        /* grow the array */
+        else if (shift > 0) {
+            DYNSELF.set_integer_native(length + shift);
+
+            /* move the existing values */
+            /* start at length-1 so we don't overwrite values we'll need */
+            for (i=length-1; i>=offset; i--)
+                VTABLE_set_pmc_keyed_int(INTERP, SELF, i + shift,
+                    VTABLE_get_pmc_keyed_int(INTERP, SELF, i));
+        }
+
+        /* copy the new values */
+        for (i=0; i<elems; i++)
+            VTABLE_set_pmc_keyed_int(INTERP, SELF, i + offset,
+                VTABLE_get_pmc_keyed_int(INTERP, value, i));
+    }
 }
 
 

Modified: trunk/t/pmc/resizablestringarray.t
==============================================================================
--- trunk/t/pmc/resizablestringarray.t  (original)
+++ trunk/t/pmc/resizablestringarray.t  Sun Feb 18 23:40:12 2007
@@ -1,6 +1,6 @@
 #!./parrot
 
-.const int NUM_OF_TESTS = 173
+.const int NUM_OF_TESTS = 184
 
 .sub main :main
     load_bytecode 'library/Test/More.pir'
@@ -45,8 +45,10 @@
     'unshift_float'()
 
     'does'()
-    'get_string'()
+#    'get_string'()
     'sparse'()
+
+       'splice'()
 .end
 
 #
@@ -63,7 +65,7 @@
     ok = get_hll_global ['Test::More'], 'ok'
 
     .local pmc array
-    array = new .ResizablePMCArray
+       array = new .ResizableStringArray
 
     $I0 = array
     $I1 = elements array
@@ -1188,7 +1190,7 @@
     is = get_hll_global ['Test::More'], 'is'
 
     .local pmc array
-    array = new .ResizablePMCArray
+    array = new .ResizableStringArray
 
     $I0 = does array, 'array'
     is($I0, 1, "does array")
@@ -1282,3 +1284,98 @@
     ok(0, "sparse 2")
     .return()
 .end
+
+
+
+
+
+.sub 'splice'
+    .local pmc is, like
+    is = get_hll_global ['Test::More'], 'is'
+    like = get_hll_global ['Test::More'], 'like'
+
+       $P1 = new .ResizableStringArray
+       $P1 = 3
+       $P1[0] = '1'
+       $P1[1] = '2'
+       $P1[2] = '3'
+       $P2 = new .ResizableStringArray
+       $P2 = 1
+       $P2[0] = 'A'
+       splice $P1, $P2, 0, 2
+       $S0 = join "", $P1
+       is($S0, "A3", "splice replace")
+
+       $P1 = new .ResizableStringArray
+       $P1 = 3
+       $P1[0] = '1'
+       $P1[1] = '2'
+       $P1[2] = '3'
+       $P2 = new .ResizableStringArray
+       $P2 = 1
+       $P2[0] = 'A'
+       splice $P1, $P2, 1, 2
+       $S0 = join "", $P1
+       is($S0, "1A", "splice replace")
+
+.macro SpliceMadeEasy(code, out, testing)
+       $P1 = new .ResizableStringArray
+       $P1[0] = "1"
+       $P1[1] = "2"
+       $P1[2] = "3"
+       $P1[3] = "4"
+       $P1[4] = "5"
+       $P2 = new .ResizableStringArray
+       $P2[0] = 'A'
+       $P2[1] = 'B'
+       $P2[2] = 'C'
+       $P2[3] = 'D'
+       $P2[4] = 'E'
+.code
+       $S0 = join "", $P1
+       is($S0, .out, .testing)
+.endm
+
+       .SpliceMadeEasy({ splice $P1, $P2, 0, 5 }, "ABCDE", "splice, complete 
replace")
+       .SpliceMadeEasy({ splice $P1, $P2, 5, 0 }, "12345ABCDE", "splice, 
append")
+       .SpliceMadeEasy({ splice $P1, $P2, 4, 0 }, "1234ABCDE5", "splice, 
insert before last element")
+       .SpliceMadeEasy({ splice $P1, $P2, 3, 0 }, "123ABCDE45", "splice, 
append-in-middle")
+       .SpliceMadeEasy({ splice $P1, $P2, 0, 2 }, "ABCDE345", "splice, replace 
at beginning")
+       .SpliceMadeEasy({ splice $P1, $P2, 2, 2 }, "12ABCDE5", "splice, replace 
in middle")
+       .SpliceMadeEasy({ splice $P1, $P2, 3, 2 }, "123ABCDE", "splice, replace 
at end")
+       .SpliceMadeEasy({
+               $P2 = new .ResizableStringArray
+               splice $P1, $P2, 2, 2
+       }, "125", "splice, empty replacement")
+       .SpliceMadeEasy({
+               $P2 = new .ResizableStringArray
+               $P2[0] = "A"
+               splice $P1, $P2, 2, 1
+       }, "12A45", "splice, equal size replacement")
+
+       $P1 = new .ResizableStringArray
+       $P1[0] = "1"
+       $P1[1] = "2"
+       $P1[2] = "3"
+       $P1[3] = "4"
+       $P1[4] = "5"
+       $P2 = new .ResizablePMCArray
+       $P2[0] = 'A'
+       $P2[1] = 'B'
+       $P2[2] = 'C'
+       $P2[3] = 'D'
+       $P2[4] = 'E'
+
+       push_eh bad_type
+       splice $P1, $P2, 1, 0
+       clear_eh
+       goto still_ok
+
+       .local pmc exception
+       .local string message
+bad_type:
+       .get_results (exception, message)
+still_ok:
+       like(message, 'illegal\ type\ for\ splice', "splice with a different 
type")
+.end
+

Added: trunk/tools/util/pgegrep
==============================================================================
--- (empty file)
+++ trunk/tools/util/pgegrep    Sun Feb 18 23:40:12 2007
@@ -0,0 +1,274 @@
+#!./parrot
+# Or where ever it's at
+=head1 NAME
+
+pgegrep - A simple grep using PGE for matching
+
+=head1 SYNOPSIS
+
+B<pgegrep> [I<OPTIONS>] B<PATTERN> [I<FILE...>]
+
+=head1 DESCRIPTION
+
+pgegrep aims to be a small and easy to use program in replacement of the
+standard grep utility.  Regex support is whatever PGE will allow.  It searches 
through files line by line and tests if the given pattern matches.
+
+=head1 OPTIONS
+
+=over 4
+
+=item -v
+
+=item --invert-match
+
+print lines not matching PATTERN
+
+=item -V
+
+=item --version
+
+print the version and exit
+
+=item --help
+
+show this help and exit
+
+=item -r
+
+=item --recursive
+
+recursively descend into directories
+
+=item -L
+
+=item --files-without-matches
+
+print a list of files that do not match PATTERN
+
+=item -l
+
+=item --files-with-matches
+
+print a list of files that do match PATTERN
+
+=item -c
+
+=item --count
+
+count the number of lines that match PATTERN in each file and print
+
+=item -n
+
+=item --line-number
+
+print the line number for each match
+
+=item -H
+
+=item --with-filename
+
+print the filename for each match
+
+=back
+
+=head1 AUTHOR
+
+Written and maintained by Joshua Isom L<[EMAIL PROTECTED]>
+
+PGE is authored and maintained by Patrick Michaud L<[EMAIL PROTECTED]>
+
+=cut
+
+# Readability improved!
+.include "hllmacros.pir"
+
+.sub main :main
+       .param pmc argv
+       .local string progname
+       progname = shift argv
+       load_bytecode "Getopt/Obj.pbc"
+       load_bytecode "PGE.pbc"
+       .local pmc getopts
+       getopts = new "Getopt::Obj"
+       getopts."notOptStop"(1)
+       push getopts, "count|c"
+       push getopts, "with-filename|H"
+       push getopts, "files-with-matches|l"
+       push getopts, "files-without-matches|L"
+       push getopts, "line-number|n"
+       push getopts, "recursive|r"
+       push getopts, "invert-match|v"
+       push getopts, "version|V"
+       push getopts, "help"
+       push_eh handler
+       .local pmc opts
+       opts = getopts."get_options"(argv)
+       $I0 = defined opts["help"]
+       .If($I0, {
+               showhelp()
+       })
+       $I0 = defined opts["version"]
+       .If($I0, {
+               showversion()
+       })
+
+       
+       .local string rule
+       .local pmc p6rule_compile, matchsub
+       rule = shift argv
+       p6rule_compile = compreg "PGE::P6Regex"
+       matchsub = p6rule_compile(rule)
+       .If(null matchsub, {
+               printerr "Null matchsub, probably a syntax error\n"
+               end
+       })
+
+       .local int i, filecount
+       .local string filename
+       .local pmc File, OS, files, handle
+       files = new .ResizableStringArray
+       files = argv
+       filecount = files
+       # define with-filename if there's more than one file
+       .If(filecount >= 2, { opts["with-filename"] = 1 })
+       File = new .File
+       OS = new .OS
+       # This must be here, or else it'll get filled with junk data we use 
stdin...
+       i = 0
+       .Unless(filecount, {
+               # no args, use stdin
+       stdindashhack:
+               handle = getstdin
+               filename = '(standard input)'
+               goto stdinhack
+       })
+       .For(, i < filecount, inc i, {
+               filename = files[i]
+               .If(filename == '-', {
+                       goto stdindashhack
+               })
+               $I1 = File."is_file"(filename)
+               .IfElse($I1, {
+                       # Is a file
+                       handle = open filename, "<"
+               },{
+                       # Not a file, hopefully a directory
+                       $I1 = File."is_dir"(filename)
+                       $I0 = defined opts["recursive"]
+                       $I1 &= $I0
+                       .Unless($I1, {
+                               printerr "pgegrep: "
+                               printerr filename
+                               printerr ": Operation not supported.\n"
+                               goto nextfor_0
+                       })
+                       $P0 = OS."readdir"(filename)
+                       .Foreach($S0, $P0, {
+                               .If($S0 != '.', {
+                               .If($S0 != '..', {
+                                       $S1 = filename . '/'
+                                       $S0 = $S1 . $S0
+                                       $P1 = new .ResizableStringArray
+                                       $P1[0] = $S0
+                                       $I0 = i + 1
+                                       splice files, $P1, $I0, 0
+                               }) })
+                       })
+                       filecount = files
+                       goto nextfor_0
+               })
+       stdinhack:
+               checkfile(handle, filename, matchsub, opts)
+               close handle
+       nextfor_0:
+       })
+
+       end
+handler:
+       .local pmc exception
+       .local string message
+       .get_results (exception, message)
+       printerr "pgegrep: "
+       printerr message
+       printerr "\n"
+       end
+.end
+
+.sub checkfile
+       .param pmc handle
+       .param string filename
+       .param pmc matchsub
+       .param pmc opts
+       .local pmc match
+       .local string line
+       .local int lineno, linelen, matched
+       lineno = 1
+       matched = 0 # Only used for --files-without-matches
+       line = readline handle
+       linelen = length line 
+       .For(, linelen, { line = readline handle .NL() linelen = length line 
.NL() inc lineno }, {
+               match = matchsub(line)
+               $I1 = match.__get_bool()
+               $I0 = defined opts["files-without-matches"]
+               .If($I0, {
+                       .If($I1, { matched = 1 })
+                       goto next
+               })
+               $I0 = defined opts["files-with-matches"]
+               $I0 = $I0 && $I1
+               .If($I0, {
+                       print filename
+                       print "\n"
+                       .return()
+               })
+
+               $I0 = defined opts["invert-match"]
+               not $I0
+               $I1 = xor $I1, $I0
+               .Unless($I1, {
+                       $I0 = defined opts["with-filename"]
+                       $I1 = defined opts["recursive"] # although recursive 
isn't there yet
+                       $I0 = $I0 || $I1
+                       .If($I0, { print filename .NL() print ':' })
+                       $I0 = defined opts["line-number"]
+                       .If($I0, { print lineno .NL() print ':' })
+                       print line
+               })
+               #---------
+       next:
+       })
+       $I0 = defined opts["files-without-matches"]
+       .If($I0, { print filename .NL() print "\n" })
+       .return()
+.end
+
+.sub showhelp
+       print <<'HELP'
+Usage: pgegrep [OPTIONS] PATTERN [FILE...]
+Search for the Perl 6 Rule PATTERN in each file.
+Use `perldoc pgegrep` for fuller documentation.
+
+  -v --invert-match          print lines not matching PATTERN
+  -V --version               print the version and exit
+     --help                  show this help and exit
+  -r --recursive             recursively descend into directories
+  -L --files-without-matches print a list of files that do not match PATTERN
+  -l --files-with-matches    print a list of files that do match PATTERN
+  -c --count                 count the number of lines that match PATTERN
+                             in each file and print
+  -n --line-number           print the line number for each match
+  -H --with-filename         print the filename for each match
+
+HELP
+       end
+.end
+
+.sub showversion
+       print <<'VERSION'
+pgegrep v0.0.1
+VERSION
+       end
+.end
+
+# vim: ft=pir
+

Reply via email to