PreviousUpNext

15.4.29  src/app/future-lex/src/backends/expand-file.pkg

## expand-file.pkg
## (Used with permission)

# Compiled by:
#     src/app/future-lex/src/lexgen.lib

# Copy a template file to an output file while expanding placeholders.
# Placeholders are denoted by @id@ on a line by themselves.

###                 "It helps hand-eye coordination if,
###                  as you're doing your formulae,
###                  you gently sing the notation."
###
###                                 -- E.J. Dijkstra



stipulate
    package fil =  file__premicrothread;                                # file__premicrothread  is from   src/lib/std/src/posix/file--premicrothread.pkg
herein

    package expand_file
    : (weak)
    api {
        Hook
            =
            fil::Output_Stream -> Void;

        expand
            :
            { src:  List( String ),
              dst:  String,
              hooks:  List( (String, Hook) )
            }
            ->
            Void;

    }
    {
        package tio =  file__premicrothread;    # file__premicrothread          is from   src/lib/std/src/posix/file--premicrothread.pkg
        package ss  =  substring;       # substring     is from   src/lib/std/substring.pkg
    /*
        package re = regular_expression_matcher_g (
          package p = awk_syntax
          package e = backtrack_engine)
        package m = match_tree
    */

         Hook = fil::Output_Stream -> Void;

    /*
        placeholderRE = re::compile_string "[\\t ]*@([a-zA-Z][-a-zA-Z0-9_]* )@[\\t ]*"
        prefixPlaceholder = re::prefix placeholderRE ss::getc

        fun findPlaceholder s
            =
            case (prefixPlaceholder (ss::from_string s))

                  THE (m::Match(_, [m::Match (THE { pos, len }, _)]), _)
                     =>
                    THE (ss::string (ss::slice (pos, 0, THE len)));

                   _ => NULL;
            esac;
    */

        fun find_placeholder s
            =
            {   trim = ss::drop_suffix char::is_space (ss::drop_prefix char::is_space (ss::from_string s));
                size = ss::size trim;

                if  (size > 2                 and
                     ss::is_prefix "@" trim   and
                     ss::is_suffix "@" trim)

                     THE (ss::to_string (ss::make_slice (trim, 1, THE (size - 2))));
                else
                     NULL;
                fi;
            };

        # Copy from inStrm to outStrm expanding placeholders:
        #
        fun copy (in_strm, out_strm, hooks)
            =
            {
                fun lp [] => ();

                    lp (s ! ss)
                        =>
                        {   case (find_placeholder s)

                                 NULL   =>  tio::write (out_strm, s);
                                 THE id =>  case (list::find  (\\ (id', h) =  id == id')  hooks)

                                                 THE (_, h) =>  h out_strm;
                                                 NULL       =>  raise exception DIE "bogus placeholder";
                                            esac;
                            esac;

                            lp  ss;
                        };
                end;


                lp (in_strm);
            };

        exception OPEN_OUT;

        fun expand { src, dst, hooks }
            =
            {   dst_strm
                    =
                    tio::open_for_write  dst
                    except
                        ex  =
                            {   tio::write (tio::stdout, cat [
                                  "Warning: unable to open output file \"",
                                  dst, "\"\n"
                                ]);

                                raise exception OPEN_OUT;
                            };

                fun done ()
                    =
                    (tio::close_output dst_strm);

                copy (src, dst_strm, hooks)
                except
                    ex =  { done ();
                            raise exception ex;
                          };

                done();
            }
            except OPEN_OUT = ();
    };
end;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext