/*
       SYMP.C
       Written by Leor Zolman, 3/82

       Given a SYM file put out by ASM86, this aplphabetizes the
       symbols, eliminates all symbols starting with "L0", and writes
       the result into T.SYM.
*/

#include <bdscio.h>

char iobuf[BUFSIZ];
int strcmp();

main(argc,argv)
char **argv;
{
       char iname[30];
       int i,j,c;
       unsigned valtab[1000], newval;
       char *namtab[1000], newnam[30];
       int count;
       int ncols, colno;

       if (argc == 1) exit(puts("Usage:\nsymp <symnane> [ncols]\n"));
       ncols = 80;
       if (isdigit(argv[2][0])) ncols = atoi(argv[2]);

       strcpy(iname,argv[1]);
       strcat(iname,".SYM");

       if (fopen(iname,iobuf) == ERROR) exit(puts("Can't open input file"));

       count = 0;

       while (1) {
               while (isspace(c = getc(iobuf)))   /* skip leading space */
                       ;
               if (c == EOF || c == CPMEOF)
                       break;

               if (!ishexd(c)) {
                       printf("Bad 1st char of value: %c\n",c);
                       printf("Read %d symbols, last was: %s\n",
                                       count, namtab[count-1]);
                       exit();
               }

               newval = 0;
                               /* accumulate new hex value */
               do {
                  newval = newval * 16 + (c < ':' ? (c - '0') : (c - '7'));
                  c = getc(iobuf);
               } while (ishexd(c));

                       /* skip white space between value and symbol */
               while (isspace(c)) c = getc(iobuf);

                               /* collect up new symbol name */
               i = 0;
               do {
                       newnam[i++] = c;
               } while (!isspace(c = getc(iobuf)));
               newnam[i] = '\0';

               valtab[count] = newval;
               namtab[count] = sbrk(strlen(newnam) + 1);
               strcpy(namtab[count++],newnam);
       }

       qsort(namtab,count,2,&strcmp,valtab);   /* alphabetize */

       fclose(iobuf);
       if (fcreat("T.SYM",iobuf) == ERROR) exit(puts("Can't creat T.SYM"));

       colno = 1;
       for (i = 0; i < count; i++) {
               if (namtab[i][0] == 'L' && namtab[i][1] == '0')
                       continue;
               fprintf(iobuf, "%04x %-8s  ",valtab[i],namtab[i]);
               colno += 15;
               if (colno + 15 >= ncols) {
                       fputs("\n",iobuf);
                       colno = 1;
               }
       }
       fputs("\n",iobuf);
       putc(CPMEOF,iobuf);
       fflush(iobuf);
       fclose(iobuf);
       puts("T.SYM is ready for action...\n");
}

isspace(c)
char c;
{
       return (c == ' ' || c == '\t' || c == 0x0d || c == 0x0a);
}

qsort(base, nel, width, compar,base2)
char *base; int (*compar)();
unsigned width,nel;
{       int i, j;
       unsigned gap, ngap, t1;
       int jd, t2;

       t1 = nel * width;
       for (ngap = nel / 2; ngap > 0; ngap /= 2) {
          gap = ngap * width;
          t2 = gap + width;
          jd = base + gap;
          for (i = t2; i <= t1; i += width)
             for (j =  i - t2; j >= 0; j -= gap) {
               if ((*compar)(base+j, jd+j) <=0) break;
                        _swp(base+j, jd+j);
                        _swp(base2+j,base2+gap+j);
             }
       }
}

_swp(a,b)
int *a, *b;
{
       int temp;
       temp = *a;
       *a = *b;
       *b = temp;
}




int strcmp(s,t)
char **s, **t;
{
       char *s1, *t1;
       s1 = *s;
       t1 = *t;
       int i;
       i = 0;
       while (s1[i] == t1[i])
               if (s1[i++] == '\0')
                       return 0;
       return s1[i] - t1[i];
}

int ishexd(c)
char c;
{
       return isdigit(c) || (c >= 'A' && c <= 'F');
}