/* * [MASMGlue.java] * * Summary: Expands %includes in MASM source to create one big document usually for MASMBalancer analysis. * * Copyright: (c) 2011-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 1.0 2011-02-07 initial version. */ package com.mindprod.masmbalancer; import com.mindprod.common18.EIO; import com.mindprod.common18.ST; import com.mindprod.hunkio.HunkIO; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.regex.Matcher; import java.util.regex.Pattern; import static java.lang.System.*; /** * Expands %includes in MASM source to create one big document usually for MASMBalancer analysis. * * @author Roedy Green, Canadian Mind Products * @version 1.0 2011-02-07 initial version. * @since 2011-02-07 */ public final class MASMGlue { private static final int FIRST_COPYRIGHT_YEAR = 2011; /** * undisplayed copyright notice * * @noinspection UnusedDeclaration */ private static final String EMBEDDED_COPYRIGHT = "Copyright: (c) 2011-2017 Roedy Green, Canadian Mind Products, http://mindprod.com"; /** * date this version released. */ private static final String RELEASE_DATE = "2011-02-07"; /** * Title of the Applet */ private static final String TITLE_STRING = "MASM Glue"; /** * Version of the program */ private static final String VERSION_STRING = "1.0"; /** * search for %includes */ private static final Pattern INCLUDE_FINDER = Pattern.compile( "%include[ \t]+([!#\\$\\-\\.0-9@\\^-`a-z~]+)[ \t]*[\r\n]+" ); /** * track how many levels of nesting of incudes there are. Used to detect circularities. */ private static int nestDepth = 0; /** * called recursively to expand nested includes * * @param include file containing %includes * @param prw where to direct the expanded text */ private static void expandIncludesIn( File include, PrintWriter prw ) throws IOException { nestDepth++; if ( nestDepth > 12 ) { err.println( "likely infinite circular include recursion at " + EIO.getCanOrAbsPath( include ) ); System.exit( 1 ); } final String contents = HunkIO.readEntireFile( include ); int start; int end = 0; Matcher m = INCLUDE_FINDER.matcher( contents ); while ( m.find() ) { final String nested = m.group( 1 ); start = m.start(); // dump out material prior to include prw.print( contents.substring( end, start ) ); end = m.end(); // recursively prw.println(); prw.println( "; %include " + nested ); prw.println( "; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" ); prw.println( "; begin includes from " + nested ); prw.println( "; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" ); expandIncludesIn( new File( nested ), prw ); prw.println( "; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" ); prw.println( "; end includes from " + nested ); prw.println( "; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" ); prw.println(); } // print out the tail past the last include. prw.print( contents.substring( end ) ); nestDepth--; } /** * name of *.asm file is on command line. * Output appears in a similarly names *.glue file.. * * @param args arg[0] is name of root *.asm */ public static void main( String[] args ) { try { // O P E N final File masm = new File( args[ 0 ] ); final File glue = new File( ST.chopTrailingString( EIO.getCanOrAbsPath( masm ), ".asm" ) + ".glue" ); final PrintWriter prw = EIO.getPrintWriter( glue, 24 * 1024, EIO.UTF8 ); expandIncludesIn( masm, prw ); if ( prw != null ) { prw.close(); } out.println( "MASMGlue results in " + EIO.getCanOrAbsPath( glue ) ); } catch ( IOException e ) { err.println( "Error, file problems. " + e.getMessage() ); } } }