OpenCores
URL https://opencores.org/ocsvn/tinyvliw8/tinyvliw8/trunk

Subversion Repositories tinyvliw8

[/] [tinyvliw8/] [trunk/] [tools/] [objcopy/] [src/] [main.c] - Rev 8

Compare with Previous | Blame | View Log

/**
 * \file   main.c
 * \author Oliver Stecklina <stecklina@ihp-microelectronics.com>
 * \date   12.12.2015
 * 
 * \brief  tinyVLIW8 objcopy program
 *
 * <p>
 *    Copyright (C) 2015 IHP GmbH, Frankfurt (Oder), Germany
 *
 * This code is free software. It is licensed under the EUPL, Version 1.1
 * or - as soon they will be approved by the European Commission - subsequent
 * versions of the EUPL (the "License").
 * You may redistribute this code and/or modify it under the terms of this
 * License.
 * You may not use this work except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 * http://joinup.ec.europa.eu/software/page/eupl/licence-eupl
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * </p>
 */
 
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
 
typedef enum _bfd_e {
	_bfd_ascii = 0
} _bfd_t;
 
static unsigned char  _mem_width = 4;
static char          *_infile    = NULL;
static char          *_outfile   = NULL;
static _bfd_t         _bfdname   = _bfd_ascii;
 
static int _parse_args(int argc, char *argv[])
{
	int err, i;
 
	err = 0;
	for (i = 1; 0 == err && i < argc; i++) {
		if ('-' != *argv[i]) {
			if ((i + 1) == argc) {
				_infile = argv[i];
				break;
			}
 
			fprintf(stderr, "\tERROR! bad option <%s>\n", argv[i]);
			err = -EINVAL;
 
			break;
		}
 
		switch (*(argv[i] + 1)) {
		case 'O':
			if ((i + 1) < argc) {
				i++;
 
				if (0 == strcmp("ascii", argv[i])) {
					_bfdname = _bfd_ascii;
				}
 
				break;
			}
 
			fprintf(stderr, "\tERROR! option <%s> requires an argument\n",
			        argv[i]);
			err = -EINVAL;
 
			break;
		case 'o':
			if ((i + 1) < argc) {
				i++;
				_outfile = argv[i];
 
				break;
			}
 
			fprintf(stderr, "\tERROR! option <%s> requires an argument\n",
			        argv[i]);
			err = -EINVAL;
 
			break;
		case 'w':
			if ((i + 1) < argc) {
				long num;
 
				i++;
				num = strtol(argv[i], NULL, 0);
				switch (num) {
				case 8:
					_mem_width = 1;
					break;
				case 16:
					_mem_width = 2;
					break;
				case 32:
					_mem_width = 4;
					break;
				default:
					fprintf(stderr, "\tERROR! invalid memory width\n");
					err = -ERANGE;
				}
			} else
				err = -EINVAL;
 
			break;
		case 'h':
			printf("%s [option] <input>\n", argv[0]);
			printf("\t-O <bfdname> output object format (ascii)\n");
			printf("\t-w [8|16|32] memory width in bit (default: 32)\n");
			printf("\t-o <file>    output filename (default: stdout)\n");
			printf("\t-h           useful help\n");
 
			exit(0);
		}
	}
 
	if (0 == err && NULL == _infile) {
		fprintf(stderr, "\tERROR! no input file given\n");
		err = -EINVAL;
	}
 
	return err;
}
 
static int _load_file(const char *filename, unsigned char **buf_ptr)
{
	unsigned char *buf;
	int err;
 
	buf = NULL;
 
	err = open(filename, O_RDONLY);
	if (0 <= err) {
		struct stat s;
		int fd;
 
		fd = err;
		err = 0;
 
		err = fstat(fd, &s);
		if (0 == err) {
			buf = malloc(s.st_size);
			if (buf) {
				unsigned int r;
 
				r = 0;
				do {
					err = read(fd, buf + r, s.st_size - r);
					if (0 > err) {
						err = -errno;
						if (-EINTR != err)
							break;
 
						err = 0;
					}
 
					r += err;
					err = 0;
				} while (r < s.st_size);
 
				if (0 == err) {
					*buf_ptr = buf;
					err = s.st_size;
				}
			} else
				err = -ENOMEM;
		}
 
		close(fd);
	} else
		err = -errno;
 
	if (0 > err)
		fprintf(stderr, "load file failed, error %d\n", err);
 
	return err;
}
 
static const char *_get_filename(const char *filename)
{
	int i;
 
	i = strlen(filename);
	while (0 != i) {
		if ('/' == filename[i]) {
			i++;
			break;
		}
 
		i--;
	}
 
	return &filename[i];
}
 
static int _convert_to_ascii(const char *filename, const unsigned char *buf,
                             int size)
{
	char name[64];
	int err;
 
	err = snprintf(&name[0], 64, "%s.asc", _get_filename(filename));
	if (64 > err) {
		err = open(&name[0], O_WRONLY | O_CREAT | O_TRUNC, 00644);
		if (0 <= err) {
			int offset, fd;
 
			fd = err;
			err = 0;
 
			offset = 0;
			while (offset < size) {
				unsigned char ob[34];
				int i;
 
				memset(&ob[0], 0x00, sizeof(ob));
				for (i = 0; i < _mem_width; i++) {
					unsigned char c;
					int j;
 
					if ((i + offset) < size) {
						c = buf[i + offset];
					} else
						c = 0x00;
 
					for (j = 0; j < 8; j++) {
						if (0 != (c & (0x80 >> j)))
							ob[(i << 3) + j] = '1';
						else
							ob[(i << 3) + j] = '0';
					}
				}
 
				ob[(i << 3)] = '\n';
				err = write(fd, &ob[0], (i << 3) + 1);
				if (0 > err) {
					err = -errno;
					break;
				}
 
				offset += i;
 
				err = 0;
			}
 
			close(fd);
		} else
			err = -errno;
	} else
		err = -ENAMETOOLONG;
 
	if (0 != err)
		fprintf(stderr, "write output file failed, error %d\n", err);
 
	return err;
}
 
int main(int argc, char *argv[])
{
	int err;
 
	err = _parse_args(argc, argv);
	if (0 == err) {
		unsigned char *inbuf;
 
		err = _load_file(_infile, &inbuf);
		if (0 < err) {
			int len;
 
			len = err;
			switch (_bfdname) {
			case _bfd_ascii:
				err = _convert_to_ascii(_infile, inbuf, len);
				break;
			}
 
			free(inbuf);
		}
	}
 
	return err;
}
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.