View Raw SPL
/*****************************************************************************
*                                                                            *
*   FILEREPCHAR.SPL Copyright (C) 2012 DSP Development Corporation           *
*                               All Rights Reserved                          *
*                                                                            *
*   Author:       Randy Race                                                 *
*                                                                            *
*   Synopsis:     Replaces a character in a file                             *
*                                                                            *
*   Revisions:    25 Jun 2012  RRR  Creation                                 *
*                 26 Jul 2012  RRR  file spec, tempname flag                 *
*                                                                            *
*****************************************************************************/


#if @HELP_FILEREPCHAR

    FILEREPCHAR

    Purpose: Replaces all occurrences of a character in one or more files.

    Syntax:  FILEREPCHAR("filespec", "inchar", "outchar", recurse, usetemp)

             "filespec" - A string, the list of files to process. Filespec
                          can include wildcard characters such as * and ?.

               "inchar" - Optional. A string, the input character to
                          replace. Defaults to ",".

              "outchar" - Optional. A string, the replacement character.
                          Defaults to ".".

                recurse - Optional, an integer. Recurse into sub-directories
                          if found.

                             0: Do not recurse (default).

                             1: Recurse.

                usetemp - Optional, an integer. Write changes to a temporary
                          file instead of overwriting the original file.

                             0: Overwrite original file (default).

                             1: Use a temporary file name. The temp file
                                name is derived from the original file
                                name as "temp_XXX" where "XXX" is the
                                original file name.

    Returns: An integer, the number of character replacements.

    Example:
             filerepchar("test.txt")

             Replaces all occurrences of "," with "." in the file
             "test.txt";

    Example:
             filerepchar("\temp\test*.txt", "X", "Y")

             Replaces all occurrences of "X" with "Y" in files located
             in the \temp folder with a name that begins with "test"
             and extension ".txt".

    Example:
             filerepchar("\temp\test*.txt", "X", "Y", 1, 1)

             Replaces all occurrences of "X" with "Y" in files located
             in the\temp folder with a name that begins with "test" and
             extension ".txt". The sub-folders of \temp are also searched.
             The resulting output files begin with "temp_".

    Remarks:
             FILEREPCHAR replaces all occurrences of a single input
             character with a single output character.

             See FILESTRREP for a slower, but more general string replacement
             routine.

    See Also:
             Filestrrep
             Replace
             Strrep
#endif


/* replaces a character in one or more files in a directory */
filerepchar(filespec, srcstr, targstr, recurse, usetemp)
{
        local dirlist, filelist, file, filedir, temp, i, j, cnt = 0;

        if (argc < 5)
        {
                if (argc < 4)
                {
                        if (argc < 3)
                        {
                                if (argc < 2)
                                {
                                        if (argc < 1)
                                        {
                                                error("filerepchar - file specification required");
                                        }

                                        srcstr = ",";
                                }

                                targstr = ".";
                        }
                
                        recurse = 0;
                }

                usetemp = 0;
        }

        /* check inputs */
        if (strlen(srcstr) == 0 || strlen(filespec) == 0)
        {
                return(0);
        }

        /* get directory */
        (dir, temp) = dirpath(filespec, 1);

        /* get newline delimited filelist */
        filelist = filerepchar_filelist(filespec, recurse);

        i = 1;

        while (1)
        {
                /* get file name from list */
                file = strget(i, filelist, strescape("\n"));
                
                if (strlen(file) > 0)
                {
                        /* get directory */
                        (filedir, temp) = dirpath(file, 0);
                        
                        if (strlen(filedir) <= 0)
                        {
                                /* fullname */
                                file = dir + file;
                        }

                        /* replace string */
                        cnt += filerepchar_replace(srcstr, targstr, file, usetemp);
                        i++;
                }
                else
                {
                        break;
                }
        }
        
        return(cnt);
}


/* returns a newline delimited list of files */
filerepchar_filelist(spec, recurse)
{
        local tempfile, cmd, options, s = "";

        if (argc < 2)
        {
                if (argc < 1) spec = "*.*";
                
                recurse = 0;
        }

        /* flag to recurse into sub-directories */
        options = recurse ? "/S" : "";

        /* build temporary file */
        tempfile = getmiscpath(1, 1) + "templist.txt";

        /* directory listing command */
        cmd = sprintf('dir "%s" /b %s > "%s"', spec, options, tempfile);

        /* run listing */
        run(cmd, -1);

        /* check tempfile existence */
        if (fstat(tempfile) > 0)
        {
                /* return listing as a string */
                s = strfile(tempfile, 0, 1, 0, 0);
                delfile(tempfile);
        }
        
        return(s);
}


/* replace srcstr with targstr in a file */
filerepchar_replace(instr, outstr, fname, usetemp)
{
        local data, newdata, binser, num = 0, p, n;

        /* read file as unsigned bytes */
        data = readb(fname, ubyte);

        /* condition series */
        binser = data == charstr(instr);

        /* number of replacements */
        num = castint(sum(binser));

        /* replace instr with outstr */
        newdata = replace(data, binser, charstr(outstr));

        /* check if data changed */
        if (any(data - newdata))
        {
                if (usetemp)
                {
                        /* filename components */
                        (p, n) = dirpath(fname);

                        /* prepend "temp_" */
                        outfname = p + "temp_" + n;
                }
                else
                {
                        outfname = fname;
                }
        
                /* write temp file as unsigned bytes */
                writeb(outfname, ubyte, 1, newdata);
        }

        return(num);
}


/* error handler to ignore empty files */
filerepchar_replace_error()
{
        return(0);
}