home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
smapp100.zip
/
sm10.zip
/
smgcontf.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-05-14
|
70KB
|
2,015 lines
/* ------------------------------------------------------------------------
*
* File: smgcontf.c
* Project: Source Mapper.
* Created: June 5, 1992.
* Description: Kildekode for å koble midlertidige mellomfiler til
* endelig mellomfil (CONnect from Temporary Files).
* Her er også inkludert kode for å skj¢te mellomfiler i
* activt prosjekt til den store og midlertidige totale
* mellomfilen som brukes under selve genereringen av kart.
*
* Copyright (C) 2000 Leif-Erik Larsen.
* This file is part of the Source Mapper source package.
* Source Mapper is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, in version 2 as it comes in the
* "COPYING" file of the XWorkplace main distribution.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* ------------------------------------------------------------------------ */
#include "smg.h"
int ConnectTempFiles ( char *sfnam, finfTYPE *finf )
/* Opprettet: Fredag 5. juni 1992.
Parameter: "sfnam" Navn/katalog til kildefil.
"finf" Struktur med informasjon om kildefilen, etter tolking.
Retur : E/O.
Beskriv : Kobler de midlertidige mellomfilene (som holder den grove
og ubehandlede informasjonen etter tolking av kildefil) til
den endelige mellomfilen. Ingen av de midlertidige filene
slettes eller stenges i denne funksjonen. Dette må derfor
gj¢res hos kalleren, etter at denne funksjonen er ferdig.
*/
{
fposTYPE fpos; /* Lagrer filposisjon til datagrupper */
/* Lagre filkjennemerke og kildefilnavn, til endelig mellomfil: */
FPrintF (tempf, "%s%c%s%c", _StrMSGTEMPFILEID, EOFCHR, sfnam, '\0');
/* Lagre total kildefilinformasjon, til endelig mellomfil: */
fpos.finf = FTell (tempf);
FWrite (finf, sizeof (finfTYPE), 1, tempf);
if (errno != 0)
{
/* Failed on write to file! */
RETERR (3, GetFNames (tempf));
}
/* Lagre informasjon om funksjoner, til endelig mellomfil: */
fpos.funreg = FTell (tempf);
if (!ConnectFunReg (finf->func))
{
RETURN_ERR;
}
/* Lagre informasjon om funksjonskall, til endelig mellomfil: */
fpos.funcal = FTell (tempf);
if (!ConnectFunCal (finf->fcal))
{
RETURN_ERR;
}
/* Lagre informasjon om identifikatorer, til endelig mellomfil: */
fpos.idlst = FTell (tempf);
if (!ConnectIdLst (finf->cid))
{
RETURN_ERR;
}
/* Lagre informasjon om kildefil-linjer, til endelig mellomfil: */
fpos.lininf = FTell (tempf);
if (!ConnectLinInf (finf->ltot))
{
RETURN_ERR;
}
/* Lagre startposisjoner til datagrupper i endelig mellomfil: */
FWrite (&fpos, sizeof (fposTYPE), 1, tempf);
return (OK);
} /* ConnectTempFiles (); */
int ConnectIdLst ( uint32 count )
/* Opprettet: L¢rdag 6. juni 1992.
Parameter: "count" Antall elementer i den globale filen "idlistf".
Retur : E/O.
Beskriv : Kobler den midlertidige mellomfilen "idlistf" (som holder den
grove og ubehandlede informasjonen om identifikatorer etter
tolking av kildefil) til den endelige mellomfilen.
*/
{
FILE *diffidf; /* Fil for liste over navn */
/* Produser mellomfilen som skal midlertidig holde liste over
alle forskjellige identifikatorer i kildefilen: */
if (!MakeDiffIdF (idlistf, sizeof (idlstTYPE),
count, _StrMSGMAKEDIFIDF))
{
RETURN_ERR;
}
/* Åpner den produserte midlertidige filen med navnliste: */
if ((diffidf = FOpen (tmpn.sortfi, "r+b")) == NULL)
{
/* Failed on open temporary file! */
RETERR (11, tmpn.sortfi);
}
/* Sorter filen med liste over alle forskjellige identifikatorer: */
Display (D_HEIGH, "%s", _StrMSGSORTIDLST);
if (!sortfile (diffidf, MAXFUNCN + 1))
{
FClose (diffidf);
RETERR (12, tmpn.sortfi);
}
/* Samle data om identifikatorer: */
if (!ConnectIdLst_ (diffidf))
{
FClose (diffidf);
RETURN_ERR;
}
/* Lukk midlertidig fil for lagring av forskjellige identifikatorer */
FClose (diffidf);
return (OK);
} /* ConnectIdLst (); */
int ConnectIdLst_ ( FILE *diffidf )
/* Opprettet: Tirsdag 9. mars 1993.
Parameter: "diffidf" Fil med liste over alle forskjellige identifikatorer.
Retur : E/O.
Beskriv : Kjernen til "ConnectIdLst ()". Tar seg av styring for
å samle data om identifikatorer. Det forutsettes at det
allerede er produsert en midlertidig fil med liste over
alle forskjellige identifikatorer ("fiffidf") og at
denne er åpen for lesing.
*/
{
char idnam [MAXFUNCN + 1]; /* Ved lesing av id.navn fra fil */
long c1 = 0; /* Skal telle aktiv identifikator */
long countid; /* Antall id i liste over forskjel. id*/
long flen; /* Antall byte i fil */
idbuffTYPE idbuff;
/* Number of bytes in file of different identifiers */
if ((countid = FLength (diffidf)) == -1L)
{
/* Seek error! */
RETERR (13, GetFNames (diffidf));
}
countid /= MAXFUNCN + 1; /* Calc number of different items */
if (countid == 0) /* Any ID's? */
{
return (OK); /* No, return without connect */
}
/* Lagre linjenummer hvor de forskjellige identifikatorene brukes: */
Rewind (diffidf); /* Samtlige forskjellige id skal leses*/
/* Info til bruker: Samler data om forek. av id */
Display (D_HEIGH, "%s", _StrMSGINCLIDDATA);
/* Number of bytes in file */
if ((flen = FLength (idlistf)) == -1L)
{
/* Seek error! */
RETERR (13, GetFNames (idlistf));
}
if (flen > MemLeft () - 1000) /* Enough free memory to store items? */
{
/* Out of memory! */
RETERR (14, NULL);
}
/* Get memory to store whole item-list */
if ((idbuff.buff = Alloc (flen)) == NULL)
{
/* Out of memory! */
RETERR (14, NULL);
}
/* Number of items to store in buffer */
idbuff.cidb = (uint16) (flen / sizeof (idlstTYPE));
Rewind (idlistf); /* Place file pointer to start of file*/
/* Read list of items from file */
FRead (idbuff.buff, sizeof (idlstTYPE), idbuff.cidb, idlistf);
/* Loop to write the name of every identifier + line numbers */
while (FRead (&idnam, MAXFUNCN + 1, 1, diffidf) > 0)
{
/* Write name of item and a zero to separate */
FPrintF (tempf, "%s%c", idnam, 0);
if (errno != 0) /* Any error? */
{
Free (idbuff.buff); /* Give allocated memory back to heap */
/* Failed on write to file! */
RETERR (3, GetFNames (tempf));
}
/* Finn alle forekomster av aktiv id, og lagre linjenummer/data
i den endelige mellomfilen, fortl¢pende bak selve id-navnet: */
if (!ConnectIdLstData (idnam, &idbuff))
{
Free (idbuff.buff); /* Gi allokert minne tilbake til hop */
RETURN_ERR;
}
/* Write a long zero to mark the end of this list of line numbers */
FPutL (tempf, 0L);
if (++c1 % 7 == 0) /* Oppdater brukerinfo for hver 7: */
Display (D_LOW, "%s: %d%%", _StrMSGINCLIDDATA, (c1 * 100) / countid);
}
Free (idbuff.buff); /* Gi allokert minne tilbake til hop */
Display (D_LOW, "%s: 100%%", _StrMSGINCLIDDATA); /* 100% has finished */
return (OK);
} /* ConnectIdLst_ (); */
int ConnectIdLstData ( char *id, idbuffTYPE *idbuff )
/* Opprettet: L¢rdag 6. juni 1992.
Parameter: "id" Identifikator det skal s¢kes etter.
"idbuff" Struktur med id-buffer og info om antall id'er.
Retur : E/O.
Beskriv : Skanner gjennom "idlstf" etter identifikatoren "id", og skj¢ter
in fortl¢pende informasjon om data/linjenummer til den
aktuelle identifikatoren. Informasjonen skj¢tes til
mellomfilen "tempf".
Viktig: Det er optil kaller å f¢lge med på den globalt
deklarerte strukturen "idbuff". At det allokeres
minne til den f¢r "connect_idlstdata ()"
kalles f¢rste gang og at det allokerte minnet gis
tilbake til hopen etter at "connect_idlstdata ()" er
kallt for siste gang.
*/
{
uint16 idc = 0; /* Nummer til aktiv i i buffer (0..) */
idlstTYPE huge *idlst; /* Pointer to current id */
idlst = (idlstTYPE *) idbuff->buff; /* Initier peker til buffer */
while (idc < idbuff->cidb) /* S¢k gjennom samtlige id'er i buffer*/
{
/* Active item equal to actual item? */
if (strcmp (id, idlst->name) == 0)
{
/* Lagre linjenummer til mellomfil */
if (FWrite (&idlst->lnr, sizeof (idlst->lnr), 1, tempf) != 1)
{
/* Failed on write to file! */
RETERR (3, GetFNames (tempf));
}
if (o_idlist.riselnr == O_YES)/* Any respect to rising line numbers?*/
{
idc++; /* Next item in buffer */
idlst++;
continue; /* Don't optimize buffer if O_YES */
}
/* Decrementer antall id'er i buffer, siden siste skal flyttes: */
idbuff->cidb--;
/* Flytt bakerste id i buffer til aktiv bufferposisjon, siden
aktiv id i bufferposisjon herved er inkludert i mellomfil.
Så trenger vi ikke aktiv id lenger, og vi sparer tid ved å
slette den og gi bort bufferposisjonen til bakerste id istedet: */
memcpy (idlst,
ADRESS (idbuff->buff, idbuff->cidb, sizeof (idlstTYPE)),
sizeof (idlstTYPE));
/* Fortsett loop fra og med id som nylig ble flyttet fram i buffer: */
idc--;
idlst--;
}
idc++; /* Next item in buffer */
idlst++;
}
return (OK);
} /* ConnectIdLstData (); */
int MakeDiffIdF ( FILE *idf, int esize, uint32 count, char *userinf )
/* Opprettet: L¢rdag 6. juni 1992.
Parameter: "idf" Midlertidig fil for data om id'er/funksjonskall.
"esize" St¢rrelsen til hvert element i "idf", i byte.
"count" Antall elementer i "idf".
"userinf" Streng med informasjon til bruker om arbeidsmengde.
Retur : E/O.
Beskriv : Scanner "idf" og lager en liste over alle forskjellige
identifikatorer i denne filen. Listen lagres i en midlertidig
fil og i standard katalog for midlertidige mellomfiler.
Listen sorteres ikke her.
*/
{
char buff [BIGGEST_SCANSTRUC]; /* For storing element from "idf" */
uint16 answ; /* For lagring av testresultat */
uint32 c1 = 0; /* Skal telle aktive identifikatorer */
Display (D_HEIGH, "%s", userinf); /* Info til bruker om oppgave */
Rewind (idf); /* Tilbakestill filpeker */
/* Initier og alloker midlertidig tabell for liste over forskjellige navn:*/
if (!DiffBConstruct (tmpn.sortfi, MAXFUNCN + 1))
{
RETURN_ERR;
}
/* Scan all elements in "idf" */
while (FRead (&buff, esize, 1, idf) > 0)
{
/* Sjekk om navnet allerede finnes i listen: */
if (!DiffBIfId (buff, &answ))
{
DiffBDestruct ();
RETURN_ERR;
}
/* Lagre navnet i listen, dersom det ikke finnes der fra f¢r: */
if (answ == 0)
{
if (!DiffBAddId (buff))
{
DiffBDestruct ();
RETURN_ERR;
}
}
if (++c1 % 27 == 0) /* Oppdater brukerinfo for hver 27. */
{
/* Info til bruker (% ferdig) */
Display (D_LOW, "%s: %d%%", userinf, (c1 * 100) / count);
}
}
/* Avslutt midlertidig tabell for liste over forskjellige navn: */
if (!DiffBDestruct ())
{
RETURN_ERR;
}
if (errno != 0) /* Hvis feil ved ved "FRead ()" */
{
/* Failed on read file! */
RETERR (15, GetFNames (idf));
}
Display (D_LOW, "%s: 100%%", userinf); /* 100% has finished */
return (OK);
} /* MakeDiffIdF (); */
int ConnectFunCal ( uint32 count )
/* Opprettet: S¢ndag 7. juni 1992.
Parameter: "count" Antall elementer i "funcalf".
Retur : E/O.
Beskriv : Kobler den midlertidige mellomfilen "funcalf" (som holder den
grove og ubehandlede informasjonen om funksjonskall etter
tolking av kildefil) til den endelige mellomfilen.
*/
{
char funcnam [MAXFUNCN + 1]; /* Ved lesing av navn fra fil */
FILE *diffidf; /* Fil for lagring av liste */
long c1 = 0; /* Skal telle aktiv funksjonskall */
long countfunc; /* Antall funksjonskall i "funcalf" */
/* Produser mellomfilen som skal midlertidig holde liste over
alle forskjellige funksjonskall i kildefilen: */
if (!MakeDiffIdF (funcalf, sizeof (fcalTYPE),
count, _StrMSGMAKEDIFFCALF))
{
RETURN_ERR;
}
/* Åpne den produserte midlertidige filen med liste over navn: */
if ((diffidf = FOpen (tmpn.sortfi, "r+b")) == NULL)
{
/* Failed on open temporary file! */
RETERR (11, tmpn.sortfi);
}
/* Sorter filen med liste over alle forskjellige funksjonskall: */
Display (D_HEIGH, "%s", _StrMSGSORTFCALLST);
if (!sortfile (diffidf, MAXFUNCN + 1))
{
FClose (diffidf);
/* Failed on sort contents of file! */
RETERR (12, GetFNames (diffidf));
}
/* Antall forskjellige navn */
if ((countfunc = FLength (diffidf) / (MAXFUNCN + 1)) == -1L)
{
FClose (diffidf);
/* Seek error! */
RETERR (13, GetFNames (diffidf));
}
/* Info til bruker: Samler data om forekomster */
Display (D_HEIGH, "%s", _StrMSGINCLFCALDATA);
/* Lagre linjenummer/data om de forskjellige funksjonskallene: */
Rewind (diffidf); /* Samtlige forskjellige id skal leses*/
/* Loop to write the names of functions + line numbers */
while (FRead (&funcnam, MAXFUNCN + 1, 1, diffidf) > 0)
{
/* Write name of function + a zero to separate */
if (!FPrintF (tempf, "%s%c", funcnam, 0))
{
FClose (diffidf);
/* Failed on write to file! */
RETERR (3, GetFNames (tempf));
}
/* Finn alle forekomster av ativt funksjonskall, og lagre
linjenummer/data i den endelige mellomfilen, fortl¢pende
bak selve funksjonskall-navnet: */
if (!ConnectFunCalData (funcnam))
{
FClose (diffidf);
RETURN_ERR;
}
/* Write a long zero to mark the end of the list of line numbers */
FPutL (tempf, 0L);
if (++c1 % 7 == 0) /* Oppdater brukerinfo for hver 7. */
{
/* Info til bruker: Samler data om forekomster (% ferdig) */
Display (D_LOW, "%s: %d%%", _StrMSGINCLFCALDATA,
(c1 * 100) / countfunc);
}
}
if (errno != 0)
{
FClose (diffidf);
/* Failed on read file! */
RETERR (15, GetFNames (diffidf));
}
Display (D_LOW, "%s: 100%%", _StrMSGINCLFCALDATA); /* 100% ferdig */
/* Lukk midlertidig fil for lagring av forskjellige identifikatorer: */
FClose (diffidf);
return (OK);
} /* ConnectFunCal (); */
int ConnectFunCalData ( char *name )
/* Opprettet: S¢ndag 7. juni 1992.
Parameter: "name" Navn til funksjonskall som skal s¢kes etter.
Retur : E/O.
Beskriv : Skanner gjennom "funcalf" etter funksjonskallet "name", og
skj¢ter in fortl¢pende informasjon om data/linjenummer til
det aktuelle funksjonskallet. Informasjonen skj¢tes til
mellomfilen "tempf".
*/
{
fcalTYPE fcal;
Rewind (funcalf); /* Id-listen skal s¢kes i fra starten */
while (FRead (&fcal, /* Les inn et element om gangen */
sizeof (fcalTYPE), /* Antall byte i struktur */
1, funcalf) > 0) /* Les fra funksjonskall-liste-fil */
{
/* Hvis innlest element = name */
if (strcmp (fcal.name, name) == 0)
{
/* Adresse til f¢rste data bak navn */
if (FWrite (&fcal.lnr, sizeof (fcal.lnr), 1, tempf) != 1)
{
/* Failed on write to file! */
RETERR (3, GetFNames (tempf));
}
}
}
if (errno != 0)
{
/* Failed on read file! */
RETERR (15, GetFNames (funcalf));
}
return (OK);
} /* ConnectFunCalData (); */
int ConnectFunReg ( long count )
/* Opprettet: S¢ndag 7. juni 1992.
Parameter: "count" Antall elementer i "funregf".
Retur : E/O.
Beskriv : Kobler den midlertidige mellomfilen "funregf" (som holder det
grove og ubehandlede funksjonsregisteret etter tolking av
kildefil) til den endelige mellomfilen.
*/
{
funcTYPE func;
uint32 c1 = 0; /* Counter 1, teller aktiv funksjon */
Display (D_HEIGH, "%s", _StrMSGSORTFUNCREG); /* Sorterer funksjonsdata */
if (!sortfile (funregf, sizeof (funcTYPE)))
{
/* Failed on sort contents file! */
RETERR (12, GetFNames (funregf));
}
/* Info til bruker: Inkluderer funksjonsdata */
Display (D_HEIGH, "%s", _StrMSGINCLFUNDATA);
while (FRead (&func, sizeof (funcTYPE), 1, funregf) > 0)
{
if (FWrite (&func, sizeof (funcTYPE), 1, tempf) != 1)
{
/* Failed on write to file! */
RETERR (3, GetFNames (tempf));
}
if (++c1 % 7 == 0 && /* Oppdater brukerinfo for hver 7. */
count > 0) /* For å unngå divide error */
{
/* Info til bruker: Inkluderer funksjonsdata: (% ferdig) */
Display (D_LOW, "%s: %d%%", _StrMSGINCLFUNDATA, (c1 * 100) / count);
}
}
if (errno != 0)
{
/* Failed on read file! */
RETERR (15, GetFNames (funregf));
}
Display (D_LOW, "%s: 100%%", _StrMSGINCLFUNDATA); /* 100% ferdig */
return (OK);
} /* ConnectFunReg (); */
int ConnectLinInf ( long count )
/* Opprettet: S¢ndag 7. juni 1992.
Parameter: "count" Antall elementer i "lininff".
Retur : E/O.
Beskriv : Kobler den midlertidige mellomfilen "lininff" (som holder den
grove og ubehandlede linjeinformasjonen etter tolking av
kildefil) til den endelige mellomfilen.
*/
{
scanTYPE scan;
uint32 c1 = 0; /* Counter 1, teller aktiv linje */
Rewind (lininff);
Display (D_HEIGH, "%s", _StrMSGINCLLINEINFO);
while (FRead (&scan, sizeof (scanTYPE), 1, lininff) == 1)
{
if (FWrite (&scan, sizeof (scanTYPE), 1, tempf) != 1)
{
/* Failed on write to file! */
RETERR (3, GetFNames (tempf));
}
if (++c1 % 51 == 0) /* Oppdater brukerinfo for hver 51. */
{
/* Inkluderer linjeinformasjon: (% ferdig) */
Display (D_LOW, "%s: %d%%", _StrMSGINCLLINEINFO, (c1 * 100) / count);
}
}
if (errno != 0)
{
/* Failed on read file! */
RETERR (15, GetFNames (lininff));
}
ClrLin (); /* T¢m hele linje der cursor er */
return (OK);
} /* ConnectLinInf (); */
int JoinObjFiles ( void )
/*
Function: Join objectfiles of active project into one big
temporary objectfile.
Date: April, 21. 1993. 00:45. By LEL.
Returns: E/O.
Comment: All sourcefiles in project must have been scanned to legal
objectfiles before this function is called.
*/
{
int ok; /* Temporary storing return value */
FILE *tmpf; /* Pointer to the file */
if (prjstat.filc <= 1) /* If only one source in project */
{
/* Internal error! (Shall never happen, but in case) */
RETERR (5, NULL); /* Must use normal objectfile instead */
}
if (!MakePrjDataOK ()) /* Be sure all data is updated in prj */
{
RETURN_ERR;
}
/* Open the big temporary objectfile */
if ((tmpf = FOpen (tmpn.manobj, "w+b")) == NULL)
{
RETERR (11, tmpn.manobj); /* Failed on open temporary file! */
}
ok = JoinObjFiles_ (tmpf); /* Do the kernel function */
FClose (tmpf); /* Close the temporary file */
return (ok);
} /* JoinObjFiles (); */
int JoinObjFiles_ ( FILE *tmpf )
/*
Function: Kernel function of 'JoinObjFiles ()'.
Date: April, 21. 1993. 01:15. By LEL.
Interface: tmpf = Newly opened filepointer to temporary big
objectfile of whole project.
Returns: E/O.
*/
{
fposTYPE fpos; /* File-indexes to blocks of data */
/*------------------------------------------------------------------------*/
fpos.finf = FTell (tmpf); /* Get start position of source info */
if (!JoinSourceInfo (tmpf)) /* Join sourceinfo from objectfiles */
{
RETURN_ERR;
}
/*------------------------------------------------------------------------*/
fpos.funreg = FTell (tmpf); /* Get start pos of function info */
if (!JoinFuncInfo (tmpf)) /* Join function info from objectfiles*/
{
RETURN_ERR;
}
/*------------------------------------------------------------------------*/
fpos.funcal = FTell (tmpf); /* Get start pos of functioncall info */
if (o_funcall.incl == O_YES || /* If include list of function calls */
o_flow.incl == O_YES || /* or include info of call-sequences */
(o_lineinfo.calist == O_YES && /* or include list of callers in funcs*/
o_lineinfo.incl == O_YES))
{
if (!JoinFunCalInfo (tmpf)) /* Join functioncall inf from objfiles*/
{
RETURN_ERR;
}
}
/*------------------------------------------------------------------------*/
fpos.idlst = FTell (tmpf); /* Get start position of item info */
if (o_idlist.incl == O_YES) /* If include list of items */
{
if (!JoinIdLstInfo (tmpf)) /* Join item info from objectfiles */
{
RETURN_ERR;
}
}
/*------------------------------------------------------------------------*/
fpos.lininf = FTell (tmpf); /* Get start position of line info */
if (o_lineinfo.incl == O_YES) /* If include info of source lines */
{
if (!JoinLineInfo (tmpf)) /* Join line info from objectfiles */
{
RETURN_ERR;
}
}
/*------------------------------------------------------------------------*/
/* Save block of file-positions into temporary big objectfile */
if (FWrite (&fpos, sizeof (fposTYPE), 1, tmpf) != 1)
{
/* Failed on write to file! */
RETERR (3, GetFNames (tmpf));
}
return (OK);
} /* JoinObjFiles_ (); */
int JoinSourceInfo ( FILE *tmpf )
/*
Function: Join block of source info from all objectfiles in active
project, into the specified big temporary objectfile.
Date: April, 21. 1993. 02:00. By LEL.
Interface: tmpf = Open big temporary object file to update.
Returns: E/O.
*/
{
int countf = 0; /* Count active objectfile */
prjfeTYPE fdata; /* Data about active objectfile */
finfTYPE finf; /* Info about whole project */
reset_finftype (&finf); /* Set all items in stricture to 0 */
while (countf++ < prjstat.filc) /* All objectfiles in active project */
{
/* Read data about active objectfile */
if (!GetFDataFromPrj (countf, &fdata))
{
RETURN_ERR;
}
finf.ltot += fdata.finf.ltot; /* Lines TOTal in sourcefile */
finf.elin += fdata.finf.elin; /* Empty LINes in sourcefile */
finf.coml += fdata.finf.coml; /* COMment Lines in sourcefile */
finf.codl += fdata.finf.codl; /* CODe Lines in sourcefile */
finf.com += fdata.finf.com; /* COMment blocks in sourcefile */
finf.func += fdata.finf.func; /* FUNCtions in sourcefile */
finf.dirl += fdata.finf.dirl; /* DIRectiveLines in sourcefile */
finf.fcal += fdata.finf.fcal; /* Function CALls in sourcefile */
finf.cid += fdata.finf.cid; /* IDentifiers in sourcefile */
}
/* Write info of source in project */
if (FWrite (&finf, sizeof (finfTYPE), 1, tmpf) != 1)
{
/* Failed on write to file! */
RETERR (3, GetFNames (tmpf));
}
return (OK); /* OK join */
} /* JoinSourceInfo (); */
int JoinFuncInfo ( FILE *tmpf )
/*
Function: Join block of function info from all objectfiles in active
project, into the specified big temporary objectfile.
Date: April, 21. 1993. 02:00. By LEL.
Interface: tmpf = Open big temporary object file to update.
Returns: E/O.
*/
{
long fnr; /* Number of functions in project */
FILE *sortf;
/* Open the temporary sortfile */
if ((sortf = FOpen (tmpn.sortfi, "w+b")) == NULL)
{
/* Failed on open temporary file! */
RETERR (11, tmpn.sortfi);
}
if (!JoinSortFuncInfo (sortf, &fnr)) /* Collect and sort function info */
{
FClose (sortf); /* Close temporary sortfile if error */
RETURN_ERR;
}
if (!JoinFuncInfo_ (tmpf, sortf, fnr)) /* Join sorted funcs into 'tmpf' */
{
FClose (sortf); /* Close temporary sortfile if error */
RETURN_ERR;
}
FClose (sortf); /* Close temporary sortfile */
return (OK); /* OK join of function info */
} /* JoinFuncInfo (); */
int JoinSortFuncInfo ( FILE *sortf, long *fnr )
/*
Function: Find names of functions in all objectfiles in active
project, join all the names together in 'sortf' and
sort them in alfabetical order.
Date: April, 21. 1993. 22:00. By LEL.
Interface: sortf = Newly created temporary file to use when sort.
fnr = Returns number of functions in project.
Returns: E/O.
*/
{
int filc = 0; /* Count number of source in project */
long globlin = 0; /* Count global line number */
FILE *objf; /* Active objectfile in project */
prjfeTYPE fdata; /* Data about actice objectfile */
*fnr = 0; /* Reset number of functions in projct*/
Display (D_HEIGH, "%s", _StrMSGINCLFUNDATA);
while (filc++ < prjstat.filc) /* Loop trough all files in project */
{
/* Include index of functions */
Display (D_LOW, "%s (%d/%d)", _StrMSGINCLFUNDATA, filc, prjstat.filc);
/* Read data about active file in prjoject */
if (!GetFDataFromPrj (filc, &fdata))
{
RETURN_ERR;
}
*fnr += fdata.finf.func; /* Count number of functions in projct*/
/* Open active objectfile */
if ((objf = FOpen (fdata.objn, "r+b")) == NULL)
{
RETERR (16, fdata.objn); /* Failed on open file! */
}
/* Join function names from objectfile */
if (!JoinSortFuncInfo_ (sortf, objf, &fdata.finf, &fdata.fpos, globlin))
{
FClose (objf); /* Close active objectfile if error */
}
globlin += fdata.finf.ltot; /* Count global line number */
FClose (objf); /* Close objectfile after use */
}
/* Sort functionblocks in sortfile */
Display (D_HEIGH, "%s", _StrMSGSORTFUNCREG);
if (!sortfile (sortf, sizeof (funcTYPE)))
{
/* Failed on sort contents of file! */
RETERR (12, GetFNames (sortf));
}
return (OK); /* OK sort of function info */
} /* JoinSortFuncInfo (); */
int JoinSortFuncInfo_ ( FILE *sortf, FILE *objf,
finfTYPE *finf, fposTYPE *fpos, long globlin )
/*
Function: Kernel function of 'JoinSortFuncInfo ()'. Do the work to get
function names from active objectfile, and join these names
into sortfile.
Date: April, 21. 1993. 23:20. By LEL.
Interface: sortf = Temporary file to use when sort.
objf = Newly opened active objectfile.
finf = Total file info about actual objectfile.
fpos = Indexes to blocks of data in objectfile.
globlin = Global line number of last line in previous source.
Returns: E/O.
*/
{
funcTYPE func; /* Info about active function */
/* Index to start of function info */
FSeek (objf, fpos->funreg, SEEK_SET);
while (finf->func--) /* Loop trough all functions in objfil*/
{
/* Read next function from objectfile */
if (FRead (&func, sizeof (funcTYPE), 1, objf) != 1)
{
/* Failed on read file */
RETERR (15, GetFNames (objf));
}
func.blin += globlin; /* Convert to global line number */
func.blin_block += globlin; /* Ditto */
/* Join newly red info to sortfile */
if (FWrite (&func, sizeof (funcTYPE), 1, sortf) != 1)
{
/* Failed on write to file */
RETERR (3, GetFNames (sortf));
}
}
return (OK); /* OK join of function names */
} /* JoinSortFuncInfo_ (); */
int JoinFuncInfo_ ( FILE *tmpf, FILE *sortf, long fnr )
/*
Function: Kernel function of 'JoinFuncInfo ()'.
Join block of function info from specified objectfile, into
the specified big temporary objectfile.
Programmed by: LEL
Date: April, 21. 1993. 02:00.
Interface: tmpf = Open big temporary object file to update.
srtf = Open file of sorted functions in whole project.
fnr = Number of functions stored in 'sortf'.
Returns: E/O.
*/
{
/* We can do a raw copy of data from 'sortf' to 'tmpf' because we know
that each block of function data allways has the same size.
This size is the size of structure 'funcTYPE'. */
if (!CopyNBytesP (tmpf, sortf, 0L, fnr * sizeof (funcTYPE)))
{
/* Failed on copy filebytes to ... */
RETERR (26, GetFNames (tmpf));
}
return (OK);
} /* JoinFuncInfo_ (); */
int JoinLineInfo ( FILE *tmpf )
/*
Function: Join block of line info from all objectfiles in
active project, into the specified big temporary objectfile.
Programmed by: LEL
Date: April, 22. 1993. 01:45.
Interface: tmpf = Open big temporary object file to update.
Returns: E/O.
*/
{
int countf = 0; /* Count active objectfile */
FILE *objf; /* Active objectfile from project */
prjfeTYPE fdata; /* Data about active objectfile */
/* Includes lines info */
Display (D_HEIGH, "%s", _StrMSGINCLLINEINFO);
while (countf++ < prjstat.filc) /* All objectfiles in active project */
{
/* Includes lines info */
Display (D_LOW, "%s (%d/%d)", _StrMSGINCLLINEINFO,
countf, prjstat.filc);
/* Read data about active objectfile */
if (!GetFDataFromPrj (countf, &fdata))
{
RETURN_ERR;
}
/* Open active objectfile (flag = read binary file) */
if ((objf = FOpen (fdata.objn, "r+b")) == NULL)
{
/* Failed on open file! */
RETERR (16, fdata.objn);
}
/* We can do a raw copy of data from 'objf' to 'tmpf' because we know
that each block of line info data allways has the same size.
This size is the size of structure 'scanTYPE'. */
if (!CopyNBytesP (tmpf, objf, /* Join info of all lines from objfile*/
fdata.fpos.lininf, /* Lininfo block start in this index */
fdata.finf.ltot * /* Number of lines in active source */
sizeof (scanTYPE))) /* Number of bytes in each lineinfo */
{
FClose (objf); /* Close active objectfile if error */
/* Failed on copy filebytes to ... */
RETERR (26, GetFNames (tmpf));
}
FClose (objf); /* Close active objectfile */
}
ClrLin ();
return (OK); /* OK join */
} /* JoinLineInfo (); */
int JoinFunCalInfo ( FILE *tmpf )
/*
Function: Join block of function calls info from all objectfiles in
active project, into the specified big temporary objectfile.
Programmed by: LEL
Date: April, 22. 1993. 02:00.
Interface: tmpf = Open big temporary object file to update.
Returns: E/O.
*/
{
long fnr; /* Number of function calls in project*/
FILE *sortf;
FILE *indxf;
/* Open the temporary sortfile */
if ((sortf = FOpen (tmpn.sortfi, "w+b")) == NULL)
{
/* Failed on open temporary file! */
RETERR (11, tmpn.sortfi);
}
/* Collect and sort function calls */
if (!JoinSortFunCalInfo (sortf, &fnr))
{
FClose (sortf); /* Close temporary sortfile if error */
RETURN_ERR;
}
/* Create and open temporary index-file */
if ((indxf = FOpen (tmpn.indexf, "w+b")) == NULL)
{
FClose (sortf); /* Close temporary sortfile if error */
/* Failed on open temporary file! */
RETERR (11, tmpn.indexf);
}
/* Make indexes to func.call-names */
if (!JoinFunCalMakIndx (sortf, indxf, fnr))
{
FClose (sortf); /* Close temporary sortfile if error */
FClose (indxf); /* Close temporary indexfile if error */
RETURN_ERR;
}
/* Join sorted func. calls into 'tmpf'*/
if (!JoinFunCalInfo_ (tmpf, sortf, indxf, fnr))
{
FClose (sortf); /* Close temporary sortfile if error */
FClose (indxf); /* Close temporary indexfile if error */
RETURN_ERR;
}
FClose (sortf); /* Close temporary sortfile */
FClose (indxf); /* Close temporary indexfile */
return (OK); /* OK join of function call info */
} /* JoinFunCalInfo (); */
int JoinFunCalInfo_ ( FILE *tmpf, FILE *sortf, FILE *indxf, long fnr )
/*
Function: Kernel function of 'JoinFunCalInfo ()'.
Join function call data from all objectfiles in project,
into the specified big main temporary objectfile.
The names is joined into 'tmpf' in same order as names in
specified sortfile.
Programmed by: LEL
Date: April, 21. 1993. 02:00.
Interface: tmpf = Open big temporary object file to update.
sortf = Open file of sorted function call names.
indxf = File with stored indexes to func.cal-info in
every object files in project.
fnr = Number of different function call names in project.
Returns: E/O.
*/
{
int filec; /* Count number of files in project */
long linnr; /* Store red line number */
long globlin; /* Count global line number */
long faddr; /* Index to func.cal lines in obj.file*/
char fname [MAXFUNCN + 1]; /* Buffer to store active func.name */
FILE *objf; /* Active objectfile */
prjfeTYPE fdata; /* Data on active objectfile in prjfil*/
/* Be sure filpointer on start of file */
if (!FSeek (sortf, 0L, SEEK_SET))
{
/* Seek error */
RETERR (13, GetFNames (sortf));
}
if (!FSeek (indxf, 0L, SEEK_SET))
{
/* Seek error */
RETERR (13, GetFNames (indxf));
}
/* Collecting list of function calls */
Display (D_HEIGH, "%s", _StrMSGINCLFCALDATA);
while (fnr--) /* Loop to seek all func.call names */
{
/* Collecting list of function calls */
Display (D_LOW, "%s (%ld)", _StrMSGINCLFCALDATA, fnr + 1);
/* Get name of next function call */
if (FRead (&fname, MAXFUNCN + 1, 1, sortf) != 1)
{
/* Failed on read file */
RETERR (15, GetFNames (sortf));
}
/* Write name of func.call to main obj */
if (!FPrintF (tmpf, "%s%c", fname, 0))
{
/* Failed on write to file */
RETERR (3, GetFNames (tmpf));
}
globlin = 0; /* Reset global line number first file*/
filec = 0; /* Reset counter to active file */
while (filec++ < prjstat.filc) /* Loop trough all files in project */
{
/* Get data about active objectfile */
if (!GetFDataFromPrj (filec, &fdata))
{
RETURN_ERR;
}
if (!FGetL (indxf, &faddr)) /* Index to where this func is in objf*/
{
/* Failed on read file */
RETERR (15, GetFNames (indxf));
}
if (faddr == 0L) /* No calls of this func in this objf */
{
globlin += fdata.finf.ltot;/* Count global line number */
continue; /* So, continue to next obj.file-index*/
}
/* Open active objectfile (Read binary file) */
if ((objf = FOpen (fdata.objn, "r+b")) == NULL)
{
/* Failed on open file! */
RETERR (16, fdata.objn);
}
FSeek (objf, faddr, SEEK_SET);/* Point to actual funcn in obj.file */
while (1) /* Loop to get line nubers from objf */
{
if (!FGetL (objf, &linnr)) /* Get next line number reference */
{
FClose (objf); /* Close current objectfile if error */
/* Failed on read file */
RETERR (15, GetFNames (objf));
}
if (linnr == 0L) /* A 0L mark end of line number list */
{
break; /* So, break from line-reading loop */
}
linnr += globlin; /* Convert to global line number */
if (!FPutL (tmpf, linnr)) /* Join line number to main objectfile*/
{
FClose (objf); /* Close current objectfile if error */
/* Failed on write to file */
RETERR (3, GetFNames (tmpf));
}
}; /* 0L if end of line number list */
globlin += fdata.finf.ltot; /* Count global line number */
FClose (objf); /* Close active objectfile */
}
if (!FPutL (tmpf, 0L)) /* 0L mark end of line number list */
{
/* Failed on write to file */
RETERR (3, GetFNames (tmpf));
}
}
return (OK); /* OK join */
} /* JoinFunCalInfo_ (); */
int JoinSortFunCalInfo ( FILE *sortf, long *fnr )
/*
Function: Find names of function calls in all objectfiles in active
project, join all the names together in 'sortf' and
sort them in alfabetical order.
Programmed by: LEL
Date: April, 22. 1993. 02:15.
Interface: sortf = Newly created temporary file to use when sort.
fnr = Returns number of calls to different functions
in project.
Returns: E/O.
*/
{
int filc = 0; /* Count number of source in project */
FILE *objf; /* Active objectfile in project */
prjfeTYPE fdata; /* Data about actice objectfile */
*fnr = 0; /* Reset number of f.calls in project */
while (filc++ < prjstat.filc) /* Loop trough all files in project */
{
/* Read data about active file in prj */
if (!GetFDataFromPrj (filc, &fdata))
{
RETURN_ERR;
}
/* Open active objectfile */
if ((objf = FOpen (fdata.objn, "r+b")) == NULL)
{
/* Failed on open file! */
RETERR (16, fdata.objn);
}
/* Join function names from objectfile */
if (!JoinSortFunCalInfo_ (sortf, objf, fnr, &(fdata.fpos)))
{
FClose (objf); /* Close active objectfile if error */
RETURN_ERR;
}
FClose (objf); /* Close objectfile after use */
}
/* Sorts list of function calls */
Display (D_HEIGH, "%s", _StrMSGSORTFCALLST);
if (!sortfile (sortf, MAXFUNCN + 1)) /* Sort function names in sortfile */
{
/* Failed on sort contents of file! */
RETERR (12, GetFNames (sortf));
}
return (OK); /* OK sort of function info */
} /* JoinSortFunCalInfo (); */
int JoinSortFunCalInfo_ ( FILE *sortf, FILE *objf, long *fnr, fposTYPE *fpos )
/*
Function: Kernel function of 'JoinSortFunCalInfo ()'.
Do the work to get function call names from active
objectfile, and join these names into sortfile.
Programmed by: LEL
Date: April, 22. 1993. 02:20.
Interface: sortf = Temporary file to use when sort.
objf = Newly opened active objectfile.
fnr = Count number of different function call names
in project.
fpos = Indexes to blocks of data in objectfile.
Returns: E/O.
*/
{
char fname [MAXFUNCN + 1]; /* Buffer to store active func.name */
long res; /* Temporary store result of a test */
long lnr; /* Buffer to store last red line nr */
long curpos; /* Current file position */
FSeek (objf,fpos->funcal,SEEK_SET); /* Index to start of func. call info */
/* Making list of different calls */
Display (D_HEIGH, "%s", _StrMSGMAKEDIFFCALF);
curpos = FTell (objf);
while (curpos < fpos->idlst) /* Loop trough all func. calls in objf*/
{
memset (fname, 0, MAXFUNCN + 1); /* To prevent packmans in sortfile */
/* Get next name of function from objf */
if (!FGetS0 (fname, MAXFUNCN + 1, objf))
{
/* Failed on read file */
RETERR (15, GetFNames (objf));
}
do /* Loop to seek past line numbers */
{
if (!FGetL (objf, &lnr)) /* Read next line number ref from objf*/
{
/* Failed on read file */
RETERR (15, GetFNames (objf));
}
}
while (lnr != 0L); /* 0L if end of line number list */
curpos = FTell (objf); /* Get current file position */
/* Test to see if func.name is allready stored in sortfile */
if (!IsItemInFile (sortf, fname, MAXFUNCN + 1, *fnr, &res))
{
/* Failed on read file */
RETERR (15, GetFNames (sortf));
}
if (res) /* Is function name allready stored */
{
continue; /* Yes, so do not store it again */
}
/* Making list of different calls */
Display (D_LOW, "%s (%s)", _StrMSGMAKEDIFFCALF, fname);
/* Join name of file into sortfile */
if (FWrite (fname, MAXFUNCN + 1, 1, sortf) != 1)
{
/* Failed on write to file */
RETERR (3, GetFNames (sortf));
}
*fnr += 1; /* Count number of func. calls in prj */
}
return (OK); /* OK join of function call names */
} /* JoinSortFunCalInfo_ (); */
int JoinFunCalMakIndx ( FILE *sortf, FILE *indxf, long fnr )
/*
Function: Make indexes to all blocks of function calls in each
objectfile in whole project.
Programmed by: LEL
Date: April, 22. 1993. 20:20.
Interface: sortf = Open and sorted file of function call names.
indxf = Open and newly created file to store index data.
fnr = Number of items in 'sortf'.
Returns: E/O.
*/
{
int filec = 0; /* Count number of files in project */
FILE *objf; /* Active objectfile */
prjfeTYPE fdata; /* Data about active objectfile */
/* Fix the size of 'indxf' so that there already has been written the
necessary number of characters to the file, where all characters
wrote is 0.
The minimum number of such characters wrote must be:
sizeof (long) * |Each index pointer use a long int.
prjstat.filc * |Number of files in active project.
fnr |Number of different names of function calls.
Then, the found indexes can be written directly into its right
position on file. */
if (!FAddDummy (indxf, sizeof (long) * prjstat.filc * fnr, 0))
{
/* Failed on write to file */
RETERR (3, GetFNames (indxf));
}
/* Makes indexes of function calls */
Display (D_HEIGH, "%s", _StrMSGMAKINDXFCAL);
while (filec++ < prjstat.filc) /* Loop trough all files in project */
{
/* Makes indexes of function calls */
Display (D_LOW, "%s (%d/%d)", _StrMSGMAKINDXFCAL,
filec, prjstat.filc);
/* Get data about active objectfile */
if (!GetFDataFromPrj (filec, &fdata))
{
RETURN_ERR;
}
/* Open active objectfile */
if ((objf = FOpen (fdata.objn, "r+b")) == NULL)
{
/* Failed on open file! */
RETERR (16, fdata.objn);
}
/* Make indexes to active objectfile */
if (!JoinFunCalMakIndx_ (sortf, indxf, objf, fnr, filec, &fdata.fpos))
{
FClose (objf); /* Close active objectfile if error */
RETURN_ERR;
}
FClose (objf); /* Close active objectfile */
}
return (OK); /* OK construct of index-table */
} /* JoinFunCalMakIndx (); */
int JoinFunCalMakIndx_ ( FILE *sortf, FILE *indxf, FILE *objf,
long fnr, int objfnr, fposTYPE *fpos )
/*
Function: Kernel function of 'JoinFunCalMakIndx ()'.
Make indexes to all blocks of function calls in active
(specified) objectfile.
Programmed by: LEL
Date: April, 22. 1993. 21:10.
Interface: sortf = Open and sorted file of function call names.
indxf = Open and size-fixed file to store index data.
objf = Active objectfile.
fnr = Number of items in sortfile.
objfnr = Number of active objectfile (1..).
Returns: E/O.
*/
{
char fname[MAXFUNCN + 1]; /* Temporary store name of active func*/
long curpos; /* Current position in file */
long indxpos; /* Store index position in sortfile */
long linenr; /* Dummy store line number ref. */
FSeek (objf,fpos->funcal,SEEK_SET); /* Place file to start of funccall.inf*/
curpos = FTell (objf); /* Now, points at start of data */
while (curpos < fpos->idlst) /* Next datablock is item.ref */
{
/* Read name of function call */
if (!FGetS0 (fname, MAXFUNCN + 1, objf))
{
/* Failed on read file */
RETERR (15, GetFNames (objf));
}
/* Get index of where the name is stored */
if (!IsItemInFile (sortf, fname, MAXFUNCN + 1, fnr, &indxpos))
{
/* Failed on read file */
RETERR (15, GetFNames (sortf));
}
if (indxpos == 0) /* Did we find func. name in sortfile?*/
{
/* Error in objfile: Missing functionname in sortfile */
RETERR (5, NULL); /* 5 = A rare error due to a bug ... */
}
if (!FSeek (indxf,
/* Calc index to index-file of where to store index to
where active funcname is called in active objectfile: */
sizeof (long) *
((prjstat.filc * (indxpos - 1)) + (objfnr - 1)),
SEEK_SET))
{
/* Seek error */
RETERR (13, GetFNames (indxf));
}
/* Pos of where data on this function start */
curpos = FTell (objf);
/* Write this index-adress to indxfile */
if (FWrite (&curpos, sizeof (long), 1, indxf) != 1)
{
/* Failed on write to file */
RETERR (3, GetFNames (indxf));
}
do /* Do a dummy seek past line numbers */
{
/* Read next line number reference */
if (FRead (&linenr, sizeof (long), 1, objf) != 1)
{
/* Failed on read file */
RETERR (15, GetFNames (objf));
}
}
while (linenr != 0L); /* 0L if end of line number list */
curpos = FTell (objf); /* Get filpos to test if end of block */
}
return (OK); /* OK make of indexes */
} /* JoinFunCalMakIndx_ (); */
int JoinIdLstInfo ( FILE *tmpf )
/*
Function: Join block of item info from all objectfiles in
active project, into the specified big temporary objectfile.
Programmed by: LEL
Date: April, 23. 1993. 13:50.
Interface: tmpf = Open big temporary object file to update.
Returns: E/O.
*/
{
long inr; /* Number of items in project */
FILE *sortf;
FILE *indxf;
/* Open the temporary sortfile */
if ((sortf = FOpen (tmpn.sortfi, "w+b")) == NULL)
{
/* Failed on open temporary file! */
RETERR (11, tmpn.sortfi);
}
/* Collect and sort items */
if (!JoinSortIdLstInfo (sortf, &inr))
{
FClose (sortf); /* Close temporary sortfile if error */
RETURN_ERR;
}
/* Create and open index-file */
if ((indxf = FOpen (tmpn.indexf, "w+b")) == NULL)
{
FClose (sortf); /* Close temporary sortfile if error */
RETURN_ERR;
}
/* Make indexes to item-names */
if (!JoinIdLstMakIndx (sortf, indxf, inr))
{
FClose (sortf); /* Close temporary sortfile if error */
FClose (indxf); /* Close temporary indexfile if error */
RETURN_ERR;
}
/* Join sorted items into 'tmpf' */
if (!JoinIdLstInfo_ (tmpf, sortf, indxf, inr))
{
FClose (sortf); /* Close temporary sortfile if error */
FClose (indxf); /* Close temporary indexfile if error */
RETURN_ERR;
}
FClose (sortf); /* Close temporary sortfile */
FClose (indxf); /* Close temporary indexfile */
return (OK); /* OK join of item info */
} /* JoinIdLstInfo (); */
int JoinIdLstInfo_ ( FILE *tmpf, FILE *sortf, FILE *indxf, long inr )
/*
Function: Kernel function of 'JoinIdLstInfo ()'.
Join item data from all objectfiles in project,
into the specified big main temporary objectfile.
The names is joined into 'tmpf' in same order as names in
specified sortfile.
Programmed by: LEL
Date: April, 23. 1993. 13:55.
Interface: tmpf = Open big temporary object file to update.
sortf = Open file of sorted function call names.
indxf = File with stored indexes to func.cal-info in
every object files in project.
inr = Number of different item names in project.
Returns: E/O.
*/
{
int filec; /* Count number of files in project */
long linnr; /* Store red line number */
long globlin; /* Count global line number */
long faddr; /* Index to item lines in obj.file */
char iname [MAXFUNCN + 1]; /* Buffer to store active item name */
FILE *objf; /* Active objectfile */
prjfeTYPE fdata; /* Data on active objectfile in prjfil*/
/* Be sure filpointer on start of file */
FSeek (sortf, 0L, SEEK_SET);
FSeek (indxf, 0L, SEEK_SET);
/* Collects list of items */
Display (D_HEIGH, "%s", _StrMSGINCLIDDATA);
while (inr--) /* Loop to seek all item names */
{
/* Collects list of items */
Display (D_LOW, "%s (%ld)", _StrMSGINCLIDDATA, inr + 1);
/* Get name of next item */
if (FRead (&iname, MAXFUNCN + 1, 1, sortf) != 1)
{
/* Failed on read file */
RETERR (15, GetFNames (sortf));
}
/* Write name of item to main obj */
if (!FPrintF (tmpf, "%s%c", iname, 0))
{
/* Failed on write to file */
RETERR (3, GetFNames (tmpf));
}
globlin = 0; /* Reset global line number first file*/
filec = 0; /* Reset counter to active file */
while (filec++ < prjstat.filc) /* Loop trough all files in project */
{
/* Get data about active objectfile */
if (!GetFDataFromPrj (filec, &fdata))
{
RETURN_ERR;
}
if (!FGetL (indxf, &faddr)) /* Index to where this item is in objf*/
{
/* Failed on read file */
RETERR (15, GetFNames (indxf));
}
if (faddr == 0L) /* No use of this item in this objf */
{
globlin += fdata.finf.ltot;/* Count global line number */
continue; /* So, continue to next obj.file-index*/
}
/* Open active objectfile (read binary file) */
if ((objf = FOpen (fdata.objn, "r+b")) == NULL)
{
/* Failed on open file! */
RETERR (16, fdata.objn);
}
FSeek (objf, faddr, SEEK_SET);/* Point to actual item in obj.file */
while (1) /* Loop to get line nubers from objf */
{
if (!FGetL (objf, &linnr)) /* Get next line number reference */
{
FClose (objf); /* Close current objectfile if error */
/* Failed on read file */
RETERR (15, GetFNames (objf));
}
if (linnr == 0L) /* A 0L mark end of line number list */
{
break; /* So, break line-reading loop */
}
linnr += globlin; /* Convert to global line number */
if (!FPutL (tmpf, linnr)) /* Join line number to main objectfile*/
{
FClose (objf); /* Close current objectfile if error */
/* Failed on write to file */
RETERR (3, GetFNames (tmpf));
}
};
globlin += fdata.finf.ltot; /* Count global line number */
FClose (objf); /* Close active objectfile */
}
if (!FPutL (tmpf, 0L)) /* 0L mark end of line number list */
{
/* Failed on write to file */
RETERR (3, GetFNames (tmpf));
}
}
return (OK);
} /* JoinIdLstInfo_ (); */
int JoinSortIdLstInfo ( FILE *sortf, long *inr )
/*
Function: Find names of items in all objectfiles in active
project, join all the names together in 'sortf' and
sort them in alfabetical order.
Programmed by: LEL
Date: April, 23. 1993. 14:00.
Interface: sortf = Newly created temporary file to use when sort.
inr = Returns number of different items in project.
Returns: E/O.
*/
{
int filc = 0; /* Count number of source in project */
FILE *objf; /* Active objectfile in project */
prjfeTYPE fdata; /* Data about actice objectfile */
*inr = 0; /* Reset number of items in project */
while (filc++ < prjstat.filc) /* Loop trough all files in project */
{
/* Read data about active file in prj */
if (!GetFDataFromPrj (filc, &fdata))
{
RETURN_ERR;
}
/* Open active objectfile */
if ((objf = FOpen (fdata.objn, "r+b")) == NULL)
{
/* Failed on open file! */
RETERR (16, fdata.objn);
}
/* Join item names from objectfile */
if (!JoinSortIdLstInfo_ (sortf, objf, inr, &fdata.fpos))
{
FClose (objf); /* Close active objectfile if error */
RETURN_ERR;
}
FClose (objf); /* Close objectfile after use */
}
/* Sorts list of items */
Display (D_HEIGH, "%s", _StrMSGSORTIDLST);
if (!sortfile (sortf, MAXFUNCN + 1)) /* Sort item names in sortfile */
{
/* Failed on sort contents of file! */
RETERR (12, GetFNames (sortf));
}
return (OK); /* OK sort of item info */
} /* JoinSortIdLstInfo (); */
int JoinSortIdLstInfo_ ( FILE *sortf, FILE *objf, long *inr, fposTYPE *fpos )
/*
Function: Kernel function of 'JoinSortIdLstInfo ()'.
Do the work to get item names from active
objectfile, and join these names into sortfile.
Programmed by: LEL
Date: April, 23. 1993. 14:05.
Interface: sortf = Temporary file to use when sort.
objf = Newly opened active objectfile.
inr = Count number of different item names in project.
fpos = Indexes to blocks of data in objectfile.
Returns: E/O.
*/
{
char iname [MAXFUNCN+1]; /* Buffer to store active item name */
long res; /* Temporary store result of a test */
long lnr; /* Buffer to store last red line nr */
long curpos; /* Current file position */
FSeek (objf, fpos->idlst, SEEK_SET);/* Index to start of item info */
/* Makes list of different items */
Display (D_HEIGH, "%s", _StrMSGMAKEDIFIDF);
curpos = FTell (objf);
while (curpos < fpos->lininf) /* Loop trough all items in objfile */
{
memset (iname, 0, MAXFUNCN + 1); /* To prevent packmans in sortfile */
/* Get next name of item from objfile */
if (!FGetS0 (iname, MAXFUNCN + 1, objf))
{
/* Failed on read file */
RETERR (15, GetFNames (objf));
}
do /* Loop to seek past line numbers */
{
if (!FGetL (objf, &lnr)) /* Read next line number ref from objf*/
{
/* Failed on read file */
RETERR (15, GetFNames (objf));
}
}
while (lnr != 0L); /* 0L if end of line number list */
curpos = FTell (objf); /* Get current file position */
/* Test to see if item name is allready stored in sortfile */
if (!IsItemInFile (sortf, iname, MAXFUNCN + 1, *inr, &res))
{
/* Failed on read file */
RETERR (15, GetFNames (sortf));
}
if (res) /* Is item name allready stored */
{
continue; /* Yes, so do not store it again */
}
/* Makes list of different items */
Display (D_LOW, "%s (%s)", _StrMSGMAKEDIFIDF, iname);
/* Join name of item into sortfile */
if (FWrite (iname, MAXFUNCN + 1, 1, sortf) != 1)
{
/* Failed on write to file */
RETERR (3, GetFNames (sortf));
}
*inr += 1; /* Count number of items in project */
}
return (OK); /* OK join of item names */
} /* JoinSortIdLstInfo_ (); */
int JoinIdLstMakIndx ( FILE *sortf, FILE *indxf, long inr )
/*
Function: Make indexes to all blocks of items in each
objectfile in whole project.
Programmed by: LEL
Date: April, 23. 1993. 14:10.
Interface: sortf = Open and sorted file of function call names.
indxf = Open and newly created file to store index data.
inr = Number of items in 'sortf'.
Returns: E/O.
*/
{
int filec = 0; /* Count number of files in project */
FILE *objf; /* Active objectfile */
prjfeTYPE fdata; /* Data about active objectfile */
/* Fix the size of 'indxf' so that there already has been written the
necessary number of characters to the file, where all characters
wrote is 0.
The minimum number of such characters wrote must be:
sizeof (long) * |Each index pointer use a long int.
prjstat.filc * |Number of files in active project.
inr |Number of different names of items.
Then, the found indexes can be written directly into its right
position on file. */
if (!FAddDummy (indxf, sizeof (long) * prjstat.filc * inr, 0))
{
/* Failed on write to file */
RETERR (3, GetFNames (indxf));
}
/* Makes indexes to items */
Display (D_HEIGH, "%s", _StrMSGMAKINDXIDLST);
while (filec++ < prjstat.filc) /* Loop trough all files in project */
{
/* Makes indexes to items */
Display (D_LOW, "%s (%d/%d)", _StrMSGMAKINDXIDLST, filec, prjstat.filc);
/* Get data about active objectfile */
if (!GetFDataFromPrj (filec, &fdata))
{
RETURN_ERR;
}
/* Open active objectfile */
if ((objf = FOpen (fdata.objn, "r+b")) == NULL)
{
/* Failed on open file! */
RETERR (16, fdata.objn);
}
/* Make indexes to active objectfile */
if (!JoinIdLstMakIndx_ (sortf, indxf, objf, inr, filec, &fdata.fpos))
{
FClose (objf); /* Close active objectfile if error */
RETURN_ERR;
}
FClose (objf); /* Close active objectfile */
}
return (OK); /* OK construct of index-table */
} /* JoinIdLstMakIndx (); */
int JoinIdLstMakIndx_ ( FILE *sortf, FILE *indxf, FILE *objf,
long inr, int objfnr, fposTYPE *fpos )
/*
Function: Kernel function of 'JoinIdLstMakIndx ()'.
Make indexes to all blocks of items in active
(specified) objectfile.
Programmed by: LEL
Date: April, 23. 1993. 14:13.
Interface: sortf = Open and sorted file of function call names.
indxf = Open and size-fixed file to store index data.
objf = Active objectfile.
inr = Number of items in sortfile.
objfnr = Number of active objectfile (1..).
Returns: E/O.
*/
{
char iname[MAXFUNCN + 1]; /* Temporary store name of active item*/
long curpos; /* Current position in file */
long indxpos; /* Store index position in sortfile */
long linenr; /* Dummy store line number ref. */
FSeek (objf, fpos->idlst, SEEK_SET);/* Place file to start of item info */
curpos = FTell (objf); /* Now, points at start of data */
while (curpos < fpos->lininf) /* Next datablock is line info */
{
/* Read name of item */
if (!FGetS0 (iname, MAXFUNCN + 1, objf))
{
/* Failed on read file */
RETERR (15, GetFNames (objf));
}
/* Get index of where the name is stored */
if (!IsItemInFile (sortf, iname, MAXFUNCN + 1, inr, &indxpos))
{
/* Failed on read file */
RETERR (15, GetFNames (sortf));
}
if (indxpos == 0) /* Did we find item name in sortfile? */
{
/* Error in objfile: Missing itemname in sortfile */
RETERR (5, NULL); /* A rare error due to a bug in the program ... */
}
if (!FSeek (indxf,
/* Calc index to index-file of where to store index to
where active item name is used in active objectfile: */
sizeof (long) *
(prjstat.filc * (indxpos - 1) + (objfnr - 1)),
SEEK_SET))
{
/* Seek error */
RETERR (13, GetFNames (indxf));
}
/* Pos of where data of this item start */
curpos = FTell (objf);
/* Write this index-adress to indxfile */
if (FWrite (&curpos, sizeof (long), 1, indxf) != 1)
{
/* Failed on write to file */
RETERR (3, GetFNames (indxf));
}
do /* Do a dummy seek past line numbers */
{
/* Read next line number reference */
if (FRead (&linenr, sizeof (long), 1, objf) != 1)
{
/* Failed on read file */
RETERR (15, GetFNames (objf));
}
}
while (linenr != 0L); /* 0L if end of line number list */
curpos = FTell (objf); /* Get filpos to test if end of block */
}
return (OK); /* OK make of indexes */
} /* JoinIdLstMakIndx_ (); */