www.delorie.com/archives/browse.cgi   search  
Mail Archives: geda-user/2013/06/10/09:46:40

X-Authentication-Warning: delorie.com: mail set sender to geda-user-bounces using -f
X-Recipient: geda-user AT delorie DOT com
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=gmail.com; s=20120113;
h=mime-version:date:message-id:subject:from:to:content-type;
bh=TQtYlBRsxNw8m+ZgFHCEnacTGPl6hcUiBKFi8rcAhr0=;
b=o+NQIdEk6i6s51cFC9pDJP727F8L5LE/HaG+egGHhMz6xDSq0FRBvwlW4iH5U3pzPT
/95l2OhJwFRVUpPm1VH92kM3ys7ndP0ntFFyvXg3GwZYYXkwGXUZY4RzF5h/zyHFKRJX
mX7x+/qAefxIE2R3bXggUBowikq73dUWt2LdMPjCy+vre7TA69OqmYbm1GdSqYmCJnS9
/eGQWhCprTlWKsgK5YmEqAsW2UBuDynuaX1g0uP9n45Oz7cFBsAWiNXQmI5SwQI0RkdB
NULg2aU8RzAqBEZSJIUJ8gWOqEy64Bvj8EBU2xkM5JmHBtNkUTJff0OMjCw2M3ssHIGE
SnuQ==
MIME-Version: 1.0
X-Received: by 10.194.235.99 with SMTP id ul3mr5729515wjc.6.1370871903266;
Mon, 10 Jun 2013 06:45:03 -0700 (PDT)
Date: Mon, 10 Jun 2013 09:45:03 -0400
Message-ID: <CACPio-6WYXOFAKA61dtcZhnf1jrQRbV8aOLsqv6Y3+fO5Kcn4g@mail.gmail.com>
Subject: [geda-user] ActionResub
From: Nathan Stewart <therealnathanstewart AT gmail DOT com>
To: "geda-user AT delorie DOT com" <geda-user AT delorie DOT com>
Reply-To: geda-user AT delorie DOT com

--089e013d1ff8d3dc5804deccfcaf
Content-Type: text/plain; charset=ISO-8859-1

Ok - here' s my proposed command, rewritten to use regex. I realized that
there is a usecase for regex based replacement, rather than just simple
prefixing. You can do:

:resub ^ S1/

And it will prepend S1/ to all selected refdes. (ie, C3 becomes S1/C3)

 This is handy for doing board layouts without resorting to the dummy
schematic workflow presented here on this topic before. The regex can occur
anywhere within the name. The 2nd arg can be blank, and it will replace the
regex with the empty string. The replacement string is fixed - it doesn't
do any incrementing or interpolation.

I'm not stuck on the command name - I just needed something to get rolling
(they won't let you leave the hospital without naming your baby).  And yes,
it compiles without warnings. The gcc/regex.h/restrict thing took me a
minute to figure out, but after that last email to the list, I wasn't about
to let any warnings through :)


diff --git a/src/action.c b/src/action.c
index 1d6d8f9..27a07ec 100644
--- a/src/action.c
+++ b/src/action.c
@@ -78,6 +78,10 @@
 #include <dmalloc.h>
 #endif

+#ifdef HAVE_REGEX_H
+#include <regex.h>
+#endif
+
 /* for fork() and friends */
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
@@ -3219,6 +3223,100 @@ ActionRemoveSelected (int argc, char **argv, Coord
x, Coord y)
   return 0;
 }

+
+#ifdef HAVE_REGEX_H
+/*
---------------------------------------------------------------------------
*/
+static const char resub_syntax[] = "Resub(pattern, replacement)\n";
+static const char resub_help[] = "Rename selected using regex
substitution.";
+
+static int
+ActionResub (int argc, char **argv, Coord x, Coord y)
+{
+    enum { NOERR = 0, ERROR = -1, BAD_REGEX = -2} ;
+    int  status = NOERR;
+    if (argc == 2)
+    {
+        char *rawpat = ARG(0);
+        char *replace = ARG(1);
+         size_t select_count = 0;
+        size_t renamed_count = 0;
+        regex_t pattern;
+         ElementType **renamed_elements;
+
+        if (regcomp(&pattern, rawpat, REG_EXTENDED)  == REG_NOERROR)
+        {
+            // size the elments to be renamed
+            ELEMENT_LOOP (PCB->Data);
+            {
+                if (TEST_FLAG (SELECTEDFLAG, element))
+                select_count++;
+            }
+            END_LOOP;
+
+            // collect selected elements for renaming
+            renamed_elements = (ElementType **)calloc (select_count,
sizeof (ElementType *));
+            ELEMENT_LOOP (PCB->Data);
+            {
+                if (TEST_FLAG (SELECTEDFLAG, element))
+                {
+                    char *origname = NAMEONPCB_NAME (element);
+                    const size_t nmatch = 1;
+                    regmatch_t matches[nmatch];
+
+                    if (origname && regexec(&pattern, origname,  nmatch,
(regmatch_t * restrict) matches, 0) == 0)
+                    {
+                        regmatch_t *match = &matches[0];
+                        if (match->rm_so != -1)
+                        {
+                            size_t pos = 0;
+                            size_t start = match->rm_so;
+                            size_t end = match->rm_eo;
+                            size_t patlen = end - start;
+                            size_t replen = strlen(replace);
+                            size_t origlen = strlen(origname);
+                            size_t newlen = origlen - patlen + replen;
+                            char  *rename = (char*) calloc (newlen + 1,
sizeof(char));
+
+                            if (start > 0)
+                            {
+                                strncpy(rename, origname, start);
+                                pos += start;
+                            }
+
+                            strncpy(rename + pos, replace, replen);
+                            pos += replen;
+
+                            if (start + patlen < origlen)
+                            {
+                                ssize_t remaining = origlen-patlen;
+                                strncpy(rename + pos, origname + start +
patlen, remaining);
+                            }
+                            rename[newlen] = 0;
+
+                            renamed_elements[renamed_count] = element;
+                            AddObjectToChangeNameUndoList (ELEMENT_TYPE,
NULL, NULL, renamed_elements[renamed_count], origname);
+                            ChangeObjectName (ELEMENT_TYPE,
renamed_elements[renamed_count], NULL, NULL, rename);
+                            renamed_count++;
+                        }
+                    }
+                    else
+                    {
+                        status = BAD_REGEX;
+                    }
+                }
+            }
+            END_LOOP;
+        }
+        else
+        {
+            status = BAD_REGEX;
+        }
+        regfree(&pattern);
+    }
+
+     return status;
+}
+#endif
 /*
---------------------------------------------------------------------------
*/

 static const char renumber_syntax[] = "Renumber()\n"
@@ -8104,6 +8202,11 @@ HID_Action action_action_list[] = {
   {"RemoveSelected", 0, ActionRemoveSelected,
    removeselected_help, removeselected_syntax}
   ,
+#ifdef HAVE_REGEX_H
+  {"Resub", 0, ActionResub,
+   resub_help, resub_syntax}
+  ,
+#endif
   {"Renumber", 0, ActionRenumber,
    renumber_help, renumber_syntax}
   ,

--089e013d1ff8d3dc5804deccfcaf
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: base64

PGRpdiBkaXI9Imx0ciI+PGRpdj48ZGl2Pk9rIC0gaGVyZSYjMzk7IHMgbXkgcHJvcG9zZWQgY29t
bWFuZCwgcmV3cml0dGVuIHRvIHVzZSByZWdleC4gSSByZWFsaXplZCB0aGF0IHRoZXJlIGlzIGEg
dXNlY2FzZSBmb3IgcmVnZXggYmFzZWQgcmVwbGFjZW1lbnQsIHJhdGhlciB0aGFuIGp1c3Qgc2lt
cGxlIHByZWZpeGluZy4gWW91IGNhbiBkbzo8YnI+PGJyPjwvZGl2PjpyZXN1YiBeIFMxLyA8YnI+
DQo8YnI+PC9kaXY+QW5kIGl0IHdpbGwgcHJlcGVuZCBTMS8gdG8gYWxsIHNlbGVjdGVkIHJlZmRl
cy4gKGllLCBDMyBiZWNvbWVzIFMxL0MzKTxicj48YnI+oFRoaXMgaXMgaGFuZHkgZm9yIGRvaW5n
IGJvYXJkIGxheW91dHMgd2l0aG91dCByZXNvcnRpbmcgdG8gdGhlIGR1bW15IHNjaGVtYXRpYyB3
b3JrZmxvdyBwcmVzZW50ZWQgaGVyZSBvbiB0aGlzIHRvcGljIGJlZm9yZS4gVGhlIHJlZ2V4IGNh
biBvY2N1ciBhbnl3aGVyZSB3aXRoaW4gdGhlIG5hbWUuIFRoZSAybmQgYXJnIGNhbiBiZSBibGFu
aywgYW5kIGl0IHdpbGwgcmVwbGFjZSB0aGUgcmVnZXggd2l0aCB0aGUgZW1wdHkgc3RyaW5nLiBU
aGUgcmVwbGFjZW1lbnQgc3RyaW5nIGlzIGZpeGVkIC0gaXQgZG9lc24mIzM5O3QgZG8gYW55IGlu
Y3JlbWVudGluZyBvciBpbnRlcnBvbGF0aW9uLiA8YnI+DQo8YnI+SSYjMzk7bSBub3Qgc3R1Y2sg
b24gdGhlIGNvbW1hbmQgbmFtZSAtIEkganVzdCBuZWVkZWQgc29tZXRoaW5nIHRvIGdldCByb2xs
aW5nICh0aGV5IHdvbiYjMzk7dCBsZXQgeW91IGxlYXZlIHRoZSBob3NwaXRhbCB3aXRob3V0IG5h
bWluZyB5b3VyIGJhYnkpLqAgQW5kIHllcywgaXQgY29tcGlsZXMgd2l0aG91dCB3YXJuaW5ncy4g
VGhlIGdjYy9yZWdleC5oL3Jlc3RyaWN0IHRoaW5nIHRvb2sgbWUgYSBtaW51dGUgdG8gZmlndXJl
IG91dCwgYnV0IGFmdGVyIHRoYXQgbGFzdCBlbWFpbCB0byB0aGUgbGlzdCwgSSB3YXNuJiMzOTt0
IGFib3V0IHRvIGxldCBhbnkgd2FybmluZ3MgdGhyb3VnaCA6KTxicj4NCjxicj48YnI+ZGlmZiAt
LWdpdCBhL3NyYy9hY3Rpb24uYyBiL3NyYy9hY3Rpb24uYzxicj5pbmRleCAxZDZkOGY5Li4yN2Ew
N2VjIDEwMDY0NDxicj4tLS0gYS9zcmMvYWN0aW9uLmM8YnI+KysrIGIvc3JjL2FjdGlvbi5jPGJy
PkBAIC03OCw2ICs3OCwxMCBAQDxicj6gI2luY2x1ZGUgJmx0O2RtYWxsb2MuaCZndDs8YnI+oCNl
bmRpZjxicj6gPGJyPisjaWZkZWYgSEFWRV9SRUdFWF9IPGJyPg0KKyNpbmNsdWRlICZsdDtyZWdl
eC5oJmd0Ozxicj4rI2VuZGlmPGJyPis8YnI+oC8qIGZvciBmb3JrKCkgYW5kIGZyaWVuZHMgKi88
YnI+oCNpZmRlZiBIQVZFX1VOSVNURF9IPGJyPqAjaW5jbHVkZSAmbHQ7dW5pc3RkLmgmZ3Q7PGJy
PkBAIC0zMjE5LDYgKzMyMjMsMTAwIEBAIEFjdGlvblJlbW92ZVNlbGVjdGVkIChpbnQgYXJnYywg
Y2hhciAqKmFyZ3YsIENvb3JkIHgsIENvb3JkIHkpPGJyPg0KoKAgcmV0dXJuIDA7PGJyPqB9PGJy
PqA8YnI+Kzxicj4rI2lmZGVmIEhBVkVfUkVHRVhfSDxicj4rLyogLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
ICovPGJyPitzdGF0aWMgY29uc3QgY2hhciByZXN1Yl9zeW50YXhbXSA9ICZxdW90O1Jlc3ViKHBh
dHRlcm4sIHJlcGxhY2VtZW50KVxuJnF1b3Q7Ozxicj4NCitzdGF0aWMgY29uc3QgY2hhciByZXN1
Yl9oZWxwW10gPSAmcXVvdDtSZW5hbWUgc2VsZWN0ZWQgdXNpbmcgcmVnZXggc3Vic3RpdHV0aW9u
LiZxdW90Ozs8YnI+Kzxicj4rc3RhdGljIGludDxicj4rQWN0aW9uUmVzdWIgKGludCBhcmdjLCBj
aGFyICoqYXJndiwgQ29vcmQgeCwgQ29vcmQgeSk8YnI+K3s8YnI+K6CgoCBlbnVtIHsgTk9FUlIg
PSAwLCBFUlJPUiA9IC0xLCBCQURfUkVHRVggPSAtMn0gOzxicj4NCiugoKAgaW50oCBzdGF0dXMg
PSBOT0VSUjs8YnI+K6CgoCBpZiAoYXJnYyA9PSAyKTxicj4roKCgIHs8YnI+K6CgoCCgoKAgY2hh
ciAqcmF3cGF0ID0gQVJHKDApOzxicj4roKCgIKCgoCBjaGFyICpyZXBsYWNlID0gQVJHKDEpOzxi
cj4roKCgIKCgoKAgc2l6ZV90IHNlbGVjdF9jb3VudCA9IDA7PGJyPiugoKAgoKCgIHNpemVfdCBy
ZW5hbWVkX2NvdW50ID0gMDs8YnI+K6CgoCCgoKAgcmVnZXhfdCBwYXR0ZXJuOzxicj4NCisgoKCg
IKCgoCBFbGVtZW50VHlwZSAqKnJlbmFtZWRfZWxlbWVudHM7PGJyPiugoKAgoKCgIDxicj4roKCg
IKCgoCBpZiAocmVnY29tcCgmYW1wO3BhdHRlcm4sIHJhd3BhdCwgUkVHX0VYVEVOREVEKaAgPT0g
UkVHX05PRVJST1IpIDxicj4roKCgIKCgoCB7PGJyPiugoKAgoKCgIKCgoCAvLyBzaXplIHRoZSBl
bG1lbnRzIHRvIGJlIHJlbmFtZWQ8YnI+K6CgoCCgoKAgoKCgIEVMRU1FTlRfTE9PUCAoUENCLSZn
dDtEYXRhKTs8YnI+DQoroKCgIKCgoCCgoKAgezxicj4roKCgIKCgoCCgoKAgoKCgIGlmIChURVNU
X0ZMQUcgKFNFTEVDVEVERkxBRywgZWxlbWVudCkpPGJyPiugoKAgoKCgIKCgoCCgoKAgc2VsZWN0
X2NvdW50Kys7PGJyPiugoKAgoKCgIKCgoCB9PGJyPiugoKAgoKCgIKCgoCBFTkRfTE9PUDs8YnI+
Kzxicj4roKCgIKCgoCCgoKAgLy8gY29sbGVjdCBzZWxlY3RlZCBlbGVtZW50cyBmb3IgcmVuYW1p
bmc8YnI+K6CgoCCgoKAgoKCgIHJlbmFtZWRfZWxlbWVudHMgPSAoRWxlbWVudFR5cGUgKiopY2Fs
bG9jIChzZWxlY3RfY291bnQsIHNpemVvZiAoRWxlbWVudFR5cGUgKikpOzxicj4NCiugoKAgoKCg
IKCgoCBFTEVNRU5UX0xPT1AgKFBDQi0mZ3Q7RGF0YSk7PGJyPiugoKAgoKCgIKCgoCB7IDxicj4r
oKCgIKCgoCCgoKAgoKCgIGlmIChURVNUX0ZMQUcgKFNFTEVDVEVERkxBRywgZWxlbWVudCkpPGJy
PiugoKAgoKCgIKCgoCCgoKAgezxicj4roKCgIKCgoCCgoKAgoKCgIKCgoCBjaGFyICpvcmlnbmFt
ZSA9IE5BTUVPTlBDQl9OQU1FIChlbGVtZW50KTs8YnI+K6CgoCCgoKAgoKCgIKCgoCCgoKAgY29u
c3Qgc2l6ZV90IG5tYXRjaCA9IDE7PGJyPg0KK6CgoCCgoKAgoKCgIKCgoCCgoKAgcmVnbWF0Y2hf
dCBtYXRjaGVzW25tYXRjaF07PGJyPiugoKAgoKCgIKCgoCCgoKAgoKCgIDxicj4roKCgIKCgoCCg
oKAgoKCgIKCgoCBpZiAob3JpZ25hbWUgJmFtcDsmYW1wOyByZWdleGVjKCZhbXA7cGF0dGVybiwg
b3JpZ25hbWUsoCBubWF0Y2gsIChyZWdtYXRjaF90ICogcmVzdHJpY3QpIG1hdGNoZXMsIDApID09
IDApPGJyPiugoKAgoKCgIKCgoCCgoKAgoKCgIHugoKAgPGJyPg0KK6CgoCCgoKAgoKCgIKCgoCCg
oKAgoKCgIHJlZ21hdGNoX3QgKm1hdGNoID0gJmFtcDttYXRjaGVzWzBdOzxicj4roKCgIKCgoCCg
oKAgoKCgIKCgoCCgoKAgaWYgKG1hdGNoLSZndDtybV9zbyAhPSAtMSk8YnI+K6CgoCCgoKAgoKCg
IKCgoCCgoKAgoKCgIHs8YnI+K6CgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCBzaXplX3QgcG9z
ID0gMDs8YnI+K6CgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCBzaXplX3Qgc3RhcnQgPSBtYXRj
aC0mZ3Q7cm1fc287PGJyPg0KK6CgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCBzaXplX3QgZW5k
ID0gbWF0Y2gtJmd0O3JtX2VvOzxicj4roKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIHNpemVf
dCBwYXRsZW4gPSBlbmQgLSBzdGFydDs8YnI+K6CgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCBz
aXplX3QgcmVwbGVuID0gc3RybGVuKHJlcGxhY2UpOzxicj4roKCgIKCgoCCgoKAgoKCgIKCgoCCg
oKAgoKCgIHNpemVfdCBvcmlnbGVuID0gc3RybGVuKG9yaWduYW1lKTs8YnI+DQoroKCgIKCgoCCg
oKAgoKCgIKCgoCCgoKAgoKCgIHNpemVfdCBuZXdsZW4gPSBvcmlnbGVuIC0gcGF0bGVuICsgcmVw
bGVuOzxicj4roKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIGNoYXKgICpyZW5hbWUgPSAoY2hh
ciopIGNhbGxvYyAobmV3bGVuICsgMSwgc2l6ZW9mKGNoYXIpKTs8YnI+Kzxicj4roKCgIKCgoCCg
oKAgoKCgIKCgoCCgoKAgoKCgIGlmIChzdGFydCAmZ3Q7IDApPGJyPg0KK6CgoCCgoKAgoKCgIKCg
oCCgoKAgoKCgIKCgoCB7PGJyPiugoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIHN0cm5j
cHkocmVuYW1lLCBvcmlnbmFtZSwgc3RhcnQpOzxicj4roKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAg
oKCgIKCgoCBwb3MgKz0gc3RhcnQ7PGJyPiugoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgfTxi
cj4rPGJyPiugoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgc3RybmNweShyZW5hbWUgKyBwb3Ms
IHJlcGxhY2UsIHJlcGxlbik7PGJyPg0KK6CgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCBwb3Mg
Kz0gcmVwbGVuOzxicj4rPGJyPiugoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgaWYgKHN0YXJ0
ICsgcGF0bGVuICZsdDsgb3JpZ2xlbik8YnI+K6CgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCB7
PGJyPiugoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIHNzaXplX3QgcmVtYWluaW5nID0g
b3JpZ2xlbi1wYXRsZW47PGJyPg0KK6CgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgc3Ry
bmNweShyZW5hbWUgKyBwb3MsIG9yaWduYW1lICsgc3RhcnQgKyBwYXRsZW4sIHJlbWFpbmluZyk7
PGJyPiugoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgfTxicj4roKCgIKCgoCCgoKAgoKCgIKCg
oCCgoKAgoKCgIHJlbmFtZVtuZXdsZW5dID0gMDs8YnI+Kzxicj4roKCgIKCgoCCgoKAgoKCgIKCg
oCCgoKAgoKCgIHJlbmFtZWRfZWxlbWVudHNbcmVuYW1lZF9jb3VudF0gPSBlbGVtZW50Ozxicj4N
CiugoKAgoKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgQWRkT2JqZWN0VG9DaGFuZ2VOYW1lVW5kb0xp
c3QgKEVMRU1FTlRfVFlQRSwgTlVMTCwgTlVMTCwgcmVuYW1lZF9lbGVtZW50c1tyZW5hbWVkX2Nv
dW50XSwgb3JpZ25hbWUpOzxicj4roKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIENoYW5nZU9i
amVjdE5hbWUgKEVMRU1FTlRfVFlQRSwgcmVuYW1lZF9lbGVtZW50c1tyZW5hbWVkX2NvdW50XSwg
TlVMTCwgTlVMTCwgcmVuYW1lKTs8YnI+DQoroKCgIKCgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIHJl
bmFtZWRfY291bnQrKzs8YnI+K6CgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIH08YnI+K6CgoCCgoKAg
oKCgIKCgoCCgoKAgfTxicj4roKCgIKCgoCCgoKAgoKCgIKCgoCBlbHNlPGJyPiugoKAgoKCgIKCg
oCCgoKAgoKCgIHs8YnI+K6CgoCCgoKAgoKCgIKCgoCCgoKAgoKCgIHN0YXR1cyA9IEJBRF9SRUdF
WDs8YnI+K6CgoCCgoKAgoKCgIKCgoCCgoKAgfTxicj4NCiugoKAgoKCgIKCgoCCgoKAgfTxicj4r
oKCgIKCgoCCgoKAgfTxicj4roKCgIKCgoCCgoKAgRU5EX0xPT1A7PGJyPiugoKAgoKCgIH08YnI+
K6CgoCCgoKAgZWxzZTxicj4roKCgIKCgoCB7PGJyPiugoKAgoKCgIKCgoCBzdGF0dXMgPSBCQURf
UkVHRVg7PGJyPiugoKAgoKCgIH08YnI+K6CgoCCgoKAgcmVnZnJlZSgmYW1wO3BhdHRlcm4pOzxi
cj4roKCgIH08YnI+Kzxicj4rIKCgoCByZXR1cm4gc3RhdHVzOzxicj4NCit9PGJyPisjZW5kaWY8
YnI+oC8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLzxicj6gPGJyPqBzdGF0aWMgY29uc3QgY2hhciBy
ZW51bWJlcl9zeW50YXhbXSA9ICZxdW90O1JlbnVtYmVyKClcbiZxdW90Ozxicj5AQCAtODEwNCw2
ICs4MjAyLDExIEBAIEhJRF9BY3Rpb24gYWN0aW9uX2FjdGlvbl9saXN0W10gPSB7PGJyPg0KoKAg
eyZxdW90O1JlbW92ZVNlbGVjdGVkJnF1b3Q7LCAwLCBBY3Rpb25SZW1vdmVTZWxlY3RlZCw8YnI+
oKCgIHJlbW92ZXNlbGVjdGVkX2hlbHAsIHJlbW92ZXNlbGVjdGVkX3N5bnRheH08YnI+oKAgLDxi
cj4rI2lmZGVmIEhBVkVfUkVHRVhfSDxicj4roCB7JnF1b3Q7UmVzdWImcXVvdDssIDAsIEFjdGlv
blJlc3ViLDxicj4roKAgcmVzdWJfaGVscCwgcmVzdWJfc3ludGF4fTxicj4roCAsPGJyPg0KKyNl
bmRpZjxicj6goCB7JnF1b3Q7UmVudW1iZXImcXVvdDssIDAsIEFjdGlvblJlbnVtYmVyLDxicj6g
oKAgcmVudW1iZXJfaGVscCwgcmVudW1iZXJfc3ludGF4fTxicj6goCAsPGJyPjxicj48L2Rpdj4N
Cg==
--089e013d1ff8d3dc5804deccfcaf--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019