2d85d900e1d3 — Duncan Ross Palmer 1 year, 2 months ago
Migrate over all code -- working now, but all bytes are zeroed
1 files changed, 196 insertions(+), 190 deletions(-)

M bin/raw2c
M bin/raw2c +196 -190
@@ 40,6 40,8 @@ sub new {
 
 	return bless({
 		handle => undef,
+		isDir => undef,
+		fileInfo => undef,
 	}, $class);
 }
 

          
@@ 49,6 51,26 @@ sub handle {
 	return $self->{handle};
 }
 
+sub fileInfo {
+	my ($self, @args) = @_;
+	($self->{fileInfo}) = @args if (scalar(@args));
+	return $self->{fileInfo};
+}
+
+sub isDir {
+	my ($self, @args) = @_;
+
+	if (scalar(@args)) {
+		if (defined($self->{isDir})) {
+			die('Cannot set isDir on same object twice');
+		} else {
+			($self->{isDir}) = @args;
+		}
+	}
+
+	return $self->{isDir};
+}
+
 package Options;
 use strict;
 use warnings;

          
@@ 85,10 107,10 @@ sub outputFileName {
 	return $self->{outputFileName};
 }
 
-sub symbolName {
+sub symbol {
 	my ($self, @args) = @_;
-	($self->{symbolName}) = @args if (scalar(@args));
-	return $self->{symbolName};
+	($self->{symbol}) = @args if (scalar(@args));
+	return $self->{symbol};
 }
 
 sub nullTerminator {

          
@@ 144,7 166,7 @@ sub parse {
 		} elsif ($arg eq '-r') {
 			$options->recurse(1);
 		} elsif ($arg =~ m/^--symbol=(\w+)$/o) {
-			$options->symbolName($1);
+			$options->symbol($1);
 		} elsif ($arg =~ m/^--header=(.*)$/o) {
 			$options->header($1);
 		} else { # Must be a filename

          
@@ 162,12 184,12 @@ sub parse {
 		die('Must specify input & output filenames');
 	}
 
-	if (!$options->symbolName) {
+	if (!$options->symbol) {
 		if (!$options->quiet) {
 			print("No symbol name was specified, a random symbol will be generated.\n");
 		}
 
-		$options->symbolName($self->randomSymbol());
+		$options->symbol($self->randomSymbol());
 	}
 
 	return $options;

          
@@ 176,8 198,12 @@ sub parse {
 package Main;
 use strict;
 use warnings;
+use Carp qw(confess);
 use English qw(-no_match_vars);
-use POSIX qw(EXIT_SUCCESS);
+use Fcntl 'S_ISDIR';
+use File::stat;
+use IO::File;
+use POSIX qw(EXIT_FAILURE EXIT_SUCCESS);
 
 sub new {
 	my ($class) = @_;

          
@@ 220,26 246,179 @@ sub title {
 	return;
 }
 
+sub initFileOrDir {
+	my ($fileOrDir, $isDir) = @_;
+
+	$fileOrDir->isDir($isDir);
+	$fileOrDir->handle(undef);
+
+	return;
+}
+
+sub fileSizeWarning {
+	my ($fileName, $sz) = @_;
+
+	my $threshold = (64 * 1024) -1;
+
+	if ($threshold > $sz) {
+		return;
+	}
+
+	printf(
+		STDERR
+		"WARNING! \"%s\" is over %lu bytes, on 16-bit architectures, this could overflow a segment\n" .
+		"\tFor large files, consider using librttb; https://hg.sr.ht/~m6kvm/rttb\n",
+		$fileName, $threshold,
+	);
+
+	return;
+}
+
+sub openFiles {
+	my ($self, $pInput, $pOutput, $pHeader) = @_;
+
+	# Find out if the input is a directory
+	my $fileInfo = stat($self->options->inputFileName);
+	if ($fileInfo) {
+		$pInput->fileInfo($fileInfo);
+	} else {
+		printf(STDERR "Cannot stat %s\n", $self->options->inputFileName);
+		return EXIT_FAILURE;
+	}
+
+	initFileOrDir($pInput, S_ISDIR($fileInfo->mode));
+
+	# Find out if the file is "too large" and warn user
+	fileSizeWarning($self->options->inputFileName, $pInput->fileInfo->size);
+
+	initFileOrDir($pOutput, S_ISDIR($fileInfo->mode));
+
+	# Open the files or directories
+	if ($pInput->isDir) {
+		confess('TODO');
+	} else {
+		if (!$pInput->handle(IO::File->new($self->options->inputFileName, 'r'))) {
+			printf("Can\'t open input file \"%s\"\n", $self->options->inputFileName);
+			return EXIT_FAILURE;
+		}
+	}
+
+	if ($pOutput->isDir) {
+		confess('TODO');
+	} else {
+		if (!$pOutput->handle(IO::File->new($self->options->outputFileName, 'w'))) {
+			print("Can\'t open output file \"%s\"\n", $self->options->outputFileName);
+			$pInput->handle->close(); # Cleanup one that worked
+			return EXIT_FAILURE;
+		}
+	}
+
+	if ($self->options->header) {
+		initFileOrDir($pHeader, S_ISDIR($fileInfo->mode)); # FIXME: Seems to me we're reusing stat -- could be a bug in C version too
+		if (!$pHeader->handle(IO::File->new($self->options->header, 'w'))) {
+			printf("Can\'t open header file \"%s\"\n", $self->options->header);
+
+			# Cleanup file which worked
+			$pInput->handle->close();
+			$pOutput->handle->close();
+
+			return EXIT_FAILURE;
+		}
+	}
+
+	return EXIT_SUCCESS;
+}
+
+sub makeHeader {
+	my ($self, $pHeader) = @_;
+
+	confess('Assertion failed') if ($pHeader->isDir);
+#	rewind(pHeader->handle.file);
+
+	my $handle = $pHeader->handle;
+	print($handle getHead()); # Put top comment into source
+	printf($handle "extern const char %s[];\n", $self->options->symbol);
+
+	return;
+}
+
+sub makeSource {
+	my ($self, $pIn, $pOut) = @_;
+
+	my ($counter, $length) = (0);
+
+	confess('Assertion failed') if ($pIn->isDir);
+	#rewind(pIn->handle.file);
+	confess('Assertion failed') if ($pOut->isDir);
+	#rewind(pOut->handle.file);
+	$length = $pIn->fileInfo->size;
+	$length++ if ($self->options->nullTerminator);
+
+	my $pOutHandle = $pOut->handle;
+	print($pOutHandle getHead()); # Put top comment into source
+
+	if ($self->options->header) {
+		printf($pOutHandle "#include \"%s\"\n", $self->options->header);
+	}
+
+	printf($pOutHandle "const char %s[] = {\n\t", $self->options->symbol);
+	while ($counter < $length) {
+
+		my $thisByte = '';
+		my $readResult;
+
+		if ($counter+1 >= $length) { # At the end?
+			$thisByte = '\0' if ($self->options->nullTerminator); # A null terminator
+			$readResult = 1;
+		} else {
+			my $pInHandle = $pIn->handle;
+			my $ref = \$thisByte;
+			$readResult = read($pInHandle, $ref, 1);
+		}
+
+		if ($readResult >= 1) {
+			printf($pOutHandle "\'\\x%02X\'", ord($thisByte));
+		}
+
+		if ($counter+1 < $length) { # More to go
+			print($pOutHandle ', ');
+		}
+
+		# Seperate half paragraph boundries
+		if (0 == ((1+$counter) % 8)) {
+			print($pOutHandle "\n\t");
+		}
+
+		$counter++;
+	}
+
+	printf($pOutHandle "\n};\n");
+	return;
+}
+
 sub main {
 	my ($self) = @_;
 	srand($PID + (time() % 100_000));
 
-	my ($input, $output, $header) = FileOrDir->new();
+	my ($input, $output, $header) = (
+		FileOrDir->new(),
+		FileOrDir->new(),
+		FileOrDir->new(),
+	);
 
 	$self->options($self->optionsParser->parse(\@ARGV));
 
 	title() unless ($self->options->quiet);
 
-#	if (openFiles(&input, &output, &header))
-#		return EXIT_FAILURE;
+	return EXIT_FAILURE if ($self->openFiles($input, $output, $header));
+
+	$self->makeHeader($header) if ($self->options->header);
+	$self->makeSource($input, $output);
 
-#	if (options.headerName) makeHeader(&header);
-#	makeSource(&input, &output);
-
-#	/* Close files */
-#	fclose(input.handle.file);
-#	fclose(output.handle.file);
-#	if (options.headerName) fclose(header.handle.file);
+	# Close files
+	$input->handle->close();
+	$output->handle->close();
+	$header->handle->close();
 
 	return EXIT_SUCCESS;
 }

          
@@ 249,176 428,3 @@ use strict;
 use warnings;
 
 exit(Main->new->main()) unless (caller());
-
-#### XXX
-
-#static void initFileOrDir(struct FileOrDir *fileOrDir, const int isDir);
-#static int openFiles(
-#	struct FileOrDir *pInput,
-#	struct FileOrDir *pOutput,
-#	struct FileOrDir *pHeader
-#);
-#static void makeSource(struct FileOrDir *pIn, struct FileOrDir *pOut);
-#static void makeHeader(struct FileOrDir *pHeader);
-#static unsigned long int getFileLength(FILE *fileHandle);
-#static void fileSizeWarning(const char *const fileName, const off_t sz);
-
-#static void initFileOrDir(struct FileOrDir *fileOrDir, const int isDir) {
-
-#	fileOrDir->isDir = isDir;
-#	if (fileOrDir->isDir) {
-#		fileOrDir->handle.dir = NULL;
-#	} else {
-#		fileOrDir->handle.file = NULL;
-#	}
-
-#	return;
-#}
-
-#static int openFiles(
-#	struct FileOrDir *pInput,
-#	struct FileOrDir *pOutput,
-#	struct FileOrDir *pHeader
-#) {
-
-#	struct stat fileInfo;
-
-#	/* Find out if the input is a directory */
-#	if (0 != stat(options.inputFileName, &fileInfo)) {
-#		fprintf(stderr, "Cannot stat %s\n", options.inputFileName);
-#		return EXIT_FAILURE;
-#	}
-#	initFileOrDir(pInput, S_ISDIR(fileInfo.st_mode));
-
-#	/* Find out if the file is "too large" and warn user */
-#	fileSizeWarning(options.inputFileName, fileInfo.st_size);
-
-#	initFileOrDir(pOutput, S_ISDIR(fileInfo.st_mode));
-
-#	/* Open the files or directories */
-#	if (pInput->isDir) {
-#		abort(); /* TODO */
-#	} else {
-#		pInput->handle.file = fopen(options.inputFileName, "rb");
-
-#		if (!pInput->handle.file) {
-#			printf("Can\'t open input file \"%s\"\n", options.inputFileName);
-#			return EXIT_FAILURE;
-#		}
-#	}
-
-#	if (pOutput->isDir) {
-#		abort(); /* TODO */
-#	} else {
-#		pOutput->handle.file = fopen(options.outputFileName, "wt");
-
-#		if (!pOutput->handle.file) {
-#			printf("Can\'t open output file \"%s\"\n", options.outputFileName);
-#			fclose(pOutput->handle.file); /* Cleanup one that worked */
-#			return EXIT_FAILURE;
-#		}
-#	}
-
-#	if (options.headerName) {
-#		initFileOrDir(pHeader, S_ISDIR(fileInfo.st_mode));
-#		pHeader->handle.file = fopen(options.headerName, "wt");
-#		if (!pHeader->handle.file) {
-#			printf("Can\'t open header file \"%s\"\n", options.headerName);
-
-#			/* Cleanup file which worked */
-#			fclose(pInput->handle.file);
-#			fclose(pOutput->handle.file);
-
-#			return EXIT_FAILURE;
-#		}
-#	}
-
-#	return EXIT_SUCCESS;
-#}
-
-#static void makeSource(struct FileOrDir *pIn, struct FileOrDir *pOut) {
-
-#	unsigned long int counter = 0UL;
-#	unsigned long int length;
-
-#	assert(!pIn->isDir);
-#	rewind(pIn->handle.file);
-#	assert(!pOut->isDir);
-#	rewind(pOut->handle.file);
-#	length = getFileLength(pIn->handle.file);
-#	if (options.null_terminator) length++;
-
-#	fprintf(pOut->handle.file, head); /* Put top comment into source */
-
-#	if (options.headerName)
-#		fprintf(pOut->handle.file, "#include \"%s\"\n", options.headerName);
-
-#	fprintf(pOut->handle.file, "const char %s[] = {\n\t", options.symbolName);
-#	while (counter < length) {
-
-#		unsigned char thisByte;
-#		size_t freadResult;
-
-#		if (counter+1 >= length) { /* At the end? */
-#			if (options.null_terminator) thisByte = '\0'; /* A null terminator */
-#			freadResult = 1;
-#		} else {
-#			freadResult = fread(&thisByte, sizeof(thisByte), 1, pIn->handle.file);
-#		}
-
-#		if (freadResult >= 1)
-#			fprintf(pOut->handle.file, "\'\\x%02X\'", thisByte);
-
-#		if (counter+1 < length) /* More to go */
-#			fprintf(pOut->handle.file, ", ");
-
-#		/* Seperate half paragraph boundries */
-#		if (0 == ((1+counter) % 8)) {
-#			fputc('\n', pOut->handle.file);
-#			fputc('\t', pOut->handle.file);
-#		}
-
-#		counter++;
-#	}
-
-#	fprintf(pOut->handle.file, "\n};\n");
-#	return;
-#}
-
-#static void makeHeader(struct FileOrDir *pHeader) {
-
-#	assert(!pHeader->isDir);
-#	rewind(pHeader->handle.file);
-
-#	fprintf(pHeader->handle.file, head); /* Put top comment into source */
-#	fprintf(pHeader->handle.file, "extern const char %s[];\n", options.symbolName);
-#
-#	return;
-#}
-
-#static unsigned long int getFileLength(FILE *fileHandle) {
-
-#	long int endPos;
-#	long int stackedPos = ftell(fileHandle); /* Save file position */
-
-#	fseek(fileHandle, 0, SEEK_END); /* Go to end of file */
-#	endPos = ftell(fileHandle);
-#	fseek(fileHandle, stackedPos, SEEK_SET); /* Restore file pos */
-
-#	return (unsigned long int)endPos;
-#}
-
-#static void fileSizeWarning(const char *const fileName, const off_t sz) {
-
-#	const off_t threshold = (64 * 1024) -1;
-
-#	if (threshold > sz)
-#		return;
-
-#	fprintf(
-#		stderr,
-#		"WARNING! \"%s\" is over %lu bytes, on 16-bit architectures, this could overflow a segment\n"
-#		"\tFor large files, consider using librttb; https://bitbucket.org/2E0EOL/rttb\n",
-#		fileName, threshold
-#	);
-#}