Re: Array of Pointers to Structs

From: Grant Austin (gaustin_at_foo.foo.bar.net)
Date: 03/03/04


Date: Wed, 03 Mar 2004 22:30:43 GMT


> I would have looked at it with a debugger, but alas it
> does not compile.

I was cutting it down and didn't test it.

My working copy is now included. I also included one of the
test inputs.
(a few more output spam debug statements,but it compiles.)

I'm trying to get gcc to compile with debugging symbols so I can
use gdb. Not having a whole lot of luck.

-Grant "needs a better newsreader" Austin

list.h

#ifndef _LIST_H
#define _LIST_H

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

/* list structures */

struct motNode {
  struct motNode * next;
  unsigned int opCode;
  char type;
  unsigned int numArgs;
  char *opName;
};
typedef struct motNode motList;

struct lcNode{
  struct lcNode *next;
  unsigned int lc;
};
typedef struct lcNode lcList;

struct hashNode{
  struct hashNode * next;
  lcList * lc_head;
  int defined; /*boolean flag non-zero is defined*/
  unsigned int lc;
  char *symbol;
};
typedef struct hashNode hashList;
/* end list structures */

/* hash function */
 int hash(char * s, int T){
  int
    h = 0; /* holds number for bit-wise ops */
  int
    a = 127;
  
  for (; *s != 0; s++)
    h = (a * h + *s) % T;
  return h;
}
/* end hash function */

int lcList_insert(lcList **lc_head, unsigned int lc){

  lcList *lc_cur = malloc(sizeof *lc_cur);
  if(lc_cur == NULL) return 0;
  lc_cur->lc = lc;
  lc_cur->next = *lc_head;
  *lc_head = lc_cur;
  return 1;
}

void lcList_free(lcList **lc_cur){
  printf("lclist free\n");
  lcList *tmp;
  for( ; *lc_cur; *lc_cur = tmp){
    tmp = (*lc_cur)->next;
    free(*lc_cur);
  }
  return;
}

void lcList_dump(lcList * lc_cur){
 
  while(lc_cur){
    printf("lc dump :: %d\n",lc_cur->lc);
    lc_cur = lc_cur->next;
  }
}

hashList * hash_search(hashList *hash_cur, char * symbol){
 
  printf("hashcur %u\n",hash_cur);
  if(hash_cur == NULL) return hash_cur;
  while(hash_cur){
    if(strcmp(hash_cur->symbol,symbol) == 0){
      printf("symbol %s found in %d\n",symbol,hash_cur);
      return hash_cur;
    }
    else {
      printf("1else %u %u\n",hash_cur,hash_cur->next);
      hash_cur = hash_cur->next;
    }
  }

  printf("end hash search for %s : hash_cur %d\n",symbol,hash_cur);
  return hash_cur;
}

int hash_insert(hashList * hash_head[], int defined, unsigned int lc,
                char * symbol){
  /*
    return 0 if unable to insert, return 1 if success, -1 for
    other error
    care must be taken so that a symbol is not set as defined
    without the correct lc value.
  */

  unsigned int hidx;

  hashList * hash_cur = malloc(sizeof *hash_cur);
  hashList * hash_test = NULL;
  if(hash_cur == NULL) return 0;
  
  hidx = hash(symbol,22);
  printf("Symbol : %s\n",symbol);
  printf("hidx : %d\n",hidx);
  printf("lc : %d\n",lc);
  if((hash_cur->symbol = malloc(strlen(symbol)+1)) == NULL){
    free(hash_cur);
    return -1;
  }
  strcpy(hash_cur->symbol,symbol);
  hash_cur->defined = defined;
  hash_cur->lc = lc;
  hash_cur->lc_head = NULL;
  hash_cur->next = hash_head[hidx];
  hash_head[hidx] = hash_cur;
  printf("inserted\n");
  return 1;
}

unsigned int isDefined(hashList * hash_head[], char * symbol){
  /* returns 1 if symbol is defined, 0 else */
  unsigned int hidx;
  printf("IsDEFINED FN\n");
  hashList * hash_test = malloc(sizeof *hash_test);
  hidx = hash(symbol,22);
  printf("PRESEARCH\n");
  if ((hash_test = hash_search(hash_head[hidx], symbol)) != NULL){
    printf("POSTSEARCH\n");
    return hash_test->defined;
  }
  printf("POST @\n");
  return 0;
}

unsigned int symDefine(hashList * hash_head[], char * symbol,unsigned int lc){
  unsigned int hidx;

  hashList *hash_test = malloc(sizeof *hash_test);
  hidx = hash(symbol,22);

  if ((hash_test = hash_search(hash_head[hidx], symbol)) != NULL){
    hash_test->defined = 1;
    hash_test->lc = lc;
    return 1;
  }
  return 0;
}

void hashList_free(hashList **hash_cur){
  hashList *tmp;
  for( ; *hash_cur; *hash_cur = tmp){
    tmp = (*hash_cur)->next;
    free((*hash_cur)->symbol);
    free(*hash_cur);
  }
  return;
}

int mot_insert(motList **mot_head,unsigned int opCode, char type,
           unsigned int numArgs,const char * opName){

  motList *mot_cur = malloc(sizeof *mot_cur);

  if(mot_cur == NULL) return 0;
  if((mot_cur->opName = malloc(strlen(opName)+1)) == NULL)
    {
      free(mot_cur);
      return 0;
    }

  mot_cur->opCode = opCode;
  mot_cur->type = type;
  mot_cur->numArgs= numArgs;
  strcpy(mot_cur->opName, opName);
  mot_cur->next = *mot_head;
  *mot_head = mot_cur;
  return 1;
}

motList * mot_search(motList *mot_cur,const char * opTrg){
  while(mot_cur){
    if(strcmp(mot_cur->opName,opTrg) == 0){
      return mot_cur;
    }
    else {
    mot_cur = mot_cur->next;
    }
  }
  return mot_cur;
}

void mot_dump(motList *mot_cur){
   while(mot_cur){
    printf("%s\n",mot_cur->opName);
    mot_cur = mot_cur->next;
  }
   return;
}

void generate_mot(motList **mot_cur){
  mot_insert(mot_cur,0,'r',0,"hlt");
  mot_insert(mot_cur,1,'r',3,"add");
  mot_insert(mot_cur,2,'r',3,"sub");
  mot_insert(mot_cur,3,'r',3,"mul");
  mot_insert(mot_cur,4,'r',3,"div");
  mot_insert(mot_cur,5,'r',3,"mod");
  mot_insert(mot_cur,6,'r',2,"move");
  mot_insert(mot_cur,7,'r',3,"and");
  mot_insert(mot_cur,8,'r',3,"or");
  mot_insert(mot_cur,9,'r',3,"xor");
  mot_insert(mot_cur,10,'r',2,"com");
  mot_insert(mot_cur,11,'r',3,"sll");
  mot_insert(mot_cur,12,'r',3,"srl");
  mot_insert(mot_cur,13,'r',3,"sra");
  mot_insert(mot_cur,14,'r',3,"jr");
  mot_insert(mot_cur,15,'r',1,"rdr");
  mot_insert(mot_cur,16,'r',1,"prr");
  mot_insert(mot_cur,17,'r',1,"prh");

  /* I format */
  mot_insert(mot_cur,18,'i',2,"li");
  mot_insert(mot_cur,19,'i',3,"addi");
  mot_insert(mot_cur,20,'i',3,"subi");
  mot_insert(mot_cur,21,'i',3,"muli");
  mot_insert(mot_cur,22,'i',3,"divi");
  mot_insert(mot_cur,23,'i',3,"modi");
  mot_insert(mot_cur,24,'i',3,"lwb");
  mot_insert(mot_cur,25,'i',3,"swb");

  /* J format */
  mot_insert(mot_cur,26,'j',2,"lwa");
  mot_insert(mot_cur,27,'i',2,"swa");
  mot_insert(mot_cur,28,'i',1,"j");
  mot_insert(mot_cur,29,'i',1,"jal");
  mot_insert(mot_cur,30,'i',1,"jeq");
  mot_insert(mot_cur,31,'i',1,"jne");
  mot_insert(mot_cur,32,'i',1,"jlt");
  mot_insert(mot_cur,33,'i',1,"jle");
  mot_insert(mot_cur,34,'i',1,"jgt");
  mot_insert(mot_cur,35,'i',1,"jge");
}

void mot_free(motList **mot_cur){
  motList *tmp;
  for( ; *mot_cur; *mot_cur = tmp){
    tmp = (*mot_cur)->next;
    free((*mot_cur)->opName);
    free(*mot_cur);
  }
  return;
}

#endif

assem.h

#include <stdio.h>
#include <string.h>
#define MAX_INPUT 81

int process_token(char * token,motList * mot, hashList * hash_table[],
                  FILE * lst,FILE * err,int lc){
  /*do work
    free parts
  */
  char * tok;

  printf("token %s last char %c\n",token,token[strlen(token)-1]);
  if( token[strlen(token)-1] == ':'){
    /* symbol in label field */
    printf("tok\n");
    tok = malloc(strlen(token));
    strncpy(tok,token,(strlen(token)-1));
    strcat(tok,"\0");
    printf("tok malloc and cpy\n");
/* if(isDefined(hash_table,tok) > 0){ */
/* printf("multiply defined\n"); */
/* }else{ */
    hash_insert(hash_table,1,lc,tok);
/* } */
  }

}
int parseln(char * line, FILE * lst,FILE * err,unsigned int lc,
            motList * mot, hashList * hash_table[]){
  char * tch;

  tch = strtok(line, " \t");
  while(tch != NULL){
    process_token(tch,mot,hash_table,lst,err,lc);
    tch = strtok(NULL," \t");
  }
}

void assemble(const char * fnroot,motList * mot,
              hashList * hash_table[], FILE * infle){
  char inputStr[MAX_INPUT];
  char errorStr[255];
  char * filename;
  char * err_filename;
  FILE
    * obj,
    * lst,
    * edt,
    * erf;
  FILE
    * errfle;
  unsigned int lc = 1;

  filename = malloc(strlen(fnroot) + 4);
  strcpy(filename,fnroot);
  strcat(filename, ".lst");
  if((lst = fopen(filename,"w+")) == NULL){
    fprintf(stderr,"Error opening file: %s\n",filename);
  }
  free(filename);
 
  err_filename = malloc(strlen(fnroot) + 4);
  strcpy(err_filename,fnroot);
  strcat(err_filename, ".err");
  if((errfle = fopen(err_filename,"w+")) == NULL){
    fprintf(stderr,"Error opening file: %s\n",err_filename);
  }

  while(feof(infle) == 0){
    fgets(inputStr,81,infle);
    if(strlen(inputStr) == 1){
      fprintf(lst,"%d\n",lc);
      lc++;
      continue;
    }
    if(feof(infle) == 0 ){

      if(inputStr[0] == '#'){
        fprintf(lst,"%d\t%s",lc,inputStr);
        lc++;
        continue;
      } else{
        fprintf(lst,"%d\t%s",lc,inputStr);
        parseln(inputStr,lst,errfle,lc,mot,hash_table);
        lc++;
        continue;
        }
    }
  }

/* copy errors from temp error file to lst file then remove temp */
  rewind(errfle);
  while(feof(errfle) == 0){
    fgets(errorStr,256,errfle);
    if(feof(errfle) == 0){
      fprintf(lst,"\n");
      fprintf(lst,"%s",errorStr);
    }
  }
  
  fclose(lst);
  unlink(err_filename);
  free(err_filename);
  free(filename);
}

main.c

#include <stdio.h>
#include "list.h"
#include "assem.h"

int main(int argv, char * argc[]){
  FILE * infle;
  char * fnroot;
  int fcount = 2;
  char * eor;
  char * inputStr;
  char * ftest;

  motList *mot_head = NULL;
  hashList *hash_head[22];
  hash_insert(hash_head,1,-1,"dUmMy_HSAH_00"); /* init hash table */
  isDefined(hash_head,"dUmMy_HSAH_00");
  hash_insert(hash_head,1,-1,"111111dUmMy_HSAH_00");
  if(argv < 3){
    fprintf(stderr,"Too few arguments\n");
    fprintf(stderr,"\tusage:\tp2 <flag> <input files:minimum of one>\n");
    exit(1);
  }
  

  do{
    printf("top of do\n");
    printf("infle :: %s\n",argc[fcount]);
    if((infle = fopen(argc[fcount],"r")) == NULL){
      fprintf(stderr,"Unable to open data file %s\n",argc[fcount]);
    }
    else{
      eor = strrchr(argc[fcount],'.');
      fnroot = malloc(eor-argc[fcount]+1);
      strncpy(fnroot,argc[fcount],eor-argc[fcount]);
      strcat(fnroot,"\0");
      //do work
      assemble(fnroot,mot_head,hash_head,infle);
      free(fnroot);
      fclose(infle);
    }
    fcount++;
  } while(fcount < argv);
  
  mot_free(&mot_head);
  return 0;
}

test1.asm

#Test case 1 for assembler -- no .edef or .eref.

               .text
test1: lwa $1,val1 #Puts -1 in $1.
               prh $1

val12: lwa $2,val2
               prh $2
               sll $3,$2,16
               prh $3

val123: srl $4,$1,16
               prh $4

val1234: sra $5,$1,16
               prh $5

#A label with 8 characters.
val12345: xor $6,$1,$2
               prh $6
               lwb $7,0($1)
               prh $7
               hlt

               .data
val1: .word -1:4
val2: .word 65535:1

#No more lines.



Relevant Pages