#include #include #include #include void *root=NULL; typedef struct { char symbol[8]; char u; char e[3]; char u13; char base[8]; char plus; char displacement[8]; char u31; char t; char p; char d[3]; char u37; char source[4]; char u42; char a; char r; char description[28]; int reladdr; #define REL_MASK 0x0003ffff short nda; short resp_cnt; char reserved1[3]; char status; #define ACTIVE 0x80 #define COLLISION 0x08 int reserved2; } DATAPOOL; int format=0; #define SAVE 1 #define LOG 2 char dp_file[128]="MAIN"; FILE * dp_file_p; void *xmalloc(unsigned n) { void *p; p = malloc(n); if(p) return p; fprintf(stderr, "insufficient memory\n"); exit(1); memset((char *) p, '\0',n); } int compare(const void *pa, const void *pb) { DATAPOOL *node1 = (DATAPOOL *) pa; DATAPOOL *node2 = (DATAPOOL *) pb; // fprintf(stderr, "compare: %8.8s|%8.8s\n",node1->symbol, node2->symbol); return (memcmp(node1->symbol, node2->symbol,sizeof(node1->symbol))); } void action(const void *nodep, const VISIT which, const int depth) { DATAPOOL *datap; void *val; int bytes_written; switch(which) { case preorder: break; case postorder: datap = *(DATAPOOL **)nodep; if (format==LOG) printf(" LOG %72.72s %6X %7d %2d\n", (char *)&datap->symbol, datap->reladdr, datap->resp_cnt, 0); else if (format==SAVE) { if (96!= (bytes_written=fwrite((char *)datap, 1, 96, dp_file_p))) perror("SAVE"); } break; case endorder: datap = *(DATAPOOL **)nodep; // (void)tdelete(datap, &root, compare); // free(datap); break; case leaf: datap = *(DATAPOOL **)nodep; if (format==LOG) printf(" LOG %72.72s %6X %7d %2d\n", (char *)&datap->symbol, datap->reladdr, datap->resp_cnt, 0); else if (format==SAVE) { if (96!= (bytes_written=fwrite((char *)datap, 1, 96, dp_file_p))) perror("SAVE"); } // val = tdelete(datap, &root, compare); // free(datap); break; } return; } int main() { int i; int bytes_read=0; int records_read=0; int rel_addr=-1; int disp=-1; int base_addr=-1; int dim=-1; void *val; DATAPOOL dp_record, *ptr; DATAPOOL base_record, *base_ptr; DATAPOOL old_record, *old_ptr, *del_ptr; char read_buffer[128]; for (records_read=0;;records_read++) { // bytes_read=read(0, &read_buffer, 81); // if (0==bytes_read) break; if (NULL==fgets(read_buffer, 82, stdin)) break; bytes_read=strlen(read_buffer); for (i=bytes_read-1;i<81;i++) read_buffer[i]=' '; read_buffer[80]='\0'; // if ((73 > bytes_read)||(81 < bytes_read)) { // perror("DPEDIT: read"); // break; // } if (read_buffer[0]=='/') { //process DPEDIT directives if (0==strncmp(&read_buffer[1],"DPD",3)) { for (i=4;i<72 && read_buffer[i]==' ';i++); strncpy(dp_file, (char *)&read_buffer[i], 17); if (NULL==(dp_file_p=fopen(dp_file, "rb"))) { perror("DPD open failed"); exit(1); } else { // read in existing datapool file do { ptr = (DATAPOOL *)xmalloc(sizeof(dp_record)); bytes_read=fread(&read_buffer, 1, 96, dp_file_p); memcpy((char *)ptr, &read_buffer, 96); val = tsearch((void *)ptr, &root, compare); if(val == NULL) { fprintf(stderr, "DPEDIT: out of space to insert symbol %8.8s\n", read_buffer); exit(1); } } while (96==bytes_read); fclose(dp_file_p); } } else if (0==strncmp(&read_buffer[1],"ENTER",5)) { } else if (0==strncmp(&read_buffer[1],"LOG",3)) { for (i=4;i<72 && read_buffer[i]==' ';i++) { if (0==strncmp(&read_buffer[i],"REL",3)) { } else if (0==strncmp(&read_buffer[i],"ALPHA",5)) { printf("DPD: %s\n",dp_file); printf(" ERROR FUNCTION SYMBOL U E BASE DISP TP D SC AR DESCRIPTION RELATIVE RESP CM\n"); printf(" CODE SYMBOL ADDRESS CNT \n"); format=LOG; twalk(root, action); } else { } } } else if (0==strncmp(&read_buffer[1],"REMAP",5)) { fprintf(stderr,"REMAP not implemented\n"); } else if (0==strncmp(&read_buffer[1],"SAVE",4)) { if (NULL==(dp_file_p=fopen(dp_file, "wb"))) { perror("SAVE open failed"); exit(1); } else { // write out internal tree to existing datapool file format=SAVE; twalk(root, action); fclose(dp_file_p); } } else if (0==strncmp(&read_buffer[1],"VERIFY",6)) { fprintf(stderr,"VERIFY not implemented\n"); } else { fprintf(stderr,"Unknown DPEDIT directive %s16.16\n",read_buffer); } } else { //process DATAPOOL statements ptr = (DATAPOOL *)xmalloc(sizeof(dp_record)); memcpy((char *)ptr, &read_buffer, 72); // If Change then merge fields as indicated if (ptr->u == '*') { memcpy(&old_record, (char*)ptr->base,8); old_ptr = *(DATAPOOL**) tfind((void *)&old_record, &root, compare); if(old_ptr == NULL) { fprintf(stderr, "DPEDIT: old symbol not found"); exit(1); } // Update base field for (i=0;i<8;i++) { if (ptr->base[i]==' ') ptr->base[i] = old_ptr->base[i]; else if (ptr->base[i]=='#') { if (old_ptr->resp_cnt ) { fprintf(stderr,"Can\'t change base\n"); } else ptr->base[i] = ' '; } else if (old_ptr->resp_cnt ) { fprintf(stderr,"Can\'t change base\n"); } } // Update displacement field if (old_ptr->resp_cnt && ptr->plus=='+') fprintf(stderr,"Can\'t change displacement\n"); else { for (i=0;i<8;i++) { if (ptr->displacement[i]==' ') ptr->displacement[i] = old_ptr->displacement[i]; else if (ptr->displacement[i]=='#') ptr->displacement[i] = ' '; } } // Update all other fields if (ptr->t==' ') ptr->t = old_ptr->t; else if (ptr->t=='#') ptr->t = ' '; if (ptr->p==' ') ptr->p = old_ptr->p; else if (ptr->p=='#') ptr->p = ' '; for (i=0;i<3;i++) { if (ptr->d[i]==' ') ptr->d[i] = old_ptr->d[i]; else if (ptr->d[i]=='#') ptr->d[i] = ' '; } for (i=0;i<4;i++) { if (ptr->source[i]==' ') ptr->source[i] = old_ptr->source[i]; else if (ptr->source[i]=='#') ptr->source[i] = ' '; } if (ptr->a==' ') ptr->a = old_ptr->a; else if (ptr->a=='#') ptr->a = ' '; if (ptr->r==' ') ptr->r = old_ptr->r; else if (ptr->r=='#') ptr->r = ' '; for (i=0;i<28;i++) { if (ptr->description[i]==' ') ptr->description[i] = old_ptr->description[i]; else if (ptr->description[i]=='#') ptr->description[i] = ' '; } } // If Delete or Change then delete old record if ((ptr->u == '-') || (ptr->u == '*')) { memcpy(&base_record, (char*)ptr->base,8); base_ptr = *(DATAPOOL**) tfind((void *)&base_record, &root, compare); if(base_ptr != NULL) { fprintf(stderr, "DPEDIT: cannot delete base symbol"); exit(1); } else { del_ptr = tdelete((void *)ptr, &root, compare); if(del_ptr == NULL) { fprintf(stderr, "DPEDIT: symbol not found"); exit(1); } } if (ptr->u == '-') free(ptr); } // If Add or Change then insert new record if ((ptr->u == ' ') || (ptr->u == '*')) { if (ptr->base[0] == '$') { rel_addr=0; } else { memcpy(&base_record, (char*)ptr->base,8); base_ptr = *(DATAPOOL**) tfind((void *)&base_record, &root, compare); if(base_ptr == NULL) { fprintf(stderr, "DPEDIT: base symbol not found"); exit(1); } else { base_ptr->resp_cnt++; base_addr = base_ptr->reladdr; if ((ptr->plus==' ') && (ptr->displacement[0]==' ')) disp=0; else if ((ptr->displacement[0] == 'X') && (ptr->displacement[1] == '\'')) sscanf(&(ptr->displacement[2]), "%x", &disp); else { sscanf(&(ptr->displacement[0]), "%d", &disp); for (i=0;i<8 && isdigit(ptr->displacement[i]);i++); if (i<8 && ptr->displacement[i]=='B') disp*=1; else if (i<8 && ptr->displacement[i]=='H') disp*=2; else if (i<8 && ptr->displacement[i]=='W') disp*=4; else if (i<8 && ptr->displacement[i]=='D') disp*=8; } rel_addr=base_addr+disp; } } ptr->reladdr= rel_addr; val = tsearch((void *)ptr, &root, compare); if(val == NULL) { fprintf(stderr, "DPEDIT: out of space to insert symbol %8.8s\n", ptr->symbol); exit(1); } } } } printf(" 1 2 3 4 5 6 7 8 9 0 1 2\n"); printf("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\n"); printf("DPD: %s\n",dp_file); printf(" ERROR FUNCTION SYMBOL U E BASE DISP TP D SC AR DESCRIPTION RELATIVE RESP CM\n"); printf(" CODE SYMBOL ADDRESS CNT \n"); format=LOG; twalk(root, action); return 0; }