--| REPLACER v0.1 |------------------------------------------------------------+
--| Fabio [Allanon] Falcucci                                        05.12.2006 |
--+----------------------------------------------------------------------------+
--| String replacer utility
--| Search within <filename> the string(s) <search> and replace it with 
--| the <replacer> string.
--| 
--| Can be used with the commands "Lua" or "Amilua"
--|
--| Usage: amilua Replacer.lua <option> <filename> <search> <replace>
--|    <options>    Option's flags as follow:
--|                 B   = Backup (make a backup before elaboration)
--|                 V   = Full Verbose Mode (activate verbose mode)
--|                 v   = Short Verbose Mode (activate short verbose mode)
--|    <filename>   File to elaborate
--|    <search>     String to search and replace with...
--|    <replace>    ...the replacer string.
--|
--| The script returns false in case of error otherwise returns true
--|
--| Example:
--| Shell> lua Replacer.lua Bv Ram:sourcefile.txt "Me & you" "Me and You"
--| 
--| In the file "Ram:sourcefile.txt" all "Me & You" occurances will be replaced
--| with "Me and You", line my line.
--+-----------------------------------------------------------------------------

--------------------------------------------------------------------------------
function Exists(filename)
--+-----------------------------------------------------------------------------
--| Return true if the given <filename> exists otherwise returns false.
--|    INPUT:  filename		--> File name to check
--|    OUTPUT: check		--> true if <filename> exists, otherwise false
--|            error		--> System Error/Warning description
--+-----------------------------------------------------------------------------
   --> Try to open the provided <filename>
   if filename == nil then
      filename = ""
   end
   
   fh, msg = io.open(filename)
   
   --> Check if the filehandle is valid
   if fh == nil then 
      --> <filename> does not exists or is unavailable, in the last case the
      --> variable <msg> should be checked
      return false, msg
   else
      --> <filename> exists and is available
      fh:close()
      return true, msg
   end
end
--------------------------------------------------------------------------------

--| Check the arguments |-------------------------------------------------------
if arg[1] == nil then
    --> no given arguments, print usage
    print("Replacer v0.1")
    print("-------------")
    print("Usage: lua Replacer <filename> <options> <search> <replace>")
    print("       <options>  = B (make a backup before elaboration) optional parameter")
    print("                  = V (verbose mode)")
    print("       <filename> = file to scan")
    print("       <search>   = string to search and replace with...")
    print("       <replace>  = ...the replacer string\n")
    return false
else
    --| Load & check all arguments |--------------------------------------------
    arg1 = arg[1]
    arg2 = arg[2]
    arg3 = arg[3]
    arg4 = arg[4]
    if arg4 == nil then
        --> gotten 3 arguments (no options specified)
        options  = nil
        filename = arg1
        search   = arg2
        replace  = arg3
    else
        --> gotten 4 arguments
        options  = arg1
        filename = arg2
        search   = arg3
        replace  = arg4
    end
    
    if filename == nil then
        print("Please, specify a filename")
        return false
    end
    
    if search == nil then
        print("Please, specify a string to be replaced")
        return false
    end
    
    if replace == nil then
        print("Please, specify a replacer string")
        return false
    end
    
    --> Check if filename exists
    if Exists(filename) then
        if options ~= nil then
            --| Parse supported options |---------------------------------------
            
            --> check for <V> (verbose mode)
            s = string.find(options, "V")
            if s ~= nil then
                --> Verbose flag found, activate it
                verbose = true
            else
                verbose = nil
            end

            --> check for <v> (short verbose mode)
            s = string.find(options, "v")
            if s ~= nil then
                --> Short Verbose flag found, activate it
                shverbose = true
            else
                shverbose = nil
            end
            
            --> check for <B> (Backup)
            s = string.find(options, "B")
            if s ~= nil then            
                --> Backup flag found, make a backup
                backfilename = filename..".ReplacerBackup"
                if verbose or shverbose then print("Creating a backup file <"..backfilename..">") end
                os.execute("copy "..filename.." ".."backupfilename")
                if verbose then print("Done.") end
            end
            
            --> ... continue with options parsing...
            
        end

        --| Pocess all file's lines and stores the processed lines |------------
        newfile = {}
        nflines = 0
        repnr   = 0
        
        for line in io.lines(filename) do
            nflines = nflines + 1
            if verbose then print("Processing line "..tostring(nflines)..":"..line) end            
            newfile[nflines], rn = string.gsub(line, search, replace)
            repnr = repnr + rn
        end
        if shverbose then print("Processed "..tostring(nflines).." lines") end

        --| Rebuild the processed file |----------------------------------------
        if verbose or shverbose then print("Writing processed file") end
        filehdl = io.open(filename, "w+")
        for i = 1, nflines do
            if verbose then print("Writing line "..tostring(i)..":"..newfile[i]) end
            if i == nflines then
                filehdl:write(newfile[i])
            else
                filehdl:write(newfile[i].."\n")
            end
        end
        filehdl:close()
        if verbose or shverbose then
            print("All done, replaced "..tostring(repnr).." strings.")
        end
        
        --| PROCESS COMPLETED! |------------------------------------------------
        return true
        
    else
        --> the given filename doesn't exists, print an error message
        print("Replacer error message:")
        print("The filename <"..filename.."> doesn't exists.\n")
        return false
    end
end
