Category : C Source Code
Archive   : SDB.ZIP
Filename : SDBSRT.C

 
Output of file : SDBSRT.C contained in archive : SDB.ZIP
/* SDBSRT - sort routines */

#include "sdbio.h"

extern int dbv_token;
extern char dbv_tstring[];
extern int dbv_tvalue;

/* local variables */
static struct skey *skeys;
static struct scan *inscan,*outscan;
static int intnum,outtnum;

/* external routines */
extern char *malloc();

/* forward declarations */
static int getrec(),putrec(),cmprec();
static struct skey *get_skeys();

/* db_sort - sort tuples in a relation */
int db_sort(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9)
char *fmt;
{
int result;

/* check for a command line */
if (fmt != NULL)
db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9);

/* checks for relation name */
if (db_token() == ID)
db_ntoken();
else
strcpy(dbv_tstring,"sdbcur");

/* open the relation */
if ((inscan = db_ropen(dbv_tstring)) == NULL)
return (FALSE);
if ((outscan = db_ropen(dbv_tstring)) == NULL) {
db_rclose(inscan);
return (FALSE);
}

/* checks for "by " */
if (db_ntoken() != BY)
return (db_ferror(SYNTAX));
if (get_skeys(inscan) == NULL) {
db_rclose(inscan);
db_rclose(outscan);
return (FALSE);
}

/* do the sort */
intnum = outtnum = 1;
result = sort(getrec,putrec,cmprec,inscan->sc_relation->rl_size);

/* close the relation */
db_rclose(inscan);
db_rclose(outscan);

/* free the sort keys */
free_skeys();

/* return successfully */
return (TRUE);
}

/* get_skeys - get sort key list */
static struct skey *get_skeys(sptr)
struct scan *sptr;
{
struct skey *newskey,*lastskey;

/* parse a list of attribute names */
skeys = lastskey = NULL;
while (TRUE) {

/* get attribute name */
if (db_ntoken() != ID)
return (db_nerror(SYNTAX));

/* allocate a sort key structure */
if ((newskey = (struct skey *)malloc(sizeof(struct skey))) == NULL)
return (db_nerror(INSMEM));

/* initialize the sort key structure */
newskey->sk_next = NULL;

/* lookup the attribute name */
if (!find_attr(sptr,newskey,dbv_tstring)) {
free(newskey);
return (NULL);
}

/* check for ascending or descending */
if (db_token() == ASCENDING || dbv_token == DESCENDING) {
newskey->sk_type = dbv_token;
db_ntoken();
}
else
newskey->sk_type = ASCENDING;

/* link the sort key structure into the list */
if (lastskey == NULL)
skeys = newskey;
else
lastskey->sk_next = newskey;
lastskey = newskey;

/* check for more attributes */
if (db_token() != ',')
break;
db_ntoken();
}

/* return successfully */
return (skeys);
}

/* free_skeys - free a list of sort keys */
static free_skeys()
{
struct skey *thisskey;

for (thisskey = skeys; skeys != NULL; thisskey = skeys) {
skeys = skeys->sk_next;
free(thisskey);
}
}

/* find_attr - find an attribute */
static int find_attr(sptr,newskey,aname)
struct scan *sptr; struct skey *newskey; char *aname;
{
struct attribute *aptr;
int i,astart;

/* loop through each attribute within the relation */
astart = 1;
for (i = 0; i < NATTRS; i++) {

/* get a pointer to the current attribute */
aptr = &sptr->sc_relation->rl_header.hd_attrs[i];

/* check for last attribute */
if (aptr->at_name[0] == 0)
break;

/* check for attribute name match */
if (db_sncmp(aname,aptr->at_name,ANSIZE) == 0) {
newskey->sk_start = astart;
newskey->sk_aptr = aptr;
return (TRUE);
}

/* update the attribute start */
astart += aptr->at_size;
}

/* attribute name not found */
return (db_ferror(ATUNDF));
}

/* getrec - get a record for the sort */
static int getrec(buf)
char *buf;
{
if (intnum <= inscan->sc_relation->rl_tcnt)
return (db_rget(inscan,intnum++,buf));
else
return (FALSE);
}

/* putrec - put a record for the sort */
static int putrec(buf)
char *buf;
{
return (db_rput(outscan,outtnum++,buf));
}

/* cmprec - compare two tuples */
static int cmprec(rec1,rec2)
char *rec1,*rec2;
{
struct skey *cskey;
int result;

for (cskey = skeys; cskey != NULL; cskey = cskey->sk_next)
if ((result = cattr(cskey,rec1,rec2)) != 0)
break;
return (result);
}

/* cattr - compare two attributes */
static int cattr(cskey,rec1,rec2)
struct skey *cskey; char *rec1,*rec2;
{
int astart,aend,i;

astart = cskey->sk_start;
aend = astart + cskey->sk_aptr->at_size;

for (i = astart; i < aend; i++)
if (rec1[i] != rec2[i])
break;

if (i == aend)
return (0);
else if (rec1[i] < rec2[i])
return (cskey->sk_type == ASCENDING ? -1 : 1);
else
return (cskey->sk_type == ASCENDING ? 1 : -1);
}



  3 Responses to “Category : C Source Code
Archive   : SDB.ZIP
Filename : SDBSRT.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/