misc.c
来自「一个很有名的硬件模拟器。可以模拟CPU」· C语言 代码 · 共 1,190 行 · 第 1/2 页
C
1,190 行
val = (largeint_t)va_arg(v, word_t); /* set buffer pointer to last digit */ p = bp = buf + MAXDIGS; if (val & HIBITL) *--bp = _lowdigit(&val); goto decimal; case 'o': mradix = 7; lradix = 2; goto fixed; case 'p': /* target address */ if (sizeof(md_addr_t) > 4) flagword |= LENGTH; /* fallthru */ case 'X': case 'x': mradix = 15; lradix = 3; fixed: /* fetch the argument to be printed */ if (flagword & LENGTH) val = va_arg(v, largeint_t); else val = (largeint_t)va_arg(v, word_t); /* set translate table for digits */ tab = (fcode == 'X') ? "0123456789ABCDEF" : "0123456789abcdef"; /* develop the digits of the value */ p = bp = buf + MAXDIGS; { slargeint_t qval = val; if (qval == 0) { otherlength = lzero = 1; flagword |= LZERO; } else do { *--bp = tab[qval & mradix]; qval = ((qval >> 1) & ~HIBITL) >> lradix; } while (qval != 0); } break;#ifndef HOST_HAS_QWORD process_float:#endif /* !HOST_HAS_QWORD */ case 'f': if (flagword & DOTSEEN) sprintf(buf1, "%%%d.%df", width, prec); else if (width) sprintf(buf1, "%%%df", width); else sprintf(buf1, "%%f"); /* fetch the argument to be printed */ fval = va_arg(v, dfloat_t); /* print floating point value */ sprintf(buf, buf1, fval); bp = buf; p = bp + strlen(bp); break; case 's': bp = va_arg(v, char *); if (bp == NULL) bp = "(null)"; p = bp + strlen(bp); break; case '%': buf[0] = fcode; goto c_merge; case 'c': buf[0] = va_arg(v, int); c_merge: p = (bp = &buf[0]) + 1; break; default: /* this is technically an error; what we do is to back up the format pointer to the offending char and continue with the format scan */ format--; continue; } /* calculate number of padding blanks */ k = (n = p - bp) + prefixlength + otherlength; if (width <= k) count += k; else { count += width; /* set up for padding zeroes if requested; otherwise emit padding blanks unless output is to be left-justified */ if (flagword & PADZERO) { if (!(flagword & LZERO)) { flagword |= LZERO; lzero = width - k; } else lzero += width - k; /* cancel padding blanks */ k = width; } else { /* blanks on left if required */ PAD(_blanks, width - k); } } /* prefix, if any */ if (prefixlength != 0) { PUT(prefix, prefixlength); } /* zeroes on the left */ if (flagword & LZERO) { PAD(_zeroes, lzero); } /* the value itself */ if (n > 0) { PUT(bp, n); } }}/* portable sprintf with qword support, returns end pointer */char *mysprintf(char *obuf, char *format, ...){ /* vararg parameters */ va_list v; va_start(v, format); return myvsprintf(obuf, format, v);}/* portable vfprintf with qword support, returns end pointer */voidmyvfprintf(FILE *stream, char *format, va_list v){ /* temp buffer */ char buf[2048]; myvsprintf(buf, format, v); fputs(buf, stream);}/* portable fprintf with qword support, returns end pointer */voidmyfprintf(FILE *stream, char *format, ...){ /* temp buffer */ char buf[2048]; /* vararg parameters */ va_list v; va_start(v, format); myvsprintf(buf, format, v); fputs(buf, stream);}#ifdef HOST_HAS_QWORD#define LL_MAX LL(9223372036854775807)#define LL_MIN (-LL_MAX - 1)#define ULL_MAX (ULL(9223372036854775807) * ULL(2) + 1)/* convert a string to a signed result */sqword_tmyatosq(char *nptr, char **endp, int base){ char *s, *save; int negative, overflow; sqword_t cutoff, cutlim, i; unsigned char c; extern int errno; if (!nptr || !*nptr) panic("strtoll() passed a NULL string"); s = nptr; /* skip white space */ while (isspace((int)(*s))) ++s; if (*s == '\0') goto noconv; if (base == 0) { if (s[0] == '0' && toupper(s[1]) == 'X') base = 16; else base = 10; } if (base <= 1 || base > 36) panic("bogus base: %d", base); /* check for a sign */ if (*s == '-') { negative = 1; ++s; } else if (*s == '+') { negative = 0; ++s; } else negative = 0; if (base == 16 && s[0] == '0' && toupper(s[1]) == 'X') s += 2; /* save the pointer so we can check later if anything happened */ save = s; cutoff = LL_MAX / (unsigned long int) base; cutlim = LL_MAX % (unsigned long int) base; overflow = 0; i = 0; for (c = *s; c != '\0'; c = *++s) { if (isdigit (c)) c -= '0'; else if (isalpha (c)) c = toupper(c) - 'A' + 10; else break; if (c >= base) break; /* check for overflow */ if (i > cutoff || (i == cutoff && c > cutlim)) overflow = 1; else { i *= (unsigned long int) base; i += c; } } /* check if anything actually happened */ if (s == save) goto noconv; /* store in ENDP the address of one character past the last character we converted */ if (endp != NULL) *endp = (char *) s; if (overflow) { errno = ERANGE; return negative ? LL_MIN : LL_MAX; } else { errno = 0; /* return the result of the appropriate sign */ return (negative ? -i : i); }noconv: /* there was no number to convert */ if (endp != NULL) *endp = (char *) nptr; return 0;}/* convert a string to a unsigned result */qword_tmyatoq(char *nptr, char **endp, int base){ char *s, *save; int overflow; qword_t cutoff, cutlim, i; unsigned char c; extern int errno; if (!nptr || !*nptr) panic("strtoll() passed a NULL string"); s = nptr; /* skip white space */ while (isspace((int)(*s))) ++s; if (*s == '\0') goto noconv; if (base == 0) { if (s[0] == '0' && toupper(s[1]) == 'X') base = 16; else base = 10; } if (base <= 1 || base > 36) panic("bogus base: %d", base); if (base == 16 && s[0] == '0' && toupper(s[1]) == 'X') s += 2; /* save the pointer so we can check later if anything happened */ save = s; cutoff = ULL_MAX / (unsigned long int) base; cutlim = ULL_MAX % (unsigned long int) base; overflow = 0; i = 0; for (c = *s; c != '\0'; c = *++s) { if (isdigit (c)) c -= '0'; else if (isalpha (c)) c = toupper(c) - 'A' + 10; else break; if (c >= base) break; /* check for overflow */ if (i > cutoff || (i == cutoff && c > cutlim)) overflow = 1; else { i *= (unsigned long int) base; i += c; } } /* check if anything actually happened */ if (s == save) goto noconv; /* store in ENDP the address of one character past the last character we converted */ if (endp != NULL) *endp = (char *) s; if (overflow) { errno = ERANGE; return ULL_MAX; } else { errno = 0; /* return the result of the appropriate sign */ return i; }noconv: /* there was no number to convert */ if (endp != NULL) *endp = (char *) nptr; return 0;}#ifdef TESTITvoidtestit(char *s){ char buf[128]; qword_t qval; qval = myatoq(s, NULL, 10); myqtoa(qval, "%x", buf, NULL); fprintf(stderr, "x: %s\n", buf); myqtoa(qval, "%16x", buf, NULL); fprintf(stderr, "16x: %s\n", buf); myqtoa(qval, "%016x", buf, NULL); fprintf(stderr, "016x: %s\n", buf); myqtoa(qval, "0x%016x", buf, NULL); fprintf(stderr, "0x016x: %s\n", buf); myqtoa(qval, "0x%08x", buf, NULL); fprintf(stderr, "0x08x: %s\n", buf); myqtoa(qval, "%d", buf, NULL); fprintf(stderr, "d: %s\n", buf); myqtoa(qval, "%22d", buf, NULL); fprintf(stderr, "22d: %s\n", buf); myqtoa(qval, "%022d", buf, NULL); fprintf(stderr, "022d: %s\n", buf); myqtoa(qval, "%u", buf, NULL); fprintf(stderr, "u: %s\n", buf); myqtoa(qval, "%o", buf, NULL); fprintf(stderr, "o: %s\n", buf);}voidstestit(char *s){ char buf[128]; sqword_t sqval; sqval = myatosq(s, NULL, 10); myqtoa(sqval, "%x", buf, NULL); fprintf(stderr, "x: %s\n", buf); myqtoa(sqval, "%d", buf, NULL); fprintf(stderr, "d: %s\n", buf); myqtoa(sqval, "%u", buf, NULL); fprintf(stderr, "u: %s\n", buf);}voidxtestit(char *s){ char buf[128]; qword_t qval; qval = myatoq(s, NULL, 16); myqtoa(qval, "%x", buf, NULL); fprintf(stderr, "x: %s\n", buf); myqtoa(qval, "%d", buf, NULL); fprintf(stderr, "d: %s\n", buf); myqtoa(qval, "%u", buf, NULL); fprintf(stderr, "u: %s\n", buf);}#endif /* TESTIT */#endif /* HOST_HAS_QWORD */#ifdef GZIP_PATHstatic struct { char *type; char *ext; char *cmd;} gzcmds[] = { /* type */ /* extension */ /* command */ { "r", ".gz", "%s -dc %s" }, { "rb", ".gz", "%s -dc %s" }, { "r", ".Z", "%s -dc %s" }, { "rb", ".Z", "%s -dc %s" }, { "w", ".gz", "%s > %s" }, { "wb", ".gz", "%s > %s" }};/* same semantics as fopen() except that filenames ending with a ".gz" or ".Z" will be automagically get compressed */FILE *gzopen(char *fname, char *type){ int i; char *cmd = NULL, *ext; FILE *fd; char str[2048]; /* get the extension */ ext = mystrrchr(fname, '.'); /* check if extension indicates compressed file */ if (ext != NULL && *ext != '\0') { for (i=0; i < N_ELT(gzcmds); i++) { if (!strcmp(gzcmds[i].type, type) && !strcmp(gzcmds[i].ext, ext)) { cmd = gzcmds[i].cmd; break; } } } if (!cmd) { /* open file */ fd = fopen(fname, type); } else { /* open pipe to compressor/decompressor */ sprintf(str, cmd, GZIP_PATH, fname); fd = popen(str, type); } return fd;}/* close compressed stream */voidgzclose(FILE *fd){ /* attempt pipe close, otherwise file close */ if (pclose(fd) == -1) fclose(fd);}#else /* !GZIP_PATH */FILE *gzopen(char *fname, char *type){ return fopen(fname, type);}voidgzclose(FILE *fd){ fclose(fd);}#endif /* GZIP_PATH *//* compute 32-bit CRC one byte at a time using the high-bit first (big-endian) bit ordering convention */#define POLYNOMIAL 0x04c11db7Lstatic int crc_init = FALSE;static unsigned long crc_table[256];/* generate the table of CRC remainders for all possible bytes */static voidcrc_gentab(void){ int i, j; word_t crc_accum; for (i=0; i < 256; i++) { crc_accum = ((unsigned long)i << 24); for (j=0; j < 8; j++) { if (crc_accum & 0x80000000L) crc_accum = (crc_accum << 1) ^ POLYNOMIAL; else crc_accum = (crc_accum << 1); } crc_table[i] = crc_accum; } return;}/* update the CRC on the data block one byte at a time */word_tcrc(word_t crc_accum, word_t data){ int i, j; if (!crc_init) { crc_gentab(); crc_init = TRUE; } for (j=0; j < sizeof(word_t); j++) { i = ((int)(crc_accum >> 24) ^ (data >> (j*8))) & 0xff; crc_accum = (crc_accum << 8) ^ crc_table[i]; } return crc_accum;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?