summaryrefslogtreecommitdiffstatshomepage
path: root/src/tools/srcclean.cpp
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2015-11-08 12:56:12 +0100
committer Miodrag Milanovic <mmicko@gmail.com>2015-11-08 12:56:12 +0100
commit7c19aac60e12d6f5ea301bdb34d7826a01e0b06f (patch)
treef310d86aa2c6bfc19d115307dedde4eb0cd52dad /src/tools/srcclean.cpp
parenta57b46ae933badd7441ce1644711dbb851e2b504 (diff)
Rename *.c -> *.cpp in our source (nw)
Diffstat (limited to 'src/tools/srcclean.cpp')
-rw-r--r--src/tools/srcclean.cpp402
1 files changed, 402 insertions, 0 deletions
diff --git a/src/tools/srcclean.cpp b/src/tools/srcclean.cpp
new file mode 100644
index 00000000000..24db9bca880
--- /dev/null
+++ b/src/tools/srcclean.cpp
@@ -0,0 +1,402 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles, smf
+/***************************************************************************
+
+ srcclean.c
+
+ Basic source code cleanear.
+
+****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+
+#include "corestr.h"
+#include "osdcore.h"
+
+
+/***************************************************************************
+ CONSTANTS & DEFINES
+***************************************************************************/
+
+#define MAX_FILE_SIZE (32 * 1024 * 1024)
+
+
+
+/***************************************************************************
+ GLOBAL VARIABLES
+***************************************************************************/
+
+static UINT8 original[MAX_FILE_SIZE];
+static UINT8 modified[MAX_FILE_SIZE];
+
+
+static int le_convert(char *buffer, int size)
+{
+ char *pos;
+ char *end = buffer + size;
+
+ /* brute force */
+ *end = 0;
+ pos = strchr(buffer, 0x0d);
+ while (pos != NULL)
+ {
+ memmove(pos, pos+1,end - pos + 1);
+ size--;
+ buffer = pos + 1;
+ pos = strchr(buffer, 0x0d);
+ }
+ return size;
+}
+
+/***************************************************************************
+ MAIN
+***************************************************************************/
+
+int main(int argc, char *argv[])
+{
+ bool unix_le = false;
+ int removed_tabs = 0;
+ int added_tabs = 0;
+ int removed_spaces = 0;
+ int removed_continuations = 0;
+ int fixed_dos_style = 0;
+ int fixed_mac_style = 0;
+ int fixed_nix_style = 0;
+ int added_newline = 0;
+ int removed_newlines = 0;
+ int src = 0;
+ int dst = 0;
+ bool in_multiline_comment = false;
+ bool in_singleline_comment = false;
+ int indent_multiline_comment = 0;
+ int in_c_string = FALSE;
+ int hichars = 0;
+ bool is_c_file;
+ bool is_xml_file;
+ const char *ext;
+ FILE *file;
+ int bytes;
+ int col = 0;
+ int escape = 0;
+ int consume = 0;
+ const int tab_size = 4;
+ bool arg_found = true;
+ bool dry_run = false;
+
+ while (arg_found && argc > 1) {
+ if (strcmp(argv[1], "-u") == 0)
+ {
+ unix_le = true;
+ argc--;
+ argv++;
+ }
+ else if (strcmp(argv[1], "-d") == 0)
+ {
+ dry_run = true;
+ argc--;
+ argv++;
+ }
+ else
+ arg_found = false;
+
+ }
+
+ /* print usage info */
+ if (argc < 2)
+ {
+ printf("Usage:\nsrcclean [-u] [-d] <file>\n");
+ return 0;
+ }
+
+ /* read the file */
+ file = fopen(argv[1], "rb");
+ if (file == NULL)
+ {
+ fprintf(stderr, "Can't open %s\n", argv[1]);
+ return 1;
+ }
+ bytes = fread(original, 1, MAX_FILE_SIZE, file);
+ fclose(file);
+
+ /* check whether we have dos line endings and are in unix mode */
+ if (unix_le && (strchr((char *) original, 0x0d) != NULL))
+ fixed_dos_style = 1;
+
+ /* determine if we are a C file */
+ ext = strrchr(argv[1], '.');
+ is_c_file = (ext && (core_stricmp(ext, ".c") == 0 || core_stricmp(ext, ".h") == 0 || core_stricmp(ext, ".cpp") == 0 || core_stricmp(ext, ".inc") == 0 || core_stricmp(ext, ".lst") == 0));
+ is_xml_file = (ext && core_stricmp(ext, ".xml") == 0);
+
+ /* rip through it */
+ for (src = 0; src < bytes; )
+ {
+ UINT8 ch = original[src++];
+
+ if (consume == 0)
+ {
+ /* C-specific handling */
+ if (is_c_file)
+ {
+ /* check for string/char literals */
+ if ((ch == '"' || ch == '\'') && !in_multiline_comment && !in_singleline_comment )
+ {
+ if (ch == in_c_string && !escape)
+ in_c_string = 0;
+ else if (!in_c_string)
+ in_c_string = ch;
+ }
+
+ /* Update escape state */
+ if (in_c_string)
+ escape = (ch == '\\') ? !escape : 0;
+
+ if (!in_c_string && !in_singleline_comment)
+ {
+ /* track whether or not we are within a C-style comment */
+ if (!in_multiline_comment && ch == '/' && original[src] == '*')
+ {
+ in_multiline_comment = true;
+ if (col > 0 && modified[dst-1] == 0x09)
+ {
+ indent_multiline_comment = col;
+ }
+ else
+ {
+ indent_multiline_comment = 0;
+ }
+ consume = 2;
+ }
+ else if (in_multiline_comment && ch == '*' && original[src] == '/')
+ {
+ in_multiline_comment = false;
+ indent_multiline_comment = 0;
+ consume = 2;
+ }
+
+ /* track whether or not we are within a C++-style comment */
+ else if (!in_multiline_comment && ch == '/' && original[src] == '/')
+ {
+ in_singleline_comment = true;
+ consume = 2;
+ }
+ }
+ }
+
+ if (is_xml_file)
+ {
+ /* track whether or not we are within a XML comment */
+ if (!in_multiline_comment && ch == '<' && original[src] == '!' && original[src+1] == '-' && original[src+2] == '-')
+ {
+ in_multiline_comment = true;
+ if (col > 0 && modified[dst-1] == 0x09)
+ {
+ indent_multiline_comment = col;
+ }
+ else
+ {
+ indent_multiline_comment = 0;
+ }
+ consume = 4;
+ }
+ else if (in_multiline_comment && ch == '-' && original[src] == '-' && original[src+1] == '>')
+ {
+ in_multiline_comment = false;
+ indent_multiline_comment = 0;
+ consume = 3;
+ }
+ }
+ }
+
+ if (consume != 0)
+ {
+ modified[dst++] = ch;
+ col++;
+ consume--;
+ }
+
+ /* if we hit a CR or LF, clean up from there */
+ else if (ch == 0x0d || ch == 0x0a)
+ {
+ while (true)
+ {
+ /* remove all extra spaces/tabs at the end */
+ if (dst > 0 && (modified[dst-1] == ' ' || modified[dst-1] == 0x09))
+ {
+ removed_spaces++;
+ dst--;
+ }
+ /* remove extraneous line continuation followed by a blank line */
+ else if (is_c_file && !in_multiline_comment && dst > 2 && modified[dst-3] == '\\' && modified[dst-2] == 0x0d && modified[dst-1]==0x0a)
+ {
+ removed_continuations++;
+ dst -= 3;
+ }
+ /* remove blank lines following an opening brace */
+ else if (is_c_file && !in_multiline_comment && dst > 2 && modified[dst-3] == '{' && modified[dst-2] == 0x0d && modified[dst-1]==0x0a)
+ {
+ removed_newlines++;
+ dst -= 2;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /* insert a proper CR/LF */
+ modified[dst++] = 0x0d;
+ modified[dst++] = 0x0a;
+ col = 0;
+
+ /* skip over any LF in the source file */
+ if (ch == 0x0d && original[src] == 0x0a)
+ src++;
+ else if (ch == 0x0a)
+ fixed_nix_style = 1;
+ else
+ fixed_mac_style = 1;
+
+ /* we are no longer in a C++-style comment */
+ in_singleline_comment = false;
+
+ if (in_c_string && modified[dst-3] != '\\')
+ {
+ printf("Error: unterminated string literal: %x (%s)\n", src, argv[1]);
+ return 1;
+ }
+ }
+
+ /* if we hit a tab... */
+ else if (ch == 0x09)
+ {
+ int spaces = tab_size - (col % tab_size);
+
+ /* convert tabs to spaces, if not used for indenting */
+ if ((in_multiline_comment && col >= indent_multiline_comment) || (col != 0 && modified[dst-1] != 0x09))
+ {
+ while (spaces > 0)
+ {
+ modified[dst++] = ' ';
+ col++;
+ spaces--;
+ }
+
+ removed_tabs++;
+ }
+ else
+ {
+ modified[dst++] = ch;
+ col += spaces;
+ }
+ }
+
+ /* if we hit a space... */
+ else if (ch == 0x20)
+ {
+ int spaces = 1;
+
+ while (original[src] == 0x20)
+ {
+ spaces++;
+ src++;
+ }
+
+ /* Remove invisible spaces */
+ if (original[src] == 0x09)
+ {
+ int realign = (col + spaces) % tab_size;
+ removed_spaces += realign;
+ spaces -= realign;
+ }
+
+ /* convert spaces to tabs, if used for indenting */
+ while (spaces > 0 && (!in_multiline_comment || col < indent_multiline_comment) && (col == 0 || modified[dst-1] == 0x09) && !in_c_string)
+ {
+ modified[dst++] = 0x09;
+ spaces -= tab_size;
+ col += tab_size;
+ added_tabs++;
+ }
+
+ while (spaces > 0)
+ {
+ modified[dst++] = ' ';
+ col++;
+ spaces--;
+ }
+ }
+
+ /* otherwise, copy the source character */
+ else
+ {
+ /* check for invalid upper-ASCII chars, but only for non-xml files (swlists might contain UTF-8 chars) */
+ if (!is_xml_file && (ch < 32 || ch > 127))
+ {
+ ch = '?';
+ hichars++;
+ }
+
+ modified[dst++] = ch;
+ col++;
+ }
+ }
+
+ /* if we didn't find an end of comment, we screwed up */
+ if (in_multiline_comment)
+ {
+ printf("Error: unmatched multi-line comment (%s)!\n", argv[1]);
+ return 1;
+ }
+
+ if (is_c_file)
+ {
+ if (modified[dst - 1] != 0x0a)
+ {
+ modified[dst++] = 0x0d;
+ modified[dst++] = 0x0a;
+ added_newline = 1;
+ }
+ else
+ {
+ while (dst >= 4 && modified[dst - 4] == 0x0d && modified[dst - 3] == 0x0a)
+ {
+ dst -= 2;
+ removed_newlines++;
+ }
+ }
+ }
+
+ /* convert to unix_le if requested */
+
+ if (unix_le)
+ dst = le_convert((char *) modified, dst);
+
+ /* if the result == original, skip it */
+ if (dst != bytes || memcmp(original, modified, bytes))
+ {
+ /* explain what we did */
+ printf("Cleaned up %s:", argv[1]);
+ if (added_newline) printf(" added newline at end of file");
+ if (removed_newlines) printf(" removed %d newline(s)", removed_newlines);
+ if (removed_spaces) printf(" removed %d space(s)", removed_spaces);
+ if (removed_continuations) printf(" removed %d continuation(s)", removed_continuations);
+ if (removed_tabs) printf(" removed %d tab(s)", removed_tabs);
+ if (added_tabs) printf(" added %d tab(s)", added_tabs);
+ if (hichars) printf(" fixed %d high-ASCII char(s)", hichars);
+ if (fixed_nix_style && !unix_le) printf(" fixed *nix-style line-ends");
+ if (fixed_mac_style) printf(" fixed Mac-style line-ends");
+ if (fixed_dos_style) printf(" fixed Dos-style line-ends");
+ printf("\n");
+
+ if (!dry_run)
+ {
+ /* write the file */
+ file = fopen(argv[1], "wb");
+ fwrite(modified, 1, dst, file);
+ fclose(file);
+ }
+ }
+
+ return 0;
+}