Source

ocaml-pkgbuild / pbexpand.ml

open Expy
open Expl

module Pbexpand =
  struct
    let find_unescaped_from str idx findme =
      let rec find_from findme str idx len =
        let foundidx = String.index_from str idx findme in
        if str.[foundidx-1] != '\\' || foundidx == 0 then
          foundidx
        else if (foundidx + 1) == len then
          raise Not_found
        else
          find_from findme str (foundidx + 1) len
      in find_from findme str idx (String.length str)

    exception Unbalanced_quotes of int

    let string str =
      let rec rawexpand str =
      pbexp pbexplex (Lexing.from_string str)

      and split_and_rec str len begidx endidx action =
        let oldstr = String.sub str 0 begidx in
        let midstr = String.sub str (begidx+1) (endidx-1-begidx) in
        let remstr = (* remaining str to process *)
          if endidx == (len-1) then ""
          else String.sub str (endidx+1) (len-(endidx+1)) in
        try
          (rawexpand oldstr)
          ^ (action midstr)
          ^ (expand_from remstr 0 (String.length remstr))
        with
          Unbalanced_quotes(idx) -> raise (Unbalanced_quotes (idx+endidx+1))
              
      and expand_from str idx len =
        if idx == len then
          rawexpand str
        else try
          match str.[idx] with
        (* Expands everything except text in single-quotes *)
            '\'' ->
              let endidx = String.index_from str (idx+1) '\'' in
              split_and_rec str len idx endidx (fun str -> str)
          | '"' ->
              let endidx = find_unescaped_from str (idx+1) '"' in
              split_and_rec str len idx endidx rawexpand
          | _ ->
              expand_from str (idx+1) len
        with
          Invalid_argument(_) | Not_found -> raise (Unbalanced_quotes idx)

      in

      reset_pbexp () ;
      expand_from str 0 (String.length str)

    let list strlist = List.map string strlist
  end
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.