#include <stdlib.h>
#include <string.h>
#include <bastard.h>
#include <extension.h>


struct EXT__LANG *settings;

void ext_lang_init( void *param ) {
   settings = (struct EXT__LANG *)param;

   /* set Language-Specific information */
   if (! param) return;
   

   /* fill function pointers */
//   settings->findstr = &FindString;
//   settings->makestr = &MakeString;
   return;
}

int add_data_types(int mach_word) {
   /* TODO: someday make this param actually be used */
   switch (mach_word) {
      case 2:
      case 4:
      case 8:
      default:
         settings->s4 = DefineDataType( "int", 4, DT_SIGNED);
         settings->u4 = DefineDataType( "unsigned int", 4, DT_UNSIGNED);
         settings->s2 = DefineDataType( "short", 2, DT_SIGNED);
         settings->u2 = DefineDataType( "unsigned short", 2, DT_UNSIGNED);
         settings->s1 = DefineDataType( "char", 1, DT_SIGNED);
         settings->u1 = DefineDataType( "unsigned char", 1, DT_UNSIGNED);
         DefineDataType( "long", 4, DT_SIGNED);
         DefineDataType( "unsigned long", 4, DT_UNSIGNED);
         settings->s8 = DefineDataType( "long long", 8, DT_SIGNED);
         settings->u8 = DefineDataType( "unsigned long long", 8, DT_UNSIGNED);
         DefineDataType( "float", 4, DT_UNSIGNED);
         DefineDataType( "double", 8, DT_UNSIGNED);
         DefineDataType( "long double", 12, DT_UNSIGNED); 
   }
   return(1);
}

int makestr(char *buf, char *text, int text_len, int type){
   char *ptr = buf;
   int len = 0;
   
   switch (type){
      case STR_STD:
         /* get length of string */
         while(*ptr) ptr++;
         len = ptr - buf;
         /* make text representation from string */
         strncpy(text, buf, text_len - 1);
         text[text_len] = 0;
         break;
      case STR_WIDE:
         break;
   }
   return(len); /* return length of string */
}

/* buf     : buffer to search for string
 * len     : length of buffer
 * pos     : pointer to integer to fill w/ offset into buffer of found string
 * text    : buffer to copy found string to
 * text_len: size of buffer 'text'
 * type    : type of string [wide or standard]
 * returns : size of string found */
#define isgood(x) ( (x >= 0x20 && x <= 0x7E) || (x >= 0x09 && x <= 0x0D) )
int findstr(char *buf, int len, int *pos, char *text, int text_len,int type){
   int x, size;
   unsigned char *c;

   for (x = 0; x < len; ++x){
      /* look for a minimum string length of 4 chars */

      c = &buf[x];
      switch(type){
         case STR_STD:
            if (isgood(c[0]) && isgood(c[1]) && isgood(c[2]) &&
                isgood(c[3]) ){
               /* we have a suspect */
               size = 4;
               while (isgood(c[size])) ++size;
               if (! buf[x+size] ) { /* check for buffer termination */
                  /* we have a string! */
                  strncpy(text, &buf[x], text_len); 
                  *pos = x;
                  return(size);
               } 
            }
            break;
         case STR_WIDE:
            break;
      } /* end switch */

   }
   return(0);
}

/* sprint a prototype for a given function */
int sprint_proto(char *buf, int len, int func_id){
   /* sprint $ret-type $name( */
   /* for i in fuc_params strncat (i) */
   /* sprint );\n */
      return(1);
}

/* sprint an entire function [usig fin_code] in HLL */
int sprint_func(char *buf, int len, int func_id){
   /* sprint proto */
   /* remove las char (;) */
   /* sprint {\n */
   /* for i in func_locals strncat \t$i\n */
   /* for i in fin_code strncat $i\n */
   /* sprint \n}\n */
      return(1);
}
/* generate the final high-level code for a function */
int gen_final(int func_id){
   /* for i in int_code do something magic.... */
      return(1);
}
/* generate a high-level language file for target */
int gen_file( char *path) {
   /* do data types */
   /* for i in functions sprint_func */
   /* remainder */
      return(1);
}
