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; }