gbdk-releases/sdcc/as/mcs51/lklist.c
2015-01-10 16:25:09 +01:00

1097 lines
21 KiB
C

/* lklist.c */
/*
* (C) Copyright 1989-1995
* All Rights Reserved
*
* Alan R. Baldwin
* 721 Berkeley St.
* Kent, Ohio 44240
*
* 28-Oct-97 JLH:
* - lstarea: show s_id as string rather than array [NCPS]
* - lstarea: show a_id as string rather than array [NCPS]
* 31-Oct-97 JLH: add NoICE output file genration in lstarea
* 02-Apr-98 JLH: add XDATA, DATA, BIT flags to area output
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "aslink.h"
/*)Module lklist.c
*
* The module lklist.c contains the functions which
* output the linker .map file and produce a relocated
* listing .rst file.
*
* lklist.c contains the following functions:
* int dgt()
* VOID lstarea()
* VOID lkulist()
* VOID lkalist()
* VOID lkglist()
* VOID newpag()
* VOID slew()
*
* lklist.c contains no local variables.
*/
/*)Function VOID slew(fp)
*
* FILE * fp output file handle
*
* The function slew() increments the page line counter.
* If the number of lines exceeds the maximum number of
* lines per page then a page skip and a page header are
* output.
*
* local variables:
* int i loop counter
*
* global variables:
* int lop current line number on page
* int xflag Map file radix type flag
*
* functions called:
* int fprintf() c_library
* VOID newpag() lklist.c
*
* side effects:
* The page line and the page count may be updated.
*/
VOID
slew(fp)
FILE *fp;
{
register int i;
if (lop++ >= NLPP) {
newpag(fp);
if (xflag == 0) {
fprintf(fp, "Hexadecimal\n\n");
} else
if (xflag == 1) {
fprintf(fp, "Octal\n\n");
} else
if (xflag == 2) {
fprintf(fp, "Decimal\n\n");
}
fprintf(fp, "Area Addr Size");
fprintf(fp, " Decimal Bytes (Attributes)\n");
for(i=0;i<4;++i)
fprintf(fp, " Value--Global");
fprintf(fp, "\n\n");
lop += 6;
}
}
/*)Function VOID newpag()
*
* The function newpag() outputs a page skip, writes the
* first page header line, sets the line count to 1, and
* increments the page counter.
*
* local variables:
* none
*
* global variables:
* int lop current line number on page
* int page current page number
*
* functions called:
* int fprintf() c_library
*
* side effects:
* The page and line counters are updated.
*/
VOID
newpag(fp)
FILE *fp;
{
fprintf(fp, "\fASxxxx Linker %s, page %u.\n", VERSION, ++page);
lop = 1;
}
/* Used for qsort call in lstsym */
static int _cmpSymByAddr(const void *p1, const void *p2)
{
struct sym **s1 = (struct sym **)(p1);
struct sym **s2 = (struct sym **)(p2);
int delta = ((*s1)->s_addr + (*s1)->s_axp->a_addr) -
((*s2)->s_addr + (*s2)->s_axp->a_addr);
/* Sort first by address, then by name. */
if (delta)
{
return delta;
}
return strcmp((*s1)->s_id,(*s2)->s_id);
}
#if NCPS-8
/* NCPS != 8 */
/*)Function VOID lstarea(xp)
*
* area * xp pointer to an area structure
*
* The function lstarea() creates the linker map output for
* the area specified by pointer xp. The generated output
* area header includes the area name, starting address,
* size of area, number of words (in decimal), and the
* area attributes. The symbols defined in this area are
* sorted by ascending address and output one per line
* in the selected radix.
*
* local variables:
* areax * oxp pointer to an area extension structure
* int c character value
* int i loop counter
* int j bubble sort update status
* char * ptr pointer to an id string
* int nmsym number of symbols in area
* Addr_T a0 temporary
* Addr_T ai temporary
* Addr_T aj temporary
* sym * sp pointer to a symbol structure
* sym ** p pointer to an array of
* pointers to symbol structures
*
* global variables:
* FILE *mfp Map output file handle
* sym *symhash[NHASH] array of pointers to NHASH
* linked symbol lists
* int xflag Map file radix type flag
*
* functions called:
* int fprintf() c_library
* VOID free() c_library
* char * malloc() c_library
* char putc() c_library
* VOID slew() lklist.c
*
* side effects:
* Map output generated.
*/
VOID
lstarea(xp)
struct area *xp;
{
register struct areax *oxp;
register int i;
/* int j; */
register char *ptr;
int nmsym;
/* Addr_T a0; */
Addr_T ai, aj;
struct sym *sp;
struct sym **p;
int memPage;
putc('\n', mfp);
if (xflag == 0) {
fprintf(mfp, "Hexadecimal\n\n");
} else
if (xflag == 1) {
fprintf(mfp, "Octal\n\n");
} else
if (xflag == 2) {
fprintf(mfp, "Decimal\n\n");
}
fprintf(mfp, "Area ");
fprintf(mfp, "Addr Size Decimal Bytes (Attributes)\n");
fprintf(mfp, "-------------------------------- ");
fprintf(mfp, "---- ---- ------- ----- ------------\n");
/*
* Output Area Header
*/
ptr = &xp->a_id[0];
fprintf(mfp, "%-32s", ptr ); /* JLH: width matches --- above */
ai = xp->a_addr;
aj = xp->a_size;
if (xflag == 0) {
fprintf(mfp, " %04X %04X", ai, aj);
} else
if (xflag == 1) {
fprintf(mfp, " %06o %06o", ai, aj);
} else
if (xflag == 2) {
fprintf(mfp, " %05u %05u", ai, aj);
}
fprintf(mfp, " = %6u. bytes ", aj);
if (xp->a_flag & A_ABS) {
fprintf(mfp, "(ABS");
} else {
fprintf(mfp, "(REL");
}
if (xp->a_flag & A_OVR) {
fprintf(mfp, ",OVR");
} else {
fprintf(mfp, ",CON");
}
if (xp->a_flag & A_PAG) {
fprintf(mfp, ",PAG");
}
memPage = 0x00;
if (xp->a_flag & A_CODE) {
fprintf(mfp, ",CODE");
memPage = 0x0C;
}
if (xp->a_flag & A_XDATA) {
fprintf(mfp, ",XDATA");
memPage = 0x0D;
}
if (xp->a_flag & A_BIT) {
fprintf(mfp, ",BIT");
memPage = 0x0B;
}
fprintf(mfp, ")");
if (xp->a_flag & A_PAG) {
ai = (ai & 0xFF);
aj = (aj > 256);
if (ai || aj) { fprintf(mfp, " "); }
if (ai) { fprintf(mfp, " Boundary"); }
if (ai & aj) { fprintf(mfp, " /"); }
if (aj) { fprintf(mfp, " Length"); }
if (ai || aj) { fprintf(mfp, " Error"); }
}
/*
* Find number of symbols in area
*/
nmsym = 0;
oxp = xp->a_axp;
while (oxp) {
for (i=0; i<NHASH; i++) {
sp = symhash[i];
while (sp != NULL) {
if (oxp == sp->s_axp)
++nmsym;
sp = sp->s_sp;
}
}
oxp = oxp->a_axp;
}
if (nmsym == 0) {
putc('\n', mfp);
return;
}
/*
* Allocate space for an array of pointers to symbols
* and load array.
*/
if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *)))
== NULL) {
fprintf(mfp, "\nInsufficient space to build Map Segment.\n");
return;
}
nmsym = 0;
oxp = xp->a_axp;
while (oxp) {
for (i=0; i<NHASH; i++) {
sp = symhash[i];
while (sp != NULL) {
if (oxp == sp->s_axp) {
p[nmsym++] = sp;
}
sp = sp->s_sp;
}
}
oxp = oxp->a_axp;
}
#if 0
/*
* Bubble Sort of Addresses in Symbol Table Array
*/
j = 1;
while (j) {
j = 0;
sp = p[0];
a0 = sp->s_addr + sp->s_axp->a_addr;
for (i=1; i<nmsym; ++i) {
sp = p[i];
ai = sp->s_addr + sp->s_axp->a_addr;
if (a0 > ai) {
j = 1;
p[i] = p[i-1];
p[i-1] = sp;
}
a0 = ai;
}
}
#else
qsort(p, nmsym, sizeof(struct sym *), _cmpSymByAddr);
#endif
/*
* Symbol Table Output
*/
i = 0;
fprintf(mfp, "\n\n");
fprintf(mfp, " Value Global\n");
fprintf(mfp, " -------- --------------------------------");
while (i < nmsym) {
fprintf(mfp, "\n");
if (memPage != 0)
fprintf(mfp, " %02X:", memPage);
else
fprintf(mfp, " ");
sp = p[i];
aj = sp->s_addr + sp->s_axp->a_addr;
if (xflag == 0) {
fprintf(mfp, "%04X ", aj);
} else
if (xflag == 1) {
fprintf(mfp, "%06o ", aj);
} else
if (xflag == 2) {
fprintf(mfp, "%05u ", aj);
}
ptr = &sp->s_id[0];
fprintf(mfp, "%s", ptr );
/* if cdb flag set the output cdb Information
and the symbol has a '$' sign in it then */
if (dflag &&
strchr(ptr,'$'))
fprintf(dfp,"L:%s:%X\n",ptr,aj);
/* NoICE output of symbol */
if (jflag) DefineNoICE( ptr, aj, memPage );
i++;
}
putc('\n', mfp);
free(p);
}
#else
/* NCPS == 8 */
/*)Function VOID lstarea(xp)
*
* area * xp pointer to an area structure
*
* The function lstarea() creates the linker map output for
* the area specified by pointer xp. The generated output
* area header includes the area name, starting address,
* size of area, number of words (in decimal), and the
* area attributes. The symbols defined in this area are
* sorted by ascending address and output four per line
* in the selected radix.
*
* local variables:
* areax * oxp pointer to an area extension structure
* int c character value
* int i loop counter
* int j bubble sort update status
* char * ptr pointer to an id string
* int nmsym number of symbols in area
* Addr_T a0 temporary
* Addr_T ai temporary
* Addr_T aj temporary
* sym * sp pointer to a symbol structure
* sym ** p pointer to an array of
* pointers to symbol structures
*
* global variables:
* FILE *mfp Map output file handle
* sym *symhash[NHASH] array of pointers to NHASH
* linked symbol lists
* int xflag Map file radix type flag
*
* functions called:
* int fprintf() c_library
* VOID free() c_library
* char * malloc() c_library
* char putc() c_library
* VOID slew() lklist.c
*
* side effects:
* Map output generated.
*/
VOID
lstarea(xp)
struct area *xp;
{
register struct areax *oxp;
register c, i, j;
register char *ptr;
int nmsym;
Addr_T a0, ai, aj;
struct sym *sp;
struct sym **p;
int page;
putc('\n', mfp);
slew(mfp);
/*
* Output Area Header
*/
ptr = &xp->a_id[0];
while (ptr < &xp->a_id[NCPS]) {
if ((c = *ptr++) != 0) {
putc(c, mfp);
} else {
putc(' ', mfp);
}
}
ai = xp->a_addr;
aj = xp->a_size;
if (xflag == 0) {
fprintf(mfp, " %04X %04X", ai, aj);
} else
if (xflag == 1) {
fprintf(mfp, " %06o %06o", ai, aj);
} else
if (xflag == 2) {
fprintf(mfp, " %05u %05u", ai, aj);
}
fprintf(mfp, " = %6u. bytes ", aj);
if (xp->a_flag & A_ABS) {
fprintf(mfp, "(ABS");
} else {
fprintf(mfp, "(REL");
}
if (xp->a_flag & A_OVR) {
fprintf(mfp, ",OVR");
} else {
fprintf(mfp, ",CON");
}
if (xp->a_flag & A_PAG) {
fprintf(mfp, ",PAG");
}
page = 0x00;
if (xp->a_flag & A_CODE) {
fprintf(mfp, ",CODE");
memPage = 0x0C;
}
if (xp->a_flag & A_XDATA) {
fprintf(mfp, ",XDATA");
memPage = 0x0D;
}
if (xp->a_flag & A_BIT) {
fprintf(mfp, ",BIT");
memPage = 0x0B;
}
fprintf(mfp, ")");
if (xp->a_flag & A_PAG) {
ai = (ai & 0xFF);
aj = (aj > 256);
if (ai || aj) { fprintf(mfp, " "); }
if (ai) { fprintf(mfp, " Boundary"); }
if (ai & aj) { fprintf(mfp, " /"); }
if (aj) { fprintf(mfp, " Length"); }
if (ai || aj) { fprintf(mfp, " Error"); }
}
/*
* Find number of symbols in area
*/
nmsym = 0;
oxp = xp->a_axp;
while (oxp) {
for (i=0; i<NHASH; i++) {
sp = symhash[i];
while (sp != NULL) {
if (oxp == sp->s_axp)
++nmsym;
sp = sp->s_sp;
}
}
oxp = oxp->a_axp;
}
if (nmsym == 0) {
putc('\n', mfp);
slew(mfp);
return;
}
/*
* Allocate space for an array of pointers to symbols
* and load array.
*/
if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *)))
== NULL) {
fprintf(mfp, "\nInsufficient space to build Map Segment.\n");
slew(mfp);
return;
}
nmsym = 0;
oxp = xp->a_axp;
while (oxp) {
for (i=0; i<NHASH; i++) {
sp = symhash[i];
while (sp != NULL) {
if (oxp == sp->s_axp) {
p[nmsym++] = sp;
}
sp = sp->s_sp;
}
}
oxp = oxp->a_axp;
}
#if 0
/*
* Bubble Sort of Addresses in Symbol Table Array
*/
j = 1;
while (j) {
j = 0;
sp = p[0];
a0 = sp->s_addr + sp->s_axp->a_addr;
for (i=1; i<nmsym; ++i) {
sp = p[i];
ai = sp->s_addr + sp->s_axp->a_addr;
if (a0 > ai) {
j = 1;
p[i] = p[i-1];
p[i-1] = sp;
}
a0 = ai;
}
}
#else
qsort(p, nmsym, sizeof(struct sym *), _cmpSymByAddr);
#endif
/*
* Symbol Table Output
*/
i = 0;
while (i < nmsym) {
fprintf(mfp, "\n");
slew(mfp);
fprintf(mfp, " ");
sp = p[i];
aj = sp->s_addr + sp->s_axp->a_addr;
if (xflag == 0) {
fprintf(mfp, " %04X ", aj);
} else
if (xflag == 1) {
fprintf(mfp, "%06o ", aj);
} else
if (xflag == 2) {
fprintf(mfp, " %05u ", aj);
}
ptr = &sp->s_id[0];
fprintf(mfp, "%s", ptr );
/* NoICE output of symbol */
if (jflag) DefineNoICE( ptr, aj, memPage );
}
putc('\n', mfp);
free(p);
slew(mfp);
}
#endif
/*)Function VOID lkulist(i)
*
* int i i # 0 process LST to RST file
* i = 0 copy remainder of LST file
* to RST file and close files
*
* The function lkulist() creates a relocated listing (.rst)
* output file from the ASxxxx assembler listing (.lst)
* files. The .lst file's program address and code bytes
* are changed to reflect the changes made by ASlink as
* the .rel files are combined into a single relocated
* output file.
*
* local variables:
* Addr_T pc current program counter address
*
* global variables:
* int hilo byte order
* int gline get a line from the LST file
* to translate for the RST file
* char rb[] read listing file text line
* FILE *rfp The file handle to the current
* output RST file
* int rtcnt count of data words
* int rtflg[] output the data flag
* Addr_T rtval[] relocated data
* FILE *tfp The file handle to the current
* LST file being scanned
*
* functions called:
* int fclose() c_library
* int fgets() c_library
* int fprintf() c_library
* VOID lkalist() lklist.c
* VOID lkglist() lklist.c
*
* side effects:
* A .rst file is created for each available .lst
* file associated with a .rel file.
*/
VOID
lkulist(i)
int i;
{
Addr_T pc;
/*
* Exit if listing file is not open
*/
if (tfp == NULL)
return;
/*
* Normal processing of LST to RST
*/
if (i) {
/*
* Evaluate current code address
*/
if (hilo == 0) {
pc = ((rtval[1] & 0xFF) << 8) + (rtval[0] & 0xFF);
} else {
pc = ((rtval[0] & 0xFF) << 8) + (rtval[1] & 0xFF);
}
/*
* Line with only address
*/
if (rtcnt == 2) {
lkalist(pc);
/*
* Line with address and code
*/
} else {
for (i=2; i < rtcnt; i++) {
if (rtflg[i]) {
lkglist(pc++, rtval[i] & 0xFF);
}
}
}
/*
* Copy remainder of LST to RST
*/
} else {
if (gline == 0)
fprintf(rfp, "%s", rb);
while (fgets(rb, sizeof(rb), tfp) != 0) {
fprintf(rfp, "%s", rb);
}
fclose(tfp);
tfp = NULL;
fclose(rfp);
rfp = NULL;
}
}
/*)Function VOID lkalist(pc)
*
* int pc current program counter value
*
* The function lkalist() performs the following functions:
*
* (1) if the value of gline = 0 then the current listing
* file line is copied to the relocated listing file output.
*
* (2) the listing file is read line by line and copied to
* the relocated listing file until a valid source
* line number and a program counter value of the correct
* radix is found. The new relocated pc value is substituted
* and the line is written to the RST file.
*
* local variables:
* int i loop counter
* char str[] temporary string
*
* global variables:
* int gcntr data byte counter
* int gline get a line from the LST file
* to translate for the RST file
* char rb[] read listing file text line
* char *rp pointer to listing file text line
* FILE *rfp The file handle to the current
* output RST file
* FILE *tfp The file handle to the current
* LST file being scanned
*
* functions called:
* int dgt() lklist.c
* int fclose() c_library
* int fgets() c_library
* int fprintf() c_library
* int sprintf() c_library
* char * strncpy() c_library
*
* side effects:
* Lines of the LST file are copied to the RST file,
* the last line copied has the code address
* updated to reflect the program relocation.
*/
VOID
lkalist(pc)
Addr_T pc;
{
char str[8];
int i;
/*
* Exit if listing file is not open
*/
loop: if (tfp == NULL)
return;
/*
* Copy current LST to RST
*/
if (gline == 0) {
fprintf(rfp, "%s", rb);
gline = 1;
}
/*
* Clear text line buffer
*/
for (i=0,rp=rb; i<sizeof(rb); i++) {
*rp++ = 0;
}
/*
* Get next LST text line
*/
if (fgets(rb, sizeof(rb), tfp) == NULL) {
fclose(tfp);
tfp = NULL;
fclose(rfp);
rfp = NULL;
return;
}
/*
* Must have an ASxxxx Listing line number
*/
if (!dgt(RAD10, &rb[30], 1)) {
fprintf(rfp, "%s", rb);
goto loop;
}
/*
* Must have an address in the expected radix
*/
if (radix == 16) {
if (!dgt(RAD16, &rb[3], 4)) {
fprintf(rfp, "%s", rb);
goto loop;
}
sprintf(str, "%04X", pc);
strncpy(&rb[3], str, 4);
} else
if (radix == 10) {
if (!dgt(RAD10, &rb[3], 5)) {
fprintf(rfp, "%s", rb);
goto loop;
}
sprintf(str, "%05d", pc);
strncpy(&rb[3], str, 5);
} else
if (radix == 8) {
if (!dgt(RAD8, &rb[3], 6)) {
fprintf(rfp, "%s", rb);
goto loop;
}
sprintf(str, "%06o", pc);
strncpy(&rb[3], str, 6);
}
/*
* Copy updated LST text line to RST
*/
fprintf(rfp, "%s", rb);
gcntr = 0;
}
/*)Function VOID lkglist(pc,v)
*
* int pc current program counter value
* int v value of byte at this address
*
* The function lkglist() performs the following functions:
*
* (1) if the value of gline = 1 then the listing file
* is read line by line and copied to the
* relocated listing file until a valid source
* line number and a program counter value of the correct
* radix is found.
*
* (2) The new relocated values and code address are
* substituted and the line may be written to the RST file.
*
* local variables:
* int i loop counter
* char str[] temporary string
*
* global variables:
* int gcntr data byte counter
* set to -1 for a continuation line
* int gline get a line from the LST file
* to translate for the RST file
* char rb[] read listing file text line
* char *rp pointer to listing file text line
* FILE *rfp The file handle to the current
* output RST file
* FILE *tfp The file handle to the current
* LST file being scanned
*
* functions called:
* int dgt() lklist.c
* int fclose() c_library
* int fgets() c_library
* int fprintf() c_library
* int sprintf() c_library
* char * strncpy() c_library
*
* side effects:
* Lines of the LST file are copied to the RST file
* with updated data values and code addresses.
*/
VOID
lkglist(pc,v)
Addr_T pc;
int v;
{
char str[8];
int i;
/*
* Exit if listing file is not open
*/
loop: if (tfp == NULL)
return;
/*
* Get next LST text line
*/
if (gline) {
/*
* Clear text line buffer
*/
for (i=0,rp=rb; i<sizeof(rb); i++) {
*rp++ = 0;
}
/*
* Get next LST text line
*/
if (fgets(rb, sizeof(rb), tfp) == NULL) {
fclose(tfp);
tfp = NULL;
fclose(rfp);
rfp = NULL;
return;
}
/*
* Check for a listing line number if required
*/
if (gcntr != -1) {
if (!dgt(RAD10, &rb[30], 1)) {
fprintf(rfp, "%s", rb);
goto loop;
}
gcntr = 0;
}
gline = 0;
}
/*
* Hex Listing
*/
if (radix == 16) {
/*
* Data Byte Pointer
*/
if (gcntr == -1) {
rp = &rb[8];
} else {
rp = &rb[8 + (3 * gcntr)];
}
/*
* Number must be of proper radix
*/
if (!dgt(RAD16, rp, 2)) {
fprintf(rfp, "%s", rb);
gline = 1;
goto loop;
}
/*
* Output new data value, overwrite relocation codes
*/
sprintf(str, " %02X", v);
strncpy(rp-1, str, 3);
if (gcntr == -1) {
gcntr = 0;
}
/*
* Output relocated code address
*/
if (gcntr == 0) {
if (dgt(RAD16, &rb[3], 4)) {
sprintf(str, "%04X", pc);
strncpy(&rb[3], str, 4);
}
}
/*
* Output text line when updates finished
*/
if (++gcntr == 6) {
fprintf(rfp, "%s", rb);
gline = 1;
gcntr = -1;
}
} else
/*
* Decimal Listing
*/
if (radix == 10) {
/*
* Data Byte Pointer
*/
if (gcntr == -1) {
rp = &rb[9];
} else {
rp = &rb[9 + (3 * gcntr)];
}
/*
* Number must be of proper radix
*/
if (!dgt(RAD10, rp, 3)) {
fprintf(rfp, "%s", rb);
gline = 1;
goto loop;
}
/*
* Output new data value, overwrite relocation codes
*/
sprintf(str, " %03d", v);
strncpy(rp-1, str, 4);
if (gcntr == -1) {
gcntr = 0;
}
/*
* Output relocated code address
*/
if (gcntr == 0) {
if (dgt(RAD10, &rb[3], 5)) {
sprintf(str, "%05d", pc);
strncpy(&rb[3], str, 5);
}
}
/*
* Output text line when updates finished
*/
if (++gcntr == 4) {
fprintf(rfp, "%s", rb);
gline = 1;
gcntr = -1;
}
} else
/*
* Octal Listing
*/
if (radix == 8) {
/*
* Data Byte Pointer
*/
if (gcntr == -1) {
rp = &rb[10];
} else {
rp = &rb[10 + (3 * gcntr)];
}
/*
* Number must be of proper radix
*/
if (!dgt(RAD8, rp, 3)) {
fprintf(rfp, "%s", rb);
gline = 1;
goto loop;
}
/*
* Output new data value, overwrite relocation codes
*/
sprintf(str, " %03o", v);
strncpy(rp-1, str, 4);
if (gcntr == -1) {
gcntr = 0;
}
/*
* Output relocated code address
*/
if (gcntr == 0) {
if (dgt(RAD8, &rb[3], 6)) {
sprintf(str, "%06o", pc);
strncpy(&rb[3], str, 6);
}
}
/*
* Output text line when updates finished
*/
if (++gcntr == 4) {
fprintf(rfp, "%s", rb);
gline = 1;
gcntr = -1;
}
}
}
/*)Function int dgt(rdx,str,n)
*
* int rdx radix bit code
* char *str pointer to the test string
* int n number of characters to check
*
* The function dgt() verifies that the string under test
* is of the specified radix.
*
* local variables:
* int i loop counter
*
* global variables:
* ctype[] array of character types
*
* functions called:
* none
*
* side effects:
* none
*/
int
dgt(rdx, str, n)
int rdx, n;
char *str;
{
int i;
for (i=0; i<n; i++) {
if ((ctype[(int)*str++] & rdx) == 0)
return(0);
}
return(1);
}