FreeCalypso > hg > freecalypso-reveng
view fluid-mnf/misc.c @ 345:b595ff13547b
fluid-mnf/target.c: ported, passed compilation
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 13 Mar 2020 06:11:33 +0000 |
parents | 1cd24530c0ae |
children | f89a20e7adc7 |
line wrap: on
line source
/****************************************************************************** * FLUID (Flash Loader Utility Independent of Device) * * Copyright Texas Instruments, 2001. * Mads Meisner-Jensen, mmj@ti.com. * * Miscellaneous Utility Functions * * $Id: misc.c 1.14 Fri, 11 Oct 2002 08:40:21 +0200 mmj $ * ******************************************************************************/ #include "misc.h" #include "fluid.h" #include "trace.h" #include <stdio.h> #include <string.h> #include <time.h> #if defined(MSC) || defined(BCC) #include "windows.h" #endif /****************************************************************************** * File And Path Name Functions ******************************************************************************/ // Return the length of the directory name preceding the leafname. The // terminating slash is included in the length. Length can be zero, if there // is no dirname. int dirname_len(const char *pathname) { char *p; int len; tr(TrUtility, "dirname_len('%s')\n", pathname); if ((len = strlen(pathname)) == 0) return 0; p = (char *) (pathname + len - 1); tr(TrUtility, "{ %d }\n", len); while (*p != '/' && *p != '\\' && len-- > 1) p--; return len; } // Construct a full pathname from <dirname> and <leafname>. The full // pathname is copied in the buffer <buf> of size <size>. On success, the // full length of the pathname is returned. Otherwise, if the buffer is too // small, -1 is returned. NOTE: The <dirname> is supposed to end with a // slash. If not, the leafname part (if present) of the <dirname> will be // removed. int pathname_make(char *buf, int size, const char *dirname, const char *leafname) { int dir_len, leaf_len, result; tr(TrBegin|TrUtility, "pathname_make(*, %d, '%s', '%s') {\n", size, dirname, leafname); dir_len = dirname_len(dirname); leaf_len = strlen(leafname); if (dir_len > size - leaf_len - 1) result = E_BUFFER; else { memcpy(buf, dirname, dir_len); strcpy(buf + dir_len, leafname); result = dir_len + leaf_len; } tr(TrEnd|TrUtility, "} %d\n", result); return result; } /****************************************************************************** * Utility Funcions ******************************************************************************/ // Return the base 2 logarithm of <number>. Return -1 if <number> is zero. unsigned int my_log2(unsigned int number) { int result = -1; while (number > 0) { number >>= 1; result++; } return result; } /****************************************************************************** * Progress and Timer Functions ******************************************************************************/ static int progress_mul; static int progress_index; static char progress_string[35] = "(---------------------------------)"; static char progress_backup[33] = "\b\b\b\b\b\b\b\b" "\b\b\b\b\b\b\b\b" "\b\b\b\b\b\b\b\b" "\b\b\b\b\b\b\b\b"; void progress_begin(int n) { tr(TrUtility, "progress_begin(%d)\n", n); progress_index = 0; switch (arg_progress) { case 'a': // We select a progress multiplier that is a power of two. Then we // generate a progress indicator that is in the range [16..32[ chars // in length. progress_mul = n / 32; progress_mul = 1 << (my_log2(progress_mul) + 1); n = (n + progress_mul - 1) / progress_mul; progress_string[1 + n] = ')'; progress_string[1 + n + 1] = 0; flowf(NORMAL, "%s\b%s", progress_string, &progress_backup[32 - n]); break; case 'c': break; case 'd': break; } } void progress_update_simple(int n) { tr(TrUtility, "progress_update_simple(%d)\n", n); switch (arg_progress) { case 'c': flowf(NORMAL, "%c", n); break; } } void progress_update(int n) { char ch; tr(TrUtility, "progress_update(%d)\n", n); switch (arg_progress) { case 'a': if (n / progress_mul > progress_index) { progress_index++; flowf(NORMAL, "*"); } n = n % progress_mul; ch = n + (n <= 9 ? '0' : 'A' - 10); flowf(NORMAL, "%c\b", ch); break; case 'c': break; case 'd': flowf(NORMAL, "."); break; } } void progress_end(int n) { switch (arg_progress) { case 'a': if (n % progress_mul) flowf(NORMAL, "*) "); else flowf(NORMAL, ") "); break; case 'c': case 'd': flowf(NORMAL, " "); break; } } int stopwatch_start(void) { #if defined(MSC) || defined(BCC) return GetTickCount(); #else return 1000 * time(NULL); #endif } int stopwatch_stop(int time_start) { #if defined(MSC) || defined(BCC) return GetTickCount() - time_start; #else return 1000 * (time(NULL) - time_start); #endif } /****************************************************************************** * Hexdumping ******************************************************************************/ void hexdump(unsigned char *buf, int size, unsigned int addr, int unitsize) { int n, i; char string[(8+1+1) + (1+16+1+1) + (3*16) + 1]; char *s; while (size > 0) { s = string; s += sprintf(s, "%8x ", addr); // print offset n = (size > 16 ? 16 : size); // print the textual representation for (i = 0; i < n; i++) { if (buf[i] >= ' ' && buf[i] < 127) *s++ = buf[i]; else *s++ = '.'; } // pad textual representation with spaces for (i = 0; i < 16 - n; i++) { *s++ = ' '; } *s++ = ' '; // print hexedecimal representation for (i = 0; i < n; i += unitsize) { switch (unitsize) { case 1: s += sprintf(s, "%02x ", *(uint8 *) (buf+i)); break; case 2: s += sprintf(s, "%04x ", *(uint16 *) (buf+i)); break; case 4: s += sprintf(s, "%08x ", (int) (*(uint32 *) (buf+i))); break; } } buf += 16; addr += 16; size -= 16; puts(string); } }