home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / OBJASM.ZIP / OEXTRA.C < prev    next >
C/C++ Source or Header  |  1990-12-19  |  11KB  |  367 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "o.h"
  5.  
  6. #define LINE_SIZE   80
  7.  
  8. /*
  9. ** Local Prototypes
  10. */
  11. SEG_T *find_seg_by_name( char * );
  12. char *ignore_whitespace( char * );
  13. char *get_text( char *, char * );
  14. char *get_num( char *, unsigned long * );
  15.  
  16. struct hint_word_s {
  17.     char    *text;
  18.     int     type;
  19. };
  20.  
  21. struct hint_word_s hint_words[] = {
  22.     { "DB", BYTE_PTR },
  23.     { "DW", WORD_PTR },
  24.     { "DD", DWORD_PTR },
  25.     { "DF", FWORD_PTR },
  26.     { "DQ", QWORD_PTR },
  27.     { "DT", TBYTE_PTR },
  28. };
  29.  
  30. int hint_nwords = sizeof(hint_words)/sizeof(char *);
  31.  
  32. int hint_compare( rec_1, rec_2 )
  33.     HINT_T  *rec_1;
  34.     HINT_T  *rec_2;
  35. {
  36.     if ( rec_1->seg_idx > rec_2->seg_idx ) {
  37.         return( LEFT );
  38.     } else {
  39.         if ( rec_1->seg_idx < rec_2->seg_idx ) {
  40.             return( RIGHT );
  41.         } else {
  42.             if ( rec_1->offset > rec_2->offset ) {
  43.                 return( LEFT );
  44.             } else {
  45.                 if ( rec_1->offset < rec_2->offset ) {
  46.                     return( RIGHT );
  47.                 } else {
  48.                     return( EQUAL );
  49.                 }
  50.             }
  51.         }
  52.     }
  53. }
  54.  
  55. void hint_insert( seg_idx, offset, hint_type, length )
  56.     int             seg_idx;
  57.     unsigned long   offset;
  58.     int             hint_type;
  59.     unsigned long   length;
  60. {
  61.     HINT_T          *hint_rec;
  62.  
  63.     hint_rec = (HINT_T *)o_malloc( sizeof(HINT_T) );
  64.     hint_rec->seg_idx   = seg_idx;
  65.     hint_rec->offset    = offset;
  66.     hint_rec->hint_type = hint_type;
  67.     hint_rec->length    = length;
  68.     insert( (char *)hint_rec, hint_tree, hint_compare );
  69. }
  70.  
  71. SEG_T *find_seg_by_name( seg_text )
  72.     char    *seg_text;
  73. {
  74.     SEG_T   *seg_rec;
  75.     NODE_T  *seg_node;
  76.     NAME_T  search;
  77.     NAME_T  *name;
  78.  
  79.     seg_node = start( segment_tree, RIGHT );
  80.     while ( seg_node != segment_tree ) {
  81.         seg_rec = (SEG_T *)seg_node->data;
  82.         search.index = seg_rec->name;
  83.         name = (NAME_T *)find( (char *)&search, name_tree,
  84.                                             name_compare, NULL );
  85.         if ( name == NULL ) fmt_error( "Undefined segment name" );
  86.  
  87.         if ( strcmp(name->name,seg_text) == 0 ) {
  88.             return( seg_rec );
  89.         }
  90.         seg_node = traverse( seg_node, RIGHT );
  91.     }
  92.     return( NULL );
  93. }
  94.  
  95. char *ignore_whitespace( start )
  96.     char    *start;
  97. {
  98.     char    *pc;
  99.     char    ch;
  100.  
  101.     pc = start;
  102.     while ( (ch=*pc) != '\0' ) {
  103.         if ( ch != ' ' && ch != '\t' && ch != '\n' ) {
  104.             break;
  105.         }
  106.         pc++;
  107.     }
  108.     return( pc );
  109. }
  110.  
  111. char *get_text( destination, start )
  112.     char    *destination;
  113.     char    *start;
  114. {
  115.     char    *pc;
  116.     char    ch;
  117.     int     len;
  118.  
  119.     len = 0;
  120.     pc = start;
  121.     while ( (ch=*pc) != ' ' && ch != '\t' && ch != '=' && ch != '\0'
  122.             && ch != ':' && ch != '\n' ) {
  123.         *destination++ = ch;
  124.         pc++;
  125.         len++;
  126.         if ( len == NAMESIZE ) {
  127.             break;
  128.         }
  129.     }
  130.     *destination = '\0';
  131.     return( pc );
  132. }
  133.  
  134. char *get_num( start, value )
  135.     char            *start;
  136.     unsigned long   *value;
  137. {
  138.     char            *pc;
  139.     char            ch;
  140.     unsigned long   dec_form;
  141.     unsigned long   hex_form;
  142.     int             is_hex;
  143.     int             decable;
  144.     int             char_ok;
  145.  
  146.     dec_form = 0L;
  147.     hex_form = 0L;
  148.  
  149.     pc = start;
  150.     is_hex = FALSE;
  151.     decable = TRUE;
  152.  
  153.     while ( (ch=*pc) != '\0' ) {
  154.         char_ok = FALSE;
  155.         if ( ch >= '0' && ch <= '9' ) {
  156.             dec_form *= 10;
  157.             dec_form += ch - '0';
  158.             hex_form *= 16;
  159.             hex_form += ch - '0';
  160.             char_ok = TRUE;
  161.         }
  162.         if ( ch >= 'a' && ch <= 'f' ) {
  163.             decable = FALSE;
  164.             hex_form *= 10;
  165.             hex_form += ch - 'a' + 10;
  166.             char_ok = TRUE;
  167.         }
  168.         if ( ch >= 'A' && ch <= 'F' ) {
  169.             decable = FALSE;
  170.             hex_form *= 10;
  171.             hex_form += ch - 'A' + 10;
  172.             char_ok = TRUE;
  173.         }
  174.         if ( ch == 'h' || ch == 'H' ) {
  175.             is_hex = TRUE;
  176.             pc++;
  177.             break;
  178.         }
  179.         if ( !char_ok ) {
  180.             break;
  181.         }
  182.         pc++;
  183.     }
  184.     if ( is_hex ) {
  185.         *value = hex_form;
  186.     } else {
  187.         if ( decable ) {
  188.             *value = dec_form;
  189.         } else {
  190.             *value = 0L;
  191.         }
  192.     }
  193.     return( pc );
  194. }
  195.  
  196. void load_extra( exename, filename )
  197.     char            *exename;
  198.     char            *filename;
  199. {
  200.     FILE            *e_file;
  201.     char            temp_name[50];
  202.     char            e_line[LINE_SIZE+1];
  203.     int             line_num;
  204.     char            *pc;
  205.     char            *semicolon;
  206.     char            *equal;
  207.     char            *colon;
  208.     char            seg_text[NAMESIZE+1];
  209.     char            lab_text[NAMESIZE+1];
  210.     int             segment_type;
  211.     unsigned long   disp;
  212.     int             count;
  213.  
  214. #ifdef DEBUG
  215.     printf("Loading from extra file %s\n", filename );
  216. #endif
  217.  
  218.     strcpy( temp_name, filename );
  219.     if ( strchr(temp_name,'.') == NULL ) {  /* Append ".add" if not extension */
  220.         strcat( temp_name, ".add" );        /* is supplied                    */
  221.     }
  222.     e_file = fopen( temp_name, "r" );
  223.     if ( e_file == NULL ) {
  224.         fprintf( stderr, "%s: Cannot open %s\n", exename, temp_name );
  225.         exit(6);
  226.     }
  227.  
  228.     line_num = 1;
  229.  
  230.     /*
  231.     ** Process lines of format:
  232.     **
  233.     **  SEG segname CODE/DATA                 Pick segment type
  234.     **  labname = segname : offset            Create label
  235.     **  segname : offset : DB/DW/DD/DF/DQ/DT  Control dis-assembly
  236.     */
  237.  
  238.     while ( fgets(e_line,LINE_SIZE,e_file) != NULL ) {
  239.         semicolon = strchr( e_line, ';' );
  240.         if ( semicolon ) {
  241.             *semicolon = '\0';
  242.         }
  243.         pc = ignore_whitespace( e_line );
  244. #ifdef DEBUG
  245. fprintf(stderr, "%s", pc );
  246. #endif
  247.         if ( strnicmp(pc,"SEG ",4) == 0 ) {
  248.             pc = ignore_whitespace( pc+4 );
  249.             pc = get_text( seg_text, pc );
  250.             pc = ignore_whitespace( pc );
  251.             segment_type = 0;
  252.             if ( strnicmp(pc,"CODE",4) == 0 ) {
  253.                 pc += 4;
  254.                 segment_type = 1;
  255.             }
  256.             if ( strnicmp(pc,"DATA",4) == 0 ) {
  257.                 pc += 4;
  258.                 segment_type = 2;
  259.             }
  260.             if ( segment_type == 0 ) {
  261.                 fprintf( stderr,
  262.                   "%s: Syntax error on line %d of %s (should be CODE/DATA).\n",
  263.                   exename, line_num, temp_name );
  264.                 exit(7);
  265.             }
  266.             seg_rec = find_seg_by_name( seg_text );
  267.             if ( !seg_rec ) {
  268.                 fprintf( stderr,
  269.             "%s: Syntax error on line %d of %s (segment '%s' not found)\n",
  270.                     exename, line_num, temp_name, seg_text );
  271.                 exit(7);
  272.             }
  273.             if ( segment_type == 1 ) {
  274.                 seg_rec->code = TRUE;
  275.             } else {
  276.                 seg_rec->code = FALSE;
  277.             }
  278.         }
  279.         equal = strchr(pc, '=' );
  280.         if ( equal ) {
  281.             pc = get_text(lab_text, pc );
  282.             pc = ignore_whitespace(pc);
  283.             if ( strnicmp(pc,"=",1) != 0 ) {
  284.                 fprintf( stderr,
  285.             "%s: Syntax error on line %d of %s (expecting '=' after label)\n",
  286.                     exename, line_num, temp_name );
  287.                 exit(7);
  288.             }
  289.             pc=ignore_whitespace(pc+1);
  290.             colon=strchr(pc,':');
  291.             if ( colon == NULL ) {
  292.                 fprintf( stderr,
  293.             "%s: Syntax error on line %d of %s (expecting ':')\n",
  294.                     exename, line_num, temp_name );
  295.                 exit(7);
  296.             }
  297.             pc = get_text( seg_text, pc );
  298.             pc = ignore_whitespace( colon+1 );
  299.             pc = get_num( pc, &disp );
  300.             seg_rec = find_seg_by_name( seg_text );
  301.             if ( !seg_rec ) {
  302.                 fprintf( stderr,
  303.             "%s: Syntax error on line %d of %s (segment '%s' not found)\n",
  304.                     exename, line_num, temp_name, seg_text );
  305.                 exit(7);
  306.             }
  307.             pub_insert( seg_rec->index, disp, lab_text, LOCAL, FALSE );
  308.         }
  309.         colon = strchr(pc,':');
  310.         if ( colon ) {
  311.             pc = get_text( seg_text, pc );
  312.             seg_rec = find_seg_by_name( seg_text );
  313.             if ( !seg_rec ) {
  314.                 fprintf( stderr,
  315.             "%s: Syntax error on line %d of %s (segment '%s' not found)\n",
  316.                     exename, line_num, temp_name, seg_text );
  317.                 exit(7);
  318.             }
  319.             pc = ignore_whitespace( pc );
  320.             if ( strnicmp(pc,":",1) != 0 ) {
  321.                 fprintf( stderr,
  322.             "%s: Syntax error on line %d of %s (expecting ':' seperator)\n",
  323.                     exename, line_num, temp_name );
  324.                 exit(7);
  325.             }
  326.             pc = get_num( pc+1, &disp );
  327.             pc = ignore_whitespace( pc );
  328.             if ( strnicmp(pc,":",1) != 0 ) {
  329.                 fprintf( stderr,
  330.             "%s: Syntax error on line %d of %s (expecting ':' seperator)\n",
  331.                     exename, line_num, temp_name );
  332.                 exit(7);
  333.             }
  334.             pc = ignore_whitespace( pc+1 );
  335.             pc = get_text( lab_text, pc );  /* Is really data type text */
  336.             count = 0;
  337.             while ( count < hint_nwords ) {
  338.                 if ( stricmp(lab_text,hint_words[count].text) == 0 ) {
  339.                     break;
  340.                 }
  341.                 count++;
  342.             }
  343.             if ( count == hint_nwords ) {
  344.                 fprintf( stderr,
  345.             "%s: Syntax error on line %d of %s (expecting DB/DW/DD/DF/DQ/DT)\n",
  346.                     exename, line_num, temp_name );
  347.                 exit(7);
  348.             }
  349.             hint_insert(seg_rec->index,disp,hint_words[count].type,1);
  350.         }
  351.         pc = ignore_whitespace( pc );
  352.         if ( strlen(pc) != 0 ) {
  353.                 fprintf( stderr,
  354.        "%s: Syntax error on line %d of %s (too many characters on line '%s')\n",
  355.                     exename, line_num, temp_name, pc );
  356.                 exit(7);
  357.         }
  358.         line_num++;
  359.     }
  360.  
  361. #ifdef DEBUG
  362. fprintf(stderr, "\n", e_line );
  363. #endif
  364.  
  365.     fclose( e_file );
  366. }
  367.