Skip to content

Instantly share code, notes, and snippets.

@silverweed
Last active April 13, 2023 13:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save silverweed/05227fd7046a017bbe5034f0fb27ac40 to your computer and use it in GitHub Desktop.
Save silverweed/05227fd7046a017bbe5034f0fb27ac40 to your computer and use it in GitHub Desktop.
// @author silverweed
// Finds all svg files under the current directory and appends a newline to them if they don't end with a newline already.
#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <strsafe.h>
BOOL verbose = 0;
// Concats path1 and path2 into abs_path
static BOOL concat_path(TCHAR* abs_path, size_t max_abs_path_len, TCHAR* path1, TCHAR* path2)
{
HRESULT res = StringCchCopy(abs_path, max_abs_path_len, path1);
if (FAILED(res)) {
fprintf(stderr, "Failed to copy path %s to abs_path\n", path1);
return 0;
}
res = StringCchCat(abs_path, max_abs_path_len, "\\");
if (FAILED(res)) {
fprintf(stderr, "Failed to cat '\\' to new dir.\n");
return 0;
}
res = StringCchCat(abs_path, max_abs_path_len, path2);
if (FAILED(res)) {
fprintf(stderr, "Failed to cat path %s to abs_path\n", path2);
return 0;
}
return 1;
}
static int process_svg(TCHAR *svg_file_name) {
if (verbose) printf("Opening %s...\n", svg_file_name);
HANDLE svg_file = CreateFile(svg_file_name, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (!svg_file) {
fprintf(stderr, "Failed to open %s: %d\n", svg_file_name, GetLastError());
return 0;
}
DWORD res;
res = SetFilePointer(svg_file, -2, NULL, FILE_END);
if (res == INVALID_SET_FILE_POINTER) {
fprintf(stderr, "Failed to seek end of file %s.\n", svg_file_name);
return 0;
}
char buf[3] = {0};
DWORD bytes_read;
res = ReadFile(svg_file, buf, 2, &bytes_read, NULL);
if (!res) {
fprintf(stderr, "Error reading file %s: %d\n", svg_file_name, GetLastError());
return 0;
}
//printf("Read %d bytes from file.\n", bytes_read);
//printf("Last 2 bytes: '%s' %hhx %hhx\n", buf, buf[0], buf[1]);
if (buf[1] != '\n') {
printf("Appending newline to %s...\n", svg_file_name);
// Append newline
SetFilePointer(svg_file, 0, NULL, FILE_END);
DWORD bytes_written;
res = WriteFile(svg_file, "\n", 1, &bytes_written, NULL);
if (!res) {
fprintf(stderr, "Error writing file %s: %d\n", svg_file_name, GetLastError());
return 0;
}
if (bytes_written != 1) {
fprintf(stderr, "Error: %d bytes were written to %s (expected: 1)\n", bytes_written, svg_file_name);
return 0;
}
} else {
printf("%s already ends with a newline, not modifying\n", svg_file_name);
}
return 1;
}
static void process_next_dir(TCHAR *dir)
{
TCHAR query[MAX_PATH];
HRESULT res = StringCchCopy(query, MAX_PATH, dir);
if (FAILED(res)) {
fprintf(stderr, "Failed to copy %s to query.\n", dir);
return;
}
res = StringCchCat(query, MAX_PATH, "\\*");
if (FAILED(res)) {
fprintf(stderr, "Failed to concatenate to query.\n");
return;
}
WIN32_FIND_DATA find_data;
HANDLE find_hdl = FindFirstFile(query, &find_data);
if (find_hdl == INVALID_HANDLE_VALUE) {
fprintf(stderr, "Failed to find the first file under %s.\n", query);
return;
}
if (verbose) printf("Processing %s\n", dir);
do {
if (find_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN || find_data.cFileName[0] == '.') {
continue;
}
if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
TCHAR new_dir[MAX_PATH];
if (concat_path(new_dir, MAX_PATH, dir, find_data.cFileName)) {
// Recurse
process_next_dir(new_dir);
}
} else {
TCHAR *ext = strrchr(find_data.cFileName, '.');
if (!ext) {
continue;
}
if (strcmp(ext, ".svg") == 0) {
TCHAR abs_svg_path[MAX_PATH];
concat_path(abs_svg_path, MAX_PATH, dir, find_data.cFileName);
process_svg(abs_svg_path);
}
}
} while (FindNextFile(find_hdl, &find_data));
}
int main(int argc, char **argv)
{
if (argc > 1 && strcmp(argv[1], "-v") == 0)
verbose = 1;
TCHAR cwd[MAX_PATH];
DWORD written = GetCurrentDirectory(sizeof(cwd) / sizeof(TCHAR), cwd);
if (!written) {
fprintf(stderr, "Failed to get the current directory.\n");
return 1;
}
process_next_dir(cwd);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment