Patch text files by line pattern replacement, in a revokable way, with automatic backup creation.

sfk patch [-revoke|-redo] yourpatchfile.cpp [-sim|-verify]

search text blocks in file(s) and replace them by other text blocks,
including backup creation and optional restore of original files.

-revoke: undo all patches, by replacing the modified targets
         by the backup files which sfk stores in save_patch.
         the target files are touched afterwards (date/time update)
         to enforce proper recompile. use -keep-dates to avoid this.
-redo  : undo all patches and then re-apply patches.
         best used whenever you change the patchfile itself,
         to have your changes updated in the target files.
-exact-match: by default, leading whitespaces are ignored.
              use this option enforce exact 1:1 line matching.
-keep-dates: by default, revoked files get touched. use this option
             to enforce original file dates (yet windows only).
-sim     : simulate what the patch would do, don't change anything.
-qs      : quick summary, just tell a one-line status.
-stats   : show statistics of select-replace usage.
-verify  : check if an applied patch is still intact.
-nopid   : apply irrevocable patch without [patch-id].
-anyroot : ignore the :root dir entry in a patch file.

patchfile rules:
- patches are executed exactly in the order as given in the patchfile.
- each :from/:to statement is executed exactly once.
- if ANY of the :from/:to statements doesn't match the input,
  the whole file is NOT patched.
- the first :to block for a new target file must contain
  the word [patch-id],
  by using a comment in the target file's syntax, e.g. in
  C++: // [patch-id].
  this marks the file as being patched
  -> sfk will not patch it again.

it is recommended that your patchfiles have the ending .cpp 
  (or .java etc.)
to enable syntax highlighting with your favourite text editor.

sfk patch -example
   shows a detailed patchfile example.
sfk patch -template
   gives a simple, empty patchfile template.
 
patchfile example, containing all supported patchfile commands:

:patch "enable FooBar testing"
:info makes some stuff public, for direct access by test funcs

:root foosrc

:file include\Foobar.hpp
:from 
private:
    bool             isAvailable               (int nResource);
    void             openBar                   (int nMode);
:to
public: // [patch-id]
    bool             isAvailable               (int nResource);
    void             openBar                   (int nMode);
:from 
    // returns the application type, 0x00 == not set.
    UInt16           getAppType                ( );
:to
    // returns the application type, 0x00 == not set.
    UInt16           getAppType                ( );
    UInt32           getAppTypeInternal        ( );
:done

:# this is a remark, allowed only outside :file blocks.
:# the above syntax is sufficient for most cases; but now follow some
:# more commands for global replace, file and dir creation, etc.
:# select-replace has 3 parms, and applies changes (parms 2+3) only
:# in lines containing the search term (parm 1).

:file include\Another.cpp
:select-replace /MY_TRACE(/\n"/"/
:select-replace _printf("spam: _printf(_while(0) printf(_
:set only-lf-output
:from 
    bool                  existsFile                (char *psz);
:to
    // [patch-id]
    long                  existsFile                (char *psz);
:done

:mkdir sources
:create sources\MyOwnFix.hpp
// this file is generated by sfk patch.
#define OTHER_SYMBOL MY_OWN_SYMBOL
:done

:skip-begin
this is outcommented stuff. the skip-end is optional.
:skip-end

an empty patchfile template:

:patch "thepatch"

:root theproject

:file include\file1.hpp
:from 
:to
    // [patch-id]
:from 
:to
:done

:file sources\file1.cpp
:from 
:to
    // [patch-id]
:done