diff --git a/README.md b/README.md index 20b693b..95e7d65 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Those are the steps done by the helpers: * You don't need to use sudo in order to run those scripts, but some extra packages are needed: - `sudo apt-get install cdbs devscripts dpkg-dev git gnupg gnupg2 patch python2 quilt rename rpl sed python3-jsonschema` + `sudo apt-get install cdbs devscripts dpkg-dev git gnupg gnupg2 patch quilt rename rpl sed python3-jsonschema` * Take care to use the right sourcePackageName, many source packages produce several binary packages. `apt-cache showsrc binary-package` can help you. diff --git a/helpers/DATA/rpl b/helpers/DATA/rpl index 8da0013..262057e 100755 --- a/helpers/DATA/rpl +++ b/helpers/DATA/rpl @@ -1,4 +1,4 @@ -#!/usr/bin/python2.7 +#!/usr/bin/python3 import optparse, sys, os, tempfile, re try: import readline @@ -6,7 +6,7 @@ except ImportError: pass from stat import * def show_license(*eat): - print """rpl - replace strings in files + print("""rpl - replace strings in files Copyright (C) 2004-2005 Goran Weinholt Copyright (C) 2004 Christian Haggstrom @@ -23,7 +23,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -""" +""") sys.exit(0) def get_files(filenames, recurse, suffixen, verbose, hidden_files): @@ -31,7 +31,7 @@ def get_files(filenames, recurse, suffixen, verbose, hidden_files): for filename in filenames: try: perms = os.lstat(filename) - except OSError, e: + except OSError as e: sys.stderr.write("\nrpl: Unable to read permissions of %s." % filename) sys.stderr.write("\nrpl: Error: %s" % e) @@ -71,26 +71,43 @@ def unescape(s): regex = re.compile(r'\\([0-7]{1,3}|x[0-9a-fA-F]{2}|[nrtvafb\\])') return regex.sub(lambda match: eval('"%s"' % match.group()), s) -def blockrepl(instream, outstream, regex, before, after, blocksize=None): - patlen = len(before) - sum = 0 - if not blocksize: blocksize = 2*patlen - tonext = '' - while 1: - block = instream.read(blocksize) - if not block: break - parts = regex.split(tonext+block) - sum += len(parts)-1 - lastpart = parts[-1] - if lastpart: - tonext = lastpart[-patlen:] - parts[-1] = lastpart[:-len(tonext)] - else: - tonext = '' - outstream.write(after.join(parts)) - outstream.write(tonext) - return sum +def blockrepl(instream, outstream, regex, before, after, blocksize=None, encoding="latin-1"): + """ + Read blocks as bytes, decode, regex-replace, re-encode, write. + Keeps python2 behavior but avoids str/bytes errors on python3. + """ + patlen = len(before) + if blocksize is None: + blocksize = 2 * patlen if patlen else 4096 + + matches = 0 + carry = "" # tail carried to the next block, as str + + while True: + chunk = instream.read(blocksize) + if not chunk: + break + # Decode the new bytes and prepend any carry‑over from previous loop + block = carry + chunk.decode(encoding, errors="surrogateescape") + + parts = regex.split(block) + matches += len(parts) - 1 + + # Preserve the last *patlen* chars in case the pattern straddles blocks + tail = parts[-1] + if tail: + carry = tail[-patlen:] + parts[-1] = tail[:-len(carry)] + else: + carry = "" + + outstream.write(after.join(parts).encode(encoding, errors="surrogateescape")) + + if carry: + outstream.write(carry.encode(encoding, errors="surrogateescape")) + + return matches def main(): # First we parse the command line arguments... usage = "usage: %prog [options] old_string new_string target_file(s)" @@ -163,7 +180,7 @@ def main(): sys.stderr.write("(ignoring case)? (Y/[N]) ") else: sys.stderr.write("(case sensitive)? (Y/[N]) ") - line = raw_input() + line = input() if line != "" and line[0] in "nN": sys.stderr.write("\nrpl: User cancelled operation.\n") sys.exit(os.EX_TEMPFAIL) @@ -195,7 +212,7 @@ def main(): for filename, perms in files: # Open the input file try: f = open(filename, "rb") - except IOError, e: + except IOError as e: sys.stderr.write("\nrpl: Unable to open %s for reading." % fn) sys.stderr.write("\nrpl: Error: %s" % e) sys.stderr.write("\nrpl: SKIPPING %s\n\n" % fn) @@ -209,7 +226,7 @@ def main(): try: o, tmp_path = tempfile.mkstemp("", ".tmp.") o = os.fdopen(o, "wb") - except OSError, e: + except OSError as e: sys.stderr.write("\nrpl: Unable to create temp file.") sys.stderr.write("\nrpl: Error: %s" % e) sys.stderr.write("\nrpl: (Type \"rpl -h\" and consider \"-t\" to specify temp file location.)") @@ -220,7 +237,7 @@ def main(): try: os.chown(tmp_path, perms.st_uid, perms.st_gid) os.chmod(tmp_path, perms.st_mode) - except OSError, e: + except OSError as e: sys.stderr.write("\nrpl: Unable to set owner/group/perms of %s" % filename) sys.stderr.write("\nrpl: Error: %s" % e) @@ -250,7 +267,7 @@ def main(): if opts.dry_run: try: fn = os.path.realpath(filename) - except OSError, e: + except OSError as e: fn = filename if not opts.quiet: sys.stderr.write(" %s\n" % fn) os.unlink(tmp_path) @@ -261,7 +278,7 @@ def main(): sys.stderr.write("\nSave '%s' ? ([Y]/N) " % filename) line = "" while line == "" or line[0] not in "Yy\nnN": - line = raw_input() + line = input() if line[0] in "nN": sys.stderr.write("Not Saved.\n") os.unlink(tmp_path) @@ -270,14 +287,14 @@ def main(): if opts.do_backup: try: os.rename(filename, filename + "~") - except OSError, e: + except OSError as e: sys.stderr.write("rpl: An error occured renaming %s to %s." % (filename, filename + "~")) sys.stderr.write("\nrpl: Error: %s" % e) continue # Rename the file try: os.rename(tmp_path, filename) - except OSError, e: + except OSError as e: sys.stderr.write("rpl: An error occured replacing %s with %s." % (tmp_path, filename)) sys.stderr.write("\nrpl: Error: %s" % e) @@ -287,7 +304,7 @@ def main(): # Restore the times if opts.keep_times: try: os.utime(filename, (perms.st_atime, perms.st_mtime)) - except OSError, e: + except OSError as e: sys.stderr.write("\nrpl: An error occured setting the access time and mod time of the file %s.", filename) sys.stderr.write("\nrpl: Error: %s" % e) total_matches += matches