home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- UTIL.C
- Sub Systems, Inc.
- Copyright (c) 1992, Sub Systems, Inc. All Rights Reserved.
- 159 Main Street, #8C, Stoneham, MA 02180, (617) 438-8901.
-
- FileSort and FileJoin Utilities
-
- This file is used only by the demo program. This file is not needed
- by the ReportEase Plus DLL.
-
- ******************************************************************************/
-
- #include "windows.h"
- #include "stdio.h"
- #include "stdlib.h"
- #include "ctype.h"
- #include "dos.h"
- #include "fcntl.h"
- #include "io.h"
- #include "signal.h"
- #include "string.h"
- #include "time.h"
-
- /*****************************************************************************
- Compiler specific include files and library translations
- ******************************************************************************/
- #if defined(__TURBOC__)
- #include "alloc.h"
- #include "dir.h"
- #include "string.h"
- #include "mem.h"
- #define _memavl coreleft
- #define _makepath fnmerge
- #define _splitpath fnsplit
- #else
- #include "string.h"
- #include "malloc.h"
- #include "memory.h"
- #endif
-
- /******************************************************************************
- WIN32 specific defines
- *******************************************************************************/
- #if defined (_WIN32)
- #if !defined(WIN32)
- #define WIN32
- #endif
- #endif
- #if defined (WIN32)
- #define huge
- #define _export
- #else
- #define huge huge
- #endif
-
- #include "util.h"
-
- /******************************************************************************
- Necessary Prototypes
- *******************************************************************************/
- int JoinArrayMem(void);
- int JoinExtractCommonField(struct StrJoinRec far *,int,int);
- int JoinFreeMem(struct StrJoinRec far *,int);
- int JoinReadFile(LPSTR,struct StrJoinRec far *);
- int JoinWriteFile(LPSTR);
-
- int SortArrayMem(int);
- int SortBuildKeys(void);
- int SortReadFile(LPSTR);
- int SortDoSort(void);
- int SortWriteFile(LPSTR);
-
- int FileLines(LPSTR);
- int ExtractField(LPSTR,int far *,int,char far *);
- void far *OurAlloc(long);
- void OurFree(void far *);
- int ltrm(LPSTR);
- int rtrm(LPSTR);
- int strtrm(LPSTR);
-
- /******************************************************************************
- Define statements
- *******************************************************************************/
- #define TRUE 1
- #define FALSE 0
-
- /******************************************************************************
- Global Variables
- *******************************************************************************/
- struct StrJoinRec {
- char far *rec; /* record pointer */
- char far *field; /* common field */
- } far *file1,far *file2;
-
- struct StrSortRec {
- char far *rec; /* record pointer */
- char far *key; /* key pointer */
- } far *item;
-
- int TotalLines,TotalLines1,TotalLines2,key[10],TotalKeys;
- char SortKey[10][80];
-
- /******************************************************************************
- Main routine.
- *******************************************************************************/
- int WINAPI _export FileJoin(LPSTR InputFile1,int field1,LPSTR InputFile2, int field2, LPSTR OutputFile)
- {
-
- TotalLines1=FileLines(InputFile1); /* find total number of lines in file1 */
- TotalLines2=FileLines(InputFile2); /* find total number of lines in file2 */
-
- if (TotalLines1<0 || TotalLines2<0) return FALSE;
-
- if (!JoinArrayMem()) return FALSE; /* allocate memory for the line arrays */
-
- if (!JoinReadFile(InputFile1,file1)) return FALSE; /* read the input file1 */
- if (!JoinReadFile(InputFile2,file2)) return FALSE; /* read the input file2 */
-
- if (!JoinExtractCommonField(file1,TotalLines1,field1)) return FALSE; /* extract the common field for file 1*/
- if (!JoinExtractCommonField(file2,TotalLines2,field2)) return FALSE; /* extract the common field for file 2*/
-
- if (!JoinWriteFile(OutputFile)) return FALSE; /* write the output file */
-
- if (!JoinFreeMem(file1,TotalLines1)) return FALSE; // freeup memory
- if (!JoinFreeMem(file2,TotalLines2)) return FALSE;
-
- return TRUE;
- }
-
- /*****************************************************************************
- WEP:
- Library exit routine.
- ******************************************************************************/
- CALLBACK _export WEP(int nParameter)
- {
- return 1;
- }
-
- /****************************************************************************
- JoinArrayMem:
- Allocate memory for the line array.
- *****************************************************************************/
- JoinArrayMem()
- {
-
- file1=(struct StrJoinRec far *) OurAlloc(((long)TotalLines1+1)*(long)sizeof(struct StrJoinRec));
- file2=(struct StrJoinRec far *) OurAlloc(((long)TotalLines2+1)*(long)sizeof(struct StrJoinRec));
- if (file1==NULL || file2==NULL) {
- MessageBox(NULL,"Out of RAM for file pointers","JOIN",MB_OK);return FALSE;
- }
- return TRUE;
- }
-
- /*****************************************************************************
- JoinReadFile:
- Read the file into memory.
- *****************************************************************************/
- JoinReadFile(LPSTR FileName,struct StrJoinRec far *item)
- {
-
- char line[250];
- LPSTR result;
- int i=0;
- FILE far *iStream;
-
- if (NULL==(iStream=fopen(FileName,"rt"))) {
- wsprintf(line,"Can not open the input file %s",(LPSTR)FileName);
- MessageBox(NULL,line,"JOIN",MB_OK);
- return FALSE;
- }
-
-
- NEXT_LINE:
- result=fgets(line,250,iStream);
- if (ferror(iStream)) {
- wsprintf(line,"Error in reading the file: %s",(LPSTR)FileName);
- MessageBox(NULL,line,"JOIN",MB_OK);
- return FALSE;
- }
-
- if (feof(iStream)) goto END_FILE;
-
- if (result==NULL) {
- wsprintf(line,"Error in reading file: %s",(LPSTR)FileName);
- MessageBox(NULL,line,"JOIN",MB_OK);
- return FALSE;
- }
-
- if (NULL==(item[i].rec=OurAlloc(lstrlen(line)+1))) {
- MessageBox(NULL,"Cannot load the file, out of memory\n","JOIN",MB_OK);return FALSE;
- }
-
- lstrcpy(item[i].rec,line);
-
- i++;
-
- goto NEXT_LINE;
-
- END_FILE:
- fclose(iStream);
-
- return TRUE;
- }
-
- /*****************************************************************************
- JoinFreeMem:
- Free up memory used by a file
- *****************************************************************************/
- JoinFreeMem(struct StrJoinRec far *item, int TotalLines)
- {
- int i;
-
- for (i=0;i<TotalLines;i++) {
- OurFree(item[i].rec);
- OurFree(item[i].field);
- }
- OurFree(item);
-
- return TRUE;
- }
-
- /*****************************************************************************
- JoinExtractCommonField:
- Extract the common field from the file records
- *****************************************************************************/
- JoinExtractCommonField(struct StrJoinRec far *file,int TotalLines,int fld)
- {
- int line,LineIdx,CurLen,FieldNo;
- char CurKey[240],KeyFound;
-
-
- for (line=0;line<TotalLines;line++) { /* process each line */
-
- LineIdx=0; /* prepare to scan the line */
- CurLen=lstrlen(file[line].rec);
- if (CurLen>0 && file[line].rec[CurLen-1]==0xA) CurLen--;
- KeyFound=FALSE;
- FieldNo=1;
-
- while (TRUE) {
- /* extract the fields */
- if (!ExtractField(file[line].rec,&LineIdx,CurLen,CurKey)) break;
- if (fld==FieldNo) {
- KeyFound=TRUE;
- break;
- }
- FieldNo++;
- }
- if (!KeyFound) {
- wsprintf(CurKey,"Common field not found in record number: %d",line+1);
- MessageBox(NULL,CurKey,NULL,MB_OK);
- return FALSE;
- }
-
- /* build the full key */
- if (NULL==(file[line].field=OurAlloc(lstrlen(CurKey)+1))) {
- MessageBox(NULL,"Out of Memory during Key Build","JOIN",MB_OK);return FALSE;
- }
-
- lstrcpy(file[line].field,CurKey);
- }
- return TRUE;
- }
-
- /******************************************************************************
- FileSort:
- Main Sort routine.
- *****************************************************************************/
- int WINAPI _export FileSort(LPSTR InputFile, int NumKeys, LPINT KeyTable)
- {
-
- int i;
-
-
- // save the sort keys
- TotalKeys=NumKeys;
- for (i=0;i<TotalKeys;i++) key[i]=KeyTable[i];
-
- TotalLines=FileLines(InputFile);/* find total number of lines in the file */
- if (TotalLines<0) return FALSE;
-
- if (!SortArrayMem(TotalLines)) return FALSE; /* allocate memory for the line arrays */
-
- if (!SortReadFile(InputFile)) return FALSE; /* read the input file */
-
- if (!SortBuildKeys()) return FALSE; /* build keys */
-
- if (!SortDoSort()) return FALSE; /* sort the file in the memory */
-
- if (!SortWriteFile(InputFile)) return FALSE; /* write the output file */
-
- return TRUE;
- }
-
- /****************************************************************************
- SortArrayMem:
- Allocate memory for the line array.
- *****************************************************************************/
- SortArrayMem(int TotalLines)
- {
-
- item=(struct StrSortRec far *)OurAlloc(((long)TotalLines+1)*(long)sizeof(struct StrSortRec));
- if (item==NULL) {
- MessageBox(NULL,"Out of RAM for file pointers","SORT",MB_OK);return FALSE;
- }
- return TRUE;
- }
-
- /*****************************************************************************
- SortReadFile:
- Read the file into memory.
- *****************************************************************************/
- SortReadFile(LPSTR InputFile)
- {
-
- char line[250],far *result;
- int i=0;
- FILE far *iStream;
-
- if (NULL==(iStream=fopen(InputFile,"rt"))) {
- wsprintf(line,"Can not open the input file %s",(LPSTR)InputFile);
- MessageBox(NULL,line,"SORT",MB_OK);
- return FALSE;
- }
-
-
- NEXT_LINE:
- result=fgets(line,250,iStream);
- if (ferror(iStream)) {
- wsprintf(line,"Error in reading the file: %s",(LPSTR)InputFile);
- MessageBox(NULL,line,"SORT",MB_OK);
- return FALSE;
- }
-
- if (feof(iStream)) goto END_FILE;
-
- if (result==NULL) {
- wsprintf(line,"Error in reading file: %s",(LPSTR)InputFile);
- MessageBox(NULL,line,"SORT",MB_OK);
- return FALSE;
- }
-
- if (NULL==(item[i].rec=OurAlloc(strlen(line)+1))) {
- MessageBox(NULL,"Cannot load the file, out of memory\n","SORT",MB_OK);return FALSE;
- }
-
- lstrcpy(item[i].rec,line);
-
- i++;
-
- goto NEXT_LINE;
-
- END_FILE:
- fclose(iStream);
-
- return TRUE;
- }
-
- /*****************************************************************************
- SortBuildKeys:
- Build a key for each record line.
- *****************************************************************************/
- SortBuildKeys()
- {
- int line,LineIdx,CurLen,i,FieldNo;
- char KeyString[240],CurKey[240],KeysFound;
-
-
- for (line=0;line<TotalLines;line++) { /* process each line */
-
- LineIdx=0; /* prepare to scan the line */
- CurLen=lstrlen(item[line].rec);
- if (CurLen>0 && item[line].rec[CurLen-1]==0xA) CurLen--;
- KeysFound=0;
- FieldNo=1;
- for (i=0;i<TotalKeys;i++) SortKey[0][0]=0;
-
- while (TRUE) {
- /* extract the fields */
- if (!ExtractField(item[line].rec,&LineIdx,CurLen,CurKey)) break;
- for (i=0;i<TotalKeys;i++) {
- if (key[i]==FieldNo) {
- strcpy(SortKey[i],CurKey);
- KeysFound++;
- }
- }
- FieldNo++;
- }
- if (KeysFound!=TotalKeys) {
- wsprintf(KeyString,"Sort key %d not found in record number: %d",key[KeysFound],line+1);
- MessageBox(NULL,KeyString,"SORT",MB_OK);
- return FALSE;
- }
-
- /* build the full key */
- KeyString[0]=0;
- for (i=0;i<TotalKeys;i++) strcat(KeyString,SortKey[i]);
-
- if (NULL==(item[line].key=OurAlloc(strlen(KeyString)+1))) {
- MessageBox(NULL,"Out of Memory during Key Build","SORT",MB_OK);return FALSE;
- }
-
- lstrcpy(item[line].key,KeyString);
- }
- return TRUE;
- }
-
- /*****************************************************************************
- SortDoSort:
- Sort the file in the memory
- *****************************************************************************/
- SortDoSort()
- {
- int i,j,SmallRecIdx;
- struct StrSortRec TempItem;
-
- for (i=0;i<TotalLines;i++) {
- SmallRecIdx=i;
- for(j=i;j<TotalLines;j++) {
- if (lstrcmp(item[j].key,item[SmallRecIdx].key)<0) SmallRecIdx=j;
- }
- if (SmallRecIdx!=i) { /* exchange the words */
- TempItem=item[i];
- item[i]=item[SmallRecIdx];
- item[SmallRecIdx]=TempItem;
- }
- }
-
- return TRUE;
- }
-
- /*****************************************************************************
- SortWriteFile:
- write the output file
- *****************************************************************************/
- SortWriteFile(LPSTR InputFile)
- {
- FILE far *oStream;
- int i;
- char OutputFile[128],string[300];
-
- for (i=0;i<129 && InputFile[i]!='.' && InputFile[i]!='\0';i++) OutputFile[i]=InputFile[i];
- OutputFile[i]=0;
- strcat(OutputFile,".SRT");
-
-
- unlink(OutputFile);
- if (NULL==(oStream=fopen(OutputFile,"wt"))) {
- wsprintf(string,"Can not open the output file %s",(LPSTR)OutputFile);
- MessageBox(NULL,string,"SORT",MB_OK);
- return FALSE;
- }
-
- for (i=0;i<TotalLines;i++) {
- lstrcpy(string,item[i].rec);
- fputs(string,oStream);
- }
-
- fclose(oStream);
-
- return TRUE;
- }
-
- /*****************************************************************************
- FileLines:
- find total number of lines in the file.
- *****************************************************************************/
- FileLines(LPSTR FileName)
- {
- char line[250];
- LPSTR result;
- int TotalLines=0;
- FILE far *iStream;
-
-
- if (NULL==(iStream=fopen(FileName,"rt"))) {
- wsprintf(line,"Can not open the input file %s",(LPSTR)FileName);
- MessageBox(NULL,line,"JOIN",MB_OK);
- return -1;
- }
-
- NEXT_LINE:
- result=fgets(line,250,iStream);
- if (ferror(iStream)) {
- wsprintf(line,"Error in reading the file: %s",(LPSTR)FileName);
- MessageBox(NULL,line,"JOIN",MB_OK);
- return -1;
- }
-
- if (feof(iStream)) goto END_FILE;
-
- if (result==NULL) {
- wsprintf(line,"Error in reading file: %s",(LPSTR)FileName);
- MessageBox(NULL,line,"JOIN",MB_OK);
- return -1;
- }
- TotalLines++;
-
- if (TotalLines>30000) {
- MessageBox(NULL,"Cannot sort this file larger than 30000 lines.","JOIN",MB_OK);
- return -1;
- }
-
- goto NEXT_LINE;
-
- END_FILE:
- fclose(iStream);
-
- return TotalLines;
- }
-
- /******************************************************************************
- ExtractField:
- This routine scans a text line to extract the next field.
- The fields are assumed to be of character type.
- ******************************************************************************/
- ExtractField(LPSTR line,int far *idx,int LineLen,char far *CharReturn)
- {
- char quote='"',string[240],far *ptr,SaveChar;
- int i,j,k;
-
- i=(*idx);
- while (i<LineLen && line[i]==' ') i++; /* go past the spaces */
-
- if (i>=LineLen) return FALSE; /* past the end of the line */
-
- if (line[i]==quote) {
- i++; /* skip over the first quote */
-
- for (k=i;k<LineLen;k++) if (line[k]==quote) break;
-
- if (k==LineLen) return FALSE;
-
- ptr=&line[k];
-
- j=1;
- while (ptr[j]!=',' && ptr[j]!=0) j++;/* locate the next comma */
-
- SaveChar=ptr[0]; /* extract the string */
- ptr[0]=0;
- lstrcpy(string,&line[i]);
- ptr[0]=SaveChar;
- (*idx)=i+lstrlen(string)+1+j; /* index to the next field */
- }
- else {
- for (k=i;k<LineLen;k++) if (line[k]==',') break;
-
- if (k==LineLen) ptr=&line[LineLen];
- else ptr=&line[k];
-
- SaveChar=ptr[0]; /* extract the string */
- ptr[0]=0;
- lstrcpy(string,&line[i]);
- ptr[0]=SaveChar;
- (*idx)=i+lstrlen(string)+1; /* index to the next field */
- }
-
- lstrcpy(CharReturn,string);
- return TRUE;
- }
-
- /*****************************************************************************
- JoinWriteFile:
- write the output file
- *****************************************************************************/
- JoinWriteFile(LPSTR OutputFile)
- {
- FILE far *oStream;
- int i,j,CurLen;
- char line[500];
-
- unlink(OutputFile);
- if (NULL==(oStream=fopen(OutputFile,"wt"))) {
- wsprintf(line,"Can not open the output file %s",(LPSTR)OutputFile);
- MessageBox(NULL,line,"JOIN",MB_OK);
- return FALSE;
- }
-
- for (i=0;i<TotalLines1;i++) { /* process each line of the primary file */
- for(j=0;j<TotalLines2;j++) { /* match with the secondary file */
- if (lstrcmp(file1[i].field,file2[j].field)==0) {
- lstrcpy(line,file1[i].rec);
- CurLen=lstrlen(line);
- if (CurLen>0 && line[CurLen-1]==0xA) CurLen--;
- line[CurLen]=','; /* comma delimiter */
- CurLen++;
- line[CurLen]=0;
-
- if (CurLen+lstrlen(file2[j].rec)>499) {
- MessageBox(NULL,"Record too big!","JOIN",MB_OK);
- return FALSE;
- }
- lstrcat(line,file2[j].rec);
- fputs(line,oStream);
- }
- }
- }
-
- fclose(oStream);
-
- return TRUE;
- }
-
- /*******************************************************************************
- strtrm:
- Trim the spaces on left & right of the string
- *******************************************************************************/
- strtrm(LPSTR string)
- {
- rtrm(string);
- ltrm(string);
- return TRUE;
- }
-
- /*******************************************************************************
- rtrm:
- Trim the space on right side of the string
- *******************************************************************************/
- rtrm(LPSTR string)
- {
- int i,TmpLen;
-
- TmpLen=lstrlen(string);
- for (i=TmpLen-1;i>=0 && string[i] == ' ';i--);
- string[i+1] = '\0';
-
- return TRUE;
- }
-
- /*******************************************************************************
- ltrm:
- Trim the space on left side of the string
- *******************************************************************************/
- ltrm(LPSTR string)
- {
- int i,TmpLen,BegPoint;
- char TmpStr[255];
-
- TmpLen=lstrlen(string);
- for (i=0;i < TmpLen && string[i] == ' ';i++);
- BegPoint=i;
- for (i=BegPoint;i<TmpLen;i++) TmpStr[i-BegPoint]=string[i];
- TmpStr[TmpLen-BegPoint] = '\0';
- lstrcpy(string,TmpStr);
- return TRUE;
- }
-
- /*******************************************************************************
- OurAlloc:
- This routine allocates a specified number of byte from the global heap,
- and returns a far pointer to the locked object.
- *******************************************************************************/
- void far *OurAlloc(long bytes)
- {
- HANDLE hnd;
- LPSTR result;
-
- if ( (NULL==(hnd=GlobalAlloc(GMEM_MOVEABLE,bytes+1)))
- || (NULL==(result=GlobalLock(hnd))) ) {
- MessageBox(NULL,"Ran out of memory","JOIN",MB_OK);
- return FALSE;
- }
- return result;
- }
-
- /******************************************************************************
- OurFree:
- Free up the given memory object. This object must have been allocated
- using the OurAlloc routine.
- *******************************************************************************/
- void OurFree(void far *pMem)
- {
- HGLOBAL hMem;
-
- if (pMem!=NULL) {
- #if defined(WIN32)
- hMem=GlobalHandle(pMem); // convert pointer to handle
- #else
- {
- DWORD temp=GlobalHandle((UINT)(((DWORD)pMem)>>16));
- hMem=(HGLOBAL)LOWORD(temp);
- }
- #endif
-
- GlobalUnlock(hMem);
- GlobalFree(hMem);
- }
- }
-