/* api.c : part of The Bastard disassembly environment ========================G
 *
 * Contains  the bulk of the internal code -- specifically, the API routines
 * provided for internal and scripting use. Functions should be in the same
 * order as in api.h
 */
#include <api/api_main.h>
#include <debug.h>

extern struct DISASM_TGT target;
extern struct DISASM_ENV disasm_env;
extern struct DISASM_PREFS disasm_prefs;

/* API Sections:
 *     3. Sections            :: Creating/manipulating file SECTION objects
 * /

/* ---------------------------------------------------------------Sections */
/* TODO: check that start/end are not in existing sections */
   int CreateSection(char *name, long start, int size, long pa, int type){
      struct section section;
      int ret = 1;
   
      DEBUG_PrintMsg("Creating SECTION %s\n", name);
      if ( d_keyfind(SECTION_NAME, &name) == S_OKAY) {
         SetLastError(4810);
         return(0);
      } else if (db_status == S_NOTFOUND ) {
         DefineAddr(start, size,  pa, ADDR_SECTION);

         strncpy(section.name, name, 32);
         section.rva = start;
         section.size = size;
         section.flags = type;
         if ( d_fillnew(SECTION, &section) != S_OKAY) {
            dbErrorMsg();
            ret = 0;
         }
      } 
      else {
         DEBUG_PrintMsg("Failed to load SECTION %s\n", name);
         dbError();
         ret = 0;
      }
      disasm_env.flags |= DB_MOD;
      return(ret);
   }

   int DeleteSection(char *name){
      disasm_env.flags |= DB_MOD;
      if (DBRecordDelete(SECTION_NAME, name))
         return(1);
      return(SetLastError(4820));
   }

   int GetSection( long rva, struct section *s){
      struct section sec;
      int cont;

      cont = DBIndexFirst(SECTION_RVA, &sec);
      while (cont){
         if ( rva >= sec.rva && rva < sec.rva + sec.size){
            memcpy(s, &sec, sizeof(struct section));
            return(1);
         }
         cont = DBIndexNext(SECTION_RVA, &sec);
      }
      return(0);
   }

   long GetSectionStart(char *name){
      struct section s;
   
      strcpy( s.name, name);
      if ( d_keyfind(SECTION_NAME, &s.name) == S_OKAY){ 
         d_recread(&s);
         return(s.rva);
      }
      return(SetLastError(4820));
   }

   long GetSectionEnd(char *name){
      struct section s;
   
      strcpy( s.name, name);
      if ( d_keyfind(SECTION_NAME, &s.name) == S_OKAY){ 
         d_recread(&s);
         return(s.rva + s.size - 1);
      }
      return(SetLastError(4820));
   }

   int  GetSectionName(long rva, char* buf){
      struct section s;
   
      d_keyfrst(SECTION_NAME);
      while (db_status == S_OKAY){
         d_recread(&s);   
         if ( rva >= s.rva && rva < (s.rva + s.size)){
            strncpy(buf, s.name, 32);
            return(1);
         }
      }
      return(SetLastError(4820));
   }

   int  GetSectionFlags(char *name){
      struct section s;
   
      strcpy( s.name, name);
      if ( d_keyfind(SECTION_NAME, &s.name) == S_OKAY){ 
         d_recread(&s);
         return(s.flags);
      }
      return(SetLastError(4820));
   }

   int  SetSectionStart(char *name, long start) {
      struct section s;
   
      strcpy( s.name, name);
      if ( d_keyfind(SECTION_NAME, &s.name) == S_OKAY){ 
         d_recread(&s);
         s.rva = start;
         if ( d_recwrite(&s) == S_OKAY) 
            return(1);
         else 
            return(db_status);
      }
      return(SetLastError(4820));
   }

   int  SetSectionEnd(char *name, long end){
      struct section s;
   
      strcpy( s.name, name);
      if ( d_keyfind(SECTION_NAME, &s.name) == S_OKAY){ 
         d_recread(&s);
         s.size =  end - s.rva;
         if ( d_recwrite(&s) == S_OKAY) 
            return(1);
         else 
            return(db_status);
      }
      return(SetLastError(4820));
   }

   int  SetSectionName(char *name, char *new_name){
      struct section s;
   
      strcpy( s.name, name);
      if ( d_keyfind(SECTION_NAME, &s.name) == S_OKAY){ 
         d_recread(&s);
         strcpy(s.name, new_name);
         if ( d_recwrite(&s) == S_OKAY) 
            return(1);
         else 
            return(db_status);
      }
      return(SetLastError(4820));
   }

   int  SetSectionFlags(char *name, int flags){
      struct section s;
   
      strcpy( s.name, name);
      if ( d_keyfind(SECTION_NAME, &s.name) == S_OKAY){ 
         d_recread(&s);
         s.flags = flags;   
         if ( d_recwrite(&s) == S_OKAY) 
            return(1);
         else 
            return(db_status);
      }
      return(SetLastError(4820));
   }

