h03567
s 00525/00000/00000
d D 1.1 83/03/22 19:53:36 bog 1 0
c date and time created 83/03/22 19:53:36 by bog
e
u
4
U
t
T
I 1
#include <stdio.h>
#include <rectypes.c>
#define TRUE 1
#define FALSE 0
#define MAX_NAMES 256		/* in all LNAMES in a module */

/*

Correct LIBNAM, LIBLOC and LIBDIC records in a .L86 file.

*/

/* globals */

int curr_rec;		/* type of current record being read */
unsigned record_length;	/* record length field value in current record */
unsigned bytes_left;	/* counted down by get_ch */
int checksum;		/* checksum accumulated by get_ch */

unsigned out_block = 0;	/* isis block number of output rec (128 bytes long) */
int out_byte = 0;	/*  byte within block */
int out_sum = 0;	/* checksum accumulated by put_ch */

int m_n_len = 1;	/* module names list length */
int m_d_len = 1;	/* module dictionary names list length */

FILE *fin,*fout,*fnam,*floc,*fdic;	/* fp declarations */

int next_index;			/* index of next avail name_ptr */
char *name_ptr[MAX_NAMES];	/* name_ptr[0] is ptr to next avail name_ch */
#define next_name_ch name_ptr[0]
char name_ch[MAX_NAMES*10];	/* guess at 9 byte average name size */
char n_code[] = { '\4', 'C', 'O', 'D', 'E' };
char n_data[] = { '\4', 'D', 'A', 'T', 'A' };
char n_stack[] = { '\5', 'S', 'T', 'A', 'C', 'K' };
char n_extra[] = { '\5', 'E', 'X', 'T', 'R', 'A' };
int i_code,i_data,i_stack,i_extra;

char *makefcb();

/* end globals */

/* name table utilities */

init_names()	/* initialize name table pointers etc. for a module */
{
  next_index = 1;		/* next name index is 1 */
  next_name_ch = &name_ch[0];	/* next name table character is first */
 }

get_lnames()			/* add names from LNAMES record to table */
{
  int len;

  while (bytes_left > 1) {
    name_ptr[next_index++] = next_name_ch;
    for (len = peek_ch(); len >= 0; len--) *next_name_ch++ = get_ch();
   }
 }

int tail_match(name,tail)	/* 1 if tail of name matches tail */
char *name,*tail;
{
  int len_n,len_t;

  len_n = *name;
  len_t = *tail;
  if (len_n < len_t) return(0);	/* name not long enough */
  for (name = name+len_n-len_t; len_t > 0 ; len_t--, name++, tail++)
    if (*(name+1) != *(tail+1)) return(0);
  return(1);
 }

int name_match(name0,name1)	/* 1 if name0 matches name1 */
char *name0,*name1;
{			/* tail match and lengths equal */
  return((*name0 == *name1) & tail_match(name0,name1));
 }

int name_find(name)		/* return index in table (or 0) of name */
char *name;
{
  int i;

  for (i = 1; i < next_index; i++)
    if (name_match(name_ptr[i],name))
      return(i);
  return(0);
 }

int add_name(name)	/* add a name to the name table if not present */
char *name;
{
  int i;

  if ((i = name_find(name)) == 0) {
    name_ptr[next_index] = next_name_ch;
    for (i = *name; i >= 0; i--) *next_name_ch++ = *name++;
    i = next_index++;
   }
  return(i);
 }

show_names()			/* show the list of names in the name table */
{
  char *cp;
  int i,len;
  char c;

  for (i = 1; i < next_index; i++) {
    cp = name_ptr[i];
    len = *cp++;
    c = *(cp+len);
    *(cp+len) = '\0';
/*  printf("  %d  %s\n",i,(len) ? cp : "<null>"); */
    *(cp+len) = c;
   }
 }

/* end name table utilities */

FILE *file_open(fname,fmode,ferr)	/* open a file, with error check */
char *fname,*fmode;
int ferr;
{
  FILE *fp;
  if ((fp = fopen(fname,fmode)) == NULL) {
    fprintf(stderr,"cannot open %s\n",fname);
    exit(ferr);
   }
  return(fp);
 }

int peek_ch()		/* look at but don't get next char */
{
  int c;

  ungetc((c = fgetc(fin)),fin);
  return(c);
 }

int peek_type()		/* look at but don't get next rec type; EOF if done */
{
  int c;

  if ((c = fgetc(fin)) != EOF) {
    ungetc(c,fin);
   }
  return((c == 0x1a) ? EOF : c);
 }

int get_ch()		/* get next byte (as int) */
{
  int c;

  c = fgetc(fin);
  if (bytes_left == 0) {
    printf("*** record length error ***");
   }
  bytes_left--;
  checksum = checksum+c;
  return(c);
 }

unsigned get_index()		/* get intel format index */
{
  int c;

  return (
    ((c = get_ch()) & 0x80) ? (((c & 0x7f) << 8) | get_ch()) : (c & 0x7f)
   );
 }

unsigned get_unsigned()		/* get unsigned 16-bit integer */
{
  unsigned c;

  c = get_ch();
  return(((unsigned)get_ch() << 8) + c);
 }

int get_int()			/* get signed 16-bit integer */
{
  int c;

  c = get_ch();
  return((get_ch()<<8)+c);
 }

int get_rec(func)	/* do begin & end of record; invoke func for middle */
int (*func)();
{
  checksum = 0;
  bytes_left = 1;	/* enough for type only */
  if ((curr_rec = get_ch()) == 0x1a) curr_rec = EOF;
  if (curr_rec != EOF) {
    bytes_left = 2;	/* enough for length from file */
    record_length = bytes_left = get_unsigned();
    (*func)();
    while (bytes_left > 0) get_ch();	/* skip to end of record */
    if ((checksum & 255) != 0) {
      printf("*** checksum error ***");
     }
   }
 }

put_ch(c)			/* put a character (as int) */
int c;
{
  out_sum = out_sum+c;
  fputc((char)c,fout);
  if (++out_byte > 127) {
    out_block++;
    out_byte = 0;
   }
 }

put_index(i)			/* put an intel format index */
unsigned i;
{
  if (i > 127) {
    put_ch((i >> 8) | 0x80);
    i &= 255;
   }
  put_ch(i);
 }

put_unsigned(u)			/* put an unsigned 16-bit integer */
unsigned u;
{
  put_ch((int)(u & 255));
  put_ch((int)(u >> 8));
 }

put_int(i)			/* put a signed 16-bit integer */
int i;
{
  put_ch(i & 255);
  put_ch((i >> 8) & 255);
 }

put_rec(type,length)		/* put record type and length */
int type;
unsigned length;
{
  out_sum = 0;
  put_ch(type);
  put_unsigned(length);
 }

put_checksum()			/* put checksum at end of record */
{
  put_ch((-out_sum) & 255);
 }

mod_name()			/* copy record; module name goes to fnam */
{
  int len,c;

  put_rec(curr_rec,record_length);
  for (len = peek_ch()+1; len > 0; len--) {
    c = get_ch();
    put_ch(c);
    fputc(c,fnam);
    m_n_len++;
   }
  while (bytes_left > 1) {
    put_ch(get_ch());
   }
  put_checksum();
 }

put_libhed(modules,block_num,byte_num)	/* put a LIBHED record */
unsigned modules,block_num,byte_num;
{
  put_rec(LIBHED,7);		/* library header rec type and length */
  put_unsigned(modules);	/* number of modules in library */
  put_unsigned(block_num);	/* block number of LIBNAM record */
  put_unsigned(byte_num);	/* byte number of LIBNAM record */
  put_checksum();		/* record checksum */
 }

copy_pubdef()		/* copy a PUBDEF record, saving names in nam.$$$ */
{
  int len,c;
  unsigned u,v;

  put_rec(curr_rec,record_length);
  u = get_index();		/* group index */
  put_index(u);
  v = get_index();		/* segment index */
  put_index(v);
  if ((u | v) == 0) put_unsigned(get_unsigned());	/* opt frame number */
  while (bytes_left > 1) {
    for (len = peek_ch()+1; len > 0; len--) {	/* public name */
      c = get_ch();
      put_ch(c);
      fputc(c,fdic);
      m_d_len++;
     }
    put_unsigned(get_unsigned());	/* public offset */
    put_index(get_index());	/* type index */
   }
  put_checksum();
 }

copy_segdef()			/* copy SEGDEF record, maybe changing class */
{
  int a,c,b,p;
  int seg_n_i,class_n_i;
  char *name_c_p,*name_s_p;

  put_rec(SEGDEF,record_length);

  p = get_ch();
  put_ch(p);
  a = p >> 5 & 7;		/* alignment attribute */
  c = p >> 2 & 7;		/* combine attribute */
  b = p >> 1 & 1;		/* big (seg length == 65536) attribute */
  p &= 1;			/* page-resident attribute */

  switch (a) {			/* on alignment attribute */
    case 0:			/* absolute LSEG */
    case 5:			/* unnamed absolute portion of MAS */
      put_unsigned(get_unsigned());	/* frame number */
      put_ch(get_ch());			/* offset */
      break;
    case 6:			/* LTL, paragraph-aligned LSEG */
      put_ch(get_ch());			/* LTL DAT byte */
      put_unsigned(get_unsigned());	/* maximum segment length */
      put_unsigned(get_unsigned());	/* group offset */
      break;
   }

  put_unsigned(get_unsigned());	/* segment length */

  if (a !=  5) {		/* unless unnamed */
    put_index(seg_n_i = get_index());	/* get segment name index */
    class_n_i = get_index();		/* get class name index */
    name_c_p = name_ptr[class_n_i];
    if ((~name_match(name_c_p,n_code)) && (~name_match(name_c_p,n_data)) &&
        (~name_match(name_c_p,n_stack)) && (~name_match(name_c_p,n_extra))) {
      name_s_p = name_ptr[seg_n_i];
      if (tail_match(name_s_p,n_code))
	class_n_i = i_code;
       else
	if (tail_match(name_s_p,n_data))
	  class_n_i = i_data;
	 else
	  if (tail_match(name_s_p,n_stack))
	    class_n_i = i_stack;
	   else
	    class_n_i = i_extra;
     }
    put_index(class_n_i);
    put_index(get_index());		/* overlay name index */
   }
  put_checksum();
 }

nop_rec()
{
  /* throw away input record */
 }

copy_rec()			/* copy input record to output */
{
  put_rec(curr_rec,record_length);
  while (bytes_left > 1) {
    put_ch(get_ch());
   }
  put_checksum();
 }

main(argc,argv)
int argc;
char *argv[];
{
  int c;
  char *cp;
  int module_count = 0;

  unsigned lib_block;
  int lib_byte;

  int is_lib = FALSE;

  int begin_mod = TRUE;

  char fname[32],ftname[32];

  fname[0] = ftname[0] = NULL;

  if (argc < 2) {
    printf(" 'floc <filespec>' assumes .L86; fixes library pointers");
    exit(0);
   }
  strcat(fname,*++argv);	/* copy file name asked for */
  for (c=0; fname[c] != '.' && fname[c] != NULL; c++)
    ftname[c] = fname[c];
  ftname[c] = NULL;
  strcat(ftname,".$$$");
  if (fname[c] == NULL) {	/* no extension; assume .OBJ */
    strcat(fname,".L86");
   }

  fin = file_open(fname,"rb",1);
  fout = file_open(ftname,"wb",2);
  fnam = file_open("nam.$$$","wb",3);
  floc = file_open("loc.$$$","wb",4);
  fdic = file_open("dic.$$$","wb",5);

/* pass 1 */
  if (peek_type() == LIBHED) {
    get_rec(nop_rec);	/* throw away library header */
    is_lib = TRUE;
   }
  put_libhed(0,0,0);	/* put dummy library header */
  while ((c = peek_type()) != EOF) {
    switch (c) {
      case RHEADR:
      case THEADR:
      case LHEADR:
	if (begin_mod) {
	  init_names();		/* initialize name table for this module */
	  putw(out_block,floc);	/* block & byte of module header for LIBLOC */
	  putw(out_byte,floc);
	  get_rec(mod_name);	/* module name for LIBNAM */
	  begin_mod = FALSE;
	 } else {
	  get_rec(copy_rec);
	 }
	break;
      case MODEND:
	get_rec(copy_rec);
	fputc(NULL,fdic);	/* module end for LIBDIC */
	m_d_len++;
	module_count++;
	begin_mod = TRUE;
	break;
      case PUBDEF:
	get_rec(copy_pubdef);
	break;
/*
      case LNAMES:
	do {
	  get_rec(get_lnames);
	 } while (peek_type() == LNAMES);
	i_code = add_name(n_code);
	i_data = add_name(n_data);
	i_stack = add_name(n_stack);
	i_extra = add_name(n_extra);
	put_rec(LNAMES,next_name_ch-&name_ch[0]+1);
	for (cp = &name_ch[0]; cp < next_name_ch; cp++) put_ch(*cp);
	put_checksum();
	show_names();
	break;
      case SEGDEF:
	get_rec(copy_segdef);
	break;
*/
      case LIBNAM:
      case LIBLOC:
      case LIBDIC:
	get_rec(nop_rec);
	break;
      default:
	get_rec(copy_rec);
	break;
     }
   }
  fclose(fin);
  fclose(fout);
  fclose(fnam);
  fclose(floc);
  fclose(fdic);

  lib_block = out_block;
  lib_byte = out_byte;

  fin = file_open(ftname,"rb",6);
  fout = file_open(fname,"wb",7);
  fnam = file_open("nam.$$$","rb",8);
  floc = file_open("loc.$$$","rb",9);
  fdic = file_open("dic.$$$","rb",10);

/* pass 2 */
  while ((c = peek_type()) != EOF) {
    switch (c) {
      case LIBHED:
	if ((is_lib) || (module_count > 1)) {
	  put_libhed(module_count,lib_block,lib_byte)	;/* new LIBHED */
	 }
	get_rec(nop_rec);	/* trash dummy LIBHED */
	break;
      default:
	get_rec(copy_rec);
	break;
     }
   }
  if ((is_lib) || (module_count > 1)) {
    put_rec(LIBNAM,m_n_len);
    for (; m_n_len > 1; m_n_len--) put_ch(fgetc(fnam));
    put_checksum();

    put_rec(LIBLOC,c = module_count*4+1);
    for (; c > 1; c--) put_ch(fgetc(floc));
    put_checksum();

    put_rec(LIBDIC,m_d_len);
    for (; m_d_len > 1; m_d_len--) put_ch(fgetc(fdic));
    put_checksum();
   }

  fclose(fin);
  fclose(fout);
  fclose(fnam);
  fclose(floc);
  fclose(fdic);

  bdos(19,makefcb(ftname));	/* delete <file>.$$$ */
  bdos(19,makefcb("nam.$$$"));	/* delete nam.$$$ */
  bdos(19,makefcb("loc.$$$"));	/* delete loc.$$$ */
  bdos(19,makefcb("dic.$$$"));	/* delete dic.$$$ */
 }
E 1
