int cmpgr(BSS *o_product, int n1, int n2) { // used to compare two group names char name1[61], name2[61]; if (read_dbf(o_product,n1)) { cout << "Error reading database record!\n"; return 1; } if (read_buf(o_product,name1,NULL,NULL,NULL)) { cout << "Error parsing database record!\n"; return 1; } if (read_dbf(o_product,n2)) { cout << "Error reading database record!\n"; return 1; } if (read_buf(o_product,name2,NULL,NULL,NULL)) { cout << "Error parsing database record!\n"; return 1; } return strcmp(name1,name2); }
int main(int argc, char **argv) { struct stat buf; int ret; char scratch[BUFSIZ]; char log[BUFSIZ]; char olog[BUFSIZ]; char *scratch_p = scratch; char *mytag_p; FILE *fp; extern char *getenv(); char *parse(); int c; extern char *optarg; extern int optind; int i; char *Mytag_p = Mytag; /* Get my port monitor tag out of the environment */ if ((mytag_p = getenv("PMTAG")) == NULL) { /* no place to write */ exit(1); } strcpy(Mytag, mytag_p); /* open log file */ sprintf(log, "%s/%s/%s", ALTDIR, Mytag_p, LOGNAME); sprintf(olog, "%s/%s/%s", ALTDIR, Mytag_p, OLOGNAME); if (stat(log, &buf) == 0) { /* file exists, try and save it but if we can't don't worry */ unlink(olog); rename(log, olog); } if ((i = open(log, O_WRONLY|O_CREAT|O_APPEND, 0444)) < 0) logexit(1, nologfile); /* as stated above, the log file should be file descriptor 5 */ if ((ret = fcntl(i, F_DUPFD, 5)) != 5) logexit(1, nologfile); Logfp = fdopen(ret, "a+"); /* Get my port monitor tag out of the environment */ if ((mytag_p = getenv("PMTAG")) == NULL) { logexit(1, nopmtag); } strcpy(Mytag, mytag_p); (void) umask(022); Readdb = FALSE; if (geteuid() != (uid_t) 0) { logmessage("Must be root to start listener"); logexit(1, badstart); } while ((c = getopt(argc, argv, "m:")) != EOF) switch (c) { case 'm': Minor_prefix = optarg; break; default: logexit(1, usage); break; } if ((Netspec = argv[optind]) == NULL) { logexit(1, usage); } if ((Netconf = getnetconfigent(Netspec)) == NULL) { sprintf(scratch, "no netconfig entry for <%s>", Netspec); logmessage(scratch); logexit(1, badstart); } if (!Minor_prefix) Minor_prefix = argv[optind]; if ((int) strlen(Netspec) > PATHSIZE) { logmessage(badnspmsg); logexit(1, badstart); } /* * SAC will start the listener in the correct directory, so we * don't need to chdir there, as we did in older versions */ strcpy(Provbuf, "/dev/"); strcat(Provbuf, Netspec); (void) umask(0); init_files(); /* open Accept, Sac, Pm, Pass files */ pid_open(); /* create pid file */ #ifdef DEBUGMODE sprintf(scratch, "%s/%s/%s", ALTDIR, Mytag, DBGNAME); Debugfp = fopen(scratch, "w"); #endif #ifdef DEBUGMODE if ((!Logfp) || (!Debugfp)) #else if (!Logfp) #endif logexit(1, badstart); /* * In case we started with no environment, find out what timezone we're * in. This will get passed to children, so only need to do once. */ if (getenv("TZ") == NULL) { fp = fopen(TZFILE, "r"); if (fp) { while (fgets(tzenv, BUFSIZ, fp)) { if (tzenv[strlen(tzenv) - 1] == '\n') tzenv[strlen(tzenv) - 1] = '\0'; if (!strncmp(TZSTR, tzenv, strlen(TZSTR))) { putenv(parse(tzenv)); break; } } fclose(fp); } else { sprintf(scratch, "couldn't open %s, default to GMT", TZFILE); logmessage(scratch); } } logmessage("@(#)listen:listen.c 1.19.9.1"); #ifdef DEBUGMODE logmessage("Listener process with DEBUG capability"); #endif sprintf(scratch, "Listener port monitor tag: %s", Mytag_p); logmessage(scratch); DEBUG((9, "Minor prefix: %s Netspec %s", Minor_prefix, Netspec)); /* fill in Pmmesg fields that always stay the same */ Pmmsg.pm_maxclass = MAXCLASS; strcpy(Pmmsg.pm_tag, Mytag_p); Pmmsg.pm_size = 0; /* Find out what state to start in. If not in env, exit */ if ((scratch_p = getenv("ISTATE")) == NULL) logexit(1, "ERROR: ISTATE variable not set in environment"); if (!strcmp(scratch_p, "enabled")) { State = PM_ENABLED; logmessage("Starting state: ENABLED"); } else { State = PM_DISABLED; logmessage("Starting state: DISABLED"); } /* try to get my "basename" */ Progname = strrchr(argv[0], '/'); if (Progname && Progname[1]) ++Progname; else Progname = argv[0]; catch_signals(); /* * Allocate memory for private address and file descriptor table * Here we are assuming that no matter how many private addresses * exist in the system if the system limit is 20 then we will only * get 20 file descriptors */ Ndesc = ulimit(4,0L); /* get num of file des on system */ read_dbf(DB_INIT); net_open(); /* init, open, bind names */ for (i = 3; i < Ndesc; i++) { /* leave stdout, stderr open */ fcntl(i, F_SETFD, 1); /* set close on exec flag*/ } logmessage("Initialization Complete"); listen(); return (0); }
int main(int argc, char *argv[]) { cout << "Pulse of Prices Databases Ver 1.10 creator of " << __DATE__ << "\n" "Copyright (c) 1995, 1996 by Sergey Gershtein. Ural-Relcom, Ltd.\n" "---------------------------------------------------------------\n" "This program converts Oferta's Pulse database files from " "current directory\n" "into Pulse of Prices Viewer format.\n\n"; #ifndef DEBUG char *final_dir=".\\"; if (argc>1) if (argv[1][0]=='?' || argv[1][1]=='?') { cout << "Usage: " << argv[0] << " <dest_dir>\n\n" "All the Oferta *.dbf files and optionally payments.ini file\n" "must be in current directory. The resulting pulse.* files will\n" "be stored in the <dest_dir> directory.\n" "Be prepared that it may take a long time to create the bases.\n" "You can stop the program at any time by pressing Ctrl-C.\n"; return 0; } else final_dir=argv[1]; #else if (argc>1) cout << "### This version was compiled with DEBUG option set.\n" "### It does not understand your argument '"<<argv[1]<<"'\n"; #endif cout << "Opening files:\n"; // clearing all the read-only attrs and stuff _rtl_chmod(b_address,1,0); _rtl_chmod(b_offer,1,0); _rtl_chmod(b_product,1,0); _rtl_chmod(b_prodtype,1,0); // opening the bases BSS *o_address=open_dbf(b_address); cout << " " << b_address; if (!o_address) { cout << " - error opening file\n"; return 1; } else cout << endl; BSS *o_offer = open_dbf(b_offer); cout << " " << b_offer; if (!o_offer) { cout << " - error opening file\n"; return 1; } else cout << endl; BSS *o_product = open_dbf(b_product); cout << " " << b_product; if (!o_product) { cout << " - error opening file\n"; return 1; } else cout << endl; BSS *o_prodtype = open_dbf(b_prodtype); cout << " " << b_prodtype; if (!o_prodtype) { cout << " - error opening file\n"; return 1; } else cout << endl; // bases opened. Now reading... ------------------------ PPF --------------- #ifndef NOPPF { cout << "Creating pulse.ppf... "; if (!ppf.create(final_dir,(ushort)o_address->Amount)) { cout << "file creation error!\n"; return 1; } ppf.firm = new char[17]; ppf.address = new char[61]; ppf.fullname = new char[120]; for (ushort n=1; n<=o_address->Amount; n++) { // for each record if (n%10==1) { cout.width(6); cout << n << ' '; cout << "\x8\x8\x8\x8\x8\x8\x8"; } if (read_dbf(o_address,n)) { cout << "Error reading database record!\n"; return 1; } if (read_buf(o_address,ppf.firm,NULL,ppf.address,ppf.fullname, &ppf.phone[0],&ppf.phone[1],&ppf.phone[2],&ppf.phone[3],&ppf.area)) { cout << "Error parsing database record!\n"; return 1; } for (char *s=ppf.firm; (*s=upcase(*s))!=0; s++) ; // upcase firm name if (!ppf.write()) { cout << "Error writing record!\n"; return 1; } } delete[] ppf.firm; delete[] ppf.address; delete[] ppf.fullname; ppf.close(); cout << n << " records processed.\n"; } #endif // --------------------------- creating PPG file ----------------------------- #ifndef NOPPG { int n; long dsup=0, ddem=0; cout << "Reading groups information... "; for (n=0; n<o_product->Amount; n++) { nidx[n]=n+1; cout << "\x8\x8\x8\x8\x8\x8\x8"; cout.width(6); cout << (int)n << ' '; if (read_dbf(o_product,n+1)) { cout << "Error reading database record!\n"; return 1; } unsigned int recno; long last; if (read_buf(o_product,NULL,&recno,&g1[n],&last)) { cout << "Error parsing database record!\n"; return 1; } if (read_dbf(o_prodtype,recno)) { cout << "Error reading database prodtyp_.dbf!\n"; return 1; } int supply; if (read_buf(o_prodtype,NULL,NULL,NULL,&supply)) { cout << "Error parsing database prodtyp_.dbf record!\n"; return 1; } if (supply) { dsup+=last-g1[n]+1; g1[n]-=ddem; } else { // demand ddem+=last-g1[n]+1; g1[n]-=dsup; } g1[n]--; // we start from zero, not one } cout << "\nSorting groups with InsertSort... "; for (int k=(int)o_product->Amount-2; k>=0; k--) { char save=nidx[k]; // save k-th element long sav1=g1[k]; for (int j=k+1; (j<=o_product->Amount-1) && cmpgr(o_product,save,nidx[j])>0; j++) { nidx[j-1]=nidx[j]; g1[j-1]=g1[j]; } nidx[j-1] = save; g1[j-1] = sav1; if (k%7==0) { cout.width(3); cout << k << "\x8\x8\x8"; } } cout << "Done sorting. \n"; cout << "Creating pulse.ppg... "; if (!ppg.create(final_dir,(ushort)o_product->Amount)) { cout << "file creation error!\n"; return 1; } ppg.gname = new char[61]; for (n=0; n<o_product->Amount; n++) { // for each record cout << "\x8\x8\x8\x8\x8\x8\x8"; cout.width(6); cout << (int)n << ' '; if (read_dbf(o_product,nidx[n])) { cout << "Error reading database record!\n"; return 1; } unsigned int recno; if (read_buf(o_product,ppg.gname,&recno,&ppg.gfirst,&ppg.gsize)) { cout << "Error parsing database record!\n"; return 1; } ppg.gsize-=(--ppg.gfirst); // number of records, not the last record long gf=ppg.gfirst; ppg.gfirst=g1[n]; // not absolute one, but address in the index if (read_dbf(o_prodtype,recno)) { cout << "Error reading database prodtyp_.dbf!\n"; return 1; } int supply; if (read_buf(o_prodtype,NULL,NULL,NULL,&supply)) { cout << "Error parsing database prodtyp_.dbf record!\n"; return 1; } ppg.issupply = !(ppg.isdemand=(supply==0)); if (!ppg.write()) { cout << "Error writing record!\n"; return 1; } g1[n]=gf; // now g1 contains what gfirst used to be } delete[] ppg.gname; ppg.close(); cout << "records processed.\n"; } #endif // creating .ppd file (uff..) { try { ppi.paym = new Paym[30]; // let's start with 30 payment methods ulong pmno[30]; // number of times payment methods are used ppi.npaym = 0; #ifdef DEBUG cout << "## coreleft: " << coreleft() << endl; #endif ushort cblno=(ushort)((coreleft()-20000)/2048/4); VArrayL ndx(o_offer->Amount*2+2,"s_index.$$$",2048,cblno); cout << "Virtual array created: " << cblno << " 2048-element blocks allocated" " for buffer\n"; cout << "Memory should left afterwards: " << (coreleft() - ((long)cblno)*2048*4) << endl; cout << "Creating pulse.ppd... "; ppd.dupdate.Today(); ppd.dcreate = ppd.dupdate; if (!ppd.create(final_dir)) { cout << "file creation error!\n"; return 1; } for (long n=1; n<=o_offer->Amount; n++) { // for each record if (n%19==1) { cout.width(7); cout << n << ' '; cout << "\x8\x8\x8\x8\x8\x8\x8\x8"; } if (read_dbf(o_offer,n)) { cout << "Error reading database record!\n"; return 1; } double dprice; char payment[4]; char date[7]; if (read_buf(o_offer,NULL,NULL,&ppd.drec.fcode,NULL,&dprice, payment,date,ppd.drec.ad)) { cout << "Error parsing database record!\n"; return 1; } ppd.drec.price=dprice; ppd.drec.fcode--; date[2]=date[5]=0; ppd.drec.dsubmit = Date(atoi(date),atoi(date+3),ppd.dcreate.year()); for (int i=0; i<ppi.npaym; i++)// do we know this payment method? if (upcase(ppi.paym[i].abbr[0])==upcase(payment[0]) && upcase(ppi.paym[i].abbr[1])==upcase(payment[1]) && upcase(ppi.paym[i].abbr[2])==upcase(payment[2])) break; if (i>=ppi.npaym) { // new payment method ppi.npaym = i+1; pmno[i]=0; for (int j=0; j<4; j++) ppi.paym[i].abbr[j]=payment[j]; ppi.paym[i].coef=1; // roubles form by default. } ppd.drec.pcode = i; pmno[i]++; for (char *s=ppd.drec.ad; (*s=upcase(*s))!=0; s++) ; if ((ndx[n-1]=ppd.write())==0) { cout << "Error writing record!\n"; return 1; } } ppd.close(); cout << (n-1) << " records processed.\n"; cout << (int)ppi.npaym << " payment methods were encountered:\n"; for (int i=0; i<ppi.npaym; i++) { if (i>0) cout << ", "; for (int j=0; j<4; j++) cout << ppi.paym[i].abbr[j]; cout << " - "; cout.width(7); cout << pmno[i]; } cout << endl; // finding minimum course cout << "Looking for the USD course... "; if (!ppg.open(final_dir)) { cout << "Error opening pulse.ppg!\n"; return 1; } for (int i0=0; i0<ppg.Ngroups(); i0++) { if (!ppg.read()) { cout << "Error reading pulse.ppg record "<<i0<<"!\n"; return 1; } if (strstr(ppg.gname,"‚€‹ž’€") && ppg.issupply) break; } double usdk=1e+10; if(!ppd.open(final_dir)) { cout << "Error opening pulse.ppd!\n"; return 1; } if (i0>=ppg.Ngroups()) { cout << "!!!!!!!!!!!!!!!!! Not found !!!!!!!!!!!!!!!!!!!\n"; usdk=4700; // ???? } else { for (i=0;i<ppg.gsize;i++) { // looking for course if (!ppd.read(ndx[g1[i0]+i])) { cout << "Error reading pulse.ppd records!\n"; return 1; } if (strstr(ppd.drec.ad,"��Ž„€†€ USD") && ppd.drec.price<usdk) // found usdk = ppd.drec.price; } if (usdk<1e+9) cout << usdk << " roubles/$\n"; else { cout << "Records not found!\n"; usdk = 0; } } ppg.close(); // working with payments.ini file cout << "Checking "<<payments_ini<<" file... "; ifstream inif(payments_ini,ios::in); if (!inif) cout << "File not found.\n"; else { // working with the file cout << "File found\n"; while (!inif.eof()) { char pmt[4]; char line[30]; inif.read(pmt,4); // read four characters of payment type if (inif.eof()) break; inif.getline(line,29); for (i=0; i<ppi.npaym; i++) if (upcase(ppi.paym[i].abbr[0])==upcase(pmt[0]) && upcase(ppi.paym[i].abbr[1])==upcase(pmt[1]) && upcase(ppi.paym[i].abbr[2])==upcase(pmt[2])) { // found char *c; for (c=line; *c<=' '; c++); // skip leading blanks if (*c=='$') // dollar conversion coef ppi.paym[i].coef = atof(++c)*usdk; else ppi.paym[i].coef = atof(c); cout << " "; for (int j=0; j<4; j++) cout << ppi.paym[i].abbr[j]; cout << " = " << ppi.paym[i].coef << " roubles\n"; break; } // payment methods found } // while not eof inif.close(); } // .ini file found // building demand and supply lists cout << "Building demand and supply lists... "; long nsup=0, ndem=0; // number of supply and demand records if (!ppg.open(final_dir)) { cout << "Error opening pulse.ppg!\n"; return 1; } for (i=0; i<ppg.Ngroups(); i++) { if (!ppg.read()) { cout << "Error reading pulse.ppg record "<<i<<"!\n"; return 1; } if (ppg.issupply) nsup+=ppg.gsize; else if (ppg.isdemand) { ndem+=ppg.gsize; for (int j=0; j<ppg.gsize; j++) // set high bit to 1 for demand ndx[g1[i]+j]=ndx(g1[i]+j) | 0x80000000l; } cout.width(7); cout << (ndem+nsup) << "\x8\x8\x8\x8\x8\x8\x8"; } cout << "Done \n " << nsup << " supply records.\n " << ndem << " demand records.\n"; ppg.close(); // creating ppi file ------------------------------------- cout << "Creating pulse.ppi:\n "; if (!ppi.create(final_dir)) { cout << "File creation error!\n"; return 1; } if (!ppi.write()) { // writing initial payment info records cout << "Error writing payment info records!\n"; return 1; } else cout << "Payment information stored.\n"; cout << " Writing supply records list... "; if (!ppi.iselect(iSupply)) { cout << "Error storing index offset!\n"; return 1; } for (n=0; n<o_offer->Amount; n++) // for each element if ((ndx(n) & 0x80000000l)==0) // supply if (!ppi.write(ndx(n))) { cout << "Error writing index element!\n"; return 1; } else if (n%33==1) { cout.width(7); cout << n << "\x8\x8\x8\x8\x8\x8\x8"; } cout << "Done. \n"; cout << " Writing demand records list... "; if (!ppi.iselect(iDemand)) { cout << "Error storing index offset!\n"; return 1; } for (n=0; n<o_offer->Amount; n++) // for each element if ((ndx(n) & 0x80000000l)!=0) // demand if (!ppi.write(ndx(n)&0x7fffffffl)) { cout << "Error writing index element!\n"; return 1; } else if (n%33==1) { cout.width(7); cout << n << "\x8\x8\x8\x8\x8\x8\x8"; } cout << "Done. \n"; #ifndef NOASORT qsortads(ppd,ndx,0,o_offer->Amount-1); // quick sort by names cout << " Writing supply records list... "; if (!ppi.iselect(iSrtSupply)) { cout << "Error storing index offset!\n"; return 1; } for (n=0; n<o_offer->Amount; n++) // for each element if ((ndx(n) & 0x80000000l)==0) // supply if (!ppi.write(n)) { cout << "Error writing index element!\n"; return 1; } else if (n%33==1) { cout.width(7); cout << n << "\x8\x8\x8\x8\x8\x8\x8"; } cout << "Done. \n"; cout << " Writing demand records list... "; if (!ppi.iselect(iSrtDemand)) { cout << "Error storing index offset!\n"; return 1; } for (n=0; n<o_offer->Amount; n++) // for each element if ((ndx(n) & 0x80000000l)!=0) // demand if (!ppi.write(n/*ndx(n)&0x7fffffffl*/)) { cout << "Error writing index element!\n"; return 1; } else if (n%33==1) { cout.width(7); cout << n << "\x8\x8\x8\x8\x8\x8\x8"; } cout << "Done. \n"; #endif // alpha sort cout << "Building indexes for each payment type:\n"; cout << " Supply... "; ulong pmcur[30]; // index positions for each payment type pmcur[0]=0; for (n=0; n<ppi.npaym-1; n++) { pmcur[(int)n+1]=pmcur[(int)n]+pmno[(int)n]; pmno[(int)n]=pmcur[(int)n]; #ifdef DEBUG cout << "pmcur[" << n << "]=" << pmcur[n] << " "; #endif } #ifdef DEBUG cout << endl; #endif pmno[(int)n]=pmcur[(int)n]; // now pmno points to the beginnings of the lists, pmcur - to the endings // long ll=0; for (n=0; n<nsup; n++) { if (!ppd.read(ppi(n,TRUE),FALSE)) { // not reading ad string cerr << "Error reading data #1!\n"; return 1; } union { ulong l; float f; } u; u.f = ppd.drec.price; #ifdef DEBUG if (pmcur[ppd.drec.pcode]+o_offer->Amount+1>=o_offer->Amount*2+2) { cerr << "@1: pcode=" << (int)ppd.drec.pcode << ", pmcur[pcode]=" << (long)pmcur[ppd.drec.pcode] << ", Amount=" << o_offer->Amount << endl; } #endif ndx[pmcur[ppd.drec.pcode]+o_offer->Amount+1]=u.l; ndx[pmcur[ppd.drec.pcode]++]=n; if (n%13==1) { cout.width(7); cout << n << "\x8\x8\x8\x8\x8\x8\x8"; } } cout << n << " elements done.\n"; cout << " Sorting the lists:\n"; for (n=0; n<ppi.npaym; n++) { // sorting all lists if (pmno[(int)n]>=pmcur[(int)n]) continue; // no records for this payment type #ifdef HEAPSORT cout << " HeapSorting "; #else cout << " QuickSorting "; #endif for (int j=0; j<4; j++) cout << ppi.paym[(int)n].abbr[j]; cout << "... "; #ifdef HEAPSORT heapsort(ppd,ppi,ndx,pmno[(int)n],pmcur[(int)n]-1,TRUE); #else qsortprice(ppd,ppi,ndx,pmno[(int)n],pmcur[(int)n]-1, TRUE,o_offer->Amount+1); #endif #ifdef SORTCHECK cout << "DEBUG: Checking sort order..."; if (!ppd.read(ppi(ndx(pmno[(int)n]),TRUE),FALSE)) { cout << "ee!"; return -1; } for (long ll=pmno[(int)n]+1; ll<pmcur[(int)n]; ll++) { float pr=ppd.drec.price; union { ulong l; float f; } u1; u1.l=ndx(ll+o_offer->Amount+1); if (!ppd.read(ppi(ndx(ll),TRUE))) { cout << "ee!"; return -1; } if (pr>ppd.drec.price) { cout << ll << ": SORT ERROR!\n"; // return -1; } cout.width(8); cout << ll << "\x8\x8\x8\x8\x8\x8\x8\x8"; } cout << "Sort OK\n"; #endif } cout << " Storing indexes... "; for (int jj=0; jj<o_product->Amount; jj++) nidx0[nidx[jj]-1]=jj; for (int pc=0; pc<ppi.npaym; pc++) { ppi.iselect(iPaym+pc*2); for (int gr=0; gr<o_product->Amount; gr++) gfirst[gr]=glast[gr]=-1; for (long n=pmno[pc]; n<pmcur[pc]; n++) { ppi.write(ndx(n)); // finding to which group ndx(n) belongs... Binary search int left=0, right=(int)(o_product->Amount-1), mid; while (left<right) { mid=(right+left)/2; if (ndx(n)<g1[nidx0[mid]]) right=mid-1; else if (ndx(n)>=g1[nidx0[mid]] && (mid==o_product->Amount-1 || ndx(n)<g1[nidx0[mid+1]])) { // found left=mid; break; } else left=mid+1; } // group found if (gfirst[nidx0[left]]==-1) gfirst[nidx0[left]]=n-pmno[pc]; glast[nidx0[left]]=n-pmno[pc]; // information stored in the array if (n%13==1) { cout.width(7); cout << n << "\x8\x8\x8\x8\x8\x8\x8"; } } for (gr=0; gr<o_product->Amount; gr++) ppi.writeg(gr,gfirst[gr],glast[gr]); } cout << nsup << " elements done.\n"; for (n=0; n<ppi.npaym; n++) { pmno[(int)n]=pmcur[(int)n]; } // now pmno points to the beginnings of the lists, pmcur - to the endings cout << " Demand... "; for (n=0; n<ndem; n++) { if (!ppd.read(ppi(n,FALSE),FALSE)) { // demand records cerr << "Error reading data #1!\n"; return 1; } union { ulong l; float f; } u; u.f = ppd.drec.price; ndx[pmcur[ppd.drec.pcode]+o_offer->Amount+1]=u.l; ndx[pmcur[ppd.drec.pcode]++]=n; if (n%13==1) { cout.width(7); cout << n << "\x8\x8\x8\x8\x8\x8\x8"; } } cout << n << " elements done.\n"; cout << " Sorting the lists:\n"; for (n=0; n<ppi.npaym; n++) { // sorting all lists if (pmno[(int)n]>=pmcur[(int)n]) continue; // no records for this payment type #ifdef HEAPSORT cout << " HeapSorting "; #else cout << " QuickSorting "; #endif for (int j=0; j<4; j++) cout << ppi.paym[(int)n].abbr[j]; cout << "... "; #ifdef HEAPSORT heapsort(ppd,ppi,ndx,pmno[(int)n],pmcur[(int)n]-1,FALSE); #else qsortprice(ppd,ppi,ndx,pmno[(int)n],pmcur[(int)n]-1, FALSE,o_offer->Amount+1); #endif } cout << " Storing indexes... "; for (pc=0; pc<ppi.npaym; pc++) { ppi.iselect(iPaym+pc*2+1); for (long n=pmno[pc]; n<pmcur[pc]; n++) { ppi.write(ndx(n)); if (n%13==1) { cout.width(7); cout << n << "\x8\x8\x8\x8\x8\x8\x8"; } } } cout << ndem << " elements done.\n"; ppd.close(); // NOT TO FORGET ppi.close(); delete[] ppi.paym; } catch (VArrayErr err) { cout << "Virtual array exception #" << (int)err.code() << "\n"; return 1; } catch (xalloc xa) { cout << "Memory allocation failure: " << xa.requested() << "bytes.\n"; return 1; } catch (...) { cout << "Unhandled exception!\n"; return 1; } } cout << "Closing Oferta's files... "; if (close_dbf(o_address) || close_dbf(o_product) || close_dbf(o_prodtype) || close_dbf(o_offer)) { cout << "Error closing Oferta's bases!\n"; return 1; } cout << "Done.\n"; return 0; }