xstrp4-1.8.2/0000755000175000017500000000000012666307734011430 5ustar gerdgerdxstrp4-1.8.2/LICENSE0000644000175000017500000000205412666307734012436 0ustar gerdgerdCopyright 1999 by Gerd Stolpmann The package "xtrp4" is copyright by Gerd Stolpmann. Permission is hereby granted, free of charge, to any person obtaining a copy of the "xstrp4" software (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. The Software is provided ``as is'', without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall Gerd Stolpmann be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the Software or the use or other dealings in the software. xstrp4-1.8.2/META0000644000175000017500000000047412666307734012106 0ustar gerdgerdversion = "1.8.2" requires = "camlp4,bytes" # This line counts when the compiler is invoked with # ocamlfind ocamlc -syntax -package xstrp4 archive(syntax,preprocessor) = "xstrp4.cma" # This line counts when a toploop is running and # someone types #require "xstrp4". archive(syntax,toploop) = "xstrp4.cma" xstrp4-1.8.2/Makefile0000644000175000017500000000371712666307734013100 0ustar gerdgerd# make all: make bytecode archive # make install: install bytecode archive # make uninstall: uninstall package # make clean: remove intermediate files # make distclean: remove any superflous files # make release: cleanup, create archive, tag CVS module # (for developers) include Makefile.conf #---------------------------------------------------------------------- # specific rules for this package: OBJECTS = xstrp4_here_types.cmo xstrp4_here_lexer.cmo xstrp4_here.cmo ARCHIVE = xstrp4.cma NAME = xstrp4 REQUIRES = bytes all: $(ARCHIVE) $(ARCHIVE): $(OBJECTS) $(OCAMLC) -a -o $(ARCHIVE) $(OBJECTS) sample: sample.ml ocamlfind ocamlc \ -package xstrp4 -syntax camlp4o -linkpkg \ sample.ml \ -o sample view.sample: all camlp4 $(ROPTIONS) pa_o.cmo ./xstrp4.cma pr_o.cmo sample.ml #---------------------------------------------------------------------- # general rules: OPTIONS = OCAMLC = $(OCAMLFIND) ocamlc -g $(STRING_OPTS) $(OPTIONS) $(CAMLP4_OPTS) -package "$(REQUIRES)" OCAMLOPT = $(OCAMLFIND) ocamlopt -g $(STRING_OPTS) $(OPTIONS) $(CAMLP4_OPTS) -package "$(REQUIRES)" OCAMLDEP = ocamldep $(OPTIONS) OCAMLFIND = ocamlfind #depend: *.ml *.mli # $(OCAMLDEP) *.ml *.mli >depend *.mli: .PHONY: install install: all $(OCAMLFIND) install $(NAME) *.cmi *.cma META \ -patch-version `./configure -version` .PHONY: uninstall uninstall: $(OCAMLFIND) remove $(NAME) .PHONY: clean clean: rm -f *.cmi *.cmo *.cma *.cmx *.o *.a *.cmxa sample .PHONY: distclean distclean: clean rm -f *~ depend depend.pkg RELEASE: META awk '/version/ { print substr($$3,2,length($$3)-2) }' META >RELEASE .SUFFIXES: .cmo .cmi .cmx .ml .mli .mll .ml.cmx: $(OCAMLOPT) -c $< .ml.cmo: $(OCAMLC) -c $< .mli.cmi: $(OCAMLC) -c $< .mll.ml: ocamllex $< xstrp4_here_lexer.cmo: xstrp4_here_types.cmo xstrp4_here_types.cmi xstrp4_here_lexer.cmi: xstrp4_here_types.cmi xstrp4_here.cmo: xstrp4_here_lexer.cmo xstrp4_here_lexer.cmi xstrp4_here.cmi: xstrp4_here_lexer.cmi xstrp4-1.8.2/README0000644000175000017500000000414512666307734012314 0ustar gerdgerdThis is a camlp4 extension that expands brace expansions like a shell does. See sample.ml for examples. You need findlib to 'make install'; AT LEAST VERSION 0.4 OF FINDLIB! BUILD: Just type "make all" to compile the sources. INSTALL: The module can be installed using the installation method supported by the "findlib" module. If you have installed "findlib", a "make install" copies the compiled files to their standard places. The package name is then "xstrp4". If you do not have "findlib", just copy the files manually where you like them. HOW TO USE IT: See sample.ml for explanations. See the Makefile how to compile sample.ml. KNOWN BUGS: Errors reported by xstrp4 are usually off by 2 (for O'Caml 3.10). This is O'Caml bug #4357 (http://caml.inria.fr/mantis/view.php?id=4357). CHANGES: Changed in version 1.8.1: Patching the version string in the META file Changed in version 1.8: Removal of the support for O'Caml 3.09 and earlier. Integrating Sylvain's record access patch. Changed in version 1.7: Porting to O'Caml 3.10. Still works for older O'Caml versions. Changed in version 1.6: Setting the name of the location variable explicitly because the default changed in O'Caml 3.09. Changed in version 1.5: Fixes for O'Caml 3.08. There is still a known problem: Locations in error messages may be wrong for <:here< ... >>. This seems to be a bug in camlp4. Changed in version 1.4: Better code is generated. (Suggested by Mike Potanin.) Changed in version 1.3: The backslash sequences \DDD and \xXX are recognized, e.g. \033 or \x21. (Suggested by Mike Potanin.) Changed in version 1.2: The printf qualifiers L, l, n are now supported, e.g. ${x,%ld} for an int32 variable x. (Suggested by Nadj.) Changed in version 1.0: Support for findlib-0.4 Changed in version 0.1.1: Updated the URLs in documentation. AUTHOR: The module has been written by Gerd Stolpmann, gerd@gerd-stolpmann.de You can download it from http://www.ocaml-programming.de/packages/. This module has an entry in the O'Caml link database, http://links.camlcity.org/ Subversion: See https://godirepo.camlcity.org/svn/ xstrp4-1.8.2/configure0000755000175000017500000001304612666307734013343 0ustar gerdgerd# $Id$ ####################################################################### # Helpers: # Split $PATH into words: oldifs="$IFS" IFS=" :" spacepath=`echo $PATH` IFS="$oldifs" in_path () { # Does $1 exist in $PATH? for d in $spacepath; do if test -x "$d/$1"; then return 0 fi done return 1 } get_path () { for d in $spacepath; do if test -x "$d/$1"; then echo "$d/$1" return fi done } ####################################################################### # Defaults #--- Options --- # value 0: off # value 1: on # defaults: set_defaults () { # enable_FOO=XXX # with_FOO=XXX : } ocamlc=`get_path ocamlc` set_defaults version="1.8.2" exec_suffix="" ####################################################################### # Option parsing #ehelp_FOO="XXX" #whelp_FOO="XXX" # Which options exist? eoptions for enable/disable, woptions for with/without: eoptions="" woptions="" # Packages to include anyway: requires="" print_options () { for opt in $eoptions; do e="o=\$enable_$opt" eval "$e" uopt=`echo $opt | sed -e 's/_/-/g'` if [ $o -gt 0 ]; then echo " -enable-$uopt" else echo " -disable-$uopt" fi done for opt in $woptions; do e="o=\$with_$opt" eval "$e" uopt=`echo $opt | sed -e 's/_/-/g'` if [ $o -gt 0 ]; then echo " -with-$uopt" else echo " -without-$uopt" fi done } usage () { set_defaults cat <<_EOF_ >&2 usage: ./configure [ options ] _EOF_ for opt in $eoptions; do e="help=\$ehelp_$opt" eval "$e" uopt=`echo $opt | sed -e 's/_/-/g'` echo "-enable-$uopt:" >&2 echo "-disable-$uopt:" >&2 echo " $help" >&2 done for opt in $woptions; do e="help=\$whelp_$opt" eval "$e" uopt=`echo $opt | sed -e 's/_/-/g'` echo "-with-$uopt:" >&2 echo "-without-$uopt:" >&2 echo " $help" >&2 done } while [ "$#" -gt 0 ]; do case "$1" in -enable-*) opt=`echo "$1" | sed -e 's/-enable-//' -e 's/-/_/g'` check_eopt "$opt" eval "enable_$opt=2" shift ;; -disable-*) opt=`echo "$1" | sed -e 's/-disable-//' -e 's/-/_/g'` check_eopt "$opt" eval "enable_$opt=-1" shift ;; -with-*) opt=`echo "$1" | sed -e 's/-with-//' -e 's/-/_/g'` check_wopt "$opt" eval "with_$opt=2" shift ;; -without-*) opt=`echo "$1" | sed -e 's/-without-//' -e 's/-/_/g'` check_wopt "$opt" eval "with_$opt=-1" shift ;; -version) echo "$version" exit 0 ;; *) usage esac done echo "Welcome to Xstrp4 version $version" >&2 ###################################################################### # Check ocamlfind printf "%s" "Checking for findlib... " if ocamlfind query stdlib >/dev/null 2>/dev/null; then echo "found" else echo "not found" echo "Make sure that ocamlfind is in your PATH, or download findlib" echo "from www.ocaml-programming.de" echo "ERROR" exit 1 fi ###################################################################### # immutable strings printf "%s" "Checking for -safe-string... " string_opts="" if ocamlc -safe-string >/dev/null 2>/dev/null; then echo "yes" string_opts="-safe-string" else echo "no" fi ###################################################################### # Check camlp4 version printf "%s" "Checking for camlp4... " if camlp4; then if camlp4 -loaded-modules >/dev/null 2>/dev/null; then echo "3.10 style" camlp4_style="310" camlp4_opts="-package camlp4 -syntax camlp4o -ppopt pa_extend.cmo -ppopt q_MLast.cmo" else echo "3.09 style" echo "This is no longer supported. Upgrade to at least O'Caml 3.10" echo "ERROR" exit 1 fi else echo "not found" echo "Make sure the camlp4 command is in your PATH" echo "ERROR" exit 1 fi ###################################################################### # Write Makefile.conf echo "Writing Makefile.conf" cat <<_EOF_ >Makefile.conf # The Xstrp4 version: VERSION = $version # whether to enable -safe-string STRING_OPTS = $string_opts # Camlp4 style: CAMLP4_STYLE = $camlp4_style # Camlp4 options: CAMLP4_OPTS = $camlp4_opts _EOF_ ###################################################################### # Finish echo echo "Please check Makefile.conf." echo echo "You can now compile Xstrp4 by invoking" echo " make all" echo "for the bytecode compiler, and optionally by invoking" echo " make opt" echo "for the native-code compiler (if supported on your architecture)." echo "Finally, a" echo " make install" echo "will install the package(s)." xstrp4-1.8.2/sample.file0000644000175000017500000000003612666307734013551 0ustar gerdgerd$s ${f,%f} is not ${i,%d}\x21 xstrp4-1.8.2/sample.ml0000644000175000017500000001016312666307734013244 0ustar gerdgerd(* This is an example how to use the new syntactic elements: *) (**********************************************************************) (* interpolate *) (**********************************************************************) (* interpolate "string": * In the string literal brace expansion is performed. The following * notations are allowed: * $name expands to the value of the string variable 'name' * $Module.name expands to the value of the string variable 'name' * of 'Module' * ${name} same as $name * ${Module.name} same as $Module.name * ${name,%format} expands to the value of the variable 'name' which * has been converted to a string using "%format". * The format string may be anything allowed in printf. * ${Module.name,%format} works,too * \$ A dollar character * \ Expands to the empty string * All backslash sequences of normal string constants are allowed, too. * * NOTE: For non-string variables a format specification is required; * otherwise type checking is impossible. *) let s = "The number" in let f = 3.14 in let i = 42 in print_string interpolate "$s ${f,%f} is not ${i,%d}\n";; (**********************************************************************) (* interpolate file *) (**********************************************************************) (* interpolate file "filename": * expands to the contents of the file; brace expansion is performed * (see above). * If "filename" is written without "/", it is always searched in the * same directory as the source file being compiled. Otherwise "filename" * is interpreted as relative or absolute path name. * * IMPORTANT NOTE: Of course, the file is only read during compile time. *) let s = "The number" in let f = 3.14 in let i = 42 in print_string interpolate file "sample.file";; (**********************************************************************) (* include_file *) (**********************************************************************) (* include_file "filename": * expands to the contents of the file but _no_ brace expansion is performed. * If "filename" is written without "/", it is always searched in the * same directory as the source file being compiled. Otherwise "filename" * is interpreted as relative or absolute path name. * * IMPORTANT NOTE: Of course, the file is only read during compile time. * * Note: Up to xstrp4-1.4, this construction used the notation * "include file". In xstrp4-1.5, it was changed to "include_file" * to avoid ambiguities with O'Caml's built-in "include" directive. *) print_string "sample.file: "; print_string include_file "sample.file";; (**********************************************************************) (* <:here< quotations>> *) (**********************************************************************) (* It is also possible to use the 'here' quotation which does brace * expansion on its argument. This is sometimes easier to write because * the double quotes need no escaping. Of course, $ and \ characters * must still be escaped. * Only \$, \, \>, and \\ are allowed as backslash sequences. *) let s = "The number" in let f = 3.14 in let i = 42 in print_string <:here<\ The interpolation example was: print_string interpolate "\$s \${f,%f} is not \${i,%d}\n";; -- where s was replaced by "$s", f by "${f,%f}", and i by "${i,%d}". >> (**********************************************************************) (* Access to record fields *) (**********************************************************************) (* It is also possible to access record fields. Just use the standard * OCaml notation rcrd.field. *) type rcrd = { s: string; f: float; i: int; } let rcrd = {s = "The number"; f = 3.14; i = 42} in print_string interpolate "$rcrd.s ${rcrd.f,%f} is not ${rcrd.i,%d}\n";; xstrp4-1.8.2/xstrp4_here.ml0000644000175000017500000001036612666307734014237 0ustar gerdgerd(* $Id$ * ---------------------------------------------------------------------- * *) open Xstrp4_here_types open Camlp4.PreCast open Syntax let camlp4loc (loc1,loc2) = Loc.merge (Loc.of_lexing_position loc1) (Loc.of_lexing_position loc2) class camlp4reloc reloc = object inherit Ast.map method loc _ = reloc end let interpolated_expr lexbuf _loc = (* Parse [lexbuf], and generate the syntax tree for the corresponding expression. *) let rec parse_here_expr() = let tok = Xstrp4_here_lexer.token lexbuf in match tok with Textend -> [] | x -> x :: parse_here_expr () in let rec normalize_literals = (* - Concat adjacent literals * - Remove empty literals *) function [] -> [] | Literal("",_) :: tl -> normalize_literals tl | Literal(s1,(p1,_)) :: (Literal(s2,(_,p2))) :: tl -> normalize_literals((Literal(s1^s2,(p1,p2)))::tl) | hd :: tl -> hd :: (normalize_literals tl) in let fix_position p = { Lexing.pos_fname = Loc.file_name _loc; Lexing.pos_lnum = p.Lexing.pos_lnum + Loc.start_line _loc - 1; Lexing.pos_cnum = p.Lexing.pos_cnum + Loc.start_off _loc; Lexing.pos_bol = p.Lexing.pos_bol + Loc.start_bol _loc; } in let fix_positions = function Literal(s, (p1, p2)) -> Literal(s, (fix_position p1, fix_position p2)) | Variable(sl, fmt, (p1, p2)) -> Variable(sl, fmt, (fix_position p1, fix_position p2)) | other -> other in let toklist = List.map fix_positions (normalize_literals (parse_here_expr ())) in let toklist_ast = List.map (function Literal(s,lexloc) -> let _loc = camlp4loc lexloc in <:expr< $str:s$ >> | Variable (id,fmt,lexloc) -> let _loc = camlp4loc lexloc in (* Relocate the ident to the new location *) let id = (new camlp4reloc _loc)#ident id in let node = match fmt with | "%s" -> <:expr< $id:id$ >> | ("%d"|"%i") -> <:expr< Pervasives.string_of_int $id:id$ >> | _ -> <:expr< Printf.sprintf $str:fmt$ $id:id$ >> in node | Textend -> failwith "Xstrp4.here_expr") toklist in let rec mk_list_ast l = match l with [] -> <:expr@here< [] >> | x :: l' -> let ast_l' = mk_list_ast l' in <:expr@here< [ $x$ :: $ast_l'$ ] >> in let string_mod_ast = <:expr@here< $uid:"String"$ >> in let concat_val_ast = <:expr@here< $lid:"concat"$ >> in let string_concat_ast = <:expr@here< $string_mod_ast$ . $concat_val_ast$ >> in let concat_ast = <:expr@here< $string_concat_ast$ $str:""$ >> in let list_ast = mk_list_ast toklist_ast in let result_ast = <:expr@here< $concat_ast$ $list_ast$ >> in match toklist with [] -> <:expr@here< $str:""$ >> | [Literal s] -> List.hd toklist_ast (* = <:expr< $str:s$ >> *) | _ -> (* General case: *) result_ast ;; let here_expr _loc _loc_name s = let lexbuf = Lexing.from_string s in interpolated_expr lexbuf _loc ;; let interpolated_file filename _loc = let pathname = if Filename.is_implicit filename then Filename.concat (Filename.dirname (Loc.file_name _loc)) filename else filename in let f = open_in pathname in let lexbuf = Lexing.from_channel f in let _loc = Loc.of_tuple (pathname, 1, 0, 0, 1, 0, 0, false) in interpolated_expr lexbuf _loc ;; let included_file filename _loc = let pathname = if Filename.is_implicit filename then Filename.concat (Filename.dirname (Loc.file_name _loc)) filename else filename in let f = open_in pathname in let n = in_channel_length f in let s = Bytes.create n in really_input f s 0 n; close_in f; let s = Bytes.to_string s in <:expr< $str:s$ >> ;; let interpolation = Gram.Entry.mk "interpolation";; EXTEND Gram interpolation: [[ s = STRING -> let lexbuf = Lexing.from_string s in interpolated_expr lexbuf _loc ]]; expr: AFTER "simple" [[ "interpolate"; "file"; s = STRING -> interpolated_file s _loc | "interpolate"; expr = interpolation -> expr | "include_file"; s = STRING -> included_file s _loc ]]; END ;; Quotation.add "here" Syntax.Quotation.DynAst.expr_tag here_expr ;; xstrp4-1.8.2/xstrp4_here_lexer.mll0000644000175000017500000000461412666307734015611 0ustar gerdgerd(* $Id$ * ---------------------------------------------------------------------- * *) { open Xstrp4_here_types open Camlp4.PreCast let _loc = Loc.ghost let pos lexbuf = (Lexing.lexeme_start_p lexbuf, Lexing.lexeme_end_p lexbuf) } let ucletter = [ 'A' - 'Z' ] let lcletter = [ 'a' - 'z' '_' ] let acletter = ucletter | lcletter let value_id = ( acletter+ '.' )* lcletter acletter * let format = '%' [ '0' '-' ' ' ]* (* no more modifiers are supported by Ocaml *) ['0'-'9']* ( '.' ['0'-'9']* )? ( ( ['L' 'l' 'n'] [ 'd' 'i' 'u' 'x' 'X' 'o' ]) | [ 'd' 'i' 'u' 'x' 'X' 's' 'c' 'f' 'e' 'E' 'g' 'G' 'b' 'a' 't' ] ) rule token = parse '$' (value_id as vid) { Variable (id [] (Lexing.from_string vid), "%s", pos lexbuf) } | '$' '{' (value_id as vid) ( ',' (format as fmt))? '}' { let fmt = match fmt with | Some s -> s | None -> "%s" in Variable (id [] (Lexing.from_string vid), fmt, pos lexbuf) } | '$' { failwith "Bad $ expander" } | '\\' '\n' { Literal("", pos lexbuf) } | '\\' '$' { Literal("$", pos lexbuf) } | '\\' [ '0'-'9' ] [ '0'-'9' ] [ '0'-'9' ] { let s = Lexing.lexeme lexbuf in let n = int_of_string(String.sub s 1 3) in let lit = Printf.sprintf "%c" (Char.chr n) in Literal(lit, pos lexbuf) } (* | '\\' 'o' [ '0'-'7' ] [ '0'-'7' ] [ '0'-'7' ] { Literal (let s = Lexing.lexeme lexbuf in let n = int_of_string("0" ^ String.sub s 1 4) in Printf.sprintf "%c" (Char.chr n) ) } *) | '\\' 'x' [ '0'-'9' 'a'-'f' 'A'-'F' ] [ '0'-'9' 'a'-'f' 'A'-'F' ] { let s = Lexing.lexeme lexbuf in let n = int_of_string("0" ^ String.sub s 1 3) in let lit = Printf.sprintf "%c" (Char.chr n) in Literal(lit, pos lexbuf) } | '\\' _ { let lit = Lexing.lexeme lexbuf in Literal(lit, pos lexbuf) } | [^ '$' '\\']+ { let lit = Lexing.lexeme lexbuf in Literal(lit, pos lexbuf) } | eof { Textend } | _ { let lit = Lexing.lexeme lexbuf in Literal(lit, pos lexbuf) } and id acc = parse (ucletter acletter*) as uid { id (Ast.IdUid (_loc, uid) :: acc) lexbuf } | lcletter acletter* as lid { id (Ast.IdLid (_loc, lid) :: acc) lexbuf } | '.' { id acc lexbuf } | eof { Camlp4.PreCast.Ast.idAcc_of_list (List.rev acc) } xstrp4-1.8.2/xstrp4_here_types.ml0000644000175000017500000000064712666307734015464 0ustar gerdgerd(* $Id$ * ---------------------------------------------------------------------- * *) open Camlp4 open PreCast open Ast type here_clause = Literal of (string * (Lexing.position * Lexing.position)) | Variable of (ident * string * (Lexing.position * Lexing.position)) (* [ M1; M2; ...; value ],f,pos1,pos2 * <==> M1.M2. ... .value with format f from position pos1 to pos2 *) | Textend ;; xstrp4-1.8.2/RELEASE0000644000175000017500000000000612666307734012427 0ustar gerdgerd1.8.2