// disect // // This is a Unix program for preprocessing and splitting a source file up into // multiple target files. Invoke it with "disect source-file-name". It // does not use standard input or standard output. First "m4" is invoked // on the source file, yielding a temporary file, the "modified source file". // Then, in the modified source file, a line of the form: // |-> file_1,file_2,...,file_n // (starting in column 1) causes subsequent lines in the modified source file // to be copied (in duplicate) to the files file_1,...,file_n. This rule holds // until another |-> directive is encountered. Note the following // clarifications: // // 1. Lines in the modified source file prior to the first directive // are ignored. // // 2. If a file name appears in multiple directives, the file will be // written to more than once, appending at each stage. However, // initially the file contents are purged. // // 3. The "|->" must appear in the first three columns. Thereafter, // white space in the directive is ignored, up to the end of line. // // 4. A directive may refer to between 0 and 100 files. // // 5. Directives are not written to any file. // // 6. Input lines longer than 5000 characters will cause trouble. // File names appearing in directives should not have commas or // white space in them. // // The source code for disect is C++, and it uses the gnu C++ libraries. // Compile with "g++ disect.cc -s -o disect". #include #include #include #include #include main( int argc, char* argv[ ] ) { if ( argc != 2 ) { cerr << "syntax error -- use \"disect filename\"\n"; exit(1); } system("m4 -B50000 < " + String( argv[1] ) + " > .infile"); ifstream infile( ".infile" ); SLList known; SLList current; char line[5000]; Pix p; int i; while(1) { infile.getline( line, 5000 ); if (!infile) break; if ( line[0] == '|' && line[1] == '-' && line[2] == '>' ) { for ( Pix p = current.first( ); p != 0; current.next(p) ) { current(p)->close( ); delete current(p); } current.clear( ); String linex(line); linex.gsub(RXwhite, ""); linex.del("|->"); String files[100]; int n = 0; n = split( linex, files, 100, ',' ); for ( i = 0; i < n; i++ ) { for ( p = known.first( ); p != 0; known.next(p) ) if ( files[i] == known(p) ) break; if ( p == 0 ) { known.append( files[i] ); current.append( new ofstream( files[i] ) ); } else current.append( new ofstream( files[i], ios::app ) ); } } else for ( Pix p = current.first( ); p != 0; current.next(p) ) *current(p) << line << "\n"; } remove(".infile"); }