-- --- SDE-COPYRIGHT-NOTE-BEGIN ---
-- This copyright note is auto-generated by ./scripts/Create-CopyPatch.
--
-- Filename: package/.../lua-pcre/string.lua
-- Copyright (C) 2006 The T2 SDE Project
-- Copyright (C) 2006 Juergen "George" Sawinski
--
-- More information can be found in the files COPYING and README.
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; version 2 of the License. A copy of the
-- GNU General Public License can be found in the file COPYING.
-- --- SDE-COPYRIGHT-NOTE-END ---

require "@RX@"

--[[ TODO -------------------------------------------------------------------
 - describe string.{cflags,eflags}
 - gsub does not handle eflags
--]] ------------------------------------------------------------------------

--[[ DESCRIPTION ------------------------------------------------------------

This file replaces the default string library routines "find", "gsub",
"gmatch" with mostly similiarly behaving equivalents with regular
expression syntax patterns.

The original functions are stored in the "string.orig" table.

Additional methods:

  string.study([<boolean>])

    This function causes the string replacement functions to store the
    regular expression if the argument is empty or "true". The default
    compile and execution flags cannot be changed then, however.

    Supplying "false" as argument clears the regular expression store.

  string.cflags(...)

  string.eflags(...)

--]] ------------------------------------------------------------------------

-- original string library functions
string.orig = {
  find   = string.find,
  gsub   = string.gsub,
  gmatch = string.gmatch,
}

-- default compile and excuation flags
local __default_flags__ = {
  compile = nil,
  execute = nil,
}

-- string.study -------------------------------------------------------------
local __study__ = nil

local function study_regex_new(pattern)
  assert(__study__, "study_regex_new called outside study mode.")

  if not __study__[pattern] then
    __study__[pattern] = @RX@.new(pattern, __default_flags__.compile)
  end

  return __study__[pattern]
end

local function regex_new(pattern)
  return @RX@.new(pattern, __default_flags__.compile)
end

local RX = regex_new

function string.study(what)
  if what == nil then what = true end

  if what then
    if not __study__ then __study__ = {} end
    RX = study_regex_new
  else
    if __study__ then
      for k,v in pairs(__study__) do
        v:__gc()
      end
    end

    __study__ = nil
    RX = regex_new
  end
end

-- string.cflags ------------------------------------------------------------
function string.cflags(...)
  if __study__ then error("unable to set compile flags in study mode") end

  __default_flags__.compile = @RX@.flags(arg)
end

-- string.cflags ------------------------------------------------------------
function string.eflags(...)
  if __study__ then error("unable to set execution flags in study mode") end

  __default_flags__.execute = @RX@.flags(arg)
end

-- string.find regex replacement --------------------------------------------
function string.find(str, pattern, start, plain)
  local idx_start, idx_end, capture

  if plain then
    return string.orig.find(s, pat, init, plain)
  end

  idx_start, idx_end, capture =
    RX(pattern):match(str, start, __default_flags__.execute)

  return idx_start,idx_end,unpack(capture)
end

-- string.gmatch regex replacement ------------------------------------------

-- simple result table iterator
local function @RX@_next(t)
  if t then
    local row = t[1]
    table.remove(t, 1)

    if row then return unpack(row) end
  end
end

function string.gmatch(str, pattern)
  local t = {} -- table of result tables

  local function capture(str, sub) -- record results in t
    table.insert(t, sub)
  end

  -- execute regex
  RX(pattern):gmatch(str, capture, __default_flags__.execute)

  -- return our own simple iterator
  return @RX@_next, t
end

-- string.gsub regex replacement --------------------------------------------
function string.gsub(str, pat, repl, n)
  -- FIXME execution flags
  return generic_gsub(RX, str, pat, repl, n)
end

-- original lrexlib/gsub.lua: