/*************************************************************************** srcclean.c Basic source code cleanear. Copyright Nicola Salmoria and the MAME Team. Visit http://mamedev.org for licensing and usage restrictions. ***************************************************************************/ #include #include #include "corestr.h" #include "osdcore.h" /*************************************************************************** CONSTANTS & DEFINES ***************************************************************************/ #define MAX_FILE_SIZE (10 * 1024 * 1024) /*************************************************************************** GLOBAL VARIABLES ***************************************************************************/ static UINT8 original[MAX_FILE_SIZE]; static UINT8 modified[MAX_FILE_SIZE]; /*************************************************************************** MAIN ***************************************************************************/ int main(int argc, char *argv[]) { int removed_tabs = 0, removed_spaces = 0, fixed_mac_style = 0, fixed_nix_style = 0; int src = 0, dst = 0, in_c_comment = FALSE, in_cpp_comment = FALSE; int hichars = 0; int is_c_file; const char *ext; FILE *file; int bytes; /* print usage info */ if (argc != 2) { printf("Usage:\nsrcclean \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); /* 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)); /* rip through it */ for (src = 0; src < bytes; ) { UINT8 ch = original[src++]; /* check for invalid upper-ASCII chars */ if (ch != 13 && ch != 10 && ch != 9 && (ch > 127 || ch < 32)) { ch = '?'; hichars++; } /* track whether or not we are within a C-style comment */ if (is_c_file && !in_cpp_comment) { if (!in_c_comment && ch == '/' && original[src] == '*') in_c_comment = TRUE; else if (in_c_comment && ch == '*' && original[src] == '/') in_c_comment = FALSE; } /* track whether or not we are within a C++-style comment */ if (is_c_file && !in_c_comment && ch == '/' && original[src] == '/') in_cpp_comment = TRUE; /* if we hit a LF without a CR, back up and act like we hit a CR */ if (ch == 0x0a) { src--; ch = 0x0d; fixed_nix_style = 1; } /* if we hit a CR, clean up from there */ if (ch == 0x0d) { /* remove all extra spaces/tabs at the end */ while (dst > 0 && (modified[dst-1] == ' ' || modified[dst-1] == 0x09)) { removed_spaces++; dst--; } /* insert a proper CR/LF */ modified[dst++] = 0x0d; modified[dst++] = 0x0a; /* skip over any LF in the source file */ if (original[src] == 0x0a) src++; else fixed_mac_style = 1; /* we are no longer in a C++-style comment */ in_cpp_comment = FALSE; } /* if we hit a tab within a comment, expand it */ else if (ch == 0x09 && (in_c_comment || in_cpp_comment)) { int temp, col; /* scan backwards to find the start of line */ for (temp = dst; temp >= 0; temp--) if (modified[temp] == 0x0a) break; /* scan forwards to compute the current column */ for (temp++, col = 0; temp < dst; temp++) if (modified[temp] == 0x09) col += 4 - col % 4; else col++; /* compute how many spaces */ col = 4 - col % 4; while (col--) modified[dst++] = ' '; removed_tabs++; } /* otherwise, copy the source character */ else modified[dst++] = ch; } /* if we didn't find an end of comment, we screwed up */ if (in_c_comment) { printf("Error: unmatched C-style comment (%s)!\n", argv[1]); return 1; } /* if the result == original, skip it */ if (dst != bytes || memcmp(original, modified, bytes)) { /* explain what we did */ printf("Cleaned up %s:", argv[1]); if (removed_spaces) printf(" removed %d spaces", removed_spaces); if (removed_tabs) printf(" removed %d tabs", removed_tabs); if (hichars) printf(" fixed %d high-ASCII chars", hichars); if (fixed_nix_style) printf(" fixed *nix-style line-ends"); if (fixed_mac_style) printf(" fixed Mac-style line-ends"); printf("\n"); /* write the file */ file = fopen(argv[1], "wb"); fwrite(modified, 1, dst, file); fclose(file); } return 0; }