Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <ctype.h>
  4. #include <cstring>
  5. #include <string>
  6. using namespace std;
  7.  
  8. char str[20000], *word[100];
  9. int wordlen[sizeof(word) / sizeof(word[0])];
  10.  
  11. char words_ignore[100][100] = { "?debug",
  12.                                                                 "if",
  13.                                                                 "ifdef",
  14.                                                                 "ifndef",
  15.                                                                 "endif",
  16.                                                                 "macro",
  17.                                                                 "endm",
  18.                                                                 "dgroup",
  19.                                                                 "assume",
  20.                                                                 "segment",
  21.                                                                 "ends",
  22.                                                                 "public",
  23.                                                                 "proc",
  24.                                                                 "endp",
  25.                                                                 "extrn",
  26.                                                                 "model",
  27.                                                                 "label",
  28.                                                                 "end",
  29.                                                                 ""};
  30.  
  31. #define WI_macro    (words_ignore[5])
  32. #define WI_endm     (words_ignore[6])
  33. #define WI_segment  (words_ignore[9])
  34. #define WI_ends     (words_ignore[10])
  35. #define WI_proc     (words_ignore[12])
  36. #define WI_endp     (words_ignore[13])
  37. #define WI_label    (words_ignore[16])
  38. const char *WI_END = "END";
  39.  
  40. int nwords_ignore = -1;
  41. char *words_ign_sort[sizeof(words_ignore) / sizeof(words_ignore[0])];
  42.  
  43. int strcmp1(const char *s0, int n0, const char *s1, int n1)
  44. {
  45.         while (n0 && n1)
  46.         {
  47.                 n0--; n1--;
  48.                 int c = (int)tolower(*s0) - (int)tolower(*s1);
  49.                 if (c < 0) return -1;
  50.                 if (c > 0) return 1;
  51.                 if (!*(s0++) || !*(s1++)) return 0;
  52.         }
  53.         if (n0 && *s0) return 1;
  54.         if (n1 && *s1) return -1;
  55.         return 0;
  56. }
  57.  
  58. int strlen1(const char *s, int n)
  59. {
  60.         int i = 0;
  61.         while (i < n && s[i]) i++;
  62.         return i;
  63. }
  64.  
  65. char *strcpy1(char *r, const char *s, int n)
  66. {
  67.         char *r0 = r;
  68.         while (n-- && *s) *(r++) = *(s++);
  69.         *r = 0;
  70.         return r0;
  71. }
  72.  
  73. char *strchr1(char *s, int n, char c)
  74. {
  75.         while (n-- && *s)
  76.         {
  77.                 if (*s == c) return s;
  78.                 s++;
  79.         }
  80.         return 0;
  81. }
  82.  
  83. char *first_not_space(char *s)
  84. {
  85.         while (*s && isspace(*s)) s++;
  86.         return s;
  87. }
  88.  
  89. char get_word(char *s)
  90. {
  91.         int i = 0, k;
  92.         for (k = 0; k < sizeof(word) / sizeof(word[0]); k++)
  93.         {
  94.                 s = first_not_space(s + i);
  95.                 word[k] = s;
  96.                 i = 0;
  97.                 while (s[i] && !isspace(s[i]) && s[i] != ';' && s[i] != ',' && s[i] != ':')
  98.                 {
  99.                         i++;
  100.                 }
  101.                 if (i == 0)
  102.                 {
  103.                         if (s[i] != ',' && s[i] != ':') break;
  104.                         i = 1;
  105.                 }
  106.                 wordlen[k] = i;
  107.         }
  108.         for (; k < sizeof(word) / sizeof(word[0]); k++)
  109.         {
  110.                 word[k] = s; wordlen[k] = 0;
  111.         }
  112.         return s[i];
  113. }
  114.  
  115. void build_words_ignore()
  116. {
  117.         int i, j;
  118.         nwords_ignore = 0;
  119.         while (words_ignore[nwords_ignore][0])
  120.         {
  121.                 words_ign_sort[nwords_ignore] = words_ignore[nwords_ignore];
  122.                 nwords_ignore++;
  123.         }
  124.         for (i = 0; i < nwords_ignore; i++) for (j = 0; j < i; j++)
  125.         {
  126.                 if (strcmp1(words_ign_sort[j], -1, words_ign_sort[i], -1) > 0)
  127.                 {
  128.                         char *s = words_ign_sort[j];
  129.                         words_ign_sort[j] = words_ign_sort[i];
  130.                         words_ign_sort[i] = s;
  131.                 }
  132.         }
  133.         words_ign_sort[nwords_ignore] = words_ignore[nwords_ignore];
  134. }
  135.  
  136. int find_word_ign_sort(const char *s, int n)
  137. {
  138.         int i0, i1, i;
  139.         if (nwords_ignore < 0) build_words_ignore();
  140.         i0 = -1; i1 = nwords_ignore;
  141.         while (i1 > i0 + 1)
  142.         {
  143.                 i = (i0 + i1) / 2;
  144.                 if (strcmp1(s, n, words_ign_sort[i], -1) > 0) i0 = i;
  145.                 else i1 = i;
  146.         }
  147.         return i1;
  148. }
  149.  
  150. char *find_word_ignore(const char *s, int n)
  151. {
  152.         int i = find_word_ign_sort(s, n);
  153.         return (strcmp1(s, n, words_ign_sort[i], -1) == 0) ? words_ign_sort[i] : 0;
  154. }
  155.  
  156. char *add_word_ignore(const char *s, int n)
  157. {
  158.         int i = find_word_ign_sort(s, n), j;
  159.         if (strcmp1(s, n, words_ign_sort[i], -1) != 0)
  160.         {
  161.                 if (s[0] && strlen1(s, n) < sizeof(words_ignore[0]) &&
  162.                         words_ignore[nwords_ignore+1] < words_ignore[0] + sizeof(words_ignore))
  163.                 {
  164.                         strcpy1(words_ignore[nwords_ignore], s, n);
  165.                         words_ignore[nwords_ignore+1][0] = 0;
  166.                         for (j = nwords_ignore; j >= i; j--) words_ign_sort[j+1] = words_ign_sort[j];
  167.                         words_ign_sort[i] = words_ignore[nwords_ignore];
  168.                         nwords_ignore++;
  169.                         words_ign_sort[nwords_ignore] = words_ignore[nwords_ignore];
  170.                 }
  171.                 else return 0;
  172.         }
  173.         return words_ign_sort[i];
  174. }
  175.  
  176. struct CSegment
  177. {
  178.         char name[100];
  179.         int state;
  180.         string text;
  181. };
  182.  
  183. int nsegment = 0, cursegment = 0, stack_segment[50], nstack_segment = 0;
  184. CSegment segment[100];
  185.  
  186. void push_stack_segment()
  187. {
  188.         if (nstack_segment < sizeof(stack_segment) / sizeof(stack_segment[0]))
  189.         {
  190.                 stack_segment[nstack_segment] = cursegment;
  191.         }
  192.         nstack_segment++;
  193. }
  194.  
  195. void pop_stack_segment()
  196. {
  197.         if (nstack_segment > 0) nstack_segment--;
  198.         if (nstack_segment < sizeof(stack_segment) / sizeof(stack_segment[0]))
  199.         {
  200.                 cursegment = stack_segment[nstack_segment];
  201.         }
  202. }
  203.  
  204. void newsegment()
  205. {
  206.         segment[nsegment].name[0] = 0;
  207.         segment[nsegment].state = 0;
  208.         segment[nsegment].text = "";
  209.         cursegment = nsegment++;
  210. }
  211.  
  212. void tosegment(char *name, int nameL)
  213. {
  214.         int i;
  215.         cursegment = 0;
  216.         if (strlen1(name, nameL) >= sizeof(segment[0].name)) return;
  217.         for (i = 0; i < nsegment; i++)
  218.         {
  219.                 if (strcmp1(name, nameL, segment[i].name, -1) == 0)
  220.                 {
  221.                         cursegment = i;
  222.                         return;
  223.                 }
  224.         }
  225.         if (nsegment >= sizeof(segment) / sizeof(segment[0])) return;
  226.         newsegment();
  227.         strcpy1(segment[cursegment].name, name, nameL);
  228. }
  229.  
  230. void outsegment()
  231. {
  232.         if (segment[cursegment].state == 0) return;
  233.         fputs("\nsegment", stdout);
  234.         if (segment[cursegment].name[0])
  235.         {
  236.                 fputc(' ', stdout);
  237.                 fputs(segment[cursegment].name, stdout);
  238.         }
  239.         fputc('\n', stdout);
  240.         fputs(segment[cursegment].text.c_str(), stdout);
  241.         fputs("endseg", stdout);
  242.         if (segment[cursegment].name[0])
  243.         {
  244.                 fputs("  ", stdout);
  245.                 fputs(segment[cursegment].name, stdout);
  246.         }
  247.         fputc('\n', stdout);
  248. }
  249.  
  250. void transform_label(int in_define, bool label = false)
  251. {
  252.         if (in_define)
  253.         {
  254.                 memmove(str + 8, word[0], wordlen[0]);
  255.                 memcpy(str, "nextdef ", 8);
  256.                 str[wordlen[0]+8] = '\n';
  257.                 str[wordlen[0]+9] = 0;
  258.         }
  259.         else if (label)
  260.         {
  261.                 memmove(str, word[0], wordlen[0]);
  262.                 str[wordlen[0]] = ':';
  263.                 str[wordlen[0]+1] = '\n';
  264.                 str[wordlen[0]+2] = 0;
  265.         }
  266.         segment[cursegment].state |= 4;
  267. }
  268.  
  269. int main()
  270. {
  271.         char *s;
  272.         int in_macro = 0, in_define = 0, i;
  273.         newsegment();
  274.         for (;;)
  275.         {
  276.                 i = sizeof(str) - 200;
  277.                 if (!fgets(str, i, stdin)) break;
  278.                 if ((s = strchr(str, '\n')) == NULL)
  279.                 {
  280.                         if (strlen(str) < i-1) strcat(str, "\n");
  281.                         else
  282.                         {
  283.                                 while (fgets(str, sizeof(str), stdin))
  284.                                 {
  285.                                         if (strchr(str, '\n')) break;
  286.                                 }
  287.                                 continue;
  288.                         }
  289.                 }
  290.                 char* p;
  291.                 while (p=strstr(str,"st("))
  292.                 {
  293.                         p[2]=p[3];
  294.                         memmove(p+3,p+5,strlen(p+5)+1);
  295.                 }
  296.                 get_word(str);
  297.                 if (word[1][0] == ':') transform_label(in_define, false);
  298.                 else
  299.                 {
  300.                         if (word[0][0] == '.') continue;
  301.                         if (strcmp1(word[0], wordlen[0], WI_macro, -1) == 0 ||
  302.                                 strcmp1(word[1], wordlen[1], WI_macro, -1) == 0)
  303.                         {
  304.                                 add_word_ignore(word[0], wordlen[0]);
  305.                                 in_macro++;
  306.                                 continue;
  307.                         }
  308.                         if (strcmp1(word[0], wordlen[0], WI_endm, -1) == 0)
  309.                         {
  310.                                 if (in_macro > 0) in_macro--;
  311.                                 continue;
  312.                         }
  313.                         if (strcmp1(word[1], wordlen[1], WI_segment, -1) == 0)
  314.                         {
  315.                                 push_stack_segment();
  316.                                 add_word_ignore(word[0], wordlen[0]);
  317.                                 tosegment(word[0], wordlen[0]);
  318.                                 continue;
  319.                         }
  320.                         if (strcmp1(word[1], wordlen[1], WI_ends, -1) == 0)
  321.                         {
  322.                                 pop_stack_segment();
  323.                                 continue;
  324.                         }
  325.                         if (find_word_ignore(word[0], wordlen[0])) continue;
  326.                         if (wordlen[0] == 0 || strcmp1(word[0], wordlen[0], "align", -1) == 0)
  327.                         {
  328.                                 if (word[0][0] == 0) {str[0] = '\n'; str[1] = 0;}
  329.                         }
  330.                         else if (strcmp1(word[1], wordlen[1], WI_endp, -1) == 0)
  331.                         {
  332.                                 if (in_define > 0) strcpy(str, (--in_define) ? "newdef\n" : "enddef\n");
  333.                         }
  334.                         else if (strcmp1(word[1], wordlen[1], WI_proc, -1) == 0)
  335.                         {
  336.                                 memmove(str + 8, word[0], wordlen[0]);
  337.                                 memcpy(str, (in_define++) ? "newdef  " : "define  ", 8);
  338.                                 str[wordlen[0]+8] = '\n';
  339.                                 str[wordlen[0]+9] = 0;
  340.                                 segment[cursegment].state |= 4;
  341.                         }
  342.                         else if (strcmp1(word[1], wordlen[1], WI_label, -1) == 0)
  343.                         {
  344.                                 transform_label(in_define, true);
  345.                         }
  346.                         else
  347.                         {
  348.                                 for (i = 0; i <= 1; i++)
  349.                                 {
  350.                                         if (strcmp1(word[i], wordlen[i], "db", -1) == 0 &&
  351.                                                 wordlen[i+2] >= 3 && strcmp1(word[i+2], 3, "dup", 3) == 0)
  352.                                         {
  353.                                                 if (word[i][0] == 'd') word[i][0] = 'r';
  354.                                                 else if (word[i][0] == 'D') word[i][0] = 'R';
  355.                                                 word[i+1][wordlen[i+1]] = '\n';
  356.                                                 word[i+1][wordlen[i+1]+1] = 0;
  357.                                                 segment[cursegment].state |= 2;
  358.                                                 break;
  359.                                         }
  360.                                 }
  361.                                 if (i > 1)
  362.                                 {
  363.                                         int word_shift = 0;
  364.                                         for (i = 1; i < sizeof(word) / sizeof(word[0]); i++)
  365.                                         {
  366.                                                 word[i] += word_shift;
  367.                                                 if (wordlen[i] >= 4 && word[i][0] != '[' &&
  368.                                                         word[i][wordlen[i]-1] == ']' &&
  369.                                                         (s = strchr1(word[i], wordlen[i], '[')) != 0)
  370.                                                 {
  371.                                                         *s = '+';
  372.                                                         memmove(word[i] + 1, word[i], strlen(word[i]) + 1);
  373.                                                         word[i][0] = '[';
  374.                                                         wordlen[i]++;
  375.                                                         word_shift++;
  376.                                                 }
  377.                                                 else if (wordlen[i] >= 1 && !strchr1(word[i], wordlen[i], '[') &&
  378.                                                                 strcmp1(word[i-1], wordlen[i-1], "ptr", -1) == 0)
  379.                                                 {
  380.                                                         memmove(word[i] + wordlen[i] + 2, word[i] + wordlen[i],
  381.                                                                         strlen(word[i] + wordlen[i]) + 1);
  382.                                                         memmove(word[i] + 1, word[i], wordlen[i]);
  383.                                                         word[i][0] = '['; word[i][wordlen[i] + 1] = ']';
  384.                                                         wordlen[i] += 2;
  385.                                                         word_shift += 2;
  386.                                                 }
  387.                                                 else if (wordlen[i] >= 5 && word[i][wordlen[i]-1] == ')' &&
  388.                                                                          strcmp1(word[i], wordlen[i], "st(", -1))
  389.                                                 {
  390.                                                         memmove(word[i] + 2, word[i] + 3, wordlen[i] - 4);
  391.                                                         memmove(word[i] + wordlen[i] - 2, word[i] + wordlen[i],
  392.                                                                         strlen(word[i] + wordlen[i]) + 1);
  393.                                                         word_shift -= 2;
  394.                                                 }
  395.                                         }
  396.                                         segment[cursegment].state |= 1;
  397.                                 }
  398.                         }
  399.                 }
  400.                 if (in_macro) continue;
  401.                 if ((s = strchr(str, ';')) != NULL)
  402.                 {
  403.                         s[0] = '\n'; s[1] = 0;
  404.                         if (!first_not_space(str)[0]) continue;
  405.                 }
  406.                 segment[cursegment].text += str;
  407.         }
  408.         for (cursegment = 0; cursegment < nsegment; cursegment++)
  409.         {
  410.                 if ((segment[cursegment].state & 3) != 2) outsegment();
  411.         }
  412.         fputs("\nI_END:\n", stdout);
  413.         for (cursegment = 0; cursegment < nsegment; cursegment++)
  414.         {
  415.                 if ((segment[cursegment].state & 3) == 2) outsegment();
  416.         }
  417.         fputs("\nalign 0x10\nU_END:\n", stdout);
  418.         return 0;
  419. }
  420.  
  421.