Initial commit of auxiliary tools, including my half-complete editor program.
This commit is contained in:
10
LICENSE
Normal file
10
LICENSE
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means.
|
||||||
|
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and
|
||||||
|
successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
For more information, please refer to <http://unlicense.org/>
|
196
audit.c
Normal file
196
audit.c
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
// Copyright (c) 2025, Zak Fenton
|
||||||
|
// This "audit" program is licensed under the Mulan PSL v2. You can use this
|
||||||
|
// software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
// You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
// http://license.coscl.org.cn/MulanPSL2
|
||||||
|
// THIS SOFTWARE IS PROVIDED ON AN “AS IS” BASIS, WITHOUT warranties of
|
||||||
|
// any kind, either express or implied, including but not limited to
|
||||||
|
// non-infringement, merchantability or fit for a particular purpose.
|
||||||
|
// See the Mulan PSL v2 for more details.
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define AUDIT_TYPE_OLD 1
|
||||||
|
#define AUDIT_TYPE_NEW 2
|
||||||
|
#define AUDIT_TYPE_UNMARKED 3
|
||||||
|
|
||||||
|
typedef struct audit_info audit_info_t;
|
||||||
|
typedef struct audit_filelist audit_filelist_t;
|
||||||
|
struct audit_filelist {
|
||||||
|
const char* name;
|
||||||
|
audit_filelist_t* next;
|
||||||
|
int type;
|
||||||
|
int lines;
|
||||||
|
};
|
||||||
|
struct audit_info {
|
||||||
|
int filecount;
|
||||||
|
int linecount;
|
||||||
|
audit_filelist_t* oldcode;
|
||||||
|
audit_filelist_t* newcode;
|
||||||
|
audit_filelist_t* unmarkedcode;
|
||||||
|
};
|
||||||
|
|
||||||
|
int audit_filelist_countfiles(audit_filelist_t* l) {
|
||||||
|
int total = 0;
|
||||||
|
while (l) {
|
||||||
|
total++;
|
||||||
|
l = l->next;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
int audit_filelist_countlines(audit_filelist_t* l) {
|
||||||
|
int total = 0;
|
||||||
|
while (l) {
|
||||||
|
total += l->lines;
|
||||||
|
l = l->next;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
int usage(int argc, char** argv, const char* error) {
|
||||||
|
FILE* out = error ? stderr : stdout;
|
||||||
|
fprintf(out, "ABOUT:\n");
|
||||||
|
fprintf(out, "This is a simple code audit tool to note occurrences like OLD CODE & NEW CODE\n");
|
||||||
|
fprintf(out, "The main purpose of this tool is to help gradually remove old/third-party code from a codebase,\n");
|
||||||
|
fprintf(out, "but it could be extended later e.g. for checking each file has been manually audited at a recent date.\n");
|
||||||
|
fprintf(out, "This tool isn't specific to a particular programming language and can be used for config files too.\n");
|
||||||
|
fprintf(out, "\nUSAGE:\n");
|
||||||
|
fprintf(out, "\t%s [source files...]\n", argv[0]);
|
||||||
|
if (error) {
|
||||||
|
fprintf(out, "ERROR: %s\n", error);
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int audit_check(const char* line, const char* check) {
|
||||||
|
char c;
|
||||||
|
while ((c = *line++) != 0) {
|
||||||
|
if (c == check[0]) {
|
||||||
|
const char* search = check+1;
|
||||||
|
while (*search && *search == *line) {
|
||||||
|
line++;
|
||||||
|
search++;
|
||||||
|
}
|
||||||
|
if (!*search) {
|
||||||
|
return 1; // Found!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0; // Not found
|
||||||
|
}
|
||||||
|
|
||||||
|
void audit_line(audit_info_t* info, audit_filelist_t* file, const char* line) {
|
||||||
|
if (audit_check(line, "OLD CODE")) {
|
||||||
|
file->type = AUDIT_TYPE_OLD;
|
||||||
|
} else if (file->type == AUDIT_TYPE_UNMARKED && audit_check(line, "NEW CODE")) {
|
||||||
|
file->type = AUDIT_TYPE_NEW;
|
||||||
|
}
|
||||||
|
file->lines++;
|
||||||
|
}
|
||||||
|
|
||||||
|
char linebuf[1000];
|
||||||
|
|
||||||
|
int audit_run(audit_info_t* info, const char* filename) {
|
||||||
|
FILE* f = fopen(filename, "r");
|
||||||
|
if (!f) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
audit_filelist_t* filelist = malloc(sizeof(audit_filelist_t));
|
||||||
|
if (!filelist) {
|
||||||
|
fprintf(stderr, "ERROR: Failed to allocate memory\n");
|
||||||
|
fclose(f);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
filelist->name = strdup(filename);
|
||||||
|
filelist->type = AUDIT_TYPE_UNMARKED;
|
||||||
|
filelist->lines = 0;
|
||||||
|
filelist->next = NULL;
|
||||||
|
|
||||||
|
while (fgets(linebuf, 1000, f)) {
|
||||||
|
audit_line(info, filelist, linebuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (filelist->type) {
|
||||||
|
case AUDIT_TYPE_NEW:
|
||||||
|
filelist->next = info->newcode;
|
||||||
|
info->newcode = filelist;
|
||||||
|
break;
|
||||||
|
case AUDIT_TYPE_OLD:
|
||||||
|
filelist->next = info->oldcode;
|
||||||
|
info->oldcode = filelist;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
filelist->next = info->unmarkedcode;
|
||||||
|
info->unmarkedcode = filelist;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
info->linecount += filelist->lines;
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void audit_subreport(audit_info_t* info, const char* startline, audit_filelist_t* files, FILE* out, int extrastats) {
|
||||||
|
int nfiles = audit_filelist_countfiles(files);
|
||||||
|
int nlines = audit_filelist_countlines(files);
|
||||||
|
int fpercent = (int) (((double) nfiles) / ((double) (info->filecount)) * 100);
|
||||||
|
int lpercent = (int) (((double) nlines) / ((double) (info->linecount)) * 100);
|
||||||
|
fprintf(out, "%s %d FILES (%d%%)\t%d LINES (%d%%)\n", startline, nfiles, fpercent, nlines, lpercent);
|
||||||
|
if (!files) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//fprintf(out, "%s IN ", startline);
|
||||||
|
audit_filelist_t* smallest = files;
|
||||||
|
audit_filelist_t* largest = files;
|
||||||
|
while (files) {
|
||||||
|
//fprintf(out, " %s", files->name);
|
||||||
|
if (files->lines < smallest->lines) {
|
||||||
|
smallest = files;
|
||||||
|
} else if (files->lines > largest->lines) {
|
||||||
|
largest = files;
|
||||||
|
}
|
||||||
|
files = files->next;
|
||||||
|
}
|
||||||
|
//fprintf(out, "\n");
|
||||||
|
if (extrastats) {
|
||||||
|
fprintf(out, "%s SMALLEST %s (%d lines) LARGEST %s (%d lines)\n", startline, smallest->name, smallest->lines, largest->name, largest->lines);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void audit_report(audit_info_t* info, FILE* out) {
|
||||||
|
fprintf(out, "THIS IS AN AUTOGENERATED REPORT\n");
|
||||||
|
fprintf(out, "This report was created by the 'audit' program\n");
|
||||||
|
fprintf(out, "TOTAL %d FILES %d LINES\n", info->filecount, info->linecount);
|
||||||
|
audit_subreport(info, "NEW CODE: ", info->newcode, out, 0);
|
||||||
|
audit_subreport(info, "OLD CODE: ", info->oldcode, out, 1);
|
||||||
|
audit_subreport(info, "UNMARKED CODE:", info->unmarkedcode, out, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
audit_info_t info;
|
||||||
|
info.filecount = 0;
|
||||||
|
info.oldcode = NULL;
|
||||||
|
info.newcode = NULL;
|
||||||
|
info.unmarkedcode = NULL;
|
||||||
|
|
||||||
|
for (int i = 1; i < argc; i++) {
|
||||||
|
if (audit_run(&info, argv[i]) != 0) {
|
||||||
|
fprintf(stderr, "ERROR: Failed to process file '%s'\n", argv[i]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
info.filecount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.filecount < 1) {
|
||||||
|
return usage(argc, argv, "Expecting list of source files\n");
|
||||||
|
} else {
|
||||||
|
audit_report(&info, stdout);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
1839
numbered.c
Normal file
1839
numbered.c
Normal file
File diff suppressed because it is too large
Load Diff
185
res2c.c
Normal file
185
res2c.c
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int usage(int argc, char** argv, int argerr, const char* error) {
|
||||||
|
FILE* o = error ? stderr : stdout;
|
||||||
|
char* progname = argv[0];
|
||||||
|
fprintf(o, "This program '%s' loads arbitrary files and outputs them as C code which loads them in the style of 'program resources'.\n", progname);
|
||||||
|
fprintf(o, "It is particularly designed for loading one or more ramdisks, init programs or other arbitrary 'blobs' in kernel boot images.\n\n");
|
||||||
|
fprintf(o, "By default it will produce a function which calls another function to register each resource.\n");
|
||||||
|
fprintf(o, "Using the --nofunctions option and setting the name with --arrayname you can also get it to just produce arrays similar to a simple 'bin2c' program.\n\n");
|
||||||
|
fprintf(o, "USAGE:\n");
|
||||||
|
fprintf(o, " %s [--output <filename>] [--allowempty] [--nofunctions] [--defaulttype <name>] [--loadfunction <functionname>] [--registerfunction <functionname>] [[--type <typestring>] [--arrayname <name>] [--filename <name>] resource1 [[--type <typestring>] [--arrayname <name>] [--filename <name>] resource2 [...]]]\n\n", progname);
|
||||||
|
fprintf(o, "EXAMPLES:\n");
|
||||||
|
fprintf(o, " %s --output gamemods_autogenerated.c --loadfunction mods_init --allowempty --defaulttype GAME_MOD *.mod\n\n", progname);
|
||||||
|
fprintf(o, " %s --output mybootscripts.c --type SCRIPT --name bootscript startup.script --type RAMDISK --name initramdisk startup.image\n\n", progname);
|
||||||
|
fprintf(o, " %s --allowempty\n\n", progname);
|
||||||
|
return error == NULL ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAX_RESOURCES 100
|
||||||
|
FILE* files[MAX_RESOURCES];
|
||||||
|
char* types[MAX_RESOURCES];
|
||||||
|
char* arraynames[MAX_RESOURCES];
|
||||||
|
char* filenames[MAX_RESOURCES];
|
||||||
|
unsigned long sizes[MAX_RESOURCES];
|
||||||
|
|
||||||
|
unsigned char buffer[256];
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
char* defaulttype = "RESOURCE";
|
||||||
|
char* nexttype = NULL;
|
||||||
|
char* nextarrayname = NULL;
|
||||||
|
char* nextfilename = NULL;
|
||||||
|
int nresources = 0;
|
||||||
|
int allowempty = 0;
|
||||||
|
int nofunctions = 0;
|
||||||
|
char* loadfunction = "resources_init";
|
||||||
|
char* registerfunction = "resources_register";
|
||||||
|
char* progname = argv[0];
|
||||||
|
int bytesperline = 16;
|
||||||
|
|
||||||
|
char* outputname = NULL;
|
||||||
|
|
||||||
|
char simplenamebuff[6];
|
||||||
|
simplenamebuff[0] = '_';
|
||||||
|
simplenamebuff[1] = 'r';
|
||||||
|
simplenamebuff[2] = 'e';
|
||||||
|
simplenamebuff[3] = 's';
|
||||||
|
simplenamebuff[5] = 0;
|
||||||
|
|
||||||
|
int argi = 1;
|
||||||
|
while (argi < argc) {
|
||||||
|
if (!strcmp(argv[argi], "--usage")) {
|
||||||
|
usage(argc, argv, argi, NULL);
|
||||||
|
return 0;
|
||||||
|
} else if (!strcmp(argv[argi], "--type")) {
|
||||||
|
if (argi + 1 >= argc) {
|
||||||
|
return usage(argc, argv, argi, "Missing argument after --type");
|
||||||
|
}
|
||||||
|
argi++;
|
||||||
|
nexttype = argv[argi];
|
||||||
|
} else if (!strcmp(argv[argi], "--arrayname")) {
|
||||||
|
if (argi + 1 >= argc) {
|
||||||
|
return usage(argc, argv, argi, "Missing argument after --arrayname");
|
||||||
|
}
|
||||||
|
argi++;
|
||||||
|
nextarrayname = argv[argi];
|
||||||
|
} else if (!strcmp(argv[argi], "--filename")) {
|
||||||
|
if (argi + 1 >= argc) {
|
||||||
|
return usage(argc, argv, argi, "Missing argument after --filename");
|
||||||
|
}
|
||||||
|
argi++;
|
||||||
|
nextfilename = argv[argi];
|
||||||
|
} else if (!strcmp(argv[argi], "--output") || (argv[argi][0] == '-' && argv[argi][1] == 'o' && argv[argi][2] == 0)) {
|
||||||
|
if (outputname != NULL) {
|
||||||
|
usage(argc, argv, argi, "Can't specify output more than once");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (argi + 1 >= argc) {
|
||||||
|
usage(argc, argv, argi, "Missing argument after --output");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
argi++;
|
||||||
|
outputname = argv[argi];
|
||||||
|
} else if (argv[argi][0] == '-' && argv[argi][1] == 'o') {
|
||||||
|
if (outputname != NULL) {
|
||||||
|
usage(argc, argv, argi, "Can't specify output more than once");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
outputname = argv[argi]+2;
|
||||||
|
} else if (!strcmp(argv[argi], "--allowempty")) {
|
||||||
|
allowempty = 1;
|
||||||
|
} else if (!strcmp(argv[argi], "--nofunctions")) {
|
||||||
|
nofunctions = 1;
|
||||||
|
} else {
|
||||||
|
if (nresources + 1 >= MAX_RESOURCES) {
|
||||||
|
return usage(argc, argv, argi, "Too many resources");
|
||||||
|
}
|
||||||
|
files[nresources] = fopen(argv[argi], "rb");
|
||||||
|
if (nexttype) {
|
||||||
|
types[nresources] = nexttype;
|
||||||
|
nexttype = NULL;
|
||||||
|
} else {
|
||||||
|
types[nresources] = defaulttype;
|
||||||
|
}
|
||||||
|
if (nextarrayname) {
|
||||||
|
arraynames[nresources] = nextarrayname;
|
||||||
|
nextarrayname = NULL;
|
||||||
|
} else {
|
||||||
|
simplenamebuff[4] = (char)('A' + nresources);
|
||||||
|
arraynames[nresources] = strdup(simplenamebuff);
|
||||||
|
}
|
||||||
|
if (nextfilename) {
|
||||||
|
filenames[nresources] = nextfilename;
|
||||||
|
nextfilename = NULL;
|
||||||
|
} else {
|
||||||
|
char* lastsegment = argv[argi];
|
||||||
|
char* s = lastsegment;
|
||||||
|
while (*s) {
|
||||||
|
if (*s == '/' || *s == '\\' || *s == ':') {
|
||||||
|
lastsegment = s+1;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
filenames[nresources] = lastsegment;
|
||||||
|
}
|
||||||
|
nresources++;
|
||||||
|
}
|
||||||
|
argi++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nresources < 1 && !allowempty) {
|
||||||
|
return usage(argc, argv, argi, "Expected some resources to add or --allowempty to allow an empty resource structure");
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* output = stdout;
|
||||||
|
|
||||||
|
if (outputname != NULL) {
|
||||||
|
output = fopen(outputname, "w");
|
||||||
|
if (output == NULL) {
|
||||||
|
fprintf(stderr, "ERROR: Failed to open output file '%s'\n", outputname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(output, "// This file is autogenerated by '%s'\n\n", progname);
|
||||||
|
char* hex = "0123456789ABCDEF";
|
||||||
|
for (int resi = 0; resi < nresources; resi++) {
|
||||||
|
FILE* f = files[resi];
|
||||||
|
unsigned long sz = 0;
|
||||||
|
size_t nread;
|
||||||
|
fprintf(output, "unsigned char %s[] = {\n", arraynames[resi]);
|
||||||
|
while ((nread = fread(buffer, 1, bytesperline, f)) > 0) {
|
||||||
|
if (sz > 0) {
|
||||||
|
fprintf(output, ",\n");
|
||||||
|
}
|
||||||
|
sz += (unsigned long) nread;
|
||||||
|
for (size_t bytei = 0; bytei < nread; bytei++) {
|
||||||
|
int b = ((int) buffer[bytei]) & 0xFF;
|
||||||
|
fprintf(output, "%s0x%c%c", bytei > 0 ? ", " : " ", hex[b>>4], hex[b&0xF]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(output, "\n}; // end of %s\n\n", arraynames[resi]);
|
||||||
|
|
||||||
|
sizes[resi] = sz;
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nofunctions) {
|
||||||
|
fprintf(output, "// This function should be implemented in the program code, the name can be changed with using --registerfunction <name> when generating this code\n");
|
||||||
|
fprintf(output, "void %s(const char* type, const char* name, unsigned char* data, unsigned long size);\n\n", registerfunction);
|
||||||
|
|
||||||
|
fprintf(output, "// This function should be invoked from the program code, the name can be changed with using --loadfunction <name> when generating this code\n");
|
||||||
|
fprintf(output, "void %s() {\n", loadfunction);
|
||||||
|
for (int resi = 0; resi < nresources; resi++) {
|
||||||
|
fprintf(output, " %s(\"%s\", \"%s\", %s, %lu);\n", registerfunction, types[resi], filenames[resi], arraynames[resi], sizes[resi]);
|
||||||
|
}
|
||||||
|
fprintf(output, "}\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outputname != NULL) {
|
||||||
|
fclose(output);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user