PreviousUpNext

15.4.30  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



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

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

}
{
    package tio =  file;        # file          is from   src/lib/std/src/posix/file.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 = file::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  (fn (id', h) =  id == id')  hooks)
                                          
                                             THE (_, h) =>  h out_strm;
                                             NULL       =>  raise exception FAIL "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 = ();


};


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext