PreviousUpNext

15.4.822  src/lib/make-library-glue/patchfiles.pkg

## patchfiles.pkg
#
# Adding content to files in spots
# marked by linepairs like
#
#    # Do not edit this or following lines --- they are autobuilt.
#    ...
#    # Do not edit this or preceding lines --- they are autobuilt.

# Compiled by:
#     src/lib/std/standard.lib

stipulate
    package deq =  queue;                                                                               # queue                         is from   src/lib/src/queue.pkg
    package fil =  file__premicrothread;                                                                # file__premicrothread          is from   src/lib/std/src/posix/file--premicrothread.pkg
    package pf  =  patchfile;                                                                           # patchfile                     is from   src/lib/make-library-glue/patchfile.pkg
    package sm  =  string_map;                                                                          # string_map                    is from   src/lib/src/string-map.pkg
    #
    =~     =  regex::(=~);
herein

    # This package is invoked in:
    #
    #     src/lib/make-library-glue/make-library-glue.pkg

    package  patchfiles:
             Patchfiles                                                                                 # Patchfiles                    is from   src/lib/make-library-glue/patchfiles.api
    {
        Patch_Id  =   { filename:       String,
                        patchname:      String
                      };

        Patch     =   { patch_id:       Patch_Id,
                        lines:          List(String)
                      };

        Patchfiles =   sm::Map( pf::Patchfile );                                                        # Patchfile instances, indexed by filename.

        empty      =   sm::empty:       sm::Map( pf::Patchfile );

        fun load_patchfile  (filename, patchfiles)
            =
            case (sm::get (patchfiles, filename))
                #
                THE _ =>  patchfiles;
                #
                NULL  =>  sm::set  (patchfiles,  filename,  pf::read_patchfile filename );
            esac;

        fun load_patchfiles  filenames
            =
            fold_backward  load_patchfile  empty  filenames;

        fun get_filenames  patchfiles
            =
            sm::keys_list  patchfiles;


        fun write_patchfiles  patchfiles
            =
            sm::vals_list
                (sm::map
                    (\\ patchfile =  pf::write_patchfile  patchfile)
                    patchfiles
                );


        fun get_patchfile  patchfiles  filename
            =
            case (sm::get (patchfiles, filename))
                #
                THE patchfile =>   patchfile;
                #
                NULL          =>   raise exception DIE (sprintf "No such patchable file loaded: %s" filename);
            esac;


        fun get_patch  patchfiles  (patch_id as { filename, patchname })
            =
            {   patchfile =  get_patchfile  patchfiles  filename;
                #
                (pf::get_patch (patchfile, patchname))
                    ->
                    { patchname, lines };

                { patch_id, lines };
            };


        fun apply_patch  patchfiles  { patch_id => { filename, patchname }, lines }
            =   
            {   patchfile =  get_patchfile  patchfiles  filename;
                #
                (pf::apply_patch  patchfile  { patchname, lines })
                    ->
                    patchfile;

                sm::set (patchfiles, filename, patchfile);
            };


        fun apply_patches  patchfiles  patches
            =
            apply_patches' (patchfiles, patches)
            where
                fun apply_patches' (patchfiles, []             ) =>  patchfiles;
                    apply_patches' (patchfiles, patch ! patches) =>  apply_patches'  (apply_patch patchfiles patch,  patches);
                end;
            end;

        fun append_to_patch patchfiles { patch_id => { filename, patchname }, lines }                                   # Append  given lines to named patch.
            =
            {   patchfile =  get_patchfile  patchfiles  filename;
                #
                (pf::append_to_patch  (patchfile, patchname, lines ))
                    ->
                    patchfile;

                sm::set (patchfiles, filename, patchfile);
            };
            
        fun prepend_to_patch  patchfiles  { patch_id => { filename, patchname }, lines }                                # Prepend  given lines to named patch.
            =
            {   patchfile =  get_patchfile  patchfiles  filename;
                #
                (pf::prepend_to_patch  (patchfile, patchname, lines ))
                    ->
                    patchfile;

                sm::set (patchfiles, filename, patchfile);
            };
            

        fun map_patches  user_fn  patchfiles
            =
            sm::map  map_patches'  patchfiles
            where
                fun map_patches' patchfile
                    =
                    pf::map  user_fn  patchfile;
            end;


        fun patch_apply  user_fn  patchfiles
            =
            sm::apply  patch_apply'  patchfiles
            where
                fun patch_apply' patchfile
                    =
                    pf::apply  user_fn  patchfile;
            end;


        fun patch_fold  user_fn  init  patchfiles
            =
            sm::fold_backward  patch_fold'  init  patchfiles
            where
                fun patch_fold' (patchfile, result)
                    =
                    pf::fold  user_fn  result  patchfile;
            end;


        fun empty_all_patches  patchfiles
            =
            map_patches  (\\ _ = [])  patchfiles;


        map   =  map_patches;           # Calling these 'map', 'apply' and 'fold' in the main body of the file risks confusion
        apply =  patch_apply;           # with list::map and list::apply, but exporting them as pfs::map etc is nonproblematic.
        fold  =  patch_fold;
    };
end;


## Code by Jeff Prothero: Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext