commit all archived files
This commit is contained in:
parent
3c3723ccbc
commit
6216edaea9
15
README.md
Normal file
15
README.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# rren
|
||||||
|
|
||||||
|
![](https://img.shields.io/badge/written%20in-C%2B%2B-blue)
|
||||||
|
|
||||||
|
A command-line batch renaming client for Windows, using TR1 regexes.
|
||||||
|
|
||||||
|
Supports ECMA regexes, string find/replace, and propercasing using globbing file masks. Uses TR1 regexes (so it semi-predates C++11).
|
||||||
|
|
||||||
|
Original project page: https://code.google.com/p/rren/
|
||||||
|
|
||||||
|
|
||||||
|
## Download
|
||||||
|
|
||||||
|
- [⬇️ rren.exe](dist-archive/rren.exe) *(24.50 KiB)*
|
||||||
|
- [⬇️ rren.cpp](dist-archive/rren.cpp) *(5.72 KiB)*
|
238
dist-archive/rren.cpp
Normal file
238
dist-archive/rren.cpp
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
// rren
|
||||||
|
|
||||||
|
#define RREN_VERSION L"1.1"
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#ifndef _WIN32_WINNT
|
||||||
|
#define _WIN32_WINNT 0x0500
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#define EXIT_SUCCESS 0
|
||||||
|
#define EXIT_FAILURE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <regex>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
struct twostr {
|
||||||
|
wstring first;
|
||||||
|
wstring second;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum RREN_MODES {
|
||||||
|
RREN_MODE_NONE,
|
||||||
|
RREN_MODE_REGEX,
|
||||||
|
RREN_MODE_REPLACE,
|
||||||
|
RREN_MODE_PCASE
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BUFF 255
|
||||||
|
typedef vector<twostr> V2STR;
|
||||||
|
V2STR vFiles;
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
#define PRINT_ARGS wprintf( \
|
||||||
|
L"rren v" RREN_VERSION L"\n" \
|
||||||
|
L"Usage: rren mode filemask <args>\n" \
|
||||||
|
L" -e ECMA Regex rren -e filemask \"find\" \"replace\"\n" \
|
||||||
|
L" -r Find/Replace rren -r filemask \"find\" \"replace\"\n" \
|
||||||
|
L" -p Proper case rren -p filemask\n")
|
||||||
|
#define PRINT_INVALID_ARGS \
|
||||||
|
wprintf(L"Invalid number of arguments.\n\n"); \
|
||||||
|
PRINT_ARGS;
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// Applies a find/replace ECMAScript regex over all twostr::first in vFiles
|
||||||
|
bool do_regex(wchar_t* wcFind, wchar_t* wcReplace) {
|
||||||
|
|
||||||
|
// Initialise variables
|
||||||
|
tr1::wregex rFind;
|
||||||
|
wstring sReplace = wcReplace;
|
||||||
|
try {rFind.assign(wcFind);} catch (...) {
|
||||||
|
wprintf(L"Invalid search regex.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop over vFiles
|
||||||
|
for (V2STR::iterator vi = vFiles.begin(); vi != vFiles.end(); vi++) {
|
||||||
|
vi->second = tr1::regex_replace(vi->first, rFind, sReplace);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// Applies a find/replace string search over all twostr::first in vFiles
|
||||||
|
bool do_replace(wchar_t* wcFind, wchar_t* wcReplace) {
|
||||||
|
|
||||||
|
// Initialise variables
|
||||||
|
if (std::wstring(wcReplace).find(wcFind) != wstring::npos) {
|
||||||
|
wprintf(L"Recursive find/replace.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
size_t pos = wstring::npos;
|
||||||
|
size_t flen = wcslen(wcFind);
|
||||||
|
|
||||||
|
// Loop over vFiles
|
||||||
|
for (V2STR::iterator vi = vFiles.begin(); vi != vFiles.end(); vi++) {
|
||||||
|
vi->second.assign(vi->first);
|
||||||
|
for(;;) {
|
||||||
|
pos = vi->second.find(wcFind);
|
||||||
|
if (pos == wstring::npos) break;
|
||||||
|
vi->second.replace(pos, flen, wcReplace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// Returns the proper-case version of a wstring
|
||||||
|
wstring proper_case(wstring wsInputString) {
|
||||||
|
wstring wBuff(wsInputString);
|
||||||
|
size_t pos = wstring::npos;
|
||||||
|
|
||||||
|
// All lowercase
|
||||||
|
for (;;) {
|
||||||
|
if (++pos > wBuff.size()) break;
|
||||||
|
wBuff[pos] = towlower(wBuff[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// First character becomes uppercase
|
||||||
|
if (wBuff.size() > 0) wBuff[0] = towupper(wBuff[0]);
|
||||||
|
|
||||||
|
// Everything following a space becomes uppercase
|
||||||
|
pos = 0;
|
||||||
|
for (;;) {
|
||||||
|
pos = wBuff.find(L" ", pos+1);
|
||||||
|
if (pos == wstring::npos) break;
|
||||||
|
if (wBuff.size() >= (pos+1)) {
|
||||||
|
wBuff[pos+1] = towupper(wBuff[pos+1]);
|
||||||
|
} else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wBuff;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// Modifies the case of all twostr::first in vFiles
|
||||||
|
bool do_pcase() {
|
||||||
|
for (V2STR::iterator vi = vFiles.begin(); vi != vFiles.end(); vi++) {
|
||||||
|
vi->second = proper_case(vi->first);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// Program entry point
|
||||||
|
int wmain(int argc, wchar_t* argv[]) {
|
||||||
|
|
||||||
|
// Variables
|
||||||
|
WIN32_FIND_DATA wfd;
|
||||||
|
HANDLE hFind = 0;
|
||||||
|
wchar_t wCwd[BUFF] = {0};
|
||||||
|
wstring sSearch;
|
||||||
|
twostr tsNext;
|
||||||
|
int iMode = RREN_MODE_NONE;
|
||||||
|
|
||||||
|
// Validate command-line arguments
|
||||||
|
if (argc < 3) {
|
||||||
|
PRINT_ARGS; return EXIT_FAILURE;
|
||||||
|
} else if (_wcsnicmp(argv[1], L"-e", 2)==0) {
|
||||||
|
if (argc != 5) {
|
||||||
|
PRINT_INVALID_ARGS; return EXIT_FAILURE;
|
||||||
|
} else iMode = RREN_MODE_REGEX;
|
||||||
|
} else if (_wcsnicmp(argv[1], L"-r", 2)==0) {
|
||||||
|
if (argc != 5) {
|
||||||
|
PRINT_INVALID_ARGS; return EXIT_FAILURE;
|
||||||
|
} else iMode = RREN_MODE_REPLACE;
|
||||||
|
} else if (_wcsnicmp(argv[1], L"-p", 2)==0) {
|
||||||
|
if (argc != 3) {
|
||||||
|
PRINT_INVALID_ARGS; return EXIT_FAILURE;
|
||||||
|
} else iMode = RREN_MODE_PCASE;
|
||||||
|
} else {
|
||||||
|
wprintf(L"Invalid mode.\n");
|
||||||
|
PRINT_ARGS;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create search mask from working directory
|
||||||
|
GetCurrentDirectory(BUFF-1, wCwd);
|
||||||
|
if (!wcslen(wCwd)) return EXIT_FAILURE;
|
||||||
|
sSearch.assign(wCwd);
|
||||||
|
sSearch.append(L"\\");
|
||||||
|
sSearch.append(argv[2]);
|
||||||
|
|
||||||
|
// Get all file matches
|
||||||
|
hFind = FindFirstFileW(sSearch.c_str(), &wfd);
|
||||||
|
if (!hFind) {
|
||||||
|
wprintf(L"No files.\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
vFiles.clear();
|
||||||
|
tsNext.first.clear();
|
||||||
|
tsNext.second.clear();
|
||||||
|
do {
|
||||||
|
if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||||
|
tsNext.first.assign(wfd.cFileName);
|
||||||
|
vFiles.push_back(tsNext);
|
||||||
|
}
|
||||||
|
} while (FindNextFile(hFind, &wfd));
|
||||||
|
if (vFiles.empty()) {
|
||||||
|
wprintf(L"No files.\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply transform based on argument
|
||||||
|
switch (iMode) {
|
||||||
|
case RREN_MODE_REGEX:
|
||||||
|
if (!do_regex(argv[3], argv[4])) return EXIT_FAILURE;
|
||||||
|
break;
|
||||||
|
case RREN_MODE_REPLACE:
|
||||||
|
if (!do_replace(argv[3], argv[4])) return EXIT_FAILURE;
|
||||||
|
break;
|
||||||
|
case RREN_MODE_PCASE:
|
||||||
|
if (!do_pcase()) return EXIT_FAILURE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
wprintf(L"Invalid mode.\n");
|
||||||
|
PRINT_ARGS; return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display all results
|
||||||
|
for (V2STR::iterator vi = vFiles.begin(); vi != vFiles.end(); vi++) {
|
||||||
|
wprintf(L"%s\n--> %s\n", vi->first.c_str(), vi->second.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prompt for apply
|
||||||
|
wprintf(L"\nApply changes? (y/n) ");
|
||||||
|
wint_t gwc = getwchar();
|
||||||
|
if (gwc == 'Y' || gwc == 'y') {
|
||||||
|
wprintf(L"Applying changes... ");
|
||||||
|
int count = vFiles.size(), done = 0;
|
||||||
|
for (V2STR::iterator vi = vFiles.begin(); vi != vFiles.end(); vi++) {
|
||||||
|
if (MoveFile(vi->first.c_str(), vi->second.c_str()) == TRUE) done++;
|
||||||
|
}
|
||||||
|
wprintf(L"done (%d / %d).\n", done, count);
|
||||||
|
} else {
|
||||||
|
wprintf(L"No changes were made.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
BIN
dist-archive/rren.exe
Normal file
BIN
dist-archive/rren.exe
Normal file
Binary file not shown.
BIN
doc/rren.png
Normal file
BIN
doc/rren.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.5 KiB |
Reference in New Issue
Block a user