home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / smapp100.zip / sm10.zip / smgcontf.c < prev    next >
C/C++ Source or Header  |  2000-05-14  |  70KB  |  2,015 lines

  1. /* ------------------------------------------------------------------------
  2.  *
  3.  *        File: smgcontf.c 
  4.  *     Project: Source Mapper.
  5.  *     Created: June 5, 1992.
  6.  * Description: Kildekode for å koble midlertidige mellomfiler til
  7.  *              endelig mellomfil (CONnect from Temporary Files).
  8.  *              Her er også inkludert kode for å skj¢te mellomfiler i
  9.  *              activt prosjekt til den store og midlertidige totale
  10.  *              mellomfilen som brukes under selve genereringen av kart.
  11.  *
  12.  * Copyright (C) 2000 Leif-Erik Larsen.
  13.  * This file is part of the Source Mapper source package.
  14.  * Source Mapper is free software; you can redistribute it and/or modify
  15.  * it under the terms of the GNU General Public License as published
  16.  * by the Free Software Foundation, in version 2 as it comes in the
  17.  * "COPYING" file of the XWorkplace main distribution.
  18.  * This program is distributed in the hope that it will be useful,
  19.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  * GNU General Public License for more details.
  22.  *
  23.  * ------------------------------------------------------------------------ */
  24.  
  25.  
  26.  
  27.  
  28. #include "smg.h"
  29.  
  30.  
  31.  
  32.  
  33. int ConnectTempFiles ( char *sfnam, finfTYPE *finf )
  34. /* Opprettet: Fredag 5. juni 1992.
  35.    Parameter: "sfnam" Navn/katalog til kildefil.
  36.               "finf"  Struktur med informasjon om kildefilen, etter tolking.
  37.    Retur    : E/O.
  38.    Beskriv  : Kobler de midlertidige mellomfilene (som holder den grove
  39.               og ubehandlede informasjonen etter tolking av kildefil) til
  40.               den endelige mellomfilen. Ingen av de midlertidige filene
  41.               slettes eller stenges i denne funksjonen. Dette må derfor
  42.               gj¢res hos kalleren, etter at denne funksjonen er ferdig.
  43. */
  44. {
  45.    fposTYPE fpos;                      /* Lagrer filposisjon til datagrupper */
  46.  
  47.    /* Lagre filkjennemerke og kildefilnavn, til endelig mellomfil: */
  48.    FPrintF (tempf, "%s%c%s%c", _StrMSGTEMPFILEID, EOFCHR, sfnam, '\0');
  49.  
  50.    /* Lagre total kildefilinformasjon, til endelig mellomfil: */
  51.    fpos.finf = FTell (tempf);
  52.    FWrite (finf, sizeof (finfTYPE), 1, tempf);
  53.  
  54.    if (errno != 0)
  55.    {
  56.       /* Failed on write to file! */
  57.       RETERR (3, GetFNames (tempf));
  58.    }
  59.  
  60.    /* Lagre informasjon om funksjoner, til endelig mellomfil: */
  61.    fpos.funreg = FTell (tempf);
  62.    if (!ConnectFunReg (finf->func))
  63.    {
  64.       RETURN_ERR;
  65.    }
  66.  
  67.    /* Lagre informasjon om funksjonskall, til endelig mellomfil: */
  68.    fpos.funcal = FTell (tempf);
  69.    if (!ConnectFunCal (finf->fcal))
  70.    {
  71.       RETURN_ERR;
  72.    }
  73.  
  74.    /* Lagre informasjon om identifikatorer, til endelig mellomfil: */
  75.    fpos.idlst = FTell (tempf);
  76.    if (!ConnectIdLst (finf->cid))
  77.    {
  78.       RETURN_ERR;
  79.    }
  80.  
  81.    /* Lagre informasjon om kildefil-linjer, til endelig mellomfil: */
  82.    fpos.lininf = FTell (tempf);
  83.    if (!ConnectLinInf (finf->ltot))
  84.    {
  85.       RETURN_ERR;
  86.    }
  87.  
  88.    /* Lagre startposisjoner til datagrupper i endelig mellomfil: */
  89.    FWrite (&fpos, sizeof (fposTYPE), 1, tempf);
  90.  
  91.    return (OK);
  92. } /* ConnectTempFiles (); */
  93.  
  94.  
  95.  
  96.  
  97. int ConnectIdLst ( uint32 count )
  98. /* Opprettet: L¢rdag 6. juni 1992.
  99.    Parameter: "count" Antall elementer i den globale filen "idlistf".
  100.    Retur    : E/O.
  101.    Beskriv  : Kobler den midlertidige mellomfilen "idlistf" (som holder den
  102.               grove og ubehandlede informasjonen om identifikatorer etter
  103.               tolking av kildefil) til den endelige mellomfilen.
  104. */
  105. {
  106.    FILE *diffidf;                      /* Fil for liste over navn */
  107.  
  108.    /* Produser mellomfilen som skal midlertidig holde liste over
  109.       alle forskjellige identifikatorer i kildefilen: */
  110.    if (!MakeDiffIdF (idlistf, sizeof (idlstTYPE),
  111.                               count, _StrMSGMAKEDIFIDF))
  112.    {
  113.       RETURN_ERR;
  114.    }
  115.  
  116.    /* Åpner den produserte midlertidige filen med navnliste: */
  117.    if ((diffidf = FOpen (tmpn.sortfi, "r+b")) == NULL)
  118.    {
  119.       /* Failed on open temporary file! */
  120.       RETERR (11, tmpn.sortfi);
  121.    }
  122.  
  123.    /* Sorter filen med liste over alle forskjellige identifikatorer: */
  124.    Display (D_HEIGH, "%s", _StrMSGSORTIDLST);
  125.    if (!sortfile (diffidf, MAXFUNCN + 1))
  126.    {
  127.       FClose (diffidf);
  128.       RETERR (12, tmpn.sortfi);
  129.    }
  130.  
  131.    /* Samle data om identifikatorer: */
  132.    if (!ConnectIdLst_ (diffidf))
  133.    {
  134.       FClose (diffidf);
  135.       RETURN_ERR;
  136.    }
  137.  
  138.    /* Lukk midlertidig fil for lagring av forskjellige identifikatorer */
  139.    FClose (diffidf);
  140.  
  141.    return (OK);
  142. } /* ConnectIdLst (); */
  143.  
  144.  
  145.  
  146.  
  147. int ConnectIdLst_ ( FILE *diffidf )
  148. /* Opprettet: Tirsdag 9. mars 1993.
  149.    Parameter: "diffidf" Fil med liste over alle forskjellige identifikatorer.
  150.    Retur    : E/O.
  151.    Beskriv  : Kjernen til "ConnectIdLst ()". Tar seg av styring for
  152.               å samle data om identifikatorer. Det forutsettes at det
  153.               allerede er produsert en midlertidig fil med liste over
  154.               alle forskjellige identifikatorer ("fiffidf") og at
  155.               denne er åpen for lesing.
  156. */
  157. {
  158.    char       idnam [MAXFUNCN + 1];    /* Ved lesing av id.navn fra fil */
  159.    long       c1 = 0;                  /* Skal telle aktiv identifikator */
  160.    long       countid;                 /* Antall id i liste over forskjel. id*/
  161.    long       flen;                    /* Antall byte i fil */
  162.    idbuffTYPE idbuff;
  163.  
  164.    /* Number of bytes in file of different identifiers */
  165.    if ((countid = FLength (diffidf)) == -1L)
  166.    {
  167.       /* Seek error! */
  168.       RETERR (13, GetFNames (diffidf));
  169.    }
  170.  
  171.    countid /= MAXFUNCN + 1;            /* Calc number of different items     */
  172.    if (countid == 0)                   /* Any ID's?                          */
  173.    {
  174.       return (OK);                     /* No, return without connect         */
  175.    }
  176.  
  177.    /* Lagre linjenummer hvor de forskjellige identifikatorene brukes: */
  178.  
  179.    Rewind (diffidf);                   /* Samtlige forskjellige id skal leses*/
  180.  
  181.    /* Info til bruker: Samler data om forek. av id */
  182.    Display (D_HEIGH, "%s", _StrMSGINCLIDDATA);
  183.  
  184.    /* Number of bytes in file */
  185.    if ((flen = FLength (idlistf)) == -1L)
  186.    {
  187.       /* Seek error! */
  188.       RETERR (13, GetFNames (idlistf));
  189.    }
  190.  
  191.    if (flen > MemLeft () - 1000)       /* Enough free memory to store items? */
  192.    {
  193.       /* Out of memory! */
  194.       RETERR (14, NULL);
  195.    }
  196.  
  197.    /* Get memory to store whole item-list */
  198.    if ((idbuff.buff = Alloc (flen)) == NULL)
  199.    {
  200.       /* Out of memory! */
  201.       RETERR (14, NULL);
  202.    }
  203.  
  204.    /* Number of items to store in buffer */
  205.    idbuff.cidb = (uint16) (flen / sizeof (idlstTYPE));
  206.  
  207.    Rewind (idlistf);                   /* Place file pointer to start of file*/
  208.  
  209.    /* Read list of items from file */
  210.    FRead  (idbuff.buff, sizeof (idlstTYPE), idbuff.cidb, idlistf);
  211.  
  212.    /* Loop to write the name of every identifier + line numbers */
  213.    while (FRead (&idnam, MAXFUNCN + 1, 1, diffidf) > 0)
  214.    {
  215.       /* Write name of item and a zero to separate */
  216.       FPrintF (tempf, "%s%c", idnam, 0);
  217.  
  218.       if (errno != 0)                  /* Any error?                         */
  219.       {
  220.          Free (idbuff.buff);           /* Give allocated memory back to heap */
  221.  
  222.          /* Failed on write to file! */
  223.          RETERR (3, GetFNames (tempf));
  224.       }
  225.  
  226.       /* Finn alle forekomster av aktiv id, og lagre linjenummer/data
  227.          i den endelige mellomfilen, fortl¢pende bak selve id-navnet:        */
  228.       if (!ConnectIdLstData (idnam, &idbuff))
  229.       {
  230.          Free (idbuff.buff);           /* Gi allokert minne tilbake til hop  */
  231.          RETURN_ERR;
  232.       }
  233.  
  234.       /* Write a long zero to mark the end of this list of line numbers */
  235.       FPutL (tempf, 0L);
  236.  
  237.       if (++c1 % 7 == 0)               /* Oppdater brukerinfo for hver 7:    */
  238.          Display (D_LOW, "%s: %d%%", _StrMSGINCLIDDATA, (c1 * 100) / countid);
  239.    }
  240.  
  241.    Free (idbuff.buff);                 /* Gi allokert minne tilbake til hop  */
  242.    Display (D_LOW, "%s: 100%%", _StrMSGINCLIDDATA); /* 100% has finished */
  243.  
  244.    return (OK);
  245. } /* ConnectIdLst_ (); */
  246.  
  247.  
  248.  
  249.  
  250. int ConnectIdLstData ( char *id, idbuffTYPE *idbuff )
  251. /* Opprettet: L¢rdag 6. juni 1992.
  252.    Parameter: "id"     Identifikator det skal s¢kes etter.
  253.               "idbuff" Struktur med id-buffer og info om antall id'er.
  254.    Retur    : E/O.
  255.    Beskriv  : Skanner gjennom "idlstf" etter identifikatoren "id", og skj¢ter
  256.               in fortl¢pende informasjon om data/linjenummer til den
  257.               aktuelle identifikatoren. Informasjonen skj¢tes til
  258.               mellomfilen "tempf".
  259.  
  260.               Viktig: Det er optil kaller å f¢lge med på den globalt
  261.                       deklarerte strukturen "idbuff". At det allokeres
  262.                       minne til den f¢r "connect_idlstdata ()"
  263.                       kalles f¢rste gang og at det allokerte minnet gis
  264.                       tilbake til hopen etter at "connect_idlstdata ()" er
  265.                       kallt for siste gang.
  266. */
  267. {
  268.    uint16          idc = 0;            /* Nummer til aktiv i i buffer (0..)  */
  269.    idlstTYPE huge *idlst;              /* Pointer to current id              */
  270.  
  271.    idlst = (idlstTYPE *) idbuff->buff; /* Initier peker til buffer           */
  272.    while (idc < idbuff->cidb)          /* S¢k gjennom samtlige id'er i buffer*/
  273.    {
  274.       /* Active item equal to actual item? */
  275.       if (strcmp (id, idlst->name) == 0)
  276.       {
  277.          /* Lagre linjenummer til mellomfil */
  278.          if (FWrite (&idlst->lnr, sizeof (idlst->lnr), 1, tempf) != 1)
  279.          {
  280.             /* Failed on write to file! */
  281.             RETERR (3, GetFNames (tempf));
  282.          }
  283.  
  284.          if (o_idlist.riselnr == O_YES)/* Any respect to rising line numbers?*/
  285.          {
  286.             idc++;                     /* Next item in buffer                */
  287.             idlst++;
  288.             continue;                  /* Don't optimize buffer if O_YES     */
  289.          }
  290.  
  291.          /* Decrementer antall id'er i buffer, siden siste skal flyttes:     */
  292.          idbuff->cidb--;
  293.  
  294.          /* Flytt bakerste id i buffer til aktiv bufferposisjon, siden
  295.             aktiv id i bufferposisjon herved er inkludert i mellomfil.
  296.             Så trenger vi ikke aktiv id lenger, og vi sparer tid ved å
  297.             slette den og gi bort bufferposisjonen til bakerste id istedet:  */
  298.          memcpy (idlst,
  299.                  ADRESS (idbuff->buff, idbuff->cidb, sizeof (idlstTYPE)),
  300.                  sizeof (idlstTYPE));
  301.  
  302.          /* Fortsett loop fra og med id som nylig ble flyttet fram i buffer: */
  303.          idc--;
  304.          idlst--;
  305.       }
  306.  
  307.       idc++;                           /* Next item in buffer                */
  308.       idlst++;
  309.    }
  310.  
  311.    return (OK);
  312. } /* ConnectIdLstData (); */
  313.  
  314.  
  315.  
  316.  
  317. int MakeDiffIdF ( FILE *idf, int esize, uint32 count, char *userinf )
  318. /* Opprettet: L¢rdag 6. juni 1992.
  319.    Parameter: "idf"     Midlertidig fil for data om id'er/funksjonskall.
  320.               "esize"   St¢rrelsen til hvert element i "idf", i byte.
  321.               "count"   Antall elementer i "idf".
  322.               "userinf" Streng med informasjon til bruker om arbeidsmengde.
  323.    Retur    : E/O.
  324.    Beskriv  : Scanner "idf" og lager en liste over alle forskjellige
  325.               identifikatorer i denne filen. Listen lagres i en midlertidig
  326.               fil og i standard katalog for midlertidige mellomfiler.
  327.               Listen sorteres ikke her.
  328. */
  329. {
  330.    char   buff [BIGGEST_SCANSTRUC];    /* For storing element from "idf" */
  331.    uint16 answ;                        /* For lagring av testresultat */
  332.    uint32 c1 = 0;                      /* Skal telle aktive identifikatorer */
  333.  
  334.    Display (D_HEIGH, "%s", userinf);   /* Info til bruker om oppgave */
  335.  
  336.    Rewind (idf);                       /* Tilbakestill filpeker */
  337.  
  338.    /* Initier og alloker midlertidig tabell for liste over forskjellige navn:*/
  339.    if (!DiffBConstruct (tmpn.sortfi, MAXFUNCN + 1))
  340.    {
  341.       RETURN_ERR;
  342.    }
  343.  
  344.    /* Scan all elements in "idf" */
  345.    while (FRead (&buff, esize, 1, idf) > 0)
  346.    {
  347.       /* Sjekk om navnet allerede finnes i listen: */
  348.       if (!DiffBIfId (buff, &answ))
  349.       {
  350.          DiffBDestruct ();
  351.          RETURN_ERR;
  352.       }
  353.  
  354.       /* Lagre navnet i listen, dersom det ikke finnes der fra f¢r: */
  355.       if (answ == 0)
  356.       {
  357.          if (!DiffBAddId (buff))
  358.          {
  359.             DiffBDestruct ();
  360.             RETURN_ERR;
  361.          }
  362.       }
  363.  
  364.       if (++c1 % 27 == 0)              /* Oppdater brukerinfo for hver 27. */
  365.       {
  366.          /* Info til bruker (% ferdig) */
  367.          Display (D_LOW, "%s: %d%%", userinf, (c1 * 100) / count);
  368.       }
  369.    }
  370.  
  371.    /* Avslutt midlertidig tabell for liste over forskjellige navn: */
  372.    if (!DiffBDestruct ())
  373.    {
  374.       RETURN_ERR;
  375.    }
  376.  
  377.    if (errno != 0)                     /* Hvis feil ved ved "FRead ()" */
  378.    {
  379.       /* Failed on read file! */
  380.       RETERR (15, GetFNames (idf));
  381.    }
  382.  
  383.    Display (D_LOW, "%s: 100%%", userinf); /* 100% has finished */
  384.  
  385.    return (OK);
  386. } /* MakeDiffIdF (); */
  387.  
  388.  
  389.  
  390.  
  391. int ConnectFunCal ( uint32 count )
  392. /* Opprettet: S¢ndag 7. juni 1992.
  393.    Parameter: "count" Antall elementer i "funcalf".
  394.    Retur    : E/O.
  395.    Beskriv  : Kobler den midlertidige mellomfilen "funcalf" (som holder den
  396.               grove og ubehandlede informasjonen om funksjonskall etter
  397.               tolking av kildefil) til den endelige mellomfilen.
  398. */
  399. {
  400.    char  funcnam [MAXFUNCN + 1];       /* Ved lesing av navn fra fil */
  401.    FILE *diffidf;                      /* Fil for lagring av liste */
  402.    long  c1 = 0;                       /* Skal telle aktiv funksjonskall */
  403.    long  countfunc;                    /* Antall funksjonskall i "funcalf" */
  404.  
  405.    /* Produser mellomfilen som skal midlertidig holde liste over
  406.       alle forskjellige funksjonskall i kildefilen: */
  407.    if (!MakeDiffIdF (funcalf, sizeof (fcalTYPE),
  408.                               count, _StrMSGMAKEDIFFCALF))
  409.    {
  410.       RETURN_ERR;
  411.    }
  412.  
  413.    /* Åpne den produserte midlertidige filen med liste over navn: */
  414.    if ((diffidf = FOpen (tmpn.sortfi, "r+b")) == NULL)
  415.    {
  416.       /* Failed on open temporary file! */
  417.       RETERR (11, tmpn.sortfi);
  418.    }
  419.  
  420.    /* Sorter filen med liste over alle forskjellige funksjonskall: */
  421.    Display (D_HEIGH, "%s", _StrMSGSORTFCALLST);
  422.    if (!sortfile (diffidf, MAXFUNCN + 1))
  423.    {
  424.       FClose (diffidf);
  425.  
  426.       /* Failed on sort contents of file! */
  427.       RETERR (12, GetFNames (diffidf));
  428.    }
  429.  
  430.    /* Antall forskjellige navn */
  431.    if ((countfunc = FLength (diffidf) / (MAXFUNCN + 1)) == -1L)
  432.    {
  433.       FClose (diffidf);
  434.  
  435.       /* Seek error! */
  436.       RETERR (13, GetFNames (diffidf));
  437.    }
  438.  
  439.    /* Info til bruker: Samler data om forekomster */
  440.    Display (D_HEIGH, "%s", _StrMSGINCLFCALDATA);
  441.  
  442.    /* Lagre linjenummer/data om de forskjellige funksjonskallene: */
  443.  
  444.    Rewind (diffidf);                   /* Samtlige forskjellige id skal leses*/
  445.  
  446.    /* Loop to write the names of functions + line numbers */
  447.    while (FRead (&funcnam, MAXFUNCN + 1, 1, diffidf) > 0)
  448.    {
  449.       /* Write name of function + a zero to separate */
  450.       if (!FPrintF (tempf, "%s%c", funcnam, 0))
  451.       {
  452.          FClose (diffidf);
  453.  
  454.          /* Failed on write to file! */
  455.          RETERR (3, GetFNames (tempf));
  456.       }
  457.  
  458.       /* Finn alle forekomster av ativt funksjonskall, og lagre
  459.          linjenummer/data i den endelige mellomfilen, fortl¢pende
  460.          bak selve funksjonskall-navnet: */
  461.       if (!ConnectFunCalData (funcnam))
  462.       {
  463.          FClose (diffidf);
  464.          RETURN_ERR;
  465.       }
  466.  
  467.       /* Write a long zero to mark the end of the list of line numbers */
  468.       FPutL (tempf, 0L);
  469.  
  470.       if (++c1 % 7 == 0)                 /* Oppdater brukerinfo for hver 7. */
  471.       {
  472.          /* Info til bruker: Samler data om forekomster (% ferdig) */
  473.          Display (D_LOW, "%s: %d%%", _StrMSGINCLFCALDATA,
  474.                                      (c1 * 100) / countfunc);
  475.       }
  476.    }
  477.  
  478.    if (errno != 0)
  479.    {
  480.       FClose (diffidf);
  481.  
  482.       /* Failed on read file! */
  483.       RETERR (15, GetFNames (diffidf));
  484.    }
  485.  
  486.    Display (D_LOW, "%s: 100%%", _StrMSGINCLFCALDATA); /* 100% ferdig */
  487.  
  488.    /* Lukk midlertidig fil for lagring av forskjellige identifikatorer: */
  489.    FClose (diffidf);
  490.  
  491.    return (OK);
  492. } /* ConnectFunCal (); */
  493.  
  494.  
  495.  
  496.  
  497. int ConnectFunCalData ( char *name )
  498. /* Opprettet: S¢ndag 7. juni 1992.
  499.    Parameter: "name" Navn til funksjonskall som skal s¢kes etter.
  500.    Retur    : E/O.
  501.    Beskriv  : Skanner gjennom "funcalf" etter funksjonskallet "name", og
  502.               skj¢ter in fortl¢pende informasjon om data/linjenummer til
  503.               det aktuelle funksjonskallet. Informasjonen skj¢tes til
  504.               mellomfilen "tempf".
  505. */
  506. {
  507.    fcalTYPE fcal;
  508.  
  509.    Rewind (funcalf);                   /* Id-listen skal s¢kes i fra starten */
  510.  
  511.    while (FRead (&fcal,                /* Les inn et element om gangen */
  512.                  sizeof (fcalTYPE),    /* Antall byte i struktur */
  513.                  1, funcalf) > 0)      /* Les fra funksjonskall-liste-fil */
  514.    {
  515.       /* Hvis innlest element = name */
  516.       if (strcmp (fcal.name, name) == 0)
  517.       {
  518.          /* Adresse til f¢rste data bak navn */
  519.          if (FWrite (&fcal.lnr, sizeof (fcal.lnr), 1, tempf) != 1)
  520.          {
  521.             /* Failed on write to file! */
  522.             RETERR (3, GetFNames (tempf));
  523.          }
  524.       }
  525.    }
  526.  
  527.    if (errno != 0)
  528.    {
  529.       /* Failed on read file! */
  530.       RETERR (15, GetFNames (funcalf));
  531.    }
  532.  
  533.    return (OK);
  534. } /* ConnectFunCalData (); */
  535.  
  536.  
  537.  
  538.  
  539. int ConnectFunReg ( long count )
  540. /* Opprettet: S¢ndag 7. juni 1992.
  541.    Parameter: "count" Antall elementer i "funregf".
  542.    Retur    : E/O.
  543.    Beskriv  : Kobler den midlertidige mellomfilen "funregf" (som holder det
  544.               grove og ubehandlede funksjonsregisteret etter tolking av
  545.               kildefil) til den endelige mellomfilen.
  546. */
  547. {
  548.    funcTYPE func;
  549.    uint32 c1 = 0;                      /* Counter 1, teller aktiv funksjon */
  550.  
  551.    Display (D_HEIGH, "%s", _StrMSGSORTFUNCREG); /* Sorterer funksjonsdata */
  552.    if (!sortfile (funregf, sizeof (funcTYPE)))
  553.    {
  554.       /* Failed on sort contents file! */
  555.       RETERR (12, GetFNames (funregf));
  556.    }
  557.  
  558.    /* Info til bruker: Inkluderer funksjonsdata */
  559.    Display (D_HEIGH, "%s", _StrMSGINCLFUNDATA);
  560.  
  561.    while (FRead (&func, sizeof (funcTYPE), 1, funregf) > 0)
  562.    {
  563.       if (FWrite (&func, sizeof (funcTYPE), 1, tempf) != 1)
  564.       {
  565.          /* Failed on write to file! */
  566.          RETERR (3, GetFNames (tempf));
  567.       }
  568.  
  569.       if (++c1 % 7 == 0 &&             /* Oppdater brukerinfo for hver 7. */
  570.           count > 0)                   /* For å unngå divide error */
  571.       {
  572.          /* Info til bruker: Inkluderer funksjonsdata: (% ferdig) */
  573.          Display (D_LOW, "%s: %d%%", _StrMSGINCLFUNDATA, (c1 * 100) / count);
  574.       }
  575.    }
  576.  
  577.    if (errno != 0)
  578.    {
  579.       /* Failed on read file! */
  580.       RETERR (15, GetFNames (funregf));
  581.    }
  582.  
  583.    Display (D_LOW, "%s: 100%%", _StrMSGINCLFUNDATA); /* 100% ferdig */
  584.  
  585.    return (OK);
  586. } /* ConnectFunReg (); */
  587.  
  588.  
  589.  
  590.  
  591. int ConnectLinInf ( long count )
  592. /* Opprettet: S¢ndag 7. juni 1992.
  593.    Parameter: "count" Antall elementer i "lininff".
  594.    Retur    : E/O.
  595.    Beskriv  : Kobler den midlertidige mellomfilen "lininff" (som holder den
  596.               grove og ubehandlede linjeinformasjonen etter tolking av
  597.               kildefil) til den endelige mellomfilen.
  598. */
  599. {
  600.    scanTYPE  scan;
  601.    uint32 c1 = 0;                      /* Counter 1, teller aktiv linje */
  602.  
  603.    Rewind (lininff);
  604.  
  605.    Display (D_HEIGH, "%s", _StrMSGINCLLINEINFO);
  606.  
  607.    while (FRead (&scan, sizeof (scanTYPE), 1, lininff) == 1)
  608.    {
  609.       if (FWrite (&scan, sizeof (scanTYPE), 1, tempf) != 1)
  610.       {
  611.          /* Failed on write to file! */
  612.          RETERR (3, GetFNames (tempf));
  613.       }
  614.  
  615.       if (++c1 % 51 == 0)               /* Oppdater brukerinfo for hver 51. */
  616.       {
  617.          /* Inkluderer linjeinformasjon: (% ferdig) */
  618.          Display (D_LOW, "%s: %d%%", _StrMSGINCLLINEINFO, (c1 * 100) / count);
  619.       }
  620.    }
  621.  
  622.    if (errno != 0)
  623.    {
  624.       /* Failed on read file! */
  625.       RETERR (15, GetFNames (lininff));
  626.    }
  627.  
  628.    ClrLin ();                          /* T¢m hele linje der cursor er */
  629.  
  630.    return (OK);
  631. } /* ConnectLinInf (); */
  632.  
  633.  
  634.  
  635.  
  636. int JoinObjFiles ( void )
  637. /*
  638.     Function: Join objectfiles of active project into one big
  639.               temporary objectfile.
  640.         Date: April, 21. 1993. 00:45. By LEL.
  641.      Returns: E/O.
  642.      Comment: All sourcefiles in project must have been scanned to legal
  643.               objectfiles before this function is called.
  644. */
  645. {
  646.    int   ok;                           /* Temporary storing return value     */
  647.    FILE *tmpf;                         /* Pointer to the file                */
  648.  
  649.    if (prjstat.filc <= 1)              /* If only one source in project      */
  650.    {
  651.       /* Internal error! (Shall never happen, but in case) */
  652.       RETERR (5, NULL);                /* Must use normal objectfile instead */
  653.    }
  654.  
  655.    if (!MakePrjDataOK ())              /* Be sure all data is updated in prj */
  656.    {
  657.       RETURN_ERR;
  658.    }
  659.  
  660.    /* Open the big temporary objectfile */
  661.    if ((tmpf = FOpen (tmpn.manobj, "w+b")) == NULL)
  662.    {
  663.       RETERR (11, tmpn.manobj);        /* Failed on open temporary file! */
  664.    }
  665.  
  666.    ok = JoinObjFiles_ (tmpf);          /* Do the kernel function             */
  667.  
  668.    FClose (tmpf);                      /* Close the temporary file           */
  669.  
  670.    return (ok);
  671. } /* JoinObjFiles (); */
  672.  
  673.  
  674.  
  675.  
  676. int JoinObjFiles_ ( FILE *tmpf )
  677. /*
  678.     Function: Kernel function of 'JoinObjFiles ()'.
  679.         Date: April, 21. 1993. 01:15. By LEL.
  680.    Interface: tmpf = Newly opened filepointer to temporary big
  681.                      objectfile of whole project.
  682.      Returns: E/O.
  683. */
  684. {
  685.    fposTYPE fpos;                      /* File-indexes to blocks of data     */
  686.  
  687.    /*------------------------------------------------------------------------*/
  688.    fpos.finf = FTell (tmpf);           /* Get start position of source info  */
  689.    if (!JoinSourceInfo (tmpf))         /* Join sourceinfo from objectfiles   */
  690.    {
  691.       RETURN_ERR;
  692.    }
  693.  
  694.    /*------------------------------------------------------------------------*/
  695.    fpos.funreg = FTell (tmpf);         /* Get start pos of function info     */
  696.    if (!JoinFuncInfo (tmpf))           /* Join function info from objectfiles*/
  697.    {
  698.       RETURN_ERR;
  699.    }
  700.  
  701.    /*------------------------------------------------------------------------*/
  702.    fpos.funcal = FTell (tmpf);         /* Get start pos of functioncall info */
  703.    if (o_funcall.incl     == O_YES ||  /* If include list of function calls  */
  704.        o_flow.incl        == O_YES ||  /* or include info of call-sequences  */
  705.        (o_lineinfo.calist == O_YES &&  /* or include list of callers in funcs*/
  706.         o_lineinfo.incl   == O_YES))
  707.    {
  708.       if (!JoinFunCalInfo (tmpf))      /* Join functioncall inf from objfiles*/
  709.       {
  710.          RETURN_ERR;
  711.       }
  712.    }
  713.  
  714.    /*------------------------------------------------------------------------*/
  715.    fpos.idlst = FTell (tmpf);          /* Get start position of item info    */
  716.    if (o_idlist.incl == O_YES)         /* If include list of items           */
  717.    {
  718.       if (!JoinIdLstInfo (tmpf))       /* Join item info from objectfiles    */
  719.       {
  720.          RETURN_ERR;
  721.       }
  722.    }
  723.  
  724.    /*------------------------------------------------------------------------*/
  725.    fpos.lininf = FTell (tmpf);         /* Get start position of line info    */
  726.    if (o_lineinfo.incl == O_YES)       /* If include info of source lines    */
  727.    {
  728.       if (!JoinLineInfo (tmpf))        /* Join line info from objectfiles    */
  729.       {
  730.          RETURN_ERR;
  731.       }
  732.    }
  733.  
  734.    /*------------------------------------------------------------------------*/
  735.    /* Save block of file-positions into temporary big objectfile */
  736.    if (FWrite (&fpos, sizeof (fposTYPE), 1, tmpf) != 1)
  737.    {
  738.       /* Failed on write to file! */
  739.       RETERR (3, GetFNames (tmpf));
  740.    }
  741.  
  742.    return (OK);
  743. } /* JoinObjFiles_ (); */
  744.  
  745.  
  746.  
  747.  
  748. int JoinSourceInfo ( FILE *tmpf )
  749. /*
  750.     Function: Join block of source info from all objectfiles in active
  751.               project, into the specified big temporary objectfile.
  752.         Date: April, 21. 1993. 02:00. By LEL.
  753.    Interface: tmpf = Open big temporary object file to update.
  754.      Returns: E/O.
  755. */
  756. {
  757.    int       countf = 0;               /* Count active objectfile            */
  758.    prjfeTYPE fdata;                    /* Data about active objectfile       */
  759.    finfTYPE  finf;                     /* Info about whole project           */
  760.  
  761.    reset_finftype (&finf);             /* Set all items in stricture to 0    */
  762.  
  763.    while (countf++ < prjstat.filc)     /* All objectfiles in active project  */
  764.    {
  765.       /* Read data about active objectfile  */
  766.       if (!GetFDataFromPrj (countf, &fdata))
  767.       {
  768.          RETURN_ERR;
  769.       }
  770.  
  771.       finf.ltot += fdata.finf.ltot;    /* Lines TOTal in sourcefile          */
  772.       finf.elin += fdata.finf.elin;    /* Empty LINes in sourcefile          */
  773.       finf.coml += fdata.finf.coml;    /* COMment Lines in sourcefile        */
  774.       finf.codl += fdata.finf.codl;    /* CODe Lines in sourcefile           */
  775.       finf.com  += fdata.finf.com;     /* COMment blocks in sourcefile       */
  776.       finf.func += fdata.finf.func;    /* FUNCtions in sourcefile            */
  777.       finf.dirl += fdata.finf.dirl;    /* DIRectiveLines in sourcefile       */
  778.       finf.fcal += fdata.finf.fcal;    /* Function CALls in sourcefile       */
  779.       finf.cid  += fdata.finf.cid;     /* IDentifiers in sourcefile          */
  780.    }
  781.  
  782.    /* Write info of source in project */
  783.    if (FWrite (&finf, sizeof (finfTYPE), 1, tmpf) != 1)
  784.    {
  785.       /* Failed on write to file! */
  786.       RETERR (3, GetFNames (tmpf));
  787.    }
  788.  
  789.    return (OK);                        /* OK join                            */
  790. } /* JoinSourceInfo (); */
  791.  
  792.  
  793.  
  794.  
  795. int JoinFuncInfo ( FILE *tmpf )
  796. /*
  797.     Function: Join block of function info from all objectfiles in active
  798.               project, into the specified big temporary objectfile.
  799.         Date: April, 21. 1993. 02:00. By LEL.
  800.    Interface: tmpf = Open big temporary object file to update.
  801.      Returns: E/O.
  802. */
  803. {
  804.    long  fnr;                          /* Number of functions in project     */
  805.    FILE *sortf;
  806.  
  807.    /* Open the temporary sortfile */
  808.    if ((sortf = FOpen (tmpn.sortfi, "w+b")) == NULL)
  809.    {
  810.       /* Failed on open temporary file! */
  811.       RETERR (11, tmpn.sortfi);
  812.    }
  813.  
  814.    if (!JoinSortFuncInfo (sortf, &fnr)) /* Collect and sort function info    */
  815.    {
  816.       FClose (sortf);                  /* Close temporary sortfile if error  */
  817.       RETURN_ERR;
  818.    }
  819.  
  820.    if (!JoinFuncInfo_ (tmpf, sortf, fnr)) /* Join sorted funcs into 'tmpf'   */
  821.    {
  822.       FClose (sortf);                  /* Close temporary sortfile if error  */
  823.       RETURN_ERR;
  824.    }
  825.  
  826.    FClose (sortf);                     /* Close temporary sortfile           */
  827.  
  828.    return (OK);                        /* OK join of function info           */
  829. } /* JoinFuncInfo (); */
  830.  
  831.  
  832.  
  833.  
  834. int JoinSortFuncInfo ( FILE *sortf, long *fnr )
  835. /*
  836.     Function: Find names of functions in all objectfiles in active
  837.               project, join all the names together in 'sortf' and
  838.               sort them in alfabetical order.
  839.         Date: April, 21. 1993. 22:00. By LEL.
  840.    Interface: sortf = Newly created temporary file to use when sort.
  841.               fnr   = Returns number of functions in project.
  842.      Returns: E/O.
  843. */
  844. {
  845.    int       filc = 0;                 /* Count number of source in project  */
  846.    long      globlin = 0;              /* Count global line number           */
  847.    FILE     *objf;                     /* Active objectfile in project       */
  848.    prjfeTYPE fdata;                    /* Data about actice objectfile       */
  849.  
  850.    *fnr = 0;                           /* Reset number of functions in projct*/
  851.  
  852.    Display (D_HEIGH, "%s", _StrMSGINCLFUNDATA);
  853.  
  854.    while (filc++ < prjstat.filc)       /* Loop trough all files in project   */
  855.    {
  856.       /* Include index of functions */
  857.       Display (D_LOW, "%s (%d/%d)", _StrMSGINCLFUNDATA, filc, prjstat.filc);
  858.  
  859.       /* Read data about active file in prjoject */
  860.       if (!GetFDataFromPrj (filc, &fdata))
  861.       {
  862.          RETURN_ERR;
  863.       }
  864.  
  865.       *fnr += fdata.finf.func;         /* Count number of functions in projct*/
  866.  
  867.       /* Open active objectfile */
  868.       if ((objf = FOpen (fdata.objn, "r+b")) == NULL)
  869.       {
  870.          RETERR (16, fdata.objn);      /* Failed on open file! */
  871.       }
  872.  
  873.       /* Join function names from objectfile */
  874.       if (!JoinSortFuncInfo_ (sortf, objf, &fdata.finf, &fdata.fpos, globlin))
  875.       {
  876.          FClose (objf);                /* Close active objectfile if error   */
  877.       }
  878.  
  879.       globlin += fdata.finf.ltot;      /* Count global line number           */
  880.  
  881.       FClose (objf);                   /* Close objectfile after use         */
  882.    }
  883.  
  884.    /* Sort functionblocks in sortfile */
  885.    Display (D_HEIGH, "%s", _StrMSGSORTFUNCREG);
  886.    if (!sortfile (sortf, sizeof (funcTYPE)))
  887.    {
  888.       /* Failed on sort contents of file! */
  889.       RETERR (12, GetFNames (sortf));
  890.    }
  891.  
  892.    return (OK);                        /* OK sort of function info           */
  893. } /* JoinSortFuncInfo (); */
  894.  
  895.  
  896.  
  897.  
  898. int JoinSortFuncInfo_ ( FILE *sortf, FILE *objf,
  899.                         finfTYPE *finf, fposTYPE *fpos, long globlin )
  900. /*
  901.     Function: Kernel function of 'JoinSortFuncInfo ()'. Do the work to get
  902.               function names from active objectfile, and join these names
  903.               into sortfile.
  904.         Date: April, 21. 1993. 23:20. By LEL.
  905.    Interface: sortf   = Temporary file to use when sort.
  906.               objf    = Newly opened active objectfile.
  907.               finf    = Total file info about actual objectfile.
  908.               fpos    = Indexes to blocks of data in objectfile.
  909.               globlin = Global line number of last line in previous source.
  910.      Returns: E/O.
  911. */
  912. {
  913.    funcTYPE func;                      /* Info about active function         */
  914.  
  915.    /* Index to start of function info */
  916.    FSeek (objf, fpos->funreg, SEEK_SET);
  917.  
  918.    while (finf->func--)                /* Loop trough all functions in objfil*/
  919.    {
  920.       /* Read next function from objectfile */
  921.       if (FRead (&func, sizeof (funcTYPE), 1, objf) != 1)
  922.       {
  923.          /* Failed on read file */
  924.          RETERR (15, GetFNames (objf));
  925.       }
  926.  
  927.       func.blin       += globlin;      /* Convert to global line number      */
  928.       func.blin_block += globlin;      /* Ditto                              */
  929.  
  930.       /* Join newly red info to sortfile */
  931.       if (FWrite (&func, sizeof (funcTYPE), 1, sortf) != 1)
  932.       {
  933.          /* Failed on write to file */
  934.          RETERR (3, GetFNames (sortf));
  935.       }
  936.    }
  937.  
  938.    return (OK);                        /* OK join of function names          */
  939. } /* JoinSortFuncInfo_ (); */
  940.  
  941.  
  942.  
  943.  
  944. int JoinFuncInfo_ ( FILE *tmpf, FILE *sortf, long fnr )
  945. /*
  946.         Function: Kernel function of 'JoinFuncInfo ()'.
  947.                   Join block of function info from specified objectfile, into
  948.                   the specified big temporary objectfile.
  949.    Programmed by: LEL
  950.             Date: April, 21. 1993. 02:00.
  951.        Interface: tmpf = Open big temporary object file to update.
  952.                   srtf = Open file of sorted functions in whole project.
  953.                   fnr  = Number of functions stored in 'sortf'.
  954.          Returns: E/O.
  955. */
  956. {
  957.    /* We can do a raw copy of data from 'sortf' to 'tmpf' because we know
  958.       that each block of function data allways has the same size.
  959.       This size is the size of structure 'funcTYPE'. */
  960.  
  961.    if (!CopyNBytesP (tmpf, sortf, 0L, fnr * sizeof (funcTYPE)))
  962.    {
  963.       /* Failed on copy filebytes to ... */
  964.       RETERR (26, GetFNames (tmpf));
  965.    }
  966.  
  967.    return (OK);
  968. } /* JoinFuncInfo_ (); */
  969.  
  970.  
  971.  
  972.  
  973. int JoinLineInfo ( FILE *tmpf )
  974. /*
  975.         Function: Join block of line info from all objectfiles in
  976.                   active project, into the specified big temporary objectfile.
  977.    Programmed by: LEL
  978.             Date: April, 22. 1993. 01:45.
  979.        Interface: tmpf = Open big temporary object file to update.
  980.          Returns: E/O.
  981. */
  982. {
  983.    int       countf = 0;               /* Count active objectfile            */
  984.    FILE     *objf;                     /* Active objectfile from project     */
  985.    prjfeTYPE fdata;                    /* Data about active objectfile       */
  986.  
  987.    /* Includes lines info */
  988.    Display (D_HEIGH, "%s", _StrMSGINCLLINEINFO);
  989.  
  990.    while (countf++ < prjstat.filc)     /* All objectfiles in active project  */
  991.    {
  992.       /* Includes lines info */
  993.       Display (D_LOW, "%s (%d/%d)", _StrMSGINCLLINEINFO,
  994.                                      countf, prjstat.filc);
  995.  
  996.       /* Read data about active objectfile */
  997.       if (!GetFDataFromPrj (countf, &fdata))
  998.       {
  999.          RETURN_ERR;
  1000.       }
  1001.  
  1002.       /* Open active objectfile (flag = read binary file) */
  1003.       if ((objf = FOpen (fdata.objn, "r+b")) == NULL)
  1004.       {
  1005.          /* Failed on open file! */
  1006.          RETERR (16, fdata.objn);
  1007.       }
  1008.  
  1009.       /* We can do a raw copy of data from 'objf' to 'tmpf' because we know
  1010.          that each block of line info data allways has the same size.
  1011.          This size is the size of structure 'scanTYPE'. */
  1012.  
  1013.       if (!CopyNBytesP (tmpf, objf,    /* Join info of all lines from objfile*/
  1014.                  fdata.fpos.lininf,    /* Lininfo block start in this index  */
  1015.                  fdata.finf.ltot *     /* Number of lines in active source   */
  1016.                     sizeof (scanTYPE))) /* Number of bytes in each lineinfo  */
  1017.       {
  1018.          FClose (objf);                /* Close active objectfile if error   */
  1019.  
  1020.          /* Failed on copy filebytes to ... */
  1021.          RETERR (26, GetFNames (tmpf));
  1022.       }
  1023.  
  1024.       FClose (objf);                   /* Close active objectfile            */
  1025.    }
  1026.  
  1027.    ClrLin ();
  1028.  
  1029.    return (OK);                        /* OK join                            */
  1030. } /* JoinLineInfo (); */
  1031.  
  1032.  
  1033.  
  1034.  
  1035. int JoinFunCalInfo ( FILE *tmpf )
  1036. /*
  1037.         Function: Join block of function calls info from all objectfiles in
  1038.                   active project, into the specified big temporary objectfile.
  1039.    Programmed by: LEL
  1040.             Date: April, 22. 1993. 02:00.
  1041.        Interface: tmpf = Open big temporary object file to update.
  1042.          Returns: E/O.
  1043. */
  1044. {
  1045.    long  fnr;                          /* Number of function calls in project*/
  1046.    FILE *sortf;
  1047.    FILE *indxf;
  1048.  
  1049.    /* Open the temporary sortfile */
  1050.    if ((sortf = FOpen (tmpn.sortfi, "w+b")) == NULL)
  1051.    {
  1052.       /* Failed on open temporary file! */
  1053.       RETERR (11, tmpn.sortfi);
  1054.    }
  1055.  
  1056.    /* Collect and sort function calls */
  1057.    if (!JoinSortFunCalInfo (sortf, &fnr))
  1058.    {
  1059.       FClose (sortf);                  /* Close temporary sortfile if error  */
  1060.       RETURN_ERR;
  1061.    }
  1062.  
  1063.    /* Create and open temporary index-file */
  1064.    if ((indxf = FOpen (tmpn.indexf, "w+b")) == NULL)
  1065.    {
  1066.       FClose (sortf);                  /* Close temporary sortfile if error  */
  1067.  
  1068.       /* Failed on open temporary file! */
  1069.       RETERR (11, tmpn.indexf);
  1070.    }
  1071.  
  1072.    /* Make indexes to func.call-names */
  1073.    if (!JoinFunCalMakIndx (sortf, indxf, fnr))
  1074.    {
  1075.       FClose (sortf);                  /* Close temporary sortfile if error  */
  1076.       FClose (indxf);                  /* Close temporary indexfile if error */
  1077.       RETURN_ERR;
  1078.    }
  1079.  
  1080.    /* Join sorted func. calls into 'tmpf'*/
  1081.    if (!JoinFunCalInfo_ (tmpf, sortf, indxf, fnr))
  1082.    {
  1083.       FClose (sortf);                  /* Close temporary sortfile if error  */
  1084.       FClose (indxf);                  /* Close temporary indexfile if error */
  1085.       RETURN_ERR;
  1086.    }
  1087.  
  1088.    FClose (sortf);                     /* Close temporary sortfile           */
  1089.    FClose (indxf);                     /* Close temporary indexfile          */
  1090.  
  1091.    return (OK);                        /* OK join of function call info      */
  1092. } /* JoinFunCalInfo (); */
  1093.  
  1094.  
  1095.  
  1096.  
  1097. int JoinFunCalInfo_ ( FILE *tmpf, FILE *sortf, FILE *indxf, long fnr )
  1098. /*
  1099.         Function: Kernel function of 'JoinFunCalInfo ()'.
  1100.                   Join function call data from all objectfiles in project,
  1101.                   into the specified big main temporary objectfile.
  1102.                   The names is joined into 'tmpf' in same order as names in
  1103.                   specified sortfile.
  1104.    Programmed by: LEL
  1105.             Date: April, 21. 1993. 02:00.
  1106.        Interface: tmpf  = Open big temporary object file to update.
  1107.                   sortf = Open file of sorted function call names.
  1108.                   indxf = File with stored indexes to func.cal-info in
  1109.                           every object files in project.
  1110.                   fnr   = Number of different function call names in project.
  1111.          Returns: E/O.
  1112. */
  1113. {
  1114.    int       filec;                    /* Count number of files in project   */
  1115.    long      linnr;                    /* Store red line number              */
  1116.    long      globlin;                  /* Count global line number           */
  1117.    long      faddr;                    /* Index to func.cal lines in obj.file*/
  1118.    char      fname [MAXFUNCN + 1];     /* Buffer to store active func.name   */
  1119.    FILE     *objf;                     /* Active objectfile                  */
  1120.    prjfeTYPE fdata;                    /* Data on active objectfile in prjfil*/
  1121.  
  1122.    /* Be sure filpointer on start of file */
  1123.    if (!FSeek (sortf, 0L, SEEK_SET))
  1124.    {
  1125.       /* Seek error */
  1126.       RETERR (13, GetFNames (sortf));
  1127.    }
  1128.  
  1129.    if (!FSeek (indxf, 0L, SEEK_SET))
  1130.    {
  1131.       /* Seek error */
  1132.       RETERR (13, GetFNames (indxf));
  1133.    }
  1134.  
  1135.    /* Collecting list of function calls */
  1136.    Display (D_HEIGH, "%s", _StrMSGINCLFCALDATA);
  1137.  
  1138.    while (fnr--)                       /* Loop to seek all func.call names   */
  1139.    {
  1140.       /* Collecting list of function calls */
  1141.       Display (D_LOW, "%s (%ld)", _StrMSGINCLFCALDATA, fnr + 1);
  1142.  
  1143.       /* Get name of next function call */
  1144.       if (FRead (&fname, MAXFUNCN + 1, 1, sortf) != 1)
  1145.       {
  1146.          /* Failed on read file */
  1147.          RETERR (15, GetFNames (sortf));
  1148.       }
  1149.  
  1150.       /* Write name of func.call to main obj */
  1151.       if (!FPrintF (tmpf, "%s%c", fname, 0))
  1152.       {
  1153.          /* Failed on write to file */
  1154.          RETERR (3, GetFNames (tmpf));
  1155.       }
  1156.  
  1157.       globlin = 0;                     /* Reset global line number first file*/
  1158.       filec   = 0;                     /* Reset counter to active file       */
  1159.       while (filec++ < prjstat.filc)   /* Loop trough all files in project   */
  1160.       {
  1161.          /* Get data about active objectfile */
  1162.          if (!GetFDataFromPrj (filec, &fdata))
  1163.          {
  1164.             RETURN_ERR;
  1165.          }
  1166.  
  1167.          if (!FGetL (indxf, &faddr))   /* Index to where this func is in objf*/
  1168.          {
  1169.             /* Failed on read file */
  1170.             RETERR (15, GetFNames (indxf));
  1171.          }
  1172.  
  1173.          if (faddr == 0L)              /* No calls of this func in this objf */
  1174.          {
  1175.             globlin += fdata.finf.ltot;/* Count global line number           */
  1176.             continue;                  /* So, continue to next obj.file-index*/
  1177.          }
  1178.  
  1179.          /* Open active objectfile (Read binary file) */
  1180.          if ((objf = FOpen (fdata.objn, "r+b")) == NULL)
  1181.          {
  1182.             /* Failed on open file! */
  1183.             RETERR (16, fdata.objn);
  1184.          }
  1185.  
  1186.          FSeek (objf, faddr, SEEK_SET);/* Point to actual funcn in obj.file  */
  1187.  
  1188.          while (1)                     /* Loop to get line nubers from objf  */
  1189.          {
  1190.             if (!FGetL (objf, &linnr)) /* Get next line number reference     */
  1191.             {
  1192.                FClose (objf);          /* Close current objectfile if error  */
  1193.  
  1194.                /* Failed on read file */
  1195.                RETERR (15, GetFNames (objf));
  1196.             }
  1197.  
  1198.             if (linnr == 0L)           /* A 0L mark end of line number list  */
  1199.             {
  1200.                break;                  /* So, break from line-reading loop   */
  1201.             }
  1202.  
  1203.             linnr += globlin;          /* Convert to global line number      */
  1204.  
  1205.             if (!FPutL (tmpf, linnr))  /* Join line number to main objectfile*/
  1206.             {
  1207.                FClose (objf);          /* Close current objectfile if error  */
  1208.  
  1209.                /* Failed on write to file */
  1210.                RETERR (3, GetFNames (tmpf));
  1211.             }
  1212.  
  1213.          };                            /* 0L if end of line number list      */
  1214.  
  1215.          globlin += fdata.finf.ltot;   /* Count global line number           */
  1216.          FClose (objf);                /* Close active objectfile            */
  1217.       }
  1218.  
  1219.       if (!FPutL (tmpf, 0L))           /* 0L mark end of line number list    */
  1220.       {
  1221.          /* Failed on write to file */
  1222.          RETERR (3, GetFNames (tmpf));
  1223.       }
  1224.    }
  1225.  
  1226.    return (OK);                        /* OK join                            */
  1227. } /* JoinFunCalInfo_ (); */
  1228.  
  1229.  
  1230.  
  1231.  
  1232. int JoinSortFunCalInfo ( FILE *sortf, long *fnr )
  1233. /*
  1234.         Function: Find names of function calls in all objectfiles in active
  1235.                   project, join all the names together in 'sortf' and
  1236.                   sort them in alfabetical order.
  1237.    Programmed by: LEL
  1238.             Date: April, 22. 1993. 02:15.
  1239.        Interface: sortf = Newly created temporary file to use when sort.
  1240.                   fnr   = Returns number of calls to different functions
  1241.                           in project.
  1242.          Returns: E/O.
  1243. */
  1244. {
  1245.    int       filc = 0;                 /* Count number of source in project  */
  1246.    FILE     *objf;                     /* Active objectfile in project       */
  1247.    prjfeTYPE fdata;                    /* Data about actice objectfile       */
  1248.  
  1249.    *fnr = 0;                           /* Reset number of f.calls in project */
  1250.  
  1251.    while (filc++ < prjstat.filc)       /* Loop trough all files in project   */
  1252.    {
  1253.       /* Read data about active file in prj */
  1254.       if (!GetFDataFromPrj (filc, &fdata))
  1255.       {
  1256.          RETURN_ERR;
  1257.       }
  1258.  
  1259.       /* Open active objectfile */
  1260.       if ((objf = FOpen (fdata.objn, "r+b")) == NULL)
  1261.       {
  1262.          /* Failed on open file! */
  1263.          RETERR (16, fdata.objn);
  1264.       }
  1265.  
  1266.       /* Join function names from objectfile */
  1267.       if (!JoinSortFunCalInfo_ (sortf, objf, fnr, &(fdata.fpos)))
  1268.       {
  1269.          FClose (objf);                /* Close active objectfile if error   */
  1270.          RETURN_ERR;
  1271.       }
  1272.  
  1273.       FClose (objf);                   /* Close objectfile after use         */
  1274.    }
  1275.  
  1276.    /* Sorts list of function calls */
  1277.    Display (D_HEIGH, "%s", _StrMSGSORTFCALLST);
  1278.    if (!sortfile (sortf, MAXFUNCN + 1)) /* Sort function names in sortfile   */
  1279.    {
  1280.       /* Failed on sort contents of file! */
  1281.       RETERR (12, GetFNames (sortf));
  1282.    }
  1283.  
  1284.    return (OK);                        /* OK sort of function info           */
  1285. } /* JoinSortFunCalInfo (); */
  1286.  
  1287.  
  1288.  
  1289.  
  1290. int JoinSortFunCalInfo_ ( FILE *sortf, FILE *objf, long *fnr, fposTYPE *fpos )
  1291. /*
  1292.         Function: Kernel function of 'JoinSortFunCalInfo ()'.
  1293.                   Do the work to get function call names from active
  1294.                   objectfile, and join these names into sortfile.
  1295.    Programmed by: LEL
  1296.             Date: April, 22. 1993. 02:20.
  1297.        Interface: sortf = Temporary file to use when sort.
  1298.                   objf  = Newly opened active objectfile.
  1299.                   fnr   = Count number of different function call names
  1300.                           in project.
  1301.                   fpos  = Indexes to blocks of data in objectfile.
  1302.          Returns: E/O.
  1303. */
  1304. {
  1305.    char fname [MAXFUNCN + 1];          /* Buffer to store active func.name   */
  1306.    long res;                           /* Temporary store result of a test   */
  1307.    long lnr;                           /* Buffer to store last red line nr   */
  1308.    long curpos;                        /* Current file position              */
  1309.  
  1310.    FSeek (objf,fpos->funcal,SEEK_SET); /* Index to start of func. call info  */
  1311.  
  1312.    /* Making list of different calls */
  1313.    Display (D_HEIGH, "%s", _StrMSGMAKEDIFFCALF);
  1314.  
  1315.    curpos = FTell (objf);
  1316.    while (curpos < fpos->idlst)        /* Loop trough all func. calls in objf*/
  1317.    {
  1318.       memset (fname, 0, MAXFUNCN + 1); /* To prevent packmans in sortfile    */
  1319.  
  1320.       /* Get next name of function from objf */
  1321.       if (!FGetS0 (fname, MAXFUNCN + 1, objf))
  1322.       {
  1323.          /* Failed on read file */
  1324.          RETERR (15, GetFNames (objf));
  1325.       }
  1326.  
  1327.       do                               /* Loop to seek past line numbers     */
  1328.       {
  1329.          if (!FGetL (objf, &lnr))      /* Read next line number ref from objf*/
  1330.          {
  1331.             /* Failed on read file */
  1332.             RETERR (15, GetFNames (objf));
  1333.          }
  1334.       }
  1335.       while (lnr != 0L);               /* 0L if end of line number list      */
  1336.  
  1337.       curpos = FTell (objf);           /* Get current file position          */
  1338.  
  1339.       /* Test to see if func.name is allready stored in sortfile */
  1340.       if (!IsItemInFile (sortf, fname, MAXFUNCN + 1, *fnr, &res))
  1341.       {
  1342.          /* Failed on read file */
  1343.          RETERR (15, GetFNames (sortf));
  1344.       }
  1345.  
  1346.       if (res)                         /* Is function name allready stored   */
  1347.       {
  1348.          continue;                     /* Yes, so do not store it again      */
  1349.       }
  1350.  
  1351.       /* Making list of different calls */
  1352.       Display (D_LOW, "%s (%s)", _StrMSGMAKEDIFFCALF, fname);
  1353.  
  1354.       /* Join name of file into sortfile */
  1355.       if (FWrite (fname, MAXFUNCN + 1, 1, sortf) != 1)
  1356.       {
  1357.          /* Failed on write to file */
  1358.          RETERR (3, GetFNames (sortf));
  1359.       }
  1360.  
  1361.       *fnr += 1;                       /* Count number of func. calls in prj */
  1362.    }
  1363.  
  1364.    return (OK);                        /* OK join of function call names     */
  1365. } /* JoinSortFunCalInfo_ (); */
  1366.  
  1367.  
  1368.  
  1369.  
  1370. int JoinFunCalMakIndx ( FILE *sortf, FILE *indxf, long fnr )
  1371. /*
  1372.         Function: Make indexes to all blocks of function calls in each
  1373.                   objectfile in whole project.
  1374.    Programmed by: LEL
  1375.             Date: April, 22. 1993. 20:20.
  1376.        Interface: sortf = Open and sorted file of function call names.
  1377.                   indxf = Open and newly created file to store index data.
  1378.                   fnr   = Number of items in 'sortf'.
  1379.          Returns: E/O.
  1380. */
  1381. {
  1382.    int       filec = 0;                /* Count number of files in project   */
  1383.    FILE     *objf;                     /* Active objectfile                  */
  1384.    prjfeTYPE fdata;                    /* Data about active objectfile       */
  1385.  
  1386.    /* Fix the size of 'indxf' so that there already has been written the
  1387.       necessary number of characters to the file, where all characters
  1388.       wrote is 0.
  1389.  
  1390.       The minimum number of such characters wrote must be:
  1391.  
  1392.       sizeof (long) * |Each index pointer use a long int.
  1393.       prjstat.filc *  |Number of files in active project.
  1394.       fnr             |Number of different names of function calls.
  1395.  
  1396.       Then, the found indexes can be written directly into its right
  1397.       position on file. */
  1398.  
  1399.    if (!FAddDummy (indxf, sizeof (long) * prjstat.filc * fnr, 0))
  1400.    {
  1401.       /* Failed on write to file */
  1402.       RETERR (3, GetFNames (indxf));
  1403.    }
  1404.  
  1405.    /* Makes indexes of function calls */
  1406.    Display (D_HEIGH, "%s", _StrMSGMAKINDXFCAL);
  1407.  
  1408.    while (filec++ < prjstat.filc)      /* Loop trough all files in project   */
  1409.    {
  1410.       /* Makes indexes of function calls */
  1411.       Display (D_LOW, "%s (%d/%d)", _StrMSGMAKINDXFCAL,
  1412.                                      filec, prjstat.filc);
  1413.  
  1414.       /* Get data about active objectfile */
  1415.       if (!GetFDataFromPrj (filec, &fdata))
  1416.       {
  1417.          RETURN_ERR;
  1418.       }
  1419.  
  1420.       /* Open active objectfile */
  1421.       if ((objf = FOpen (fdata.objn, "r+b")) == NULL)
  1422.       {
  1423.          /* Failed on open file! */
  1424.          RETERR (16, fdata.objn);
  1425.       }
  1426.  
  1427.       /* Make indexes to active objectfile */
  1428.       if (!JoinFunCalMakIndx_ (sortf, indxf, objf, fnr, filec, &fdata.fpos))
  1429.       {
  1430.          FClose (objf);                /* Close active objectfile if error   */
  1431.          RETURN_ERR;
  1432.       }
  1433.  
  1434.       FClose (objf);                   /* Close active objectfile            */
  1435.    }
  1436.  
  1437.    return (OK);                        /* OK construct of index-table        */
  1438. } /* JoinFunCalMakIndx (); */
  1439.  
  1440.  
  1441.  
  1442.  
  1443. int JoinFunCalMakIndx_ ( FILE *sortf, FILE *indxf, FILE *objf,
  1444.                          long fnr, int objfnr, fposTYPE *fpos )
  1445. /*
  1446.         Function: Kernel function of 'JoinFunCalMakIndx ()'.
  1447.                   Make indexes to all blocks of function calls in active
  1448.                   (specified) objectfile.
  1449.    Programmed by: LEL
  1450.             Date: April, 22. 1993. 21:10.
  1451.        Interface: sortf  = Open and sorted file of function call names.
  1452.                   indxf  = Open and size-fixed file to store index data.
  1453.                   objf   = Active objectfile.
  1454.                   fnr    = Number of items in sortfile.
  1455.                   objfnr = Number of active objectfile (1..).
  1456.          Returns: E/O.
  1457. */
  1458. {
  1459.    char fname[MAXFUNCN + 1];           /* Temporary store name of active func*/
  1460.    long curpos;                        /* Current position in file           */
  1461.    long indxpos;                       /* Store index position in sortfile   */
  1462.    long linenr;                        /* Dummy store line number ref.       */
  1463.  
  1464.    FSeek (objf,fpos->funcal,SEEK_SET); /* Place file to start of funccall.inf*/
  1465.  
  1466.    curpos = FTell (objf);              /* Now, points at start of data       */
  1467.    while (curpos < fpos->idlst)        /* Next datablock is item.ref         */
  1468.    {
  1469.       /* Read name of function call */
  1470.       if (!FGetS0 (fname, MAXFUNCN + 1, objf))
  1471.       {
  1472.          /* Failed on read file */
  1473.          RETERR (15, GetFNames (objf));
  1474.       }
  1475.  
  1476.       /* Get index of where the name is stored */
  1477.       if (!IsItemInFile (sortf, fname, MAXFUNCN + 1, fnr, &indxpos))
  1478.       {
  1479.          /* Failed on read file */
  1480.          RETERR (15, GetFNames (sortf));
  1481.       }
  1482.  
  1483.       if (indxpos == 0)                /* Did we find func. name in sortfile?*/
  1484.       {
  1485.          /* Error in objfile: Missing functionname in sortfile */
  1486.          RETERR (5, NULL);  /* 5 = A rare error due to a bug ... */
  1487.       }
  1488.  
  1489.       if (!FSeek (indxf,
  1490.  
  1491.                   /* Calc index to index-file of where to store index to
  1492.                      where active funcname is called in active objectfile:   */
  1493.  
  1494.                   sizeof (long) *
  1495.                   ((prjstat.filc * (indxpos - 1)) + (objfnr - 1)),
  1496.  
  1497.                   SEEK_SET))
  1498.       {
  1499.          /* Seek error */
  1500.          RETERR (13, GetFNames (indxf));
  1501.       }
  1502.  
  1503.       /* Pos of where data on this function start */
  1504.       curpos = FTell (objf);
  1505.  
  1506.       /* Write this index-adress to indxfile */
  1507.       if (FWrite (&curpos, sizeof (long), 1, indxf) != 1)
  1508.       {
  1509.          /* Failed on write to file */
  1510.          RETERR (3, GetFNames (indxf));
  1511.       }
  1512.  
  1513.       do                               /* Do a dummy seek past line numbers  */
  1514.       {
  1515.          /* Read next line number reference */
  1516.          if (FRead (&linenr, sizeof (long), 1, objf) != 1)
  1517.          {
  1518.             /* Failed on read file */
  1519.             RETERR (15, GetFNames (objf));
  1520.          }
  1521.       }
  1522.       while (linenr != 0L);            /* 0L if end of line number list      */
  1523.  
  1524.       curpos = FTell (objf);           /* Get filpos to test if end of block */
  1525.    }
  1526.  
  1527.    return (OK);                        /* OK make of indexes                 */
  1528. } /* JoinFunCalMakIndx_ (); */
  1529.  
  1530.  
  1531.  
  1532.  
  1533. int JoinIdLstInfo ( FILE *tmpf )
  1534. /*
  1535.         Function: Join block of item info from all objectfiles in
  1536.                   active project, into the specified big temporary objectfile.
  1537.    Programmed by: LEL
  1538.             Date: April, 23. 1993. 13:50.
  1539.        Interface: tmpf = Open big temporary object file to update.
  1540.          Returns: E/O.
  1541. */
  1542. {
  1543.    long  inr;                          /* Number of items in project         */
  1544.    FILE *sortf;
  1545.    FILE *indxf;
  1546.  
  1547.    /* Open the temporary sortfile */
  1548.    if ((sortf = FOpen (tmpn.sortfi, "w+b")) == NULL)
  1549.    {
  1550.       /* Failed on open temporary file! */
  1551.       RETERR (11, tmpn.sortfi);
  1552.    }
  1553.  
  1554.    /* Collect and sort items */
  1555.    if (!JoinSortIdLstInfo (sortf, &inr))
  1556.    {
  1557.       FClose (sortf);                  /* Close temporary sortfile if error  */
  1558.       RETURN_ERR;
  1559.    }
  1560.  
  1561.    /* Create and open index-file */
  1562.    if ((indxf = FOpen (tmpn.indexf, "w+b")) == NULL)
  1563.    {
  1564.       FClose (sortf);                  /* Close temporary sortfile if error  */
  1565.       RETURN_ERR;
  1566.    }
  1567.  
  1568.    /* Make indexes to item-names */
  1569.    if (!JoinIdLstMakIndx (sortf, indxf, inr))
  1570.    {
  1571.       FClose (sortf);                  /* Close temporary sortfile if error  */
  1572.       FClose (indxf);                  /* Close temporary indexfile if error */
  1573.       RETURN_ERR;
  1574.    }
  1575.  
  1576.    /* Join sorted items into 'tmpf' */
  1577.    if (!JoinIdLstInfo_ (tmpf, sortf, indxf, inr))
  1578.    {
  1579.       FClose (sortf);                  /* Close temporary sortfile if error  */
  1580.       FClose (indxf);                  /* Close temporary indexfile if error */
  1581.       RETURN_ERR;
  1582.    }
  1583.  
  1584.    FClose (sortf);                     /* Close temporary sortfile           */
  1585.    FClose (indxf);                     /* Close temporary indexfile          */
  1586.  
  1587.    return (OK);                        /* OK join of item info               */
  1588. } /* JoinIdLstInfo (); */
  1589.  
  1590.  
  1591.  
  1592.  
  1593. int JoinIdLstInfo_ ( FILE *tmpf, FILE *sortf, FILE *indxf, long inr )
  1594. /*
  1595.         Function: Kernel function of 'JoinIdLstInfo ()'.
  1596.                   Join item data from all objectfiles in project,
  1597.                   into the specified big main temporary objectfile.
  1598.                   The names is joined into 'tmpf' in same order as names in
  1599.                   specified sortfile.
  1600.    Programmed by: LEL
  1601.             Date: April, 23. 1993. 13:55.
  1602.        Interface: tmpf  = Open big temporary object file to update.
  1603.                   sortf = Open file of sorted function call names.
  1604.                   indxf = File with stored indexes to func.cal-info in
  1605.                           every object files in project.
  1606.                   inr   = Number of different item names in project.
  1607.          Returns: E/O.
  1608. */
  1609. {
  1610.    int       filec;                    /* Count number of files in project   */
  1611.    long      linnr;                    /* Store red line number              */
  1612.    long      globlin;                  /* Count global line number           */
  1613.    long      faddr;                    /* Index to item lines in obj.file    */
  1614.    char      iname [MAXFUNCN + 1];     /* Buffer to store active item name   */
  1615.    FILE     *objf;                     /* Active objectfile                  */
  1616.    prjfeTYPE fdata;                    /* Data on active objectfile in prjfil*/
  1617.  
  1618.    /* Be sure filpointer on start of file */
  1619.    FSeek (sortf, 0L, SEEK_SET);
  1620.    FSeek (indxf, 0L, SEEK_SET);
  1621.  
  1622.    /* Collects list of items */
  1623.    Display (D_HEIGH, "%s", _StrMSGINCLIDDATA);
  1624.  
  1625.    while (inr--)                       /* Loop to seek all item names        */
  1626.    {
  1627.       /* Collects list of items */
  1628.       Display (D_LOW, "%s (%ld)", _StrMSGINCLIDDATA, inr + 1);
  1629.  
  1630.       /* Get name of next item */
  1631.       if (FRead (&iname, MAXFUNCN + 1, 1, sortf) != 1)
  1632.       {
  1633.          /* Failed on read file */
  1634.          RETERR (15, GetFNames (sortf));
  1635.       }
  1636.  
  1637.       /* Write name of item to main obj */
  1638.       if (!FPrintF (tmpf, "%s%c", iname, 0))
  1639.       {
  1640.          /* Failed on write to file */
  1641.          RETERR (3, GetFNames (tmpf));
  1642.       }
  1643.  
  1644.       globlin = 0;                     /* Reset global line number first file*/
  1645.       filec   = 0;                     /* Reset counter to active file       */
  1646.       while (filec++ < prjstat.filc)   /* Loop trough all files in project   */
  1647.       {
  1648.          /* Get data about active objectfile */
  1649.          if (!GetFDataFromPrj (filec, &fdata))
  1650.          {
  1651.             RETURN_ERR;
  1652.          }
  1653.  
  1654.          if (!FGetL (indxf, &faddr))   /* Index to where this item is in objf*/
  1655.          {
  1656.             /* Failed on read file */
  1657.             RETERR (15, GetFNames (indxf));
  1658.          }
  1659.  
  1660.          if (faddr == 0L)              /* No use of this item in this objf   */
  1661.          {
  1662.             globlin += fdata.finf.ltot;/* Count global line number           */
  1663.             continue;                  /* So, continue to next obj.file-index*/
  1664.          }
  1665.  
  1666.          /* Open active objectfile (read binary file) */
  1667.          if ((objf = FOpen (fdata.objn, "r+b")) == NULL)
  1668.          {
  1669.             /* Failed on open file! */
  1670.             RETERR (16, fdata.objn);
  1671.          }
  1672.  
  1673.          FSeek (objf, faddr, SEEK_SET);/* Point to actual item in obj.file   */
  1674.  
  1675.          while (1)                     /* Loop to get line nubers from objf  */
  1676.          {
  1677.             if (!FGetL (objf, &linnr)) /* Get next line number reference     */
  1678.             {
  1679.                FClose (objf);          /* Close current objectfile if error  */
  1680.  
  1681.                /* Failed on read file */
  1682.                RETERR (15, GetFNames (objf));
  1683.             }
  1684.  
  1685.             if (linnr == 0L)           /* A 0L mark end of line number list  */
  1686.             {
  1687.                break;                  /* So, break line-reading loop        */
  1688.             }
  1689.  
  1690.             linnr += globlin;          /* Convert to global line number      */
  1691.  
  1692.             if (!FPutL (tmpf, linnr))  /* Join line number to main objectfile*/
  1693.             {
  1694.                FClose (objf);          /* Close current objectfile if error  */
  1695.  
  1696.                /* Failed on write to file */
  1697.                RETERR (3, GetFNames (tmpf));
  1698.             }
  1699.  
  1700.          };
  1701.  
  1702.          globlin += fdata.finf.ltot;   /* Count global line number           */
  1703.          FClose (objf);                /* Close active objectfile            */
  1704.       }
  1705.  
  1706.       if (!FPutL (tmpf, 0L))           /* 0L mark end of line number list    */
  1707.       {
  1708.          /* Failed on write to file */
  1709.          RETERR (3, GetFNames (tmpf));
  1710.       }
  1711.    }
  1712.  
  1713.    return (OK);
  1714. } /* JoinIdLstInfo_ (); */
  1715.  
  1716.  
  1717.  
  1718.  
  1719. int JoinSortIdLstInfo ( FILE *sortf, long *inr )
  1720. /*
  1721.         Function: Find names of items in all objectfiles in active
  1722.                   project, join all the names together in 'sortf' and
  1723.                   sort them in alfabetical order.
  1724.    Programmed by: LEL
  1725.             Date: April, 23. 1993. 14:00.
  1726.        Interface: sortf = Newly created temporary file to use when sort.
  1727.                   inr   = Returns number of different items in project.
  1728.          Returns: E/O.
  1729. */
  1730. {
  1731.    int       filc = 0;                 /* Count number of source in project  */
  1732.    FILE     *objf;                     /* Active objectfile in project       */
  1733.    prjfeTYPE fdata;                    /* Data about actice objectfile       */
  1734.  
  1735.    *inr = 0;                           /* Reset number of items in project   */
  1736.  
  1737.    while (filc++ < prjstat.filc)       /* Loop trough all files in project   */
  1738.    {
  1739.       /* Read data about active file in prj */
  1740.       if (!GetFDataFromPrj (filc, &fdata))
  1741.       {
  1742.          RETURN_ERR;
  1743.       }
  1744.  
  1745.       /* Open active objectfile */
  1746.       if ((objf = FOpen (fdata.objn, "r+b")) == NULL)
  1747.       {
  1748.          /* Failed on open file! */
  1749.          RETERR (16, fdata.objn);
  1750.       }
  1751.  
  1752.       /* Join item names from objectfile */
  1753.       if (!JoinSortIdLstInfo_ (sortf, objf, inr, &fdata.fpos))
  1754.       {
  1755.          FClose (objf);                /* Close active objectfile if error   */
  1756.          RETURN_ERR;
  1757.       }
  1758.  
  1759.       FClose (objf);                   /* Close objectfile after use         */
  1760.    }
  1761.  
  1762.    /* Sorts list of items */
  1763.    Display (D_HEIGH, "%s", _StrMSGSORTIDLST);
  1764.    if (!sortfile (sortf, MAXFUNCN + 1)) /* Sort item names in sortfile       */
  1765.    {
  1766.       /* Failed on sort contents of file! */
  1767.       RETERR (12, GetFNames (sortf));
  1768.    }
  1769.  
  1770.    return (OK);                        /* OK sort of item info               */
  1771. } /* JoinSortIdLstInfo (); */
  1772.  
  1773.  
  1774.  
  1775.  
  1776. int JoinSortIdLstInfo_ ( FILE *sortf, FILE *objf, long *inr, fposTYPE *fpos )
  1777. /*
  1778.         Function: Kernel function of 'JoinSortIdLstInfo ()'.
  1779.                   Do the work to get item names from active
  1780.                   objectfile, and join these names into sortfile.
  1781.    Programmed by: LEL
  1782.             Date: April, 23. 1993. 14:05.
  1783.        Interface: sortf = Temporary file to use when sort.
  1784.                   objf  = Newly opened active objectfile.
  1785.                   inr   = Count number of different item names in project.
  1786.                   fpos  = Indexes to blocks of data in objectfile.
  1787.          Returns: E/O.
  1788. */
  1789. {
  1790.    char iname [MAXFUNCN+1];            /* Buffer to store active item name   */
  1791.    long res;                           /* Temporary store result of a test   */
  1792.    long lnr;                           /* Buffer to store last red line nr   */
  1793.    long curpos;                        /* Current file position              */
  1794.  
  1795.    FSeek (objf, fpos->idlst, SEEK_SET);/* Index to start of item info        */
  1796.  
  1797.    /* Makes list of different items */
  1798.    Display (D_HEIGH, "%s", _StrMSGMAKEDIFIDF);
  1799.  
  1800.    curpos = FTell (objf);
  1801.    while (curpos < fpos->lininf)       /* Loop trough all items in objfile   */
  1802.    {
  1803.       memset (iname, 0, MAXFUNCN + 1); /* To prevent packmans in sortfile    */
  1804.  
  1805.       /* Get next name of item from objfile */
  1806.       if (!FGetS0 (iname, MAXFUNCN + 1, objf))
  1807.       {
  1808.          /* Failed on read file */
  1809.          RETERR (15, GetFNames (objf));
  1810.       }
  1811.  
  1812.       do                               /* Loop to seek past line numbers     */
  1813.       {
  1814.          if (!FGetL (objf, &lnr))      /* Read next line number ref from objf*/
  1815.          {
  1816.             /* Failed on read file */
  1817.             RETERR (15, GetFNames (objf));
  1818.          }
  1819.       }
  1820.       while (lnr != 0L);               /* 0L if end of line number list      */
  1821.  
  1822.       curpos = FTell (objf);           /* Get current file position          */
  1823.  
  1824.       /* Test to see if item name is allready stored in sortfile */
  1825.       if (!IsItemInFile (sortf, iname, MAXFUNCN + 1, *inr, &res))
  1826.       {
  1827.          /* Failed on read file */
  1828.          RETERR (15, GetFNames (sortf));
  1829.       }
  1830.  
  1831.       if (res)                         /* Is item name allready stored       */
  1832.       {
  1833.          continue;                     /* Yes, so do not store it again      */
  1834.       }
  1835.  
  1836.       /* Makes list of different items */
  1837.       Display (D_LOW, "%s (%s)", _StrMSGMAKEDIFIDF, iname);
  1838.  
  1839.       /* Join name of item into sortfile */
  1840.       if (FWrite (iname, MAXFUNCN + 1, 1, sortf) != 1)
  1841.       {
  1842.          /* Failed on write to file */
  1843.          RETERR (3, GetFNames (sortf));
  1844.       }
  1845.  
  1846.       *inr += 1;                       /* Count number of items in project   */
  1847.    }
  1848.  
  1849.    return (OK);                        /* OK join of item names              */
  1850. } /* JoinSortIdLstInfo_ (); */
  1851.  
  1852.  
  1853.  
  1854.  
  1855. int JoinIdLstMakIndx ( FILE *sortf, FILE *indxf, long inr )
  1856. /*
  1857.         Function: Make indexes to all blocks of items in each
  1858.                   objectfile in whole project.
  1859.    Programmed by: LEL
  1860.             Date: April, 23. 1993. 14:10.
  1861.        Interface: sortf = Open and sorted file of function call names.
  1862.                   indxf = Open and newly created file to store index data.
  1863.                   inr   = Number of items in 'sortf'.
  1864.          Returns: E/O.
  1865. */
  1866. {
  1867.    int       filec = 0;                /* Count number of files in project   */
  1868.    FILE     *objf;                     /* Active objectfile                  */
  1869.    prjfeTYPE fdata;                    /* Data about active objectfile       */
  1870.  
  1871.    /* Fix the size of 'indxf' so that there already has been written the
  1872.       necessary number of characters to the file, where all characters
  1873.       wrote is 0.
  1874.  
  1875.       The minimum number of such characters wrote must be:
  1876.  
  1877.       sizeof (long) * |Each index pointer use a long int.
  1878.       prjstat.filc *  |Number of files in active project.
  1879.       inr             |Number of different names of items.
  1880.  
  1881.       Then, the found indexes can be written directly into its right
  1882.       position on file. */
  1883.  
  1884.    if (!FAddDummy (indxf, sizeof (long) * prjstat.filc * inr, 0))
  1885.    {
  1886.       /* Failed on write to file */
  1887.       RETERR (3, GetFNames (indxf));
  1888.    }
  1889.  
  1890.    /* Makes indexes to items */
  1891.    Display (D_HEIGH, "%s", _StrMSGMAKINDXIDLST);
  1892.  
  1893.    while (filec++ < prjstat.filc)      /* Loop trough all files in project   */
  1894.    {
  1895.       /* Makes indexes to items */
  1896.       Display (D_LOW, "%s (%d/%d)", _StrMSGMAKINDXIDLST, filec, prjstat.filc);
  1897.  
  1898.       /* Get data about active objectfile */
  1899.       if (!GetFDataFromPrj (filec, &fdata))
  1900.       {
  1901.          RETURN_ERR;
  1902.       }
  1903.  
  1904.       /* Open active objectfile */
  1905.       if ((objf = FOpen (fdata.objn, "r+b")) == NULL)
  1906.       {
  1907.          /* Failed on open file! */
  1908.          RETERR (16, fdata.objn);
  1909.       }
  1910.  
  1911.       /* Make indexes to active objectfile */
  1912.       if (!JoinIdLstMakIndx_ (sortf, indxf, objf, inr, filec, &fdata.fpos))
  1913.       {
  1914.          FClose (objf);                /* Close active objectfile if error   */
  1915.          RETURN_ERR;
  1916.       }
  1917.  
  1918.       FClose (objf);                   /* Close active objectfile            */
  1919.    }
  1920.  
  1921.    return (OK);                        /* OK construct of index-table        */
  1922. } /* JoinIdLstMakIndx (); */
  1923.  
  1924.  
  1925.  
  1926.  
  1927. int JoinIdLstMakIndx_ ( FILE *sortf, FILE *indxf, FILE *objf,
  1928.                         long inr, int objfnr, fposTYPE *fpos )
  1929. /*
  1930.         Function: Kernel function of 'JoinIdLstMakIndx ()'.
  1931.                   Make indexes to all blocks of items in active
  1932.                   (specified) objectfile.
  1933.    Programmed by: LEL
  1934.             Date: April, 23. 1993. 14:13.
  1935.        Interface: sortf  = Open and sorted file of function call names.
  1936.                   indxf  = Open and size-fixed file to store index data.
  1937.                   objf   = Active objectfile.
  1938.                   inr    = Number of items in sortfile.
  1939.                   objfnr = Number of active objectfile (1..).
  1940.          Returns: E/O.
  1941. */
  1942. {
  1943.    char iname[MAXFUNCN + 1];           /* Temporary store name of active item*/
  1944.    long curpos;                        /* Current position in file           */
  1945.    long indxpos;                       /* Store index position in sortfile   */
  1946.    long linenr;                        /* Dummy store line number ref.       */
  1947.  
  1948.    FSeek (objf, fpos->idlst, SEEK_SET);/* Place file to start of item info   */
  1949.  
  1950.    curpos = FTell (objf);              /* Now, points at start of data       */
  1951.    while (curpos < fpos->lininf)       /* Next datablock is line info        */
  1952.    {
  1953.       /* Read name of item */
  1954.       if (!FGetS0 (iname, MAXFUNCN + 1, objf))
  1955.       {
  1956.          /* Failed on read file */
  1957.          RETERR (15, GetFNames (objf));
  1958.       }
  1959.  
  1960.       /* Get index of where the name is stored */
  1961.       if (!IsItemInFile (sortf, iname, MAXFUNCN + 1, inr, &indxpos))
  1962.       {
  1963.          /* Failed on read file */
  1964.          RETERR (15, GetFNames (sortf));
  1965.       }
  1966.  
  1967.       if (indxpos == 0)                /* Did we find item name in sortfile? */
  1968.       {
  1969.          /* Error in objfile: Missing itemname in sortfile */
  1970.          RETERR (5, NULL);   /* A rare error due to a bug in the program ... */
  1971.       }
  1972.  
  1973.       if (!FSeek (indxf,
  1974.  
  1975.                   /* Calc index to index-file of where to store index to
  1976.                      where active item name is used in active objectfile:    */
  1977.  
  1978.                   sizeof (long) *
  1979.                   (prjstat.filc * (indxpos - 1) + (objfnr - 1)),
  1980.  
  1981.                   SEEK_SET))
  1982.       {
  1983.          /* Seek error */
  1984.          RETERR (13, GetFNames (indxf));
  1985.       }
  1986.  
  1987.       /* Pos of where data of this item start */
  1988.       curpos = FTell (objf);
  1989.  
  1990.       /* Write this index-adress to indxfile */
  1991.       if (FWrite (&curpos, sizeof (long), 1, indxf) != 1)
  1992.       {
  1993.          /* Failed on write to file */
  1994.          RETERR (3, GetFNames (indxf));
  1995.       }
  1996.  
  1997.       do                               /* Do a dummy seek past line numbers  */
  1998.       {
  1999.          /* Read next line number reference */
  2000.          if (FRead (&linenr, sizeof (long), 1, objf) != 1)
  2001.          {
  2002.             /* Failed on read file */
  2003.             RETERR (15, GetFNames (objf));
  2004.          }
  2005.       }
  2006.       while (linenr != 0L);            /* 0L if end of line number list      */
  2007.  
  2008.       curpos = FTell (objf);           /* Get filpos to test if end of block */
  2009.    }
  2010.  
  2011.    return (OK);                        /* OK make of indexes                 */
  2012. } /* JoinIdLstMakIndx_ (); */
  2013.  
  2014.  
  2015.