Advertisement
Guest User

Untitled

a guest
Feb 17th, 2020
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.29 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5.  
  6. char *help =
  7. "Display binary file of known format in readable form.\n"
  8. "\nusage: ./rb <filename> <formatstring>\n"
  9. "\nGRAMMAR\n"
  10. "\nitem specifiers\n"
  11. "   c: read one byte and print as character\n"
  12. "   b/B, w/W, d/D, q/Q:\n"
  13. "      read a byte/word/dword/qword (1/2/4/8 bytes) and print as integer\n"
  14. "      lowercase is for signed, uppercase is for unsigned\n"
  15. "   f: float (32 bits)\n"
  16. "   F: double (64 bits)\n"
  17. "   n: newline\n"
  18. "   'text': just print text in single quotes\n"
  19. "\nflags are cancelled by lowercase equivalent\n"
  20. "   A: read items as aligned by its size boundary\n"
  21. "      current position is taken for base address\n"
  22. "   S: silence the processing (don't print)\n"
  23. "   Z: always 'S' when zero occurs\n"
  24. "      e.g. Zcccccccccccccccczs reads out 16-byte array\n"
  25. "      but only prints null-terminated string from it\n"
  26. "\n[tlN ...] :\n"
  27. "   repeatedly process ...\n"
  28. "   't' and 'l' are optional\n"
  29. "   t: terminate on value X\n"
  30. "   otherwise just repeat X times\n"
  31. "   l: X is Nth last processed value\n"
  32. "      0th is undefined unless there was another loop right before\n"
  33. "      in which case number of previous loop iterations is taken\n"
  34. "      negative N stands for |N| minus that 0th one\n"
  35. "   otherwise X is just N\n";
  36.  
  37. long subrou(FILE *, char *);
  38.  
  39. int main(int argc, char **argv)
  40. {
  41.     if (argc < 3) {
  42.         puts(help);
  43.         return -1;
  44.     }
  45.  
  46.     FILE *file = fopen(argv[1], "rb");
  47.     char *fmt = argv[2];
  48.  
  49.     subrou(file, fmt);
  50.  
  51.     return 0;
  52. }
  53.  
  54. #define SZMEM 0x100
  55.  
  56. #define NEXTSLOT(mem, slot) \
  57.     (slot+1==mem+SZMEM ? 0 : slot+1)
  58.  
  59. #define FMT(pref, fmt) \
  60.     isupper(fmt) ? "%"pref"u" : "%"pref"d"
  61.  
  62. char garb[SZMEM];
  63.  
  64. #define RDPAD(file, off, bound) \
  65.     fread(garb, 1, (unsigned )-off % bound, file)
  66.  
  67. long subrou(FILE *file, char *fmt)
  68. {
  69.     static char *sfmt;
  70.     static long mem[SZMEM], *slot = mem;
  71.     static int align = 0, silen = 0, zsilen = 0, curoff;
  72.     float fval;
  73.     double dval;
  74.  
  75.     sfmt = fmt;
  76.  
  77.     for (; *fmt && *fmt != ']'; ++fmt) {
  78.         switch (*fmt) {
  79.         case 'B': case 'b': case 'c':
  80.             ++curoff;
  81.             *slot = fgetc(file);
  82.             if (zsilen && !*slot) silen = 1;
  83.             if (!silen) *fmt == 'c' ? putchar(*slot)
  84.                                     : printf(FMT("hh", *fmt), (char )*slot);
  85.             slot = NEXTSLOT(mem, slot);
  86.             break;
  87.         case 'W': case 'w':
  88.             if (align) curoff += RDPAD(file, curoff, sizeof(short));
  89.             curoff += fread((*slot = 0, slot), 1, sizeof(short), file);
  90.             if (zsilen && !*slot) silen = 1;
  91.             if (!silen) printf(FMT("h", *fmt), (short )*slot);
  92.             slot = NEXTSLOT(mem, slot);
  93.             break;
  94.         case 'D': case 'd':
  95.             if (align) curoff += RDPAD(file, curoff, sizeof(int));
  96.             curoff += fread((*slot = 0, slot), 1, sizeof(int), file);
  97.             if (zsilen && !*slot) silen = 1;
  98.             if (!silen) printf(FMT("", *fmt), (int )*slot);
  99.             slot = NEXTSLOT(mem, slot);
  100.             break;
  101.         case 'Q': case 'q':
  102.             if (align) curoff += RDPAD(file, curoff, sizeof(long));
  103.             curoff += fread((*slot = 0, slot), 1, sizeof(long), file);
  104.             if (zsilen && !*slot) silen = 1;
  105.             if (!silen) printf(FMT("l", *fmt), (long )*slot);
  106.             slot = NEXTSLOT(mem, slot);
  107.             break;
  108.         case 'F':
  109.             if (align) curoff += RDPAD(file, curoff, sizeof(double));
  110.             curoff += fread(&dval, 1, sizeof(double), file);
  111.             if (zsilen && dval == 0.0) silen = 1;
  112.             if (!silen) printf("%lf", dval);
  113.             *slot = (long )dval;
  114.             slot = NEXTSLOT(mem, slot);
  115.             break;
  116.         case 'f':
  117.             if (align) curoff += RDPAD(file, curoff, sizeof(float));
  118.             curoff += fread(&fval, 1, sizeof(float), file);
  119.             if (zsilen && fval == 0.0) silen = 1;
  120.             if (!silen) printf("%f", fval);
  121.             *slot = (long )fval;
  122.             slot = NEXTSLOT(mem, slot);
  123.             break;
  124.         case 'n':
  125.             putchar('\n');
  126.             break;
  127.         case '\'':
  128.             while (*++fmt != '\'') putchar(*fmt);
  129.             break;
  130.         case 'A': case 'a':
  131.             align = isupper(*fmt);
  132.             curoff = 0;
  133.             break;
  134.         case 'S': case 's':
  135.             silen = isupper(*fmt);
  136.             break;
  137.         case 'Z': case 'z':
  138.             zsilen = isupper(*fmt);
  139.             break;
  140.         case '[': {
  141.             ++fmt;
  142.             int term, last, x, n = 0;
  143.             if (term = *fmt == 't') ++fmt;
  144.             if (last = *fmt == 'l') ++fmt;
  145.             sscanf(fmt, "%d", &x);
  146.             fmt = strchr(fmt, ' ') + 1;
  147.  
  148.             if (last) x = x < 0 ? -x - *slot
  149.                                 : slot - x < mem ? slot[SZMEM-x]
  150.                                                  : slot[-x];
  151.  
  152.             if (term) while (++n, x != subrou(file, fmt));
  153.                  else while (++n, x--) subrou(file, fmt);
  154.  
  155.             fmt = sfmt;
  156.  
  157.             *slot = n;
  158.             break;
  159.         }
  160.         default:
  161.             putchar(*fmt);
  162.         }
  163.     }
  164.     sfmt = fmt;
  165.  
  166.     return slot==mem ? mem[SZMEM-1] : slot[-1];
  167. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement