SplitSource.c
/// @SplitSource.h
typedef struct FILE FILE;
typedef int size_t;
FILE * fopen(const char *name, const char *mode);
int fclose(FILE *stream);
char * fgets(char * restrict dst, int max, FILE * restrict stream);
size_t fread(void * restrict dst, size_t size, size_t num, FILE * restrict stream);
size_t fwrite(const void * restrict src, size_t size, size_t num, FILE * restrict stream);
size_t strlen(const char *string);
char * strcpy(char * restrict dst, const char * restrict src);
int strncmp(const char *string1, const char *string2, size_t num);
int puts(const char *string);
/// @ comment
/// @SplitSource.c
/// @@#include "SplitSource.h"
char buf[512], fname[260], hdr[512];
int __cdecl main(int argc, char **argv)
{
FILE *fi, *fo, *fh;
//char buf[512], fname[260], hdr[512];
if (argc < 2) return 1;
fi = fopen(argv[1], "r");
fo = 0;
*hdr = 0;
int hdrlen = 0;
if (argc == 3) {
fh = fopen(argv[2], "r");
fread(hdr, 512, 1, fh);
fclose(fh);
hdrlen = strlen(hdr);
}
strcpy(fname, "src1/");
if (fi) {
while (fgets(buf, 512, fi)) {
int len = strlen(buf);
if (!strncmp(buf, "/// @", 5)) { // source tag "/// @"
if (*(buf+5) == '@') { // "/// @@" add line to file
if (fo) fwrite(buf+6, len-6, 1, fo);
} else {
if (fo) {
fclose(fo);
fo = 0;
}
//if (*(buf+len-2) == 'c' || *(buf+len-2) == 'h') { // source name
if (*(short*)(buf+len-3) == *(short*)".c"
|| *(short*)(buf+len-3) == *(short*)".h") { // source name
strcpy(fname+5, buf+5); // copy possible filename
*(fname+len-1) = 0;
puts(fname);
fo = fopen(fname, "w");
if (!fo) break;
if (hdrlen)
fwrite(hdr, hdrlen, 1, fo);
}
}
}
if (fo) fwrite(buf, len, 1, fo);
}
fclose(fi);
}
return 0;
}
it use tags
/// @ for filename
.c/// @@ for additional text line like
/// @@#include <commdlg.h> to add #include <commdlg.h>
usage SplitSource.exe Source.c Header.h
Header.h is added to every file for headers
Files are created to src1 folder.
example for fix case between files
/// @@#endif
/// @CopyList2File.c
/// @@#include <commdlg.h>
/// @@#ifndef NOLISTTOOLS
int CopyList2File(HWND hWnd, HWND hWndLV, int iMode)
EDIT split that renamed example
EDIT combine file
typedef struct FILE FILE;
typedef int size_t;
FILE * fopen(const char *name, const char *mode);
int fclose(FILE *stream);
char * fgets(char * restrict dst, int max, FILE * restrict stream);
size_t fread(void * restrict dst, size_t size, size_t num, FILE * restrict stream);
size_t fwrite(const void * restrict src, size_t size, size_t num, FILE * restrict stream);
size_t strlen(const char *string);
char * strcpy(char * restrict dst, const char * restrict src);
int strncmp(const char *string1, const char *string2, size_t num);
int puts(const char *string);
char buf[512], fname[260], hdr[512];
int __cdecl main(int argc, char **argv)
{
FILE *fi, *fo, *fl;
//char buf[512], fname[260], hdr[512];
if (argc < 2) {
puts("usage: SourceUnSplit.exe <file list> <source file>"); // <header file>");
return 1;
}
fi = 0;
fo = fopen(argv[2], "w");;
fl = fopen(argv[1], "r");
*hdr = 0;
strcpy(fname, "src/");
if (fl) {
while (fgets(buf, 512, fl)) {
int len = strlen(buf);
*(buf+len-1) = 0;
strcpy(fname, buf);
//puts(fname);
if ((fi = fopen(fname, "r")) != 0) {
puts(fname);
int copy = 0; // copy lines only after a local header
while (fgets(buf, 512, fi)) {
len = strlen(buf);
if (!strncmp(buf, "/// @", 5)) {
copy = 1; // start copying
if (!strncmp(buf, "#include", 8)) continue; // don't copy inserted local includes
}
if (copy && fo)
fwrite(buf, len, 1, fo);
}
fclose(fi);
}
}
fclose(fl);
}
return 0;
}