User Tools

Site Tools


blog:pushbx:2025:1223_restoring_modified_files_from_nasm_listing_files

Restoring modified files from NASM listing files

I accidentally reset a repo using the hg strip -f command, which destroys unsaved changes in the current working directory.

I still had the original .lst listing files created by NASM, however. These turned out to be expressive enough to completely restore the deleted changes in this case.

The extract perl script

#! /usr/bin/perl

# Extract source text files from NASM listing files
#  by E. C. Masloch, 2025
#
# Usage of the works is permitted provided that this
# instrument is retained with the works, so that any entity
# that uses the works is notified of this instrument.
#
# DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.

use warnings;
use strict;
use Getopt::Long;
Getopt::Long::Configure("no_auto_abbrev");

my $include;

GetOptions(
	'filter-include=s' => \$include,
) or die;

my $includelevel = -1;
my $priorlevel = -1;

while (<<>>) {
  if (/^.{0,39}$/) {
    next;
  }
  if (/^.{0,20}\*{18}\s+/) {
    next;
  }
  my $level = 0;
  if (/^.{30,36}\<([0-9]+)\>\s+/) {
    $level = int($1);
  }
  if (not defined $include and $level != 0) {
    next;
  }
  if (defined $include and /^.{40}\s*\%include\s+['"]*$include['"]*\s*(;.*)?$/i) {
    $priorlevel = $level;
    $includelevel = $level + 1;
  } elsif (defined $include and $level != $includelevel) {
    if ($level <= $priorlevel) {
      last;
    }
    next;
  }
  if (defined $include and $level != $includelevel) {
    next;
  }
  s/^.{40}//;
  print;
}

This uses the angle-bracketed numbers that appear in NASM listing files to tell when an include file level or mmacro expansion level changes. (These are currently not consistently preserved in .tls trace listing files.)

The bash scriptlets to make use of the perl script

Recreate .nas files from .lst files:

for file in drbio/bin/*.lst; do nodir="${file##*/}"; base="${nodir%.*}"; ../extract.pl "$file" > "drbio/$base.nas"; done

Display which include files are included by what source files, sorted by the include file:

grep -Eio '%include\s+\S+' drbio/bin/*.lst | perl -e 'my @array = (); while («») { s/^([^:]+):\%include\s+["]*([^"]+)["]*/$2 $1/; push( @array, $_ ); }; print sort @array;' | less

Recreate the .mac files, each from the first .nas file that includes it:

for file in drbio/*.mac; do nodir="${file##*/}"; echo "Searching $file"; matching=$(grep -Ei '\%include\s+"*'"$nodir"'"*' -l drbio/*.nas | head -n1); if [ -z "$matching" ]; then echo "No match!"; else matchnodir="${matching##*/}"; matchbase="${matchnodir%.*}"; ../extract.pl –filter-include="$nodir" "drbio/bin/$matchbase.lst" > "$file"; fi; done

Fix version.mac line endings: dos2unix drbio/version.mac

You could leave a comment if you were logged in.
blog/pushbx/2025/1223_restoring_modified_files_from_nasm_listing_files.txt · Last modified: by ecm