[fyba] 01/77: initial commit

Ruben Undheim rubund-guest at moszumanska.debian.org
Mon Sep 22 15:11:19 UTC 2014


This is an automated email from the git hooks/post-receive script.

rubund-guest pushed a commit to branch master
in repository fyba.

commit 42a825a05cec88c6e1e721e081a172579bb5d0e0
Author: Thomas Hirsch <fwd.github.20.ravn at neverbox.com>
Date:   Thu Oct 6 16:22:34 2011 +0200

    initial commit
---
 FYBA/FYBA.cpp                 |   42 +
 FYBA/FYBA_DLL.cpp             |   25 +
 FYBA/FYHO.cpp                 | 1456 ++++++++++++
 FYBA/FYLB.cpp                 | 4646 ++++++++++++++++++++++++++++++++++++++
 FYBA/FYLD.cpp                 |  111 +
 FYBA/FYLE.cpp                 |  490 ++++
 FYBA/FYLH.cpp                 | 1035 +++++++++
 FYBA/FYLI.cpp                 | 2293 +++++++++++++++++++
 FYBA/FYLO.cpp                 | 2529 +++++++++++++++++++++
 FYBA/FYLP.cpp                 | 1169 ++++++++++
 FYBA/FYLR.cpp                 | 2240 +++++++++++++++++++
 FYBA/FYLS.cpp                 |  678 ++++++
 FYBA/FYLU.cpp                 | 2904 ++++++++++++++++++++++++
 FYBA/FYLX.cpp                 | 4948 +++++++++++++++++++++++++++++++++++++++++
 FYBA/FYTA.cpp                 |  199 ++
 FYBA/Fyba_Callback.cpp        |  233 ++
 FYBA/Fyba_melding.cpp         |  201 ++
 FYBA/Fyba_melding_dll.cpp.bak |  368 +++
 FYBA/LICENSE                  |   24 +
 FYBA/fyba.h                   | 1484 ++++++++++++
 FYBA/fyba_strings.h           |  221 ++
 FYBA/fybax.h                  |  344 +++
 FYBA/fyln.cpp                 |  870 ++++++++
 FYBA/make.sh                  |    5 +
 FYBA/stdafx.cpp               |    8 +
 FYBA/stdafx.h                 |   16 +
 GM/GM.cpp                     | 3245 +++++++++++++++++++++++++++
 GM/LICENSE                    |   24 +
 GM/fygm.h                     |  129 ++
 GM/make.sh                    |    4 +
 GM/stdafx.cpp                 |    8 +
 GM/stdafx.h                   |    9 +
 UT/ANFORSEL.cpp               |  189 ++
 UT/CREDIR.cpp                 |   81 +
 UT/CopyFile.cpp               |   78 +
 UT/DELDIR.cpp                 |   78 +
 UT/DELFILE.cpp                |   43 +
 UT/DISKINFO.cpp               |  199 ++
 UT/FILNACMP.cpp               |   54 +
 UT/FULLPATH.cpp               |  309 +++
 UT/INQSIZE.cpp                |  173 ++
 UT/INQTID.cpp                 |  209 ++
 UT/LICENSE                    |   24 +
 UT/MAKEPATH.cpp               |  140 ++
 UT/SETSIZE.cpp                |  210 ++
 UT/SPLITPTH.cpp               |  226 ++
 UT/StrtPros.cpp               |  122 +
 UT/UT1.cpp                    |  817 +++++++
 UT/UT2.cpp                    | 1550 +++++++++++++
 UT/UT3.cpp                    |  575 +++++
 UT/UT4.cpp                    |  149 ++
 UT/fyut.h                     |  279 +++
 UT/make.sh                    |    4 +
 UT/stdafx.cpp                 |    8 +
 UT/stdafx.h                   |    9 +
 55 files changed, 37484 insertions(+)

diff --git a/FYBA/FYBA.cpp b/FYBA/FYBA.cpp
new file mode 100644
index 0000000..02da5ee
--- /dev/null
+++ b/FYBA/FYBA.cpp
@@ -0,0 +1,42 @@
+/*
+CH  FYBA                                             FYsak-Basesystem
+CD  ==================================================================
+CD  Rutiner for � lese, endre og skrive SOSI-filer.
+CD  ==================================================================
+CD
+CH  INSTALLERINGS- OG BRUKS-OPPLYSNINGER:
+CD
+CD  Bibliotek..: fybale.lib
+CD  Kildefiler.: fyba.c, fylo.c, fyln.c, fylr.c, fyls.c, fylx.c, fyli.c
+CD               fylh.c, fyho.c, fyle.c, fyba.h, fybax.h
+CD  Versjon....: D01
+CD  Eier.......: STATENS KARTVERK / FYSAK-prosjektet
+CD  Ansvarlig..: Andreas R�stad, Georg Langerak
+CD
+CD  Kompilator.: Microsoft C versjon 6.0
+CD  Optioner...: /c /AL /J /FPi /G2t /W4
+CD  Memory-mod.: Large
+CD  Floating-p.: Emulation
+CD  Processor..: 80286
+CD
+CD  #include...: fyba.h
+CD  Linkes med.: utle.lib    >=  versjon D
+CD              +llibce.lib  >=  versjon 6.0
+CD
+CD  ==================================================================
+*/
+
+#include "stdafx.h"
+
+
+/*
+CH LC_InqVer                                                   Identifikasjon
+CD =============================================================================
+CD Form�l:
+CD Henter versjons-identifikasjon for dette biblioteket.
+   =============================================================================
+*/
+SK_EntPnt_FYBA char *LC_InqVer(void)
+{
+   return FYBA_IDENT;
+}
diff --git a/FYBA/FYBA_DLL.cpp b/FYBA/FYBA_DLL.cpp
new file mode 100644
index 0000000..879ab83
--- /dev/null
+++ b/FYBA/FYBA_DLL.cpp
@@ -0,0 +1,25 @@
+// FYBA_DLL.cpp : Defines the entry point for the DLL application.
+//
+
+#ifdef WIN32
+
+#include "stdafx.h"
+#include "fyba.h"
+
+BOOL APIENTRY DllMain( HMODULE hModule,
+                       DWORD  ul_reason_for_call,
+                       LPVOID lpReserved
+					 )
+{
+	switch (ul_reason_for_call)
+	{
+	case DLL_PROCESS_ATTACH:
+	case DLL_THREAD_ATTACH:
+	case DLL_THREAD_DETACH:
+	case DLL_PROCESS_DETACH:
+		break;
+	}
+    return TRUE;
+}
+
+#endif
diff --git a/FYBA/FYHO.cpp b/FYBA/FYHO.cpp
new file mode 100644
index 0000000..64606c4
--- /dev/null
+++ b/FYBA/FYHO.cpp
@@ -0,0 +1,1456 @@
+/*
+AR-920214
+CH FYHO                                       "Direkte" hoderutiner
+CD =================================================================
+CD
+CD Eier.......: STATENS KARTVERK / FYSAK-prosjektet
+CD Ansvarlig..: Georg Langerak / Andreas R�stad
+CD
+CD Rutiner for � handtere hodet p� SOSI-filer direkte p� filen.
+CD  ==============================================================
+*/
+
+#include "stdafx.h"
+
+#include <math.h>
+#include <time.h>
+#include <ctype.h>
+#include <fcntl.h>
+              
+
+/* --- Globale strukturer ---------------------- */
+extern LC_SYSTEMADM Sys;
+
+extern char retur_str[LC_MAX_SOSI_LINJE_LEN];     /* Returstreng */
+
+// ----- Lokale rutiner -----
+static short ho_TestFyllKommentar(const char *pszTx);
+
+/*
+AR:2000-10-07
+CH HO_GetTransEx                                       Finner .TRANSPAR i hodet
+CD =============================================================================
+CD Form�l:
+CD Henter ut innholdet under ..TRANSPAR fra fra filhodet.
+CD
+CD Parametre:
+CD Type            Navn      I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD char           *pszFil     i   Fullstendig filnavn
+CD unsigned short *pusMaske  iu   [Inn] Styrer hvilke deler av TRANSPAR som skal hentes
+CD                                [Ut] Viser hvilke deler av TRANSPAR som er funnet/hentet.
+CD                                F�lgende konstanter er definert:
+CD                                  LC_TR_ALLT - Alle deler av ..TRANSPAR hentes
+CD                                  LC_TR_KOORDSYS - Koordsys
+CD                                  LC_TR_TRANSSYS - Transsys
+CD                                  LC_TR_GEOSYS - Geosys
+CD                                  LC_TR_GEOKOORD - Geokoord
+CD                                  LC_TR_ORIGO - Origo-n�
+CD                                  LC_TR_ENHET - Enhet
+CD                                  LC_TR_ENHETH - Enhet-h
+CD                                  LC_TR_ENHETD - Enhet-d
+CD                                  LC_TR_VERTDATUM - Vert-datum
+CD                                  LC_TR_VERTINT - Vert-int
+CD                                  LC_TR_VERTDELTA - Vert-delta
+CD
+CD LC_TRANSPAR *    pTrans    iu   Peker til struktur som skal motta ..TRANSPAR informasjonen.
+CD short           sStatus   r    Status: UT_TRUE=OK, UT_FALSE=feil (ikke funnet).
+CD
+CD Bruk:
+CD unsigned short usMaske = LC_TR_ALLT;
+CD LC_TRANSPAR Trans;
+CD ist = HO_GetTransEx("Test.sos",&usMaske,&Trans);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short HO_GetTransEx(const char *pszFil,unsigned short *pusMaske, LC_TRANSPAR * pTrans)
+{
+   short sStatus;
+   FILE * pFil;
+
+
+   /* �pner filen */
+   pFil = UT_OpenFile(pszFil,"SOS",UT_READ,UT_OLD,&sStatus);
+
+   /* �pnet OK ? */
+   if (sStatus == UT_OK) {
+      /* Hent verdier */
+      sStatus = ho_GetTransEx(pFil,pusMaske,pTrans);
+      fclose (pFil);
+
+	/* �pningsfeil p� kladdefilen */
+   } else {
+      char szError[256];
+      UT_strerror(szError,256,sStatus);
+      UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pszFil,szError);
+      LC_Error(101,"(HO_GetTransEx)",err().tx);
+      memset(pTrans,0,sizeof(LC_TRANSPAR));
+      *pusMaske = 0;
+      sStatus = UT_FALSE;
+   }
+
+   return sStatus;
+}
+
+
+/*
+AR:2000-10-07
+CH ho_GetTransEx                                         Finner .TRANSPAR i hodet
+CD =============================================================================
+CD Henter ut innholdet under ..TRANSPAR fra fra filhodet.
+CD
+CD Parametre:
+CD Type            Navn      I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD FILE           *pFil       i   Filpeker til sosi-fil.
+CD unsigned short *pusMaske  iu   [Inn] Styrer hvilke deler av TRANSPAR som skal hentes
+CD                                [Ut] Viser hvilke deler av TRANSPAR som er funnet/hentet.
+CD                                F�lgende konstanter er definert:
+CD                                  LC_TR_ALLT - Alle deler av ..TRANSPAR hentes
+CD                                  LC_TR_KOORDSYS - Koordsys
+CD                                  LC_TR_TRANSSYS - Transsys
+CD                                  LC_TR_GEOSYS - Geosys
+CD                                  LC_TR_GEOKOORD - Geokoord
+CD                                  LC_TR_ORIGO - Origo-n�
+CD                                  LC_TR_ENHET - Enhet
+CD                                  LC_TR_ENHETH - Enhet-h
+CD                                  LC_TR_ENHETD - Enhet-d
+CD                                  LC_TR_VERTDATUM - Vert-datum
+CD                                  LC_TR_VERTINT - Vert-int
+CD                                  LC_TR_VERTDELTA - Vert-delta
+CD
+CD LC_TRANSPAR *    pTrans    iu   Peker til struktur som skal motta ..TRANSPAR informasjonen.
+CD short           sStatus   r    Status: UT_TRUE=OK, UT_FALSE=feil (ikke funnet).
+CD
+CD Bruk:
+CD unsigned short usMaske = LC_TR_ALLT;
+CD LC_TRANSPAR Trans;
+CD ist = ho_GetTransEx(pFil,&usMaske,&Trans);
+   =============================================================================
+*/
+short ho_GetTransEx(FILE *pFil,unsigned short *pusMaske, LC_TRANSPAR * pTrans)
+{
+   short lin,itxi;
+   char *cp;
+   short ist = UT_TRUE;
+   unsigned short usMaskeInn = *pusMaske;
+
+
+   /* Nullstiller pTrans */
+   memset(pTrans,0,sizeof(LC_TRANSPAR));
+
+   /* Nullstiller masken */
+   *pusMaske = 0;
+
+   /* Sjekk hvilket tegnsett som skal brukes */
+	ho_GetTegnsett(pFil,&Sys.BufAdm.sTegnsett);
+
+   /* ----- Div. kontroller ----- */
+   /* Transpar */
+   lin=2;
+   if ( ! ho_GetVal(pFil,"..TRANSPAR",&lin)) {
+       LC_Error(14," (HO_GetTrans) "," ");
+       return UT_FALSE;
+   }
+
+   /* ----- Henter verdier ----- */
+
+   /* Koordsys */
+   if ((usMaskeInn & LC_TR_KOORDSYS) != 0) {
+      lin = 2;
+      cp = ho_GetVal(pFil,"...KOORDSYS",&lin);
+      if (cp == NULL) {
+         lin=2;
+         ho_GetVal(pFil,"..KOORDSYS",&lin);
+      }
+      if (cp != NULL) {
+         *pusMaske |= LC_TR_KOORDSYS;
+         UT_StrShort(cp,0,&itxi,&pTrans->sKoordsys);
+         UT_StrToken(cp,itxi,&itxi,36,pTrans->szKoordsysDatum);
+         UT_StrToken(cp,itxi,&itxi,36,pTrans->szKoordsysProjek);
+      }
+   }
+
+   /* Transsys */
+   if ((usMaskeInn & LC_TR_TRANSSYS) != 0) {
+      lin = 2;
+      if ((cp = ho_GetVal(pFil,"...TRANSSYS",&lin)) != NULL) {
+         *pusMaske |= LC_TR_TRANSSYS;
+         UT_StrShort(cp,0,&itxi,&pTrans->sTranssysTilsys);
+         UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstA1);
+         UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstB1);
+         UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstA2);
+         UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstB2);
+         UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstC1);
+         UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstC2);
+      }
+   }
+
+   /* Geosys */
+   if ((usMaskeInn & LC_TR_GEOSYS) != 0) {
+      lin = 2;
+      if ((cp = ho_GetVal(pFil,"...GEOSYS",&lin)) != NULL) {
+         *pusMaske |= LC_TR_GEOSYS;
+         UT_StrShort(cp,0,&itxi,&pTrans->sGeosysDatum);
+         UT_StrShort(cp,itxi,&itxi,&pTrans->sGeosysProj);
+         UT_StrShort(cp,itxi,&itxi,&pTrans->sGeosysSone);
+      }
+   }
+
+   /* Geokoord */ 
+   if ((usMaskeInn & LC_TR_GEOKOORD) != 0) {
+      lin = 2;
+      if ((cp = ho_GetVal(pFil,"...GEOKOORD",&lin)) != NULL) {
+         *pusMaske |= LC_TR_GEOKOORD;
+         UT_StrShort(cp,0,&itxi,&pTrans->sGeoKoord);
+      }
+   }
+
+   /* Origo */
+   if ((usMaskeInn & LC_TR_ORIGO) != 0) {
+      lin = 2;
+      if ((cp = ho_GetVal(pFil,"...ORIGO-N�",&lin)) != NULL) {
+         *pusMaske |= LC_TR_ORIGO;
+         UT_StrDbl(cp,0,&itxi,'.',&pTrans->Origo.dNord);
+         UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->Origo.dAust);
+      }
+   }
+
+   /* Enhet */
+   if ((usMaskeInn & LC_TR_ENHET) != 0) {
+      lin = 2;
+      if ((cp = ho_GetVal(pFil,"...ENHET",&lin)) != NULL) {
+         *pusMaske |= LC_TR_ENHET;
+         pTrans->dEnhet = strtod(cp,&cp);
+      }
+   }
+
+   /* Enhet-h */
+   if ((usMaskeInn & LC_TR_ENHETH) != 0) {
+      lin=2;
+      if ((cp = ho_GetVal(pFil,"...ENHET-H",&lin)) == NULL) {
+        pTrans->dEnhet_h = pTrans->dEnhet;
+      } else {
+        *pusMaske |= LC_TR_ENHETH;
+        pTrans->dEnhet_h = strtod(cp,&cp);
+      }
+   }
+
+   /* Enhet-d */
+   if ((usMaskeInn & LC_TR_ENHETD) != 0) {
+      /* Enhet-d */
+      lin=2;
+      if ((cp = ho_GetVal(pFil,"...ENHET-D",&lin)) == NULL) {
+        pTrans->dEnhet_d = pTrans->dEnhet;
+      } else {
+        *pusMaske |= LC_TR_ENHETD;
+        pTrans->dEnhet_d = strtod(cp,&cp);
+      }
+   }
+
+   /* Vert-datum */
+   if ((usMaskeInn & LC_TR_VERTDATUM) != 0) {
+      lin = 2;
+      if ((cp = ho_GetVal(pFil,"...VERT-DATUM",&lin)) != NULL) {
+         *pusMaske |= LC_TR_VERTDATUM;
+         UT_StrToken(cp,0,&itxi,7,pTrans->szVertdatHref);
+         UT_StrToken(cp,itxi,&itxi,6,pTrans->szVertdatDref);
+         UT_StrToken(cp,itxi,&itxi,6,pTrans->szVertdatFref);
+         UT_StrToken(cp,itxi,&itxi,2,pTrans->szVertdatHtyp);
+      }
+   }
+   
+   /* Vert-int */
+   if ((usMaskeInn & LC_TR_VERTINT) != 0) {
+      lin = 2;
+      if ((cp = ho_GetVal(pFil,"...VERT-INT",&lin)) != NULL) {
+         *pusMaske |= LC_TR_VERTINT;
+         UT_StrShort(cp,0,&itxi,&pTrans->sVertintHref);
+         UT_StrShort(cp,itxi,&itxi,&pTrans->sVertintDref);
+         UT_StrShort(cp,itxi,&itxi,&pTrans->sVertintFref);
+      }
+   }
+
+   /* Vert-delta */
+   if ((usMaskeInn & LC_TR_VERTDELTA) != 0) {
+      lin = 2;
+      if ((cp = ho_GetVal(pFil,"...VERT-DELTA",&lin)) != NULL) {
+         *pusMaske |= LC_TR_VERTDELTA;
+         UT_StrShort(cp,0,&itxi,&pTrans->sVdeltaMin);
+         UT_StrShort(cp,itxi,&itxi,&pTrans->sVdeltaMax);
+      }
+   }
+
+
+   /* ----- Div. sluttkontroll ----- */
+
+   /* Kontroller at det er funnet Koordsys, Transsys eller Geosys */
+   if ((usMaskeInn & LC_TR_KOORDSYS) != 0  ||
+       (usMaskeInn & LC_TR_TRANSSYS) != 0  ||
+       (usMaskeInn & LC_TR_GEOSYS) != 0     ) {
+      if ((*pusMaske & LC_TR_KOORDSYS) == 0  &&
+          (*pusMaske & LC_TR_TRANSSYS) == 0  &&
+          (*pusMaske & LC_TR_GEOSYS) == 0 ) {
+         /* Ikke noe koordinatsystem funnet */
+         LC_Error(15,"(ho_GetTransEx)","");
+         ist = UT_FALSE;
+      }
+   }
+
+   /* Kontroller at det er funnet Origo */
+   if ((usMaskeInn & LC_TR_ORIGO) != 0 &&  
+       (*pusMaske & LC_TR_ORIGO) == 0 ) {
+      /* Origo mangler */
+      LC_Error(16,"(ho_GetTransEx)","");
+      ist = UT_FALSE;
+   }
+
+   /* Kontroller at det er funnet Enhet */
+   if ((usMaskeInn & LC_TR_ENHET) != 0  &&  
+       (*pusMaske & LC_TR_ENHET) == 0 ) {
+      /* Enhet mangler */
+      LC_Error(17,"(ho_GetTransEx)","");
+      ist = UT_FALSE;
+   }
+
+   return ist;
+}
+
+
+
+/*
+AR:1999-07-12
+CH HO_GetTrans                                         Finner .TRANSPAR i hodet
+CD =============================================================================
+CD Form�l:
+CD Henter transformasjonsparametrene fra filhodet.
+CD
+CD OBS! Denne rutinen opprettholdes bare for bakoverkompatibilitet.
+CD      For nye programmer b�r HO_GetTransEx benyttes. HO_GetTransEx er
+CD      kompatibel med nye versjoner av SOSI.
+CD
+CD Parametre:
+CD Type     Navn       I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD char    *pszFil      i   Fullstendig filnavn
+CD short   *koosys      u   Koordinatsystem
+CD double  *origo_a     u   ..ORIGO-AUST
+CD double  *origo_n     u   ..ORIGO-NORD
+CD double  *enhet       u   ...ENHET
+CD double  *enhet_h     u   ...ENHET-H
+CD double  *enhet_d     u   ...ENHET-D
+CD short    sStatus     r   UT_TRUE, eller UT_FALSE.
+CD
+CD Bruk:
+CD sStatus = HO_GetTrans(fil,&koosys,&origo_a,&origo_n,&enhet,&enhet_h,&enhet_d);
+   =============================================================================
+*/
+SK_EntPnt_FYBA short HO_GetTrans(const char *pszFil,short *koosys,double *origo_a,
+					  double *origo_n,double *enhet,double *enhet_h,double *enhet_d)
+{
+   short sStatus;
+   FILE * pFil;
+
+   /* �pner filen */
+   pFil = UT_OpenFile(pszFil,"",UT_READ,UT_OLD,&sStatus);
+
+   /* �pnet OK ? */
+   if (sStatus == UT_OK) {
+      /* Hent verdier */
+      sStatus = ho_GetTrans(pFil,koosys,origo_a,origo_n,enhet,enhet_h,enhet_d);
+      fclose (pFil);
+
+	/* �pningsfeil p� kladdefilen */
+   } else {
+      char szError[256];
+      UT_strerror(szError,256,sStatus);
+      UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pszFil,szError);
+      LC_Error(101,"(HO_GetTrans)",err().tx);
+      sStatus = UT_FALSE;
+   }
+
+   return sStatus;
+}
+
+
+/*
+GL-880427
+AR-900314
+CH ho_GetTrans                                         Finner .TRANSPAR i hodet
+CD =============================================================================
+CD Form�l:
+CD Henter transformasjonsparametrene fra filhodet.
+CD
+CD Parametre:
+CD Type     Navn        I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD FILE    *pFil         i   Filpeker til sosi-fil.
+CD short   *koosys       u   Koordinatsystem
+CD double  *origo_a      u   ..ORIGO-AUST
+CD double  *origo_n      u   ..ORIGO-NORD
+CD double  *enhet        u   ...ENHET
+CD double  *enhet_h      u   ...ENHET-H
+CD double  *enhet_d      u   ...ENHET-D
+CD short    sStatus      r   UT_TRUE, eller UT_FALSE.
+CD
+CD Bruk:
+CD ho_GetTrans(pFil,&koosys,&origo_a,&origo_n,&enhet,&enhet_h,&enhet_d);
+   =============================================================================
+*/
+short ho_GetTrans(FILE *pFil,short *koosys,double *origo_a,
+					  double *origo_n,double *enhet,double *enhet_h,double *enhet_d)
+{
+   short lin;
+   char *cp;
+
+
+   /* Sjekk hvilket tegnsett som skal brukes */
+	ho_GetTegnsett(pFil,&Sys.BufAdm.sTegnsett);
+
+   lin=2;
+   if ( ! ho_GetVal(pFil,"..TRANSPAR",&lin)) {
+       LC_Error(14," (HO_GetTrans) "," ");
+       return UT_FALSE;
+   }
+
+   
+   *koosys=0;
+   lin=2;
+   cp = ho_GetVal(pFil,"...KOORDSYS",&lin);
+   if (cp == NULL) {
+   lin=2;
+   ho_GetVal(pFil,"..KOORDSYS",&lin);
+   }
+   if (cp == NULL) {
+    LC_Error(15," (HO_GetTrans) "," ");
+    return UT_FALSE;
+
+   } else {
+     *koosys = (short)atoi(cp);
+   }
+
+   lin=2;
+   if ((cp = ho_GetVal(pFil,"...ORIGO-N�",&lin)) == NULL) {
+    LC_Error(16," (HO_GetTrans) "," ");
+    return UT_FALSE;
+
+   } else {
+     *origo_n = strtod(cp,&cp);
+     *origo_a = strtod(cp,&cp);
+     lin=2;
+     if ((cp = ho_GetVal(pFil,"...ENHET",&lin)) == NULL) {
+        LC_Error(17," (HO_GetTrans) "," ");
+        return UT_FALSE;
+     } else {
+        *enhet = strtod(cp,&cp);
+     }
+     lin=2;
+     if ((cp = ho_GetVal(pFil,"...ENHET-H",&lin)) == NULL) {
+         *enhet_h = *enhet;
+     } else {
+         *enhet_h = strtod(cp,&cp);
+     }
+     lin=2;
+     if ((cp = ho_GetVal(pFil,"...ENHET-D",&lin)) == NULL) {
+         *enhet_d = *enhet;
+     } else {
+         *enhet_d = strtod(cp,&cp);
+     }
+   }
+
+   return UT_TRUE;
+}
+
+
+/*
+AR-890823
+CH HO_GetOmr                                            Finner ..OMR�DE i hodet
+CD =============================================================================
+CD Form�l:
+CD Henter omr�deangivelsen fra filhodet.
+CD
+CD Parametre:
+CD Type     Navn        I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD char    *pszFil      i   Fullstendig filnavn
+CD double  *nv_a        u
+CD double  *nv_n        u
+CD double  *oh_a        u
+CD double  *oh_n        u
+CD short    sStatus     r   UT_TRUE, eller UT_FALSE.
+CD
+CD Bruk:
+CD sStatus = HO_GetOmr(pszFil,&nv_a,&nv_n,&oh_a,&oh_n);
+	=============================================================================
+*/
+SK_EntPnt_FYBA short HO_GetOmr(const char * pszFil,double *nv_a,double *nv_n,double *oh_a,double *oh_n)
+{
+   short sStatus;
+   FILE * pFil;
+
+   /* �pner filen */
+   pFil = UT_OpenFile(pszFil,"",UT_READ,UT_OLD,&sStatus);
+
+   /* �pnet OK ? */
+   if (sStatus == UT_OK) {
+      /* Hent verdier */
+      ho_GetOmr(pFil,nv_a,nv_n,oh_a,oh_n);
+      fclose (pFil);
+      sStatus = UT_TRUE;
+
+	/* �pningsfeil */
+   } else {
+      char szError[256];
+      UT_strerror(szError,256,sStatus);
+      UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pszFil,szError);
+      LC_Error(101,"(HO_GetOmr)",err().tx);
+      sStatus = UT_FALSE;
+   }
+
+   return sStatus;
+}
+
+
+/*
+AR-890823
+CH ho_GetOmr                                            Finner ..OMR�DE i hodet
+CD =============================================================================
+CD Form�l:
+CD Henter omr�deangivelsen fra filhodet.
+CD
+CD Parametre:
+CD Type     Navn        I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD FILE    *fil          i    Filpeker til sosi-fil.
+CD double  *nv_a         u
+CD double  *nv_n         u
+CD double  *oh_a         u
+CD double  *oh_n         u
+CD short    sStatus      r    UT_TRUE, eller UT_FALSE.
+CD
+CD Bruk:
+CD sStatus = ho_GetOmr(fil,&nv_a,&nv_n,&oh_a,&oh_n);
+	=============================================================================
+*/
+short ho_GetOmr(FILE *fil,double *nv_a,double *nv_n,double *oh_a,double *oh_n)
+{
+   short lin,i;
+   char *cp;
+   short sStatus = UT_TRUE;
+
+
+   /* Sjekk hvilket tegnsett som skal brukes */
+   ho_GetTegnsett(fil,&Sys.BufAdm.sTegnsett);
+
+
+   lin=2;
+   if (ho_GetVal(fil,"..OMR�DE",&lin) == NULL) {
+      LC_Error(7,"(HO_GetOmr)","");
+      *nv_n = -9999999.0;
+      *nv_a = -9999999.0;
+      *oh_n =  9999999.0;
+      *oh_a =  9999999.0;
+      sStatus = UT_FALSE;
+
+
+   } else {
+      /* Min-N� */
+      i = lin;
+	   if ((cp = ho_GetVal(fil,"...MIN-N�",&i)) == NULL ) {
+         LC_Error(8,"(HO_GetOmr)","");
+         *nv_n = -9999999.0;
+         *nv_a = -9999999.0;
+         sStatus = UT_FALSE;
+      
+      } else {
+         *nv_n = strtod(cp,&cp);
+         *nv_a = strtod(cp,&cp);
+      }
+      
+		/* Max-N� */
+      i = lin;
+      if ((cp = ho_GetVal(fil,"...MAX-N�",&i)) == NULL) {
+         LC_Error(9,"(HO_GetOmr)","");
+         *oh_n = 999999.0;
+         *oh_a = 9999999.0;
+         sStatus = UT_FALSE;
+      
+      } else{
+         *oh_n = strtod(cp,&cp);
+         *oh_a = strtod(cp,&cp);
+      }
+   }
+
+   /* Sjekker at omr�det har utstrekning */
+   //if (*oh_a-*nv_a < 0.001  ||  *oh_n-*nv_n < 0.001) {
+   //   LC_Error(104,"(HO_GetOmr)","");
+   //   *nv_n = -9999999.0;
+   //   *nv_a = -9999999.0;
+   //   *oh_n =  9999999.0;
+   //   *oh_a =  9999999.0;
+	//}
+
+   return sStatus;
+}
+
+
+
+
+/*
+AR:1999-07-12
+CH HO_GetKvalitet                                 Finner kvalitetsopplysninger
+CD =============================================================================
+CD Form�l:
+CD Finne kvalitetsopplysninger i filhode.
+CD (Ikke aktuellt etter SOSI v. 4.00.)
+CD
+CD Parametre:
+CD Type    Navn              I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD char   *pszFil             i  Fullstendig filnavn
+CD short  *psMetode           u  Hvordan data er registrert.
+CD                                 KVAL_MET_UNDEF  metode er udefinert.
+CD long   *pLNnoyaktighet     u  Registreringsn�yaktighet
+CD                                 KVAL_NOY_UKJENT  n�yaktighet er ukjent.
+CD short  *psSynbarhet        u  Synbarhet i bilde
+CD                                 KVAL_SYN_UNDEF  synbarhet er udefinert.
+CD short  *psHoydeMetode      u  Hvordan h�yden er registrert.
+CD                                 KVAL_MET_UNDEF  metode er udefinert.
+CD long   *plHoydeNoyaktighet u  Registreringsn�yaktighet
+CD                                 KVAL_NOY_UKJENT  n�yaktighet er ukjent.
+CD short   ist                r  Statusvariabel: UT_TRUE  - OK, ..KVALITET er funnet
+CD                                               UT_FALSE - ikke funnet
+CD
+CD Bruk:
+CD      ist = HO_GetKvalitet(fil,&sMetode,&lNoyaktighet,&sSynbarhet,
+CD                           &sHoydeMetode,&lHoydeNoyaktighet);
+CD =============================================================================
+*/
+SK_EntPnt_FYBA short HO_GetKvalitet(const char *pszFil,short *psMetode,long *plNoyaktighet,
+                     short *psSynbarhet,short *psHoydeMetode,long *plHoydeNoyaktighet)
+{
+   short sStatus;
+   FILE * pFil;
+
+   /* �pner filen */
+   pFil = UT_OpenFile(pszFil,"",UT_READ,UT_OLD,&sStatus);
+
+   /* �pnet OK ? */
+   if (sStatus == UT_OK) {
+      /* Hent verdier */
+      sStatus = ho_GetKvalitet(pFil,psMetode,plNoyaktighet,psSynbarhet,psHoydeMetode,plHoydeNoyaktighet);
+      fclose (pFil);
+
+	/* �pningsfeil */
+   } else {
+      char szError[256];
+      UT_strerror(szError,256,sStatus);
+      UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pszFil,szError);
+      LC_Error(101,"(HO_GetKvalitet)",err().tx);
+      sStatus = UT_FALSE;
+   }
+
+   return sStatus;
+}
+
+
+
+/*
+OJ-891123
+CH ho_GetKvalitet                                 Finner kvalitetsopplysninger
+CD =============================================================================
+CD Form�l:
+CD Finne kvalitetsopplysninger i filhode.
+CD (Ikke aktuellt etter SOSI v. 4.00.)
+CD
+CD Parametre:
+CD Type    Navn              I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD FILE   *pFil               i  Filpeker til sosi-fil.
+CD short  *psMetode           u  Hvordan data er registrert.
+CD                                 KVAL_MET_UNDEF  metode er udefinert.
+CD long   *pLNnoyaktighet     u  Registreringsn�yaktighet
+CD                                 KVAL_NOY_UKJENT  n�yaktighet er ukjent.
+CD short  *psSynbarhet        u  Synbarhet i bilde
+CD                                 KVAL_SYN_UNDEF  synbarhet er udefinert.
+CD short  *psHoydeMetode      u  Hvordan h�yden er registrert.
+CD                                 KVAL_MET_UNDEF  metode er udefinert.
+CD long   *plHoydeNoyaktighet u  Registreringsn�yaktighet
+CD                                 KVAL_NOY_UKJENT  n�yaktighet er ukjent.
+CD short   ist                r  Statusvariabel: UT_TRUE  - OK, ..KVALITET er funnet
+CD                                               UT_FALSE - ikke funnet
+CD
+CD Bruk:
+CD      ist = ho_GetKvalitet(fil,&sMetode,&lNoyaktighet,&sSynbarhet,
+CD                           &sHoydeMetode,&lHoydeNoyaktighet);
+CD =============================================================================
+*/
+short ho_GetKvalitet(FILE *pFil,short *psMetode,long *plNoyaktighet,
+                     short *psSynbarhet,short *psHoydeMetode,long *plHoydeNoyaktighet)
+{
+	short lin;
+   char *cp;
+   short ist = UT_FALSE;
+
+
+   /* Sjekk hvilket tegnsett som skal brukes */
+   ho_GetTegnsett(pFil,&Sys.BufAdm.sTegnsett);
+
+   lin=2;
+   if ((cp = ho_GetVal(pFil,"..KVALITET",&lin)) != NULL) {     /* Kvalitet */
+      ist = UT_TRUE;
+   }
+
+   /* Tolk strengen til tallverdier */
+   LN_TolkKvalitet(cp,psMetode,plNoyaktighet,psSynbarhet,
+                   psHoydeMetode,plHoydeNoyaktighet);
+
+
+   /* Handter manglende h�yde-kvalitet spesiellt */
+	if (*psHoydeMetode == KVAL_MET_UNDEF)      *psHoydeMetode      = *psMetode;
+   if (*plHoydeNoyaktighet == KVAL_NOY_UKJENT) *plHoydeNoyaktighet = *plNoyaktighet;
+
+   return ist;
+}
+
+
+
+/*
+AR-920331
+CH HO_GetTegnsett                                            Finner tegnsett
+CD ==========================================================================
+CD Form�l:
+CD Finne tegnsett i filhodet.
+CD
+CD Parametre:
+CD Type     Navn      I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD char   *pszFil      i   Fullstendig filnavn
+CD short  *psTegnsett  u   Tegnsett, konstanter definert:
+CD                            TS_DOSN8   = DOS norsk 8-bits(standardverdi)
+CD                            TS_ND7     = Norsk Data 7-bits
+CD                            TS_DECM8   = DEC multinasjonal 8-bits
+CD                            TS_ISO8859 = ISO8859-10 Norsk/samisk tegnsett
+CD                            TS_DECN7   = DEC norsk 7-bits
+CD short   sStatus     r   Status: UT_TRUE  = Funnet
+CD                                 UT_FALSE = Ikke funnet
+CD
+CD Bruk:
+CD      sStatus = HO_GetTegnsett(pszFil,&sTegnsett);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short HO_GetTegnsett(const char *pszFil,short *psTegnsett)
+{
+   short sStatus;
+   FILE * pFil;
+
+   /* �pner filen */
+   pFil = UT_OpenFile(pszFil,"",UT_READ,UT_OLD,&sStatus);
+
+   /* �pnet OK ? */
+   if (sStatus == UT_OK) {
+      /* Hent verdier */
+      sStatus = ho_GetTegnsett(pFil,psTegnsett);
+      fclose (pFil);
+
+	/* �pningsfeil */
+   } else {
+      char szError[256];
+      UT_strerror(szError,256,sStatus);
+      UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pszFil,szError);
+      LC_Error(101,"(HO_GetTegnsett)",err().tx);
+      sStatus = UT_FALSE;
+   }
+
+   return sStatus;
+}
+
+
+/*
+AR-920331
+CH ho_GetTegnsett                                            Finner tegnsett
+CD ==========================================================================
+CD Form�l:
+CD Finne tegnsett i filhodet.
+CD
+CD Parametre:
+CD Type     Navn      I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD FILE    *fil        i   Filpeker til sosi-fil.
+CD short  *psTegnsett  u   Tegnsett, konstanter definert:
+CD                            TS_DOSN8   = DOS norsk 8-bits(standardverdi)
+CD                            TS_ND7     = Norsk Data 7-bits
+CD                            TS_DECM8   = DEC multinasjonal 8-bits
+CD                            TS_ISO8859 = ISO8859-10 Norsk/samisk tegnsett
+CD                            TS_DECN7   = DEC norsk 7-bits
+CD short   sStatus     r   Status: UT_TRUE  = Funnet
+CD                                 UT_FALSE = Ikke funnet
+CD
+CD Bruk:
+CD      sStatus = ho_GetTegnsett(fil,&sTegnsett);
+CD ==========================================================================
+*/
+short ho_GetTegnsett(FILE *pFil,short *psTegnsett)
+{
+   short lin;
+   char *cp;
+   short ist = UT_FALSE;
+
+   *psTegnsett = TS_DOSN8;       
+   lin=2;                        
+
+   if ((cp = ho_GetVal(pFil,"..TEGNSETT",&lin)) != NULL) {     /* Tegnsett */
+      ist = UT_TRUE;
+		UT_StrUpper(cp);
+      if (strcmp(cp,"ISO8859-10") == 0) {
+         *psTegnsett = TS_ISO8859;
+
+      } else if (strcmp(cp,"ISO8859-1") == 0) {
+         *psTegnsett = TS_ISO8859;
+
+      } else if (strcmp(cp,"ANSI") == 0) {
+         *psTegnsett = TS_ISO8859;
+
+      } else if (strcmp(cp,"ND7") == 0) {
+         *psTegnsett = TS_ND7;
+
+      } else if (strcmp(cp,"DECN7") == 0) {
+         *psTegnsett = TS_DECN7;
+
+      } else if (strcmp(cp,"DECM8") == 0) {
+         *psTegnsett = TS_DECM8;
+		}
+   }
+
+   return ist;
+}
+
+
+/*
+AR:1999-07-14
+CH HO_GetVal                                      Finn verdien til et SOSI-navn
+CD =============================================================================
+CD Form�l:
+CD Henter parametrene til et SOSI-navn.
+CD Strengen ligger i et felles "returbuffer" for alle get-rutiner i fyba.
+CD Dette blir �delagt ved neste kall til en "get-rutine". For � ta vare p�
+CD strengen m� den kopieres over til egen streng. (Bruk strcpy).
+CD
+CD Parametre:
+CD Type     Navn        I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD char    *pszFil       i   Fullstendig filnavn
+CD char    *sosi_navn    i   SOSI-navn det skal finnes verdi til
+CD short   *sett_nr     i/u  i: "Sett nummer"(linjenummer) for start s�king (min 1)
+CD                           u: Ved tilslag returneres "Sett nummer" for
+CD                              tilslaget.
+CD char    *para_peker   r   Peker til parameter-streng avslutta med '\0'.
+CD                           Hvis SOSI-navnet ikke er funnet returneres NULL.
+CD
+CD Bruk:
+CD para_peker = HO_GetVal(fil,sosi_navn,&sett_nr);
+	=============================================================================
+*/
+SK_EntPnt_FYBA char *HO_GetVal(const char *pszFil,char *sosi_navn,short *sett_nr)
+{
+   short sStatus;
+   FILE * pFil;
+   char *rp = NULL;               /* Retur peker */
+
+
+   /* �pner filen */
+   pFil = UT_OpenFile(pszFil,"",UT_READ,UT_OLD,&sStatus);
+
+   /* �pnet OK ? */
+   if (sStatus == UT_OK) {
+      /* Hent verdier */
+      rp = ho_GetVal(pFil,sosi_navn,sett_nr);
+      fclose (pFil);
+
+	/* �pningsfeil */
+   } else {
+      char szError[256];
+      UT_strerror(szError,256,sStatus);
+      UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pszFil,szError);
+      LC_Error(101,"(HO_GetVal)",err().tx);
+      sStatus = UT_FALSE;
+   }
+
+   return rp;
+}
+
+
+/*
+GL:1988-04-27
+AR:1989-08-23
+CH ho_GetVal                                      Finn verdien til et SOSI-navn
+CD =============================================================================
+CD Form�l:
+CD Henter parametrene til et SOSI-navn.
+CD Strengen ligger i et felles "returbuffer" for alle get-rutiner i fyba.
+CD Dette blir �delagt ved neste kall til en "get-rutine". For � ta vare p�
+CD strengen m� den kopieres over til egen streng. (Bruk strcpy).
+CD
+CD Parametre:
+CD Type     Navn        I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD FILE    *pFil         i   Filpeker til sosi-fil.
+CD char    *sosi_navn    i   SOSI-navn det skal finnes verdi til
+CD short   *sett_nr     i/u  i: "Sett nummer"(linjenummer) for start s�king (min 1)
+CD                           u: Ved tilslag returneres "Sett nummer" for
+CD                              tilslaget.
+CD char    *para_peker   r   Peker til parameter-streng avslutta med '\0'.
+CD                           Hvis SOSI-navnet ikke er funnet returneres NULL.
+CD
+CD Bruk:
+CD para_peker = ho_GetVal(pFil,sosi_navn,&sett_nr);
+	=============================================================================
+*/
+char *ho_GetVal(FILE *pFil,char *sosi_navn,short *sett_nr)
+{
+   UT_INT64 startpos;
+   short ant_par,navn_nr,type;
+   short funnet = 0;
+   short ferdig = 0;
+   short sett = 0;
+   LB_LESEBUFFER * pLb = &(Sys.BufAdm);
+   char *rp = NULL;               /* Retur peker */
+
+
+   // S�k fram til .HODE
+   if (ho_FinnHode(pFil, &startpos) == UT_TRUE) {
+      // Finn riktig info
+      // SOSI-navnet
+      LN_PakkNavn(&(Sys.SosiNavn),sosi_navn,&navn_nr,&ant_par);
+
+      /* Sikkrer at ny lesing startes */
+      pLb->sStatus = LESEBUFFER_TOM;
+      //_fseeki64(pFil,startpos,SEEK_SET);
+      UT_SetPos_i64(pFil,startpos);
+
+      do {
+         sett++;
+         /* Hent "sett" */
+         type = LB_GetSet(pFil,pLb,&(Sys.SosiNavn));
+         if (type >= 0  ||  type == LEST_GINFO) {
+            if (sett > 1  &&  pLb->cur_niv == 1) {
+               ferdig = 1;
+
+            } else {
+               if (sett >= *sett_nr) {
+                  if (pLb->cur_navn[pLb->cur_niv-1] == navn_nr) {
+                     funnet = 1;
+                     rp = pLb->pp;
+                     *sett_nr = sett;
+                  }
+               }
+            }
+         }
+         pLb->set_brukt = SET_BRUKT;
+      } while ( ! ferdig  &&  ! funnet);       /* S�k etter navnet */
+   }
+
+   pLb->sStatus = LESEBUFFER_TOM;
+   return rp;
+}
+
+
+/*
+GL-880303
+AR-891124
+CH  HO_New                                                   Lager nytt hode
+CD  =========================================================================
+CD Form�l:
+CD Genererer et nytt SOSI-filhode.
+CD Hvis omr�de ikke har noen utstrekning justeres
+CD dette med 1 meter i hver retning. 
+CD
+CD Parametre:
+CD Type     Navn         I/U    Forklaring
+CD --------------------------------------------------------------------------
+CD char    *pszFil        i    Fullstendig filnavn
+CD short    koosys        i    Koordinatsystem
+CD double   origo_a       i    Origo �st
+CD double   origo_n       i    Origo nord
+CD double   enhet         i    Enhet
+CD double   enhet_h       i    Enhet-H
+CD double   enhet_d       i    Enhet-D
+CD double   nv_a          i    Omr�de:  Nedre venstre hj�rne
+CD double   nv_n          i
+CD double   oh_a          i             �vre h�yre hj�rne
+CD double   oh_n          i
+CD short    sStatus       r    Status: UT_TRUE  = Funnet
+CD                                     UT_FALSE = Ikke funnet
+CD
+CD Bruk:
+CD sStatus = HO_New(fil,koosys,origo_a,origo_n,enhet,enhet_h-enhet_d,
+CD                  nv_a,nv_n,oh_a,oh_n);
+CD =============================================================================
+*/
+SK_EntPnt_FYBA short HO_New(const char *pszFil,short koosys,double origo_a,double origo_n,
+            double enhet,double enhet_h,double enhet_d,
+            double nv_a,double nv_n,double oh_a,double oh_n)
+{
+
+   short sStatus = UT_TRUE;
+   FILE * pFil;
+
+
+   /* �pner filen */
+   pFil = UT_OpenFile(pszFil,"",UT_UPDATE,UT_UNKNOWN,&sStatus);
+
+   /* �pnet OK ? */
+   if (sStatus == UT_OK) {
+      /* Skriv nytt hode */
+      ho_New(pFil, koosys, origo_a, origo_n, enhet, enhet_h, enhet_d,
+             nv_a, nv_n, oh_a, oh_n);
+
+      fclose (pFil);
+      sStatus = UT_TRUE;
+
+	/* �pningsfeil */
+   } else {
+      char szError[256];
+      UT_strerror(szError,256,sStatus);
+      UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pszFil,szError);
+      LC_Error(101,"(HO_New)",err().tx);
+      sStatus = UT_FALSE;
+   }
+
+   return sStatus;
+}
+
+
+/*
+GL-880303
+AR-891124
+CH  ho_New                                                   Lager nytt hode
+CD  =========================================================================
+CD Form�l:
+CD Genererer et nytt SOSI-filhode.
+CD Hvis omr�de ikke har noen utstrekning justeres
+CD dette med 1 meter i hver retning. 
+CD
+CD Parametre:
+CD Type     Navn         I/U    Forklaring
+CD --------------------------------------------------------------------------
+CD FILE    *fil           i   Filpeker til sosi-fil.
+CD short    koosys        i    Koordinatsystem
+CD double   origo_a       i    Origo �st
+CD double   origo_n       i    Origo nord
+CD double   enhet         i    Enhet
+CD double   enhet_h       i    Enhet-H
+CD double   enhet_d       i    Enhet-D
+CD double   nv_a          i    Omr�de:  Nedre venstre hj�rne
+CD double   nv_n          i
+CD double   oh_a          i             �vre h�yre hj�rne
+CD double   oh_n          i
+CD
+CD Bruk:
+CD     ho_New(fil,koosys,origo_a,origo_n,enhet,enhet_h-enhet_d,
+CD            nv_a,nv_n,oh_a,oh_n);
+CD =============================================================================
+*/
+void ho_New(FILE *fil,short koosys,double origo_a,double origo_n,
+            double enhet,double enhet_h,double enhet_d,
+            double nv_a,double nv_n,double oh_a,double oh_n)
+{
+   char tx[LC_MAX_SOSI_LINJE_LEN];
+
+
+   //_fseeki64(fil,0,SEEK_SET);
+   UT_SetPos_i64(fil,0);
+
+   LB_WriteLine(fil,LC_INTERNT_TEGNSETT,".HODE\r\n");
+   LB_WriteLine(fil,LC_INTERNT_TEGNSETT,"..TEGNSETT ISO8859-10\r\n");
+   LB_WriteLine(fil,LC_INTERNT_TEGNSETT,"..TRANSPAR\r\n");
+   UT_SNPRINTF(tx,LC_MAX_SOSI_LINJE_LEN,"...KOORDSYS  %d\r\n",koosys);
+   LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+   UT_SNPRINTF(tx,LC_MAX_SOSI_LINJE_LEN,"...ORIGO-N�  %.0f  %.0f\r\n",origo_n,origo_a);
+   LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+   
+   //UT_SNPRINTF(tx,LC_MAX_SOSI_LINJE_LEN,"...ENHET  %-.3f\r\n",enhet);
+   LB_FormaterEnhet(tx,LC_MAX_SOSI_LINJE_LEN,"...ENHET",enhet);
+   UT_StrCat(tx,"\r\n",LC_MAX_SOSI_LINJE_LEN);
+   LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+   
+   if (fabs(enhet-enhet_h)>0.000001) {
+      LB_FormaterEnhet(tx,LC_MAX_SOSI_LINJE_LEN,"...ENHET-H",enhet_h);
+      UT_StrCat(tx,"\r\n",LC_MAX_SOSI_LINJE_LEN);
+      LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+   }
+   
+   if (fabs(enhet-enhet_d)>0.000001) {
+      LB_FormaterEnhet(tx,LC_MAX_SOSI_LINJE_LEN,"...ENHET-D",enhet_d);
+      UT_StrCat(tx,"\r\n",LC_MAX_SOSI_LINJE_LEN);
+      LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+   }
+   LB_WriteLine(fil,LC_INTERNT_TEGNSETT,"..OMR�DE\r\n");
+   
+   // Hvis n�dvendig justeres omr�de
+   if (fabs(oh_n-nv_n) < 0.000001) {
+      nv_n -= 1.0;
+      oh_n += 1.0;
+   }
+   if (fabs(oh_a-nv_a) < 0.000001) {
+      nv_a -= 1.0;
+      oh_a += 1.0;
+   }
+
+   UT_SNPRINTF(tx,LC_MAX_SOSI_LINJE_LEN,"...MIN-N�   %.0f     %.0f\r\n",nv_n,nv_a);
+   LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+   UT_SNPRINTF(tx,LC_MAX_SOSI_LINJE_LEN,"...MAX-N�   %.0f     %.0f\r\n",oh_n,oh_a);
+   LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+
+   UT_SNPRINTF(tx,LC_MAX_SOSI_LINJE_LEN,"..SOSI-VERSJON %.2f\r\n",((double)FYBA_SOSI_VERSJON)/100.0);
+   LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+
+   UT_StrCopy(tx,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n",LC_MAX_SOSI_LINJE_LEN);
+   LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+   LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+   LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+   LB_WriteLine(fil,LC_INTERNT_TEGNSETT,".SLUTT\r\n");
+
+   /* chsize(fileno(fil),ftell(fil)-1); */    /* Sett filst�rrelse */
+}
+
+
+/*
+AR:1999-07-14
+CH HO_TestSOSI                                              Tester SOSI-filen
+CD =============================================================================
+CD Form�l:
+CD Sjekker at filen er en SOSI-fil, og finner posisjonen for .SLUTT.
+CD
+CD Parametre:
+CD Type      Navn       I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD char     *pszFil      i    Fullstendig filnavn
+CD UT_INT64 *sluttpos    u    Posisjon for .SLUTT
+CD short     ist         r    Status: UT_TRUE  = OK
+CD                                  UT_FALSE = feil
+CD
+CD Bruk:
+CD     ist = HO_TestSOSI(pszFil,&sluttpos);
+CD =============================================================================
+*/
+SK_EntPnt_FYBA short HO_TestSOSI(const char *pszFil,UT_INT64 *sluttpos)
+{
+   short sStatus;
+   FILE * pFil;
+
+
+   /* �pner filen */
+   pFil = UT_OpenFile(pszFil,"",UT_READ,UT_OLD,&sStatus);
+
+   /* �pnet OK ? */
+   if (sStatus == UT_OK) {
+      /* Sjekk filen */
+      sStatus = ho_TestSOSI(pFil,sluttpos);
+      fclose (pFil);
+
+	/* �pningsfeil */
+   } else {
+      char szError[256];
+      UT_strerror(szError,256,sStatus);
+      UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pszFil,szError);
+      LC_Error(101,"(HO_TestSOSI)",err().tx);
+      sStatus = UT_FALSE;
+   }
+
+   return sStatus;
+}
+
+
+/*
+AR-891205
+CH ho_TestSOSI                                              Tester SOSI-filen
+CD =============================================================================
+CD Form�l:
+CD Sjekker at filen er en SOSI-fil, og finner posisjonen for .SLUTT.
+CD
+CD Parametre:
+CD Type      Navn      I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD FILE     *pFil       i    Filpeker til sosi-fil.
+CD UT_INT64 *sluttpos   u    Posisjon for .SLUTT
+CD short     ist        r    Status: UT_TRUE  = OK
+CD                                 UT_FALSE = feil
+CD
+CD Bruk:
+CD     ist = ho_TestSOSI(pFil,&sluttpos);
+CD =============================================================================
+*/
+short ho_TestSOSI(FILE *pFil,UT_INT64 *sluttpos)
+{
+   short ferdig;
+   char tx[LC_MAX_SOSI_LINJE_LEN];
+   UT_INT64 startpos,filpos;
+   double nv_a,nv_n,oh_a,oh_n;
+   short ist = UT_FALSE;
+
+   *sluttpos = 0;
+   
+   // ----- Sjekk at filen starter med .HODE og s�k fram til .HODE
+   if (ho_FinnHode(pFil, &startpos) == UT_TRUE) {
+      ist = UT_FALSE;
+
+      // Skann siste del av filen for � finne .SLUTT
+      ferdig = 0;
+      _fseeki64(pFil,-200,SEEK_END);
+      UT_GetPos_i64(pFil,&filpos);
+
+      while (!ferdig  &&  UT_ReadLine(pFil,LC_MAX_SOSI_LINJE_LEN,tx) == UT_OK) {
+         if (*tx == '.' &&  *(tx+1) == 'S') {
+            if (strncmp(tx,".SLUTT",6) == 0) {  /* .SLUTT er funnet */
+               *sluttpos = filpos;
+               ferdig = 1;
+               ist = UT_TRUE;
+            }
+         }
+         //UT_GetPos(pFil,&filpos);
+         filpos = _ftelli64(pFil);
+      }
+                 
+      if (ist == UT_FALSE) {
+         // .SLUTT ikke er funnet, skann hele filen fra hodet 
+         ferdig = 0;
+         filpos = startpos;
+         UT_SetPos_i64(pFil,filpos);
+  
+         while (!ferdig  &&  UT_ReadLine(pFil,LC_MAX_SOSI_LINJE_LEN,tx) == UT_OK) {
+            if (*tx == '.' &&  *(tx+1) == 'S') {
+               if (strncmp(tx,".SLUTT",6) == 0) {  /* .SLUTT er funnet */
+                  *sluttpos = filpos;
+                  ferdig = 1;
+                  ist = UT_TRUE;
+               }
+            }
+            UT_GetPos_i64(pFil,&filpos);
+         }
+      }
+   }
+
+
+   /* Sjekk at hodet har transpar og fornuftig omr�de */   
+   if (ist == UT_TRUE) {
+      unsigned short usMaske = LC_TR_ALLT;
+      LC_TRANSPAR Trans;
+      ist = ho_GetTransEx(pFil,&usMaske,&Trans);
+
+      if (ist == UT_TRUE) {
+         ist = ho_GetOmr(pFil,&nv_a,&nv_n,&oh_a,&oh_n);
+      }
+   }
+
+   return ist;
+}
+
+
+/*
+HT:1998-05-19
+CH HO_SjekkTegnsett                              Sjekker tegnsett p� SOSI-filen
+CD =============================================================================
+CD Form�l:
+CD Sjekker faktisk tegnsett i .HODE.
+CD
+CD Parametre:
+CD Type    Navn       I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD char   *pszFil      i   Fullstendig filnavn
+CD short  *psTegnsett  u   Tegnsett, konstanter definert:
+CD                            TS_UKJENT  = Fikk ikke sjekket tegnsett
+CD                            TS_DOSN8   = DOS norsk 8-bits(standardverdi)
+CD                            TS_ND7     = Norsk Data 7-bits
+CD                            TS_DECM8   = DEC multinasjonal 8-bits
+CD                            TS_ISO8859 = ISO8859-10 Norsk/samisk tegnsett
+CD                            TS_DECN7   = DEC norsk 7-bits
+CD short   sStatus     r   Status:  0  = Ikke funnet
+CD                                  1  = Ett tegnsett funnet
+CD                                  2  = Flere tegnsett funnet
+CD Bruk:
+CD     sStatus = HO_SjekkTegnsett(fpek,tegnsett);
+CD =============================================================================
+*/
+SK_EntPnt_FYBA short HO_SjekkTegnsett(const char *pszFil,short *psTegnsett)
+{
+   short sStatus;
+   FILE * pFil;
+
+
+   /* �pner filen */
+   pFil = UT_OpenFile(pszFil,"",UT_READ,UT_OLD,&sStatus);
+
+   /* �pnet OK ? */
+   if (sStatus == UT_OK) {
+      /* Sjekk filen */
+      sStatus = ho_SjekkTegnsett(pFil,psTegnsett);
+      fclose (pFil);
+
+	/* �pningsfeil */
+   } else {
+      char szError[256];
+      UT_strerror(szError,256,sStatus);
+      UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pszFil,szError);
+      LC_Error(101,"(HO_SjekkTegnsett)",err().tx);
+      sStatus = 0;
+   }
+
+   return sStatus;
+}
+
+
+/*
+HT-980519
+CH ho_SjekkTegnsett                              Sjekker tegnsett p� SOSI-filen
+CD =============================================================================
+CD Form�l:
+CD Sjekker faktisk tegnsett i .HODE.
+CD
+CD Parametre:
+CD Type    Navn       I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD FILE   *fil         i   Filpeker til sosi-fil.
+CD short  *psTegnsett  u   Tegnsett, konstanter definert:
+CD                            TS_UKJENT  = Fikk ikke sjekket tegnsett
+CD                            TS_DOSN8   = DOS norsk 8-bits(standardverdi)
+CD                            TS_ND7     = Norsk Data 7-bits
+CD                            TS_DECM8   = DEC multinasjonal 8-bits
+CD                            TS_ISO8859 = ISO8859-10 Norsk/samisk tegnsett
+CD                            TS_DECN7   = DEC norsk 7-bits
+CD short   sStatus     r   Status:  0  = Ikke funnet
+CD                                  1  = Ett tegnsett funnet
+CD                                  2  = Flere tegnsett funnet
+CD Bruk:
+CD     sStatus = ho_SjekkTegnsett(fpek,tegnsett);
+CD =============================================================================
+*/
+short ho_SjekkTegnsett(FILE *fil,short *psTegnsett)
+{
+   char *ch, tx[LC_MAX_SOSI_LINJE_LEN];
+   short tegnsett, lesefeil;
+   short ferdig = 0;
+   short ant = 0; 
+
+/*          �   �   �   �   �   � 
+TS_DOSN8   146 157 143 145 155 134 
+TS_ND7      91  92  93 123 124 125 
+TS_ISO8859 198 216 197 230 248 229 */
+   static unsigned char atab[256] =
+   { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 19 */
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 39 */
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 59 */
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 79 */
+     0,0,0,0,0,0,0,0,0,0,0,TS_ND7,TS_ND7,TS_ND7,0,0,0,0,0,0, /* 99 */
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 119 */
+     0,0,0,TS_ND7,TS_ND7,TS_ND7,0,0,0,0,0,0,0,0,TS_DOSN8,0,0,0,0,0, /* 139 */
+     0,0,0,TS_DOSN8,0,TS_DOSN8,TS_DOSN8,0,0,0,0,0,0,0,0,TS_DOSN8,0,TS_DOSN8,0,0, /* 159 */
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 179 */
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,TS_ISO8859,TS_ISO8859,0, /* 199 */
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,TS_ISO8859,0,0,0, /* 219 */
+     0,0,0,0,0,0,0,0,0,TS_ISO8859,TS_ISO8859,0,0,0,0,0,0,0,0,0, /* 239 */
+     0,0,0,0,0,0,0,0,TS_ISO8859,0,0,0,0,0,0,0 };
+
+
+   tegnsett = TS_UKJENT;
+
+   /* Sjekker hva som faktisk er tegnsettet i .HODE,
+      starter f�rst p� filen og leser  */
+   UT_SetPos_i64(fil,0);
+   
+   /* Leser f�rste linje i .HODE */
+   lesefeil = UT_ReadLineNoComm(fil,LC_MAX_SOSI_LINJE_LEN,tx);
+   while (!ferdig  &&  ! lesefeil ){
+
+      /* Sjekker tegnsett*/
+      for (ch=tx; *ch; ch++) {
+                  
+         /* Hvis vi har f�tt sjekket tegnsettet, og det
+         ikke er funnet tidligere tas det vare p� n� */
+         if (atab[(unsigned char)*ch] && !(atab[(unsigned char)*ch] & tegnsett)) {
+            tegnsett |= atab[(unsigned char)*ch];
+            ant++;
+         }
+      }
+
+      /* Leser eventuellt neste linje i .HODE */
+      if (!ferdig) lesefeil = UT_ReadLineNoComm(fil,LC_MAX_SOSI_LINJE_LEN,tx);
+      
+      /* Slutt p� .HODE? */
+      ferdig = *(tx+1) != '.';  
+   }
+
+   *psTegnsett = tegnsett;
+ 
+   return ant;
+}
+
+
+/*
+AR:2004-05-05
+!---------------------------------------------------------------!
+! ho_TestFyllKommentar - Tester om en streng er fyll/kommentar. !
+!                                                               !
+! Retur:  UT_TRUE  = linjen er fyll/kommentar                   !
+!         UT_FALSE = linjen inneholder annen informasjon        !
+!                                                               !
+!---------------------------------------------------------------!
+*/
+static short ho_TestFyllKommentar(const char *pszTx)
+{
+   for (; *pszTx; ++pszTx) {
+      if (!UT_IsSpace(*pszTx)  &&  *pszTx != '!')  return (UT_FALSE);
+      if (*pszTx == '!')  return (UT_TRUE);
+   }
+
+   return (UT_TRUE);
+}
+
+
+/*
+AR:2004-05-05
+!---------------------------------------------------------------------!
+! ho_FinnHode - Finner filposisjonen til .HODE                        !
+!                                                                     !
+! Retur:  UT_TRUE  = Lovlig hode er funnet                            !
+!         UT_FALSE = .HODE er ikke funnet,                            !
+!                    eller .HODE er ikke f�rste logiske info i filen. !
+!                                                                     !
+!---------------------------------------------------------------------!
+*/
+short ho_FinnHode(FILE *pFil, UT_INT64 *lHodepos)
+{
+   char tx[LC_MAX_SOSI_LINJE_LEN], *cp;
+   short ierr;
+
+   *lHodepos = 0L;
+   
+   // ----- Sjekk at filen starter med .HODE
+   UT_SetPos_i64(pFil,0);
+
+   do
+   {
+      // Husk filposisjonen
+      *lHodepos =  _ftelli64(pFil);
+      // Les
+      if ((ierr = UT_ReadLine(pFil,LC_MAX_SOSI_LINJE_LEN,tx)) != UT_OK) {
+
+         return UT_FALSE;     // ===>  Retur pga. lesefeil
+      }
+   } while (ho_TestFyllKommentar(tx) == UT_TRUE);
+
+
+   // ----- Har n� funnet en linje som inneholder logisk informasjon
+
+   // Hopp over blanke p� starten av linjen
+   cp = &tx[0];
+   while (UT_IsSpace(*cp)) {
+      ++cp;
+      ++(*lHodepos);
+   }
+
+   if (strncmp(cp,".HODE",5) == 0) {
+         return UT_TRUE;      // ===>  Retur, .HODE er funnet
+   }
+         
+   return UT_FALSE;   // ===>  Retur, .HODE er ikke funnet
+}
diff --git a/FYBA/FYLB.cpp b/FYBA/FYLB.cpp
new file mode 100644
index 0000000..21c1472
--- /dev/null
+++ b/FYBA/FYLB.cpp
@@ -0,0 +1,4646 @@
+/* === 920909 ============================================================ */
+/*  STATENS KARTVERK  -  FYSAK-PC                                          */
+/*  Fil: fylb.c                                                            */
+/*  Ansvarlig: Andreas R�stad                                              */
+/*  Innhold: Bufferhandteringsrutiner for fysak-pc                         */
+/* ======================================================================= */
+
+#include "stdafx.h"
+
+#include <time.h>
+#include <math.h>
+#include <float.h>
+#include <ctype.h>
+#include <limits.h>
+#include <errno.h>
+
+
+/* Globale strukturer */
+extern LC_SYSTEMADM Sys;
+extern volatile short fyba_initiert;    /* Bryter for � vise at LC_Init er utf�rt */
+
+
+/*  Funksjonsdefinisjoner for interne funksjoner */
+static void  LB_WriteBlank(FILE *fil,short sTegnsett,UT_INT64 ltilpos);
+static char *LB_GetParameter(LB_LESEBUFFER *plb);
+static short LB_TestFyll(const char *pszTx);
+static void  LB_WriteRb(void);
+static short LB_FlyttGrTilSlutt(LC_FILADM *pFil, UT_INT64 start, UT_INT64 *neste);
+static short LB_RensOmkrets(LC_POL_OMKR * pPO,long lAktSnr,long lFraSnr);
+static void LR_TestEndreBuepTilKurve(double dDeltaFi);
+
+
+/*
+AR-911011
+CH LC_GetGrFi                                              Hent gruppe-filnr
+CD =============================================================================
+CD Form�l:
+CD Henter peker til FilAdm for aktuell gruppe.
+CD
+CD Parametre:
+CD Type         Navn    I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_FILADM * *ppFil    u   Peker til FilAdm-peker
+CD short        status   r   UT_TRUE = OK, UT_FALSE = Ingen aktuell gruppe
+CD
+CD Bruk:
+CD     status = LC_GetGrFi(&pFil);
+   =============================================================================
+*/
+SK_EntPnt_FYBA short LC_GetGrFi(LC_FILADM **ppFil)
+{
+
+   /* Er det noen aktuell gruppe? */
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {
+      *ppFil = Sys.GrId.pFil;
+      return UT_TRUE;
+   }
+
+   /* Ingen aktuell gruppe */
+   return UT_FALSE;
+}
+
+
+/*
+AR-911008
+CH LC_InitNextFil                                     Initier finn neste fil
+CD ==========================================================================
+CD Form�l:
+CD Initierer pFil for bruk i finn neste fil.
+CD
+CD Parametre:
+CD Type           Navn   I/U  Forklaring
+CD ------------------------------------------------------------------------
+CD LC_FILADM    **ppFil    u   Peker til FilAdm-peker
+CD
+CD Bruk:
+CD     LC_InitNextFil(&pFil)
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_InitNextFil(LC_FILADM **ppFil)
+{
+   *ppFil = (LC_FILADM *)-1L;
+}
+
+
+/*
+AR-911008
+CH LC_NextFil                                                 Finn neste fil
+CD ==========================================================================
+CD Form�l:
+CD Finn neste fil i aktuell base.
+CD
+CD Parametre:
+CD Type           Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM    **ppFil   iu   Peker til FilAdm-peker
+CD unsigned short usLag    i   Velg hvilke "lag" det skal s�kes i.
+CD                               LC_FRAMGR, LC_BAKGR og /eller LC_SEKV
+CD                               (Bruk "|" for � kombinere.)
+CD short          sStatus  r   Status  UT_TRUE=OK, UT_FALSE=ingen flere funnet
+CD
+CD Bruk:
+CD     LC_FILADM *pFil;
+CD               Denne l�kka g�r gjennom alle framgrunns-filene i basen
+CD     LC_InitNextFil(&pFil)
+CD     while (LC_NextFil(&pFil,LC_FRAMGR)) {
+CD       pszFilNavn = LC_GetFiNa(pFil);
+CD       .
+CD       Behandle filnavnet
+CD       .
+CD     }
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_NextFil(LC_FILADM **ppFil,unsigned short usLag)
+{
+   LC_FILADM *pF;
+
+   /* F�rste gang */
+   if (*ppFil == (void *)-1L) {
+      pF = Sys.pAktBase->pForsteFil;
+
+   } else {
+      /* LO_TestFilpeker(*ppFil,"LC_NextFil"); */
+      LO_TestFilpeker(*ppFil,"NextFil");
+      pF = (*ppFil)->pNesteFil;
+   }
+
+   /* Er det flere filer i basen? */
+   while (pF != NULL) {
+      /* Er filen i rett lag? */ 
+      if (pF->usLag & usLag) {
+         *ppFil = pF;
+         return UT_TRUE;
+
+      /* Ikke rett lag, fortsett til neste fil */
+      } else {
+         pF = pF->pNesteFil;
+      }
+   }
+
+   return UT_FALSE;
+}
+
+
+/*
+AR-911001
+CH LC_InitNextBgr                                  Initier finn neste gruppe
+CD ==========================================================================
+CD Form�l:
+CD Initierer Bgr for bruk i finn neste gruppe.
+CD
+CD Parametre:
+CD Type           Navn   I/U  Forklaring
+CD ------------------------------------------------------------------------
+CD LC_BGR *        pBgr    iu  Peker til gruppestruktur
+CD
+CD Bruk:
+CD     LC_InitNextBgr(&Bgr)
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_InitNextBgr(LC_BGR * pBgr)
+{
+   pBgr->pFil = Sys.pAktBase->pForsteFil;
+   pBgr->lNr = -1L;
+}
+
+
+/*
+AR-911003
+CH LC_NextBgr                                              Finn neste gruppe
+CD ==========================================================================
+CD Form�l:
+CD Finn neste gruppe i aktuell base.
+CD Sekvensielle filer blir ikke h�ndtert.
+CD
+CD Parametre:
+CD Type           Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR *        pBgr    iu   Peker til gruppestruktur der gruppenummer lagres
+CD unsigned short usLag    i   Velg hvilke "lag" det skal s�kes i.
+CD                               LC_FRAMGR og /eller LC_BAKGR
+CD                               (Bruk "|" for � kombinere.)
+CD short          sStatus  r   Status  UT_TRUE=OK, UT_FALSE=ingen flere grupper
+CD
+CD Bruk:
+CD     LC_BGR Bgr;
+CD               Denne l�kka g�r gjennom alle framgrunns-gruppene i basen
+CD     LC_InitNextBgr(&Bgr);
+CD     while (LC_NextBgr(&Bgr,LC_FRAMGR)) {
+CD       gnavn = LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+CD       .
+CD       Behandle gruppen
+CD       .
+CD     }
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_NextBgr(LC_BGR * pBgr,unsigned short usLag)
+{
+   LC_GRTAB_LINJE * grtp;
+
+
+   /* Er det noen fil i basen? */
+   while (pBgr->pFil != NULL) {
+      LO_TestFilpeker(pBgr->pFil,"NextBgr");
+      /* Er filen i rett lag? */ 
+      if (pBgr->pFil->usLag & usLag) {
+         /* Flere grupper i aktuell fil? */
+         while (pBgr->lNr < pBgr->pFil->lAntGr -1) {
+            pBgr->lNr++;
+
+            /*
+             * Sjekk gruppetabellen om gruppen er sletta
+             *
+             * (Permanent sletta, eller vanlig NGIS-modus, og
+             *  "NGIS-gruppe" merka som sletta.)
+             */
+
+            grtp = LI_GetGrt(pBgr->pFil,pBgr->lNr);
+            if (! (grtp->ngi == 0  ||
+                   (Sys.sNGISmodus == NGIS_NORMAL  &&
+                   grtp->info & GI_NGIS  &&
+                   grtp->info & GI_SLETTA))) {
+
+               return UT_TRUE;
+            }
+         }
+      }
+
+      /* Neste fil i basen */
+      pBgr->pFil = pBgr->pFil->pNesteFil;
+      pBgr->lNr = -1L;
+   }
+
+   return UT_FALSE;
+}
+
+
+/*
+AR-911003
+CH LC_InqAntFiler                                  Finn antall filer i basen
+CD ==========================================================================
+CD Form�l:
+CD Finn antall filer i aktuell base.
+CD
+CD Parametre:
+CD Type           Navn    I/U  Forklaring
+CD -------------------------------------------------------------------
+CD unsigned short usLag    i   Velg hvilke "lag" det skal s�kes i.
+CD                               LC_FRAMGR og /eller LC_BAKGR
+CD                               (Bruk "|" for � kombinere.)
+CD short          sAntall  r   Antall filer i aktuell base.
+CD
+CD Bruk:
+CD    Finner antall framgrunnsfiler i basen
+CD    sAntall = LC_InqAntFiler(LC_FRAMGR);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_InqAntFiler(unsigned short usLag)
+{
+   short sAntall = 0;
+
+   if (fyba_initiert == 1)
+   {
+      if (Sys.pAktBase != NULL)
+      {
+         if (usLag & LC_FRAMGR)  sAntall += Sys.pAktBase->sAntFramgrFil;
+         if (usLag & LC_BAKGR)   sAntall += Sys.pAktBase->sAntBakgrFil;
+      }
+   }
+
+   return sAntall;
+}
+
+
+/*
+AR-911001
+CH LC_GetGrNr                                             Hent gruppe-nummer
+CD ==========================================================================
+CD Form�l:
+CD Henter gruppenummer for aktuell gruppe.
+CD
+CD Parametre:
+CD Type    Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR * pBgr      iu   Peker til gruppestruktur der gruppenummer lagres
+CD short   status    r    Status  UT_TRUE=OK, UT_FALSE=ingen aktuell gruppe
+CD
+CD Bruk:
+CD     status = LC_GetGrNr(&Bgr)
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetGrNr(LC_BGR * pBgr)
+{
+   pBgr->pFil = Sys.GrId.pFil;
+   pBgr->lNr = Sys.GrId.lNr;
+
+   /* Er det noen aktuell gruppe? */
+   if (Sys.GrId.lNr != INGEN_GRUPPE)  return UT_TRUE;
+
+   /* Ingen aktuell gruppe */
+   return UT_FALSE;
+}
+
+
+/*
+AR-911001
+CH LC_GetGrPara                                        Hent gruppe-parametre
+CD ==========================================================================
+CD Form�l:
+CD Henter diverse opplysninger om aktuell gruppe.
+CD
+CD Parametre:
+CD Type    Navn   I/U   Forklaring
+CD-------------------------------------------------------------------------
+CD short   *ngi    u    Antall linjer GINFO
+CD long    *nko    u    Antall koordinater
+CD short   *info   u    Diverse informasjon. En sum av f�lgende:
+CD                        GI_PINFO = gruppen har PINFO
+CD                        GI_NAH   = gruppen har h�yde informasjon (..N�H)
+CD                        GI_NAD   = gruppen har dybde informasjon (..N�D)
+CD                        GI_KP    = gruppen har knutepunkt (...KP n)
+CD                        GI_REF   = gruppen har referanser (.. :n)
+CD                        GI_OY_REF= gruppen har referanser med �y
+CD                        GI_NGIS      = gruppen er tatt ut fra NGIS for oppdat.
+CD                        GI_SLETTA    = gruppen er sletta (merka som sletta)
+CD                        GI_READ_ONLY = gruppen kan ikke endres.
+CD
+CD short   gnavn   r    Gruppenavn. (Se under $LENKE<LC_RxGr>)
+CD
+CD Bruk:
+CD     gnavn = LC_GetGrPara(&ngi,&nko,&info);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetGrPara(short *ngi,long *nko,unsigned short *info)
+{
+   /* Feil ==> Ingen aktuell gruppe */
+   if (Sys.GrId.lNr == INGEN_GRUPPE) {
+      *ngi = 0;
+      *nko = 0;
+      return  INGEN_GRUPPE;
+
+   /* Lovlig gruppe */
+   } else {
+      *ngi = Sys.pGrInfo->ngi;
+      *nko = Sys.pGrInfo->nko;
+      *info = Sys.pGrInfo->info;
+      return  Sys.pGrInfo->gnavn;
+   }
+
+}
+
+
+/*
+AR-900107
+CH LC_GetGrParaBgr                           Hent gruppe-parametre for gruppe
+CD =============================================================================
+CD Form�l:
+CD Henter diverse opplysninger om gitt gruppenummer.
+CD
+CD Parametre:
+CD Type            Navn I/U  Forklaring
+CD------------------------------------------------------------------------------
+CD LC_BGR *         pBgr  i   Gruppenummer det �nskes opplysninger om.
+CD short          *ngi   u   Antall linjer GINFO  (0=sletta eller ulovlig nummer)
+CD long           *nko   u   Antall koordinater
+CD unsigned short *info  u   Diverse informasjon. En sum av f�lgende:
+CD                           GI_PINFO = gruppen har PINFO
+CD                           GI_NAH   = gruppen har h�yde informasjon (..N�H)
+CD                           GI_NAD   = gruppen har d�bde informasjon (..N�D)
+CD                           GI_KP    = gruppen har knutepunkt (...KP n)
+CD                           GI_REF   = gruppen har referanser (.. :n)
+CD                           GI_OY_REF= gruppen har referanser med �y
+CD                           GI_NGIS      = gruppen er tatt ut fra NGIS for oppdat.
+CD                           GI_SLETTA    = gruppen er sletta (merka som sletta)
+CD                           GI_READ_ONLY = gruppen kan ikke endres.
+CD short           gnavn r   Gruppenavn. (Se under $LENKE<LC_RxGr>)
+CD
+CD Bruk:
+CD     gnavn = LC_GetGrParaBgr(pBgr,&ngi,&nko,&info,&snr);
+   =============================================================================
+*/
+SK_EntPnt_FYBA short LC_GetGrParaBgr(LC_BGR * pBgr,short *ngi,long *nko,unsigned short *info)
+{
+   LC_GRTAB_LINJE * grtp;
+
+   /* Aktuell gruppe */
+   if (pBgr->pFil == Sys.GrId.pFil  &&  pBgr->lNr == Sys.GrId.lNr) {
+      *ngi = Sys.pGrInfo->ngi;
+      *nko = Sys.pGrInfo->nko;
+      *info = Sys.pGrInfo->info;
+      return  Sys.pGrInfo->gnavn;        /* ==> retur */
+   }
+
+   /* Hent fra gruppetabellen */
+   LO_TestFilpeker(pBgr->pFil,"GetGrParaBgr");
+   grtp = LI_GetGrt(pBgr->pFil,pBgr->lNr);
+
+   /* Sjekk om NGIS-gruppe og merka som sletta */
+   if (Sys.sNGISmodus == NGIS_NORMAL  &&    /* Vanlig modus, og         */
+       grtp->info & GI_NGIS  &&      /* oppdater NGIS, og        */
+       grtp->info & GI_SLETTA) {    /* merka som sletta         */
+
+      *ngi = 0;
+      *nko = 0;
+
+   } else {
+      *ngi = grtp->ngi;
+      *nko = grtp->nko;
+   }
+
+   *info = grtp->info;
+
+   return  grtp->gnavn;        /* ==> retur */
+}
+
+
+/*
+AR-900107
+CH LC_GetObjtypeBgr                                             Hent objekttype
+CD =============================================================================
+CD Form�l:
+CD Henter objekttype for gitt gruppenummer.
+CD
+CD Parametre:
+CD Type    Navn       I/U  Forklaring
+CD------------------------------------------------------------------------------
+CD LC_BGR *pBgr        i   Gruppenummer det �nskes opplysninger om.
+CD char   *pszObjtype  r   OBJTYPE
+CD                         NULL hvis gruppen ikke finnes
+CD
+CD Bruk:
+CD pszObjtype = LC_GetObjtypeBgr(pBgr);
+=============================================================================
+*/
+SK_EntPnt_FYBA const char *LC_GetObjtypeBgr(LC_BGR * pBgr)
+{
+   LC_GRTAB_LINJE * grtp;
+
+   /* Aktuell gruppe */
+   if (pBgr->pFil == Sys.GrId.pFil  &&  pBgr->lNr == Sys.GrId.lNr) {
+      return  Sys.pGrInfo->szObjtype;        /* ==> retur */
+   }
+
+   /* Hent fra gruppetabellen */
+   LO_TestFilpeker(pBgr->pFil,"GetObjtypeBgr");
+   grtp = LI_GetGrt(pBgr->pFil,pBgr->lNr);
+
+   /* Sjekk om NGIS-gruppe og merka som sletta */
+   if (Sys.sNGISmodus == NGIS_NORMAL  &&    /* Vanlig modus, og         */
+      grtp->info & GI_NGIS  &&      /* oppdater NGIS, og        */
+      grtp->info & GI_SLETTA)     /* merka som sletta         */
+   {
+      return "";           /* ==> retur */
+   }
+
+   return  grtp->szObjtype;        /* ==> retur */
+}
+
+
+/*
+AR-911001
+CH LC_RsGr                                           Les gruppe sekvensielt
+CD ==========================================================================
+CD Form�l:
+CD Leser en datagruppe fra ekstern SOSI-fil inn i aktuell gruppe i ringbuffer.
+CD Rutinen tilsvarer put fra brukerprogram inn i ringbufferet, men rutinen
+CD tildeler selv n�dvendig plass..
+CD Gruppen beholder serienummer tildelt i LC_NyGr.
+CD Brukerindeks og geografisk-indeks blir ikke oppdatert.
+CD (Dette skjer f�rst n�r gruppen skrives til basen.)
+CD
+CD Parametre:
+CD Type             Navn   I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD short           *rstat  iu   Lesestatus
+CD                                Inn: 1=Les fra starten, 0=Les neste
+CD                                Ut:  0=OK, -1=slutten av filen er n�dd
+CD LC_FILADM       *pFil    i   Peker til FilAdm
+CD short           *ngi     u   Antall linjer GINFO
+CD long            *nko     u   Antall koordinater
+CD unsigned short  *info    u   Diverse informasjon. En "sum" av f�lgende:
+CD                          GI_PINFO     = gruppen har PINFO
+CD                          GI_NAH       = gruppen har h�yde informasjon (..N�H)
+CD                          GI_NAD       = gruppen har dybde informasjon (..N�D)
+CD                          GI_KP        = gruppen har knutepunkt (...KP n)
+CD                          GI_REF       = gruppen har referanser (.. eller ..REF)
+CD                          GI_OY_REF    = gruppen har referanser med �y
+CD                          GI_NGIS      = gruppen er tatt ut fra NGIS for oppdat.
+CD                          GI_SLETTA    = gruppen er sletta (merka som sletta)
+CD                          GI_READ_ONLY = gruppen kan ikke endres.
+CD long             gml_snr u    Serienummer gruppen hadde p� ekstern fil
+CD short            gnavn   r    Gruppenavn. (Se under $LENKE<LC_RxGr>)
+CD
+CD Bruk:
+CD     gnavn = LC_RsGr(&rstat,pFil,&ngi,&nko,&info,&gml_snr);
+CD     if (info & GI_PINFO)        (gruppen har PINFO)
+CD         ;
+CD     if (info & GI_KP)           (gruppen har KP)
+CD         ;
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_RsGr(short *rstat,LC_FILADM *pFil,short *ngi,long *nko,
+				  unsigned short *info,long *gml_snr)
+{
+   short siste;
+   long  snr;
+   UT_INT64 slutt;
+
+   /* LO_TestFilpeker(pFil,"LC_RsGr"); */
+   LO_TestFilpeker(pFil,"RsGr");
+
+   if (Sys.GrId.lNr == INGEN_GRUPPE) {      /* Feil ==> Ingen aktuell gruppe */
+      LC_Error(31,"(LC_RsGr)","");
+
+                                           /* Feil ==> Ulovlig ekstern fil */
+   } else if (pFil->usLag != LC_SEKV) {
+      LC_Error(32,"(LC_RsGr)","");
+      *ngi = Sys.pGrInfo->ngi;
+      *nko = Sys.pGrInfo->nko;
+      *info = Sys.pGrInfo->info;
+
+   } else {                                 /* Lovlig gruppe */
+      Sys.sPibufStatus = LC_PIBUF_TOM;
+      Sys.sGrEndra = END_KOPI;
+      if (*rstat == 1) {
+          pFil->n64AktPos = 0L;      /* Sett ny startposisjon */
+      }
+
+      /* Husk snr */
+      snr = LC_GetSn();  
+
+      /* Les fra ekstern fil */
+      siste = LB_RGru(pFil,pFil->n64AktPos,&slutt);
+
+      /* Snr fra ekstern fil */
+      *gml_snr = LC_GetSn();
+
+      /* Legg tilbake SNR */
+      LC_PutSn(snr);
+
+      if (siste) {
+          *rstat = -1;
+
+      } else {
+          *rstat = 0;
+          pFil->n64AktPos = slutt;
+          *ngi = Sys.pGrInfo->ngi;
+          *nko = Sys.pGrInfo->nko;
+          *info = Sys.pGrInfo->info;
+      }
+   }
+   return  Sys.pGrInfo->gnavn;
+}
+
+
+/*
+AR-911001
+CH LC_RsHode                                        Les filhode sekvensiellt
+CD ==========================================================================
+CD Form�l:
+CD Leser et filhode fra ekstern SOSI-fil inn i aktuell gruppe i ringbuffer.
+CD Rutinen tilsvarer put fra brukerprogram inn i ringbufret, men rutinen
+CD tildeler selv n�dvendig plass i RB.
+CD Denne rutinen er stort sett lik LC_RsGr, men LC_RsHode forandrer
+CD ikke aktuell filposisjon p� den sekvensielle filen.
+CD Gruppen beholder serienummer hodet hadde p� SOSI-filen.
+CD
+CD Parametre:
+CD Type             Navn   I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM       *pFil    i   Peker til FilAdm
+CD short           *ngi     u   Antall linjer GINFO
+CD long            *nko     u   Antall koordinater
+CD unsigned short  *info    u   Diverse informasjon. En "sum" av f�lgende:
+CD                          GI_PINFO = gruppen har PINFO
+CD                          GI_NAH   = gruppen har h�yde informasjon (..N�H)
+CD                          GI_NAD   = gruppen har dybde informasjon (..N�D)
+CD                          GI_KP    = gruppen har knutepunkt (...KP n)
+CD                          GI_REF   = gruppen har referanser (.. :n)
+CD                          GI_OY_REF= gruppen har referanser med �y
+CD short            gnavn   r    Gruppenavn. (Se under $LENKE<LC_RxGr>)
+CD
+CD Bruk:
+CD     gnavn = LC_RsHode(pFil,&ngi,&nko,&info);
+   =============================================================================
+*/
+short LC_RsHode(LC_FILADM *pFil,short *ngi,long *nko,unsigned short *info)
+{
+   UT_INT64  slutt;
+
+   /* LO_TestFilpeker(pFil,"LC_RsHode"); */
+   LO_TestFilpeker(pFil,"RsHode");
+
+   if (Sys.GrId.lNr == INGEN_GRUPPE){          /* Feil ==> Ingen aktuell gruppe */
+      LC_Error(31,"(LC_RsHode)","");
+
+                                           /* Feil ==> Ulovlig ekstern fil */
+   } else if (pFil->usLag != LC_SEKV) {
+      LC_Error(32,"(LC_RsHode)","");
+      *ngi = Sys.pGrInfo->ngi;
+      *nko = Sys.pGrInfo->nko;
+      *info = Sys.pGrInfo->info;
+
+   } else {                                /* Lovlig gruppe */
+
+                                           /* Les fra ekstern fil */
+      LB_RGru(pFil,0,&slutt);
+
+      *ngi = Sys.pGrInfo->ngi;
+      *nko = Sys.pGrInfo->nko;
+      *info = Sys.pGrInfo->info;
+      Sys.sGrEndra = END_KOPI;
+   }
+
+   return  Sys.pGrInfo->gnavn;
+}
+
+
+/*
+AR-930610
+CH LC_WsGr                                            Skriv gruppe sekvensiellt
+CD =============================================================================
+CD Form�l:
+CD Skriver aktuell gruppe til ekstern, sekvensiell SOSI-fil.
+CD
+CD Parametre:
+CD Type       Navn  I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_FILADM *pFil   i    Peker til FilAdm
+CD
+CD Bruk:
+CD LC_WsGr(pFil);
+   =============================================================================
+*/
+SK_EntPnt_FYBA void LC_WsGr(LC_FILADM *pFil)
+{
+   UT_INT64 neste = LLONG_MAX;
+
+   LO_TestFilpeker(pFil,"WsGr");
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                /* Aktuell gruppe OK */
+                                           /* Feil ==> Ulovlig ekstern fil */
+       if (pFil->usLag != LC_SEKV) {
+          LC_Error(33,"(LC_WsGr)","");
+
+                                           /* Feil ==> Ikke skriveaksess */
+		//} else if (pFil->sAccess != UT_UPDATE  ||  pFil->lNgisLag == LC_NGIS_LES) {
+      } else if (pFil->sAccess != UT_UPDATE  || strcmp(pFil->szNgisLag,"0") == 0 ) {         
+          LC_Error(34,"(LC_WsGr)","");
+
+                                           /* OK ==> Skriv */
+       } else {
+                              /* Sjekk at SOSI-filen har hode */
+         if ((pFil->TransMaske & LC_TR_ENHET) == 0  &&  Sys.pGrInfo->gnavn != L_HODE) {
+              LC_Error(141,"(LC_WsGr)",pFil->pszNavn);
+           }
+
+           if (Sys.pGrInfo->gnavn == L_HODE) {       /* Oppdater filtabellen */
+               LO_BeFt(pFil);
+           }
+
+           LB_WGru(SKRIV_SISTE,1,Sys.pGrInfo->nko,pFil,pFil->n64AktPos,&neste);
+           pFil->n64AktPos = neste;
+
+       }
+
+   } else {                              /* Ingen aktuell gruppe */
+      LC_Error(49,"(LC_WsGr)","");
+   }
+}
+
+
+/*
+AR-930610
+CH LC_WsGrPart                              Skriv del av gruppe sekvensiellt
+CD ==========================================================================
+CD Form�l:
+CD Skriver en del av aktuell gruppe til ekstern, sekvensiell SOSI-fil.
+CD
+CD Parametre:
+CD Type       Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil      i    Peker til FilAdm
+CD long       fra_punkt i    Punktnummer for f�rste koordinat som skal skrives.
+CD                           (Lovlig:  1  <=  fra_punkt  <=  nko)
+CD long       antall    i    Antall koordinatlinjer som skal skrives.
+CD                           (Lovlig:  0  <=  antall  <=  nko)
+CD
+CD Bruk:
+CD LC_WsGrPart(pFil,fra_punkt,antall);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_WsGrPart(LC_FILADM *pFil,long fra_punkt,long antall)
+{
+   UT_INT64 neste = LLONG_MAX;
+
+   LO_TestFilpeker(pFil,"WsGrPart");
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                /* Aktuell gruppe OK */
+                                           /* Feil ==> Ulovlig ekstern fil */
+       if (pFil->usLag != LC_SEKV) {
+          LC_Error(33,"(LC_WsGr)","");
+
+                                           /* Feil ==> Ikke skriveaksess */
+		//} else if (pFil->sAccess != UT_UPDATE  ||  pFil->lNgisLag == LC_NGIS_LES) {
+      } else if (pFil->sAccess != UT_UPDATE  ||  strcmp(pFil->szNgisLag,"0") == 0 ) {  
+
+          LC_Error(34,"(LC_WsGr)","");
+
+                                           /* OK ==> Skriv */
+       } else{
+                                         /* Sjekker at punktnummer er lovlig */
+           fra_punkt = min( max(1,fra_punkt), max(1,Sys.pGrInfo->nko) );
+           antall = min( max(antall,0), (Sys.pGrInfo->nko-fra_punkt+1) );
+
+                                                        /* Skriver */
+           LB_WGru(SKRIV_SISTE,fra_punkt,antall,pFil,pFil->n64AktPos,&neste);
+           pFil->n64AktPos = neste;
+
+           if (Sys.pGrInfo->gnavn == L_HODE){           /* Oppdater filtabellen */
+               LO_BeFt(pFil);
+           }
+       }
+
+   } else{                              /* Ingen aktuell gruppe */
+      LC_Error(49,"(LC_WsGr)","");
+   }
+}
+
+
+/*
+AR:2000-10-17
+CH LC_EndreHode                            Endre hodet p� eksisterende SOSI-fil
+CD =============================================================================
+CD Form�l:
+CD Skriver aktuell gruppe til starten av sekvensiell SOSI-fil.
+CD Det er en forutsetning at aktuell gruppe er et filhode.
+CD Denne rutinen er stort sett lik LC_WsGr, men LC_EndreHode forandrer ikke
+CD aktuell filposisjon p� den sekvensielle filen.
+CD OBS!
+CD Det m� v�re nok ledig plass f�r neste gruppe for tilbakeskrivingen.
+CD Det er ikke mulig � forandre koordinatsystem, enhet eller origo p� fil
+CD som inneholder data.
+CD
+CD Parametre:
+CD Type       Navn      I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_FILADM *pFil       i    Peker til FilAdm
+CD short      oppdatert  r    Skrivestatus (1=OK, 0=Det er ikke plass
+CD                                          til � skrive hodet)
+CD
+CD Bruk:
+CD ist = LC_EndreHode(pFil);
+   =============================================================================
+*/
+SK_EntPnt_FYBA short LC_EndreHode(LC_FILADM *pFil)
+{
+   short tegnsett,siste,oppdatert=0;
+   UT_INT64 neste;
+   char* pszNgisLag;
+   unsigned short Maske = LC_TR_ALLT;
+   LC_TRANSPAR Trans;
+
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                /* Aktuell gruppe OK */
+      /* LO_TestFilpeker(pFil,"LC_EndreHode"); */
+      LO_TestFilpeker(pFil,"EndreHode");
+
+                                           /* Feil ==> Ulovlig ekstern fil */
+      if (pFil->usLag != LC_SEKV) {
+         LC_Error(33,"(LC_EndreHode)","");
+
+                                           /* Feil ==> Ikke skriveaksess */
+		} else if (pFil->sAccess != UT_UPDATE  ||  strcmp(pFil->szNgisLag,"0") == 0 ) {
+         LC_Error(34,"(LC_EndreHode)","");
+
+                                           /* OK */
+      } else {
+                                  /* Sjekk at aktuell gruppe er filhode */
+         if (Sys.pGrInfo->gnavn != L_HODE) {
+                                           /* Feil ==> Ikke filhode */
+            LC_Error(98,"(LC_EndreHode)","");
+
+         } else {                         /* OK ==> Skriv */
+                                          /* Finn ledig plass for � skrive */
+            siste = LB_Plass(pFil,0,&neste);
+                                             /* Sjekk mot ledig plass */
+            if (LB_WGru(KONTROLLER_PLASS,1,Sys.pGrInfo->nko,pFil,0,&neste)) {
+               /* Det er plass nok */
+
+               /* Hent hode-opplysninger det ikke er lov til � endre n�r det er data i filen */
+               LC_GetTransEx(&Maske,&Trans);
+               LC_GetTegnsett(&tegnsett);
+               pszNgisLag = LH_GetNgisLag();
+
+               /* Skriv hvis siste gruppe, eller  transpar, tegnsett og NGIS-lag er uendret */
+               if (siste  ||  (memcmp(&pFil->TransPar,&Trans,sizeof(LC_TRANSPAR)) == 0  &&
+                   pFil->sTegnsett == tegnsett)) {
+                               
+                  if ( strcmp(pFil->szNgisLag,pszNgisLag) == 0) {
+                     LO_BeFt(pFil);
+                     LB_WGru(SKRIV_VANLIG,1,Sys.pGrInfo->nko,pFil,0,&neste);
+                     oppdatert = 1;
+                  
+                  } else {
+                     /* Koord.sys, enhet, origo eller tegnsett er endret */
+                     LC_Error(96,"(LC_EndreHode)","");
+                  }
+                  
+               } else {
+                  /* Koord.sys, enhet, origo eller tegnsett er endret */
+                  LC_Error(96,"(LC_EndreHode)","");
+               }
+
+            } else {        /* Det er ikke plass til � skrive hodet */
+               LC_Error(97,"(LC_EndreHode)","");
+            }
+         }
+      }
+
+   } else {                              /* Ingen aktuell gruppe */
+      LC_Error(49,"(LC_EndreHode)","");
+   }
+
+   return oppdatert;
+}
+
+
+/*
+AR-920810
+CH LC_RxGr                                               Les gruppe fra base
+CD ==========================================================================
+CD Form�l:
+CD Velger en gruppe som aktiv gruppe, og leser den fra SOSI-filen hvis den
+CD ikke er i RB fra f�r. (Styres ogs� av les_sosi.)
+CD Hvis gruppen ikke finnes (sletta eller ulovlig gruppenummer) returneres
+CD ngi=0 og nko=0.
+CD
+CD Parametre:
+CD Type    Navn    I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR * pBgr     i   Peker til fil- og gruppenummer.
+CD short   les_sosi i   Lesemetode: F�lgende konstanter er definert:
+CD                         LES_OPTIMALT   (0 = Les mest effektivt base/SOSI)
+CD                         LES_SOSI       (1 = Les alltid fra SOSI-filen)
+CD short  *ngi      u   Antall linjer GINFO
+CD long   *nko      u   Antall koordinater
+CD unsigned short *info      u   Diverse informasjon. En sum av f�lgende:
+CD                       GI_PINFO     = gruppen har PINFO
+CD                       GI_NAH       = gruppen har h�yde informasjon (..N�H)
+CD                       GI_NAD       = gruppen har dybde informasjon (..N�D)
+CD                       GI_KP        = gruppen har knutepunkt (...KP n)
+CD                       GI_REF       = gruppen har referanser (.. eller ..REF)
+CD                       GI_OY_REF    = gruppen har referanser med �y
+CD                       GI_NGIS      = gruppen er tatt ut fra NGIS for oppdat.
+CD                       GI_SLETTA    = gruppen er sletta (merka som sletta)
+CD                       GI_READ_ONLY = gruppen kan ikke endres.
+CD short gnavn     r   Gruppenavn - F�lgende konstanter er definert:
+CD                                      INGEN_GRUPPE = Gruppen finnes ikke, ikke lest. 
+CD                                      L_SLUTT    =   (.SLUTT) 
+CD                                      L_PUNKT    =   (.PUNKT) 
+CD                                      L_LINJE    =   (.LINJE) 
+CD                                      L_KURVE    =   (.KURVE) 
+CD                                      L_BUE      =   (.BUE) 
+CD                                      L_BUEP     =   (.BUEP) 
+CD                                      L_SIRKEL   =   (.SIRKEL) 
+CD                                      L_SIRKELP  =   (.SIRKELP) 
+CD                                      L_KLOTOIDE =   (.KLOTOIDE)
+CD                                      L_SVERM    =   (.SVERM) 
+CD                                      L_TEKST    =   (.TEKST) 
+CD                                      L_TRASE    =   (.TRASE) 
+CD                                      L_FLATE    =   (.FLATE) 
+CD                                      L_BEZIER   =   (.BEZIER)
+CD                                      L_RASTER   =   (.RASTER) 
+CD                                      L_DEF      =   (.DEF) 
+CD                                      L_OBJDEF   =   (.OBJDEF) 
+CD                                      L_MLINJE   =   (.MLINJE)
+CD                                      L_STRUKTUR =   (.STRUKTUR)  
+CD                                      L_OBJEKT   =   (.OBJEKT) 
+CD                                      L_SYMBOL   =   (.SYMBOL) 
+CD                                      L_HODE     =   (.HODE)       
+CD                                      
+CD
+CD Bruk:
+CD     gnavn = LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+CD     if (info & GI_PINFO)        (gruppen har PINFO)
+CD         ;
+CD     if (info & GI_KP)           (gruppen har KP)
+CD         ;
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_RxGr(LC_BGR * pBgr,short les_sosi,short *ngi,long *nko,unsigned short *info)
+{
+   UT_INT64  slutt;
+   short sNyGruppe = UT_TRUE;
+
+   LO_TestFilpeker(pBgr->pFil,"RxGr");
+
+   // Har aktuell gruppe
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {
+      sNyGruppe = Sys.GrId.pFil != pBgr->pFil  ||  Sys.GrId.lNr != pBgr->lNr;
+
+      // Hvis aktuell gruppe er endret, skriv den
+      if (Sys.sGrEndra != END_UENDRA) {
+         if (!(!sNyGruppe  &&  les_sosi == LES_SOSI)) {
+            if (LC_WxGr(SKRIV_OPTIMALT) == UT_FALSE) {
+               // "Kan ikke lese ny gruppe. Du har ikke skriveaksess for � lagre aktuell gruppe som er endret. Fil :"
+               LC_Error(163, "(LC_RxGr)", Sys.GrId.pFil->pszNavn);
+            }
+         }
+      }
+   }
+
+   Sys.sGrEndra = END_UENDRA;
+   Sys.sPibufStatus = LC_PIBUF_TOM;
+
+                  /* Lovlig gruppe */
+   if (pBgr->lNr >= 0L && pBgr->lNr < pBgr->pFil->lAntGr) {
+      Sys.GrId = *pBgr;
+                                /* Hent fra gruppe-tabellen */
+      Sys.pGrInfo = LI_GetGrt(pBgr->pFil,pBgr->lNr);
+                                /* Sjekk om gruppen er sletta */
+      if (Sys.pGrInfo->ngi == 0  ||         /* Permanent sletta, eller  */
+          (Sys.sNGISmodus == NGIS_NORMAL  &&    /* Vanlig modus, og         */
+           Sys.pGrInfo->info & GI_NGIS  &&      /* oppdater NGIS, og        */
+           Sys.pGrInfo->info & GI_SLETTA)) {    /* merka som sletta         */
+
+         /* Gruppen er sletta */
+         ;
+         Sys.GrId.lNr = INGEN_GRUPPE;
+         Sys.pGrInfo = NULL;
+         *ngi = 0;
+         *nko = 0;
+         return  -1;  /* retur ===> */
+
+      } else {                             /* Gruppen er OK */
+         /* Tvungen les fra SOSI-filen av samme gruppe */
+         if (les_sosi == LES_SOSI) {
+            /* Les fra SOSI-filen */
+            LB_RGru(pBgr->pFil,Sys.pGrInfo->sosi_st,&slutt);
+            if (!sNyGruppe) {
+               Sys.sGrEndra = END_ENDRA;
+            }
+            LC_OppdaterEndret(O_GINFO);
+
+         /* Hent fra buffer-fil */
+         } else if (sNyGruppe) {
+            Sys.GrId = *pBgr;
+
+            LI_ReadRb(pBgr->pFil,Sys.pGrInfo->rb_st,Sys.Ginfo.pszTx,Sys.pGrInfo->ulGiLen, Sys.pdAust,
+                      Sys.pdNord, Sys.pInfo, Sys.pGrInfo->nko, Sys.pszPinfo,
+                      Sys.pGrInfo->ulPiLen);
+            LX_CreGiPeker(&Sys.Ginfo,Sys.pGrInfo->ngi);
+         }
+
+         *ngi = Sys.pGrInfo->ngi;
+         *nko = Sys.pGrInfo->nko;
+         *info = Sys.pGrInfo->info;
+         return Sys.pGrInfo->gnavn;      /* retur ===> */
+      }
+   }
+
+   /* Ulovlig gruppe */
+   Sys.GrId.lNr = INGEN_GRUPPE;
+   Sys.pGrInfo = NULL;
+   *ngi = 0;
+   *nko = 0;
+   return  -1;  /* retur ===> */
+}
+
+
+/*
+AR-911001
+CH LC_WxGr                                             Skriv gruppe til base
+CD ==========================================================================
+CD Form�l:
+CD Skriver aktuell gruppe til tilh�rende SOSI-fil.
+CD Brukerindeks og geografisk indeks oppdateres straks, uavhengig av k�.
+CD Ledig plass fram til neste gruppe blir blanket.
+CD Filhode blir ALLTID skrevet direkte til SOSI-filen.
+CD
+CD Parametre:
+CD Type  Navn    I/U  Forklaring
+CD ------------------------------------------------------------------------
+CD short k_stat   i   Skrivemetode:  F�lgende konstanter er definert:
+CD                      SKRIV_OPTIMALT = Skriv mest effektivt k�/SOSI
+CD                      SKRIV_SOSI     = Skriv direkte til SOSI-filen
+CD short status   r   Status: UT_TRUE = OK
+CD                            UT_FALSE = Ikke utf�rt, pga. feil.
+CD
+CD Bruk:
+CD LC_WxGr(k_stat)
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_WxGr(short k_stat)
+{
+   short pnr,nivaa;
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE)      /* Aktuell gruppe OK */
+   {
+      if (Sys.sGrEndra != END_UENDRA)     /* Gruppen er endra, m� skrive */
+      {   
+         /* Har skriveaksess? */
+         //if (Sys.GrId.pFil->sAccess == UT_UPDATE  &&
+         //    (Sys.GrId.pFil->szNgisLag[0] == '\0'  ||  strcmp(Sys.GrId.pFil->szNgisLag,"0") != 0 ) ) {
+
+         //if (Sys.GrId.pFil->sAccess == UT_UPDATE  &&
+         //    (Sys.GrId.pFil->szNgisLag[0] == '\0'  ||  Sys.sNGISmodus == NGIS_SPESIAL) ) {  
+
+		   if (Sys.GrId.pFil->sAccess != UT_UPDATE  ||
+                    ((Sys.sNGISmodus == NGIS_NORMAL) && (strcmp(Sys.GrId.pFil->szNgisLag,"0")) == 0) )
+         {  
+            /* Ikke skriveaksess */
+            LC_Error(34,"(LC_WxGr)",Sys.GrId.pFil->pszNavn);
+
+            return UT_FALSE;         // ===>  Retur ved feil
+
+         } else {
+
+            /* Sjekk at SOSI-filen har hode */
+            if ((Sys.GrId.pFil->TransMaske & LC_TR_ENHET) == 0  &&  Sys.pGrInfo->gnavn != L_HODE) {
+               LC_Error(141,"(LC_WxGr)",Sys.GrId.pFil->pszNavn);
+            }
+
+            if (Sys.sGrEndra == (short)END_ENDRA) {
+               // Kontroller prikkniv� i egenskaper ?
+
+               // Oppdater ..NGIS-FLAGG
+               LC_OppdaterEndret(O_ENDRET);     
+            }
+
+            Sys.sGrEndra = END_UENDRA;
+
+            // Filhode som ligger som f�rste gruppe p� filen
+            // Oppdater filtabellen 
+            if (Sys.pGrInfo->gnavn == L_HODE  &&  Sys.GrId.lNr == 0) {
+               LO_BeFt(Sys.GrId.pFil);
+
+            // Ajourf�rer gruppetabellen med kvalitet og enhet
+            } else {
+               nivaa = 2;
+               pnr = 1;
+               LC_GetCurKvalitet(Sys.GrId.pFil,&nivaa,pnr,
+                              &Sys.pGrInfo->Kvalitet.sMetode,
+                              &Sys.pGrInfo->Kvalitet.lNoyaktighet,
+                              &Sys.pGrInfo->Kvalitet.sSynbarhet,
+                              &Sys.pGrInfo->Kvalitet.sHoydeMetode,
+                              &Sys.pGrInfo->Kvalitet.lHoydeNoyaktighet);
+
+               nivaa = 2;
+               LC_GetCurEnhet(Sys.GrId.pFil, &nivaa, &Sys.pGrInfo->dEnhet,
+                              &Sys.pGrInfo->dEnhetHoyde, &Sys.pGrInfo->dEnhetDybde);
+
+               /* Avrund buffer til riktig enhet */
+               LC_RoundKoord();
+            }
+ 
+            /* Skriv til buffer-fil */
+            LB_WriteRb();
+
+            /* Skriv direkte, eller filhode */
+            if (k_stat == SKRIV_SOSI  ||  Sys.pGrInfo->gnavn == L_HODE) {
+               LB_Swap();
+
+            /* Legg inn i skrivek�a */
+            } else {
+               Sys.lAntSkriv++;
+               LI_SetBt (Sys.GrId.pFil, Sys.GrId.lNr, BT_SKRKO);
+
+                                           /* T�m k�a hvis den er full */
+               if (Sys.lAntSkriv > Sys.lMaxSkriv) {
+                  LC_Save();
+               }
+            }
+
+            /* ----------------------------- Oppdater indekser */
+            LS_Indx(); /* Serienummer */
+            
+            LR_Indx();      /* Prim�r geografisk */
+            
+            if (Sys.pGrInfo->gnavn == L_FLATE) {
+               LR_IndxFlate(); /* Flate geografisk */
+            }         
+
+            Sys.pGrInfo->ulPrior[0] = 0UL;  /* Prioritetstabell */
+            Sys.pGrInfo->ulPrior[1] = 0UL;
+            Sys.pGrInfo->ulPrior[2] = 0UL;
+            Sys.pGrInfo->ulPrior[3] = 0UL;
+
+         //} else {                                 /* Ikke skriveaksess */
+         //   LC_Error(34,"(LC_WxGr)","");
+         }
+      }
+   }
+
+   return UT_TRUE;
+}
+
+
+/*
+AR-930907
+CH LB_WriteRb                           Skriv aktuell gruppe til buffer-filen
+CD ===========================================================================
+CD Form�l:
+CD Skriv aktuell gruppe til buffer-filen.
+CD
+CD Parametre: ingen
+CD
+CD Bruk:
+CD LB_WriteRb();
+==============================================================================
+*/
+static void LB_WriteRb(void)
+{
+   LC_GRTAB_LINJE *pForrigeGrInfo, *pNesteGrInfo;
+   long lLen;
+
+
+   lLen = LI_BerBufferLen(Sys.pGrInfo->ulGiLen,Sys.pGrInfo->nko,Sys.pGrInfo->ulPiLen);
+
+   /* Er ikke p� filen fra f�r, tildel ny plass */
+   if (Sys.pGrInfo->rb_st == NY_RB_ST) {
+      Sys.pGrInfo->rb_st = Sys.GrId.pFil->n64NesteLedigRbPos;
+      Sys.GrId.pFil->n64NesteLedigRbPos += (UT_INT64)lLen;
+      /* Oppdater kjeden */
+      pForrigeGrInfo = LI_GetGrt (Sys.GrId.pFil, Sys.GrId.pFil->lSisteGrRb);
+      pForrigeGrInfo->rb_neste_gr = Sys.GrId.lNr;
+      Sys.pGrInfo->rb_forrige_gr = Sys.GrId.pFil->lSisteGrRb;
+      Sys.pGrInfo->rb_neste_gr = INGEN_GRUPPE;
+      Sys.GrId.pFil->lSisteGrRb = Sys.GrId.lNr;
+
+
+   /* Er p� filen, sjekk om det er nok ledig plass */
+   } else {
+      /* Siste gruppe i buffer-filen */
+      if (Sys.pGrInfo->rb_neste_gr == INGEN_GRUPPE) {
+         Sys.GrId.pFil->n64NesteLedigRbPos = Sys.pGrInfo->rb_st + (UT_INT64)lLen;
+
+      /* Inne i buffer-filen */
+      } else {
+         pNesteGrInfo = LI_GetGrt(Sys.GrId.pFil,Sys.pGrInfo->rb_neste_gr);
+
+         /* Det er ikke plass, m� flytte gruppen til slutten av filen */
+         if (Sys.pGrInfo->rb_st + lLen  > pNesteGrInfo->rb_st) {
+            /* Tett "hullet" i kjeden */
+            pNesteGrInfo->rb_forrige_gr = Sys.pGrInfo->rb_forrige_gr;
+            if (Sys.pGrInfo->rb_forrige_gr != INGEN_GRUPPE) {
+               pForrigeGrInfo = LI_GetGrt(Sys.GrId.pFil,Sys.pGrInfo->rb_forrige_gr);
+               pForrigeGrInfo->rb_neste_gr = Sys.pGrInfo->rb_neste_gr;
+            }
+
+            /* Legg til p� slutten */
+            Sys.pGrInfo->rb_st = Sys.GrId.pFil->n64NesteLedigRbPos;
+            Sys.GrId.pFil->n64NesteLedigRbPos += (UT_INT64)lLen;
+
+            pForrigeGrInfo = LI_GetGrt (Sys.GrId.pFil, Sys.GrId.pFil->lSisteGrRb);
+            pForrigeGrInfo->rb_neste_gr = Sys.GrId.lNr;
+            Sys.pGrInfo->rb_forrige_gr = Sys.GrId.pFil->lSisteGrRb;
+            Sys.pGrInfo->rb_neste_gr = INGEN_GRUPPE;
+            Sys.GrId.pFil->lSisteGrRb = Sys.GrId.lNr;
+         }
+
+      }
+   }
+
+   LI_WriteRb(Sys.GrId.pFil,Sys.pGrInfo->rb_st,Sys.Ginfo.pszTx,Sys.pGrInfo->ulGiLen,
+              Sys.pdAust, Sys.pdNord, Sys.pInfo, Sys.pGrInfo->nko,
+              Sys.pszPinfo, Sys.pGrInfo->ulPiLen);
+}
+
+
+/*
+AR-930608
+CH LC_RoundKoord                 Endre koordinatene i buffer til riktig enhet
+CD ===========================================================================
+CD Form�l:
+CD Endrer koordinatene i aktuell gruppe i buffer til valgt enhet.
+CD (Rutinen blir utf�rt fra LC_WxGr.)
+CD
+CD Parametre: ingen
+CD
+CD Bruk:
+CD LC_RoundKoord();
+==============================================================================
+*/
+SK_EntPnt_FYBA void LC_RoundKoord(void)
+{
+	short iniv;
+   long pt;
+   double enhet,enhet_h,enhet_d,tall;
+
+   /* Lovlig gruppe */
+   if (Sys.GrId.lNr != INGEN_GRUPPE){
+
+      /* Kan gruppen endres (ikke READ_ONLY) */
+      //if ((Sys.pGrInfo->info & GI_READ_ONLY) == 0 ) {
+      if ((Sys.pGrInfo->info & GI_READ_ONLY) == 0  ||  Sys.sNGISmodus == NGIS_SPESIAL ) {
+         
+         /* Finn aktuell enhet */
+         iniv = 2;
+         LC_GetCurEnhet(Sys.GrId.pFil,&iniv,&enhet,&enhet_h,&enhet_d);
+
+         /* Avrund koordinatene */
+         for (pt=0; pt<Sys.pGrInfo->nko; pt++) {
+            /* Nord */
+            tall = UT_RoundDD(*(Sys.pdNord+pt) / enhet);
+            *(Sys.pdNord+pt) = tall * enhet;
+            /* �st */
+            tall = UT_RoundDD(*(Sys.pdAust+pt) / enhet);
+            *(Sys.pdAust+pt) = tall * enhet;
+
+            /* H�yde */
+            if (Sys.pGrInfo->info & GI_NAH) {
+				   if ((Sys.pInfo+pt)->dHoyde != HOYDE_MANGLER) {
+					   tall = UT_RoundDD((Sys.pInfo+pt)->dHoyde / enhet_h);
+                  (Sys.pInfo+pt)->dHoyde = tall * enhet_h;
+               }
+
+            /* Dybde */
+            } else if (Sys.pGrInfo->info & GI_NAD) {
+               if ((Sys.pInfo+pt)->dHoyde != HOYDE_MANGLER) {
+                  tall = UT_RoundDD((Sys.pInfo+pt)->dHoyde / enhet_d);
+                  (Sys.pInfo+pt)->dHoyde = tall * enhet_d;
+               }
+            }
+         }
+      }
+   }
+}
+
+
+/*
+AR-911001
+CH LC_OppdaterEndret                                    Oppdater ..NGIS-FLAGG
+CD ==========================================================================
+CD Form�l:
+CD Oppdaterer ..NGIS-FLAGG i GINFO og ajourf�rer interne tabeller.
+CD Hvis endring = O_GINFO oppateres tabellene i forhold til
+CD eksisterende GINFO.
+CD
+CD Parametre:
+CD Navn     Type   I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD endring  short   i   Kode for endring:
+CD                       O_GINFO   (0) = Oppdater interne tabeller i fht. GINFO
+CD                       O_ENDRET  (1) = Merk for endret og oppdat. tab.
+CD                       O_SLETTET (2) = Merk for slettet og oppdat. tab.
+CD
+CD Bruk:
+CD LC_OppdaterEndret(O_ENDRET);
+=============================================================================
+*/
+SK_EntPnt_FYBA void LC_OppdaterEndret(short endring)
+{
+   short gilin;
+   char *gp;
+   char szFlagg[80];
+
+   /* Finn aktuell parameter */
+   gilin=2;
+   gp = LC_GetGP("..NGIS-FLAGG",&gilin,Sys.pGrInfo->ngi);
+   if (gp == NULL){   
+      Sys.pGrInfo->info &= (unsigned short)(~GI_NGIS);      /* Ikke NGIS-oppdatering */
+      Sys.pGrInfo->info &= (unsigned short)(~GI_READ_ONLY); /* Ikke READ_ONLY */
+
+   } else {
+      /* Tolk gammel parameter */
+      UT_StrCopy(szFlagg,gp,80);
+      
+      /*
+       * Oppdater ..NGIS-FLAGG i GINFO hvis
+       * det er NGIS-standardmodus, og ikke 
+       * intern tabelloppdatering.
+       */
+
+      if (Sys.sNGISmodus == NGIS_NORMAL  &&  endring != O_GINFO) {
+         /* Kode */
+			if (endring == O_SLETTET) {
+            szFlagg[0] = 'S';
+
+         } else if (endring == O_ENDRET) {
+            if (szFlagg[0] == 'V') {
+               szFlagg[0] = 'E';
+            }
+         }
+
+         /* Bygg opp ny ginfo */
+         LC_UpdateGP(gilin,"..NGIS-FLAGG",szFlagg);
+      }
+
+
+      /* ---------- Oppdater interne tabeller --------- */
+
+      /* NGIS-oppdatering */
+      Sys.pGrInfo->info |= GI_NGIS;   
+      
+      /* Flagg for sletting */
+      if (szFlagg[0] == 'S') {
+         Sys.pGrInfo->info |= GI_SLETTA;                     /* Sletta */
+      } else {
+         Sys.pGrInfo->info &= (unsigned short)(~GI_SLETTA);  /* Ikke sletta */
+      }
+
+      /* Flagg for lese/skrive aksess */
+      if (szFlagg[0] == 'R'  ||  szFlagg[0] == 'H') {
+         Sys.pGrInfo->info |= GI_READ_ONLY;                    /* Bare leseaksess */
+      } else {
+         Sys.pGrInfo->info &= (unsigned short)(~GI_READ_ONLY); /* B�de lese- og skriveaksess */
+      }
+   }
+}
+
+
+/*
+AR-911001
+CH LC_FiLastGr                                     Finn siste gruppe i filen
+CD ==========================================================================
+CD Form�l:
+CD Finner gruppenummer for siste gruppe i filen.
+CD
+CD Parametre:
+CD Type       Navn  I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil   i    Peker til FilAdm
+CD bgr        long   r    Gruppenummer
+CD
+CD Bruk:
+CD bgr = LC_FiLastGr(pFil);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA long LC_FiLastGr(LC_FILADM *pFil)
+{
+   /* LO_TestFilpeker(pFil,"LC_FiLastGr"); */
+   LO_TestFilpeker(pFil,"FiLastGr");
+
+   return  pFil->lAntGr - 1;
+}
+
+
+/*
+AR-930608
+CH LC_CopyGr                                                   Kopier gruppe
+CD ==========================================================================
+CD Form�l:
+CD Kopierer fra en annen gruppe inn i aktuell gruppe i buffer.
+CD Rutinen tilsvarer put fra brukerprogram inn i bufret, men rutinen
+CD tildeler selv n�dvendig plass.
+CD Gruppen beholder serienummer tildelt i LC_NyGr.
+CD Geografisk-indeks blir ikke oppdatert f�r gruppen skrives til basen.
+CD Enhet blir oppdatert slik at opprinnelig enhet blir bevart. Om n�dvendig
+CD legges det inn ..ENHET i GINFO.
+CD Kvalitet og dato blir oppdatert hvis SOSI-VERSJON < 4.00.
+CD Hvis det er filhode som kopieres skjer det ingen endring av egenskaper.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR  *pBgr     i    Gruppenummer det skal kopieres fra.
+CD short    ngis     i    Behandling for ..NGIS-FLAGG:
+CD                          OPPDATER_NGIS (0) = ..NGIS-FLAGG oppdateres i henhold
+CD                                              til hodet i filen det kopieres til.
+CD                          BEVAR_NGIS (1) = ..NGIS-FLAGG bevares uforandret i kopien
+CD short    ngi      u    Antall linjer GINFO
+CD long     nko      u    Antall koordinater
+CD unsigned short    info     u    Diverse informasjon. (Se under $LENKE<LC_RxGr>)
+CD short    gnavn    r    Gruppenavn. (Se under $LENKE<LC_RxGr>)
+CD
+CD Bruk:
+CD     gnavn = LC_CopyGr(&Bgr,ngis,&ngi,&nko,&info)
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_CopyGr (LC_BGR * pBgr,short ngis,short *ngi,long *nko,unsigned short *info)
+{
+   short gilin;
+   long snr,rb_forrige_gr,rb_neste_gr;
+   UT_INT64 rb_st,sosi_st;
+   LC_GRTAB_LINJE * grtp;
+   char *cp,szTx[256];
+   LC_R_LEAF * pRL;   /* Peker inn i geografisk s�ketre */
+
+
+   LO_TestFilpeker(pBgr->pFil,"CopyGr");
+
+   grtp = LI_GetGrt(pBgr->pFil,pBgr->lNr);
+
+   if (Sys.GrId.lNr == INGEN_GRUPPE) {       /* Feil ==> Ingen aktuell gruppe */
+      LC_Error(31,"(LC_CopyGr)","");
+
+												  /* Gruppen er sletta */
+   } else if (grtp->ngi == 0  ||                 /* Permanent sletta, eller */
+              (Sys.sNGISmodus == NGIS_NORMAL  &&   /* Vanlig modus, og        */
+               grtp->info & GI_NGIS  &&          /* oppdater NGIS, og       */
+               grtp->info & GI_SLETTA)){         /* merka som sletta        */
+      LC_Error(35,"(LC_CopyGr)","");
+
+   /* Kopierer seg selv */
+   } else if (pBgr->pFil == Sys.GrId.pFil  &&  pBgr->lNr == Sys.GrId.lNr) {
+      *ngi = Sys.pGrInfo->ngi;
+      *nko = Sys.pGrInfo->nko;
+      *info = Sys.pGrInfo->info;
+
+   } else {                                         /* Lovlig gruppe */
+
+      Sys.sGrEndra = END_KOPI;
+      Sys.sPibufStatus = LC_PIBUF_TOM;
+      snr = LC_GetSn();           /* Husk serienummer */
+
+      /* Husk viktige data fra akt.gr. */
+      sosi_st = Sys.pGrInfo->sosi_st;
+      rb_st   = Sys.pGrInfo->rb_st;
+		rb_forrige_gr = Sys.pGrInfo->rb_forrige_gr;
+      rb_neste_gr   = Sys.pGrInfo->rb_neste_gr;
+      pRL           = Sys.pGrInfo->pRL; /* Peker inn i geografisk s�ketre */
+
+      /* Kopier data om gruppen det kopieres fra */
+      *Sys.pGrInfo = *grtp;
+
+      /* Legg tilbake data om akt.gr. */
+      Sys.pGrInfo->sosi_st = sosi_st;
+      Sys.pGrInfo->rb_st   = rb_st;
+      Sys.pGrInfo->rb_forrige_gr = rb_forrige_gr;
+      Sys.pGrInfo->rb_neste_gr   = rb_neste_gr;
+      Sys.pGrInfo->pRL = pRL;
+
+      /* Les fra buffer-filen */
+      LI_ReadRb(pBgr->pFil,grtp->rb_st,Sys.Ginfo.pszTx,grtp->ulGiLen,
+                Sys.pdAust, Sys.pdNord, Sys.pInfo, grtp->nko,
+                Sys.pszPinfo, grtp->ulPiLen);
+      LX_CreGiPeker(&Sys.Ginfo,grtp->ngi);
+
+      /* Legg tilbake rett SNR */
+      LX_PutSn(snr);
+
+      // Hvis det er filhode som kopieres skjer det ingen endring av egenskaper.
+      if (pBgr->lNr != 0)
+      {
+         // ----- Handter NGIS oppdateringsflagg
+         // S�k etter ..NGIS-FLAGG, og fjern den
+         gilin=2;
+         if (LC_GetGP("..NGIS-FLAGG",&gilin,Sys.pGrInfo->ngi) != NULL)
+         {
+            if ( ngis == OPPDATER_NGIS)
+            {
+               // NGIS-flagg
+               if (*Sys.GrId.pFil->szNgisLag != '\0'  &&  strcmp(Sys.GrId.pFil->szNgisLag,"0") != 0 )
+               {         
+                  // Skriv navnet med hermetegn hvis det er blanke i navnet
+                  if (strchr(Sys.GrId.pFil->szNgisLag,' ') != NULL) {
+                     UT_SNPRINTF(szTx,256,"..NGIS-FLAGG N \"%s\"",Sys.GrId.pFil->szNgisLag);
+                  } else {
+                     UT_SNPRINTF(szTx,256,"..NGIS-FLAGG N %s",Sys.GrId.pFil->szNgisLag);
+                  }
+
+                  LC_PutGi(gilin,szTx);
+                  Sys.pGrInfo->info |= GI_NGIS;   
+
+               } else {
+                  LC_DelGiL(gilin,1);
+                  Sys.pGrInfo->info &= (unsigned short)(~GI_NGIS);     /* Ikke NGIS-oppdatering */
+               }
+
+			   } else {
+               // Flagget skal bevares
+            }
+
+         } else {
+            /* NGIS-flagg */
+            //if (Sys.GrId.pFil->lNgisLag > 0) {
+            if (*Sys.GrId.pFil->szNgisLag != '\0'  &&  strcmp(Sys.GrId.pFil->szNgisLag,"0") != 0 ) {         
+
+               // Skriv navnet med hermetegn hvis det er blanke i navnet
+               if (strchr(Sys.GrId.pFil->szNgisLag,' ') != NULL) {
+                  UT_SNPRINTF(szTx,256,"..NGIS-FLAGG N \"%s\"",Sys.GrId.pFil->szNgisLag);
+               } else {
+                  UT_SNPRINTF(szTx,256,"..NGIS-FLAGG N %s",Sys.GrId.pFil->szNgisLag);
+               }
+
+               LC_PutGi(LC_AppGiL(),szTx);
+               Sys.pGrInfo->info |= GI_NGIS;   
+            }
+         }
+
+         /* ------------ Legg inn div. standardopplysninger */
+         /* ENHET */
+         LC_UpdateGiEnhet(Sys.GrId.pFil,grtp->dEnhet, grtp->dEnhetHoyde, grtp->dEnhetDybde);
+
+         // Bare hvis filen er eldre enn SOSI v 4.0
+         if (Sys.GrId.pFil->sSosiVer < 400)
+         {
+            // Det skal aldri legges ut kvalitet p� .FLATE eller .OBJEKT
+            if (Sys.pGrInfo->gnavn != L_FLATE  &&  Sys.pGrInfo->gnavn != L_OBJEKT) {
+               // ..KVALITET
+               LC_UpdateGiKvalitet(Sys.GrId.pFil,grtp->Kvalitet.sMetode,
+                                   grtp->Kvalitet.lNoyaktighet,
+                                   grtp->Kvalitet.sSynbarhet,
+                                   grtp->Kvalitet.sHoydeMetode,
+                                   grtp->Kvalitet.lHoydeNoyaktighet);
+            }
+
+            // NGIS-fil, oppdater DATO
+            if (*Sys.GrId.pFil->szNgisLag != '\0'  &&  strcmp(Sys.GrId.pFil->szNgisLag,"0") != 0 )
+            {    
+               if (*Sys.GrId.pFil->szDato != '\0'  &&  
+                   *Sys.GrId.pFil->szDato != '*'  &&  
+                   *Sys.GrId.pFil->szDato < '4')
+               { 
+                     // ..DATO fra fil-hodet
+                  gilin=2;
+                  if ((cp = LC_GetGP("..DATO",&gilin,Sys.pGrInfo->ngi)) == NULL) {
+                     UT_SNPRINTF(szTx,256,"..DATO %s",pBgr->pFil->szDato);
+                     LC_PutGi(LC_AppGiL(),szTx);
+                  }
+               }
+            }
+
+            // SOSI-VERSJON
+            //gilin=2;
+            //if ((cp = LC_GetGP("..SOSI-VERSJON",&gilin,Sys.pGrInfo->ngi)) == NULL) {
+            //   UT_SNPRINTF(szTx,256,"..SOSI-VERSJON %.2f",((double)(pBgr->pFil->sSosiVer))/100.0);
+            //   LC_PutGi(LC_AppGiL(),szTx);
+            //}
+         }
+      }
+
+      *ngi = Sys.pGrInfo->ngi;
+      *nko = Sys.pGrInfo->nko;
+      *info = Sys.pGrInfo->info;
+   }
+
+
+   return Sys.pGrInfo->gnavn;
+}
+
+
+/*
+AR-930707
+CH LC_CopyCoord                           Kopier koordinater fra annen gruppe
+CD ===========================================================================
+CD Form�l:
+CD Kopierer koordinater fra en annen gruppe inn i aktuell gruppe i ringbuffer.
+CD De kopierte koordinatene kommer som en utvidelse av gruppen.
+CD Rutinen tilsvarer put fra brukerprogram inn i ringbufret, men rutinen
+CD tildeler selv n�dvendig plass i RB.
+CD Geografisk-indeks blir ikke oppdatert f�r gruppen skrives til basen.
+CD Kvalitet og enhet blir automatisk oppdatert slik at gruppene ikke 
+CD mister informasjon.
+CD
+CD Parametre:
+CD Type    Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_BGR *pBgr      i    Gruppenummer det skal kopieres fra.
+CD short   retning   i    Buffer-retning:
+CD                                HENT_FORRFRA ( 1) = vanlig,
+CD                                HENT_BAKFRA  (-1) = buffer skal snues.
+CD long   til_linje i    Linjenummer linjen skal skytes inn forran.
+CD                        (Lovlig: 1  til  nko+1)
+CD short   ngi       u    Antall GINFO-linjer
+CD long    nko       u    Antall koordinater
+CD short   info      u    Diverse informasjon. (Se under $LENKE<LC_RxGr>)
+CD short   sStatus   r    Status: UT_TRUE=OK, UT_FALSE=ikke utf�rt.
+CD
+CD Bruk:
+CD sStatus = LC_CopyCoord(bgr,retning,til_linje,&ngi,&nko,&info);
+   =============================================================================
+*/
+SK_EntPnt_FYBA short LC_CopyCoord(LC_BGR * pBgr,short retning,long til_linje,short *ngi,
+                  long *nko,unsigned short *info)
+{
+   long l,ko,pnr,fra_pt,til_pt;
+   unsigned short in;
+   unsigned long  ulPiLen,ulGiLen;
+   short metode,hoydemetode,synbarhet,met,hmet,syn,nivaa,gi_met,gi_hmet,gi_syn;
+   long noyaktighet,hoydenoyaktighet,noy,hnoy,gi_noy,gi_hnoy;
+   UT_INT64 rb_st;
+   double *pdAust, *pdNord;
+   LB_INFO * pInfo;
+   char *pszPinfo;
+   LC_GRTAB_LINJE * grtp;
+   short sStatus = UT_TRUE;
+
+
+	LO_TestFilpeker(pBgr->pFil,"CopyCoord");
+
+   grtp = LI_GetGrt(pBgr->pFil,pBgr->lNr);
+
+   if (Sys.GrId.lNr == INGEN_GRUPPE){        /* Feil ==> Ingen aktuell gruppe */
+      LC_Error(31,"(LC_CopyCoord)","");
+      sStatus = UT_FALSE;
+
+                                      /* Gruppen er sletta */
+   } else if (grtp->ngi == 0  ||                   /* Permanent sletta, eller */
+              (Sys.sNGISmodus == NGIS_NORMAL  &&   /* Vanlig modus, og        */
+               grtp->info & GI_NGIS  &&            /* oppdater NGIS, og       */
+               grtp->info & GI_SLETTA)){           /* merka som sletta        */
+      LC_Error(35,"(LC_CopyCoord)","");
+      sStatus = UT_FALSE;
+
+   } else if (pBgr->pFil == Sys.GrId.pFil  &&  pBgr->lNr == Sys.GrId.lNr) {
+      /* Kopierer seg selv */
+      LC_Error(99,"(LC_CopyCoord)","");
+      sStatus = UT_FALSE;
+
+   } else {                                              /* Lovlig gruppe */
+
+      /* Husk diverse opplysninger */
+      ko = grtp->nko;
+		in = grtp->info;
+      metode = grtp->Kvalitet.sMetode;
+      noyaktighet = grtp->Kvalitet.lNoyaktighet;
+      synbarhet = grtp->Kvalitet.sSynbarhet;
+      hoydemetode = grtp->Kvalitet.sHoydeMetode;
+      hoydenoyaktighet = grtp->Kvalitet.lHoydeNoyaktighet;
+
+      rb_st = grtp->rb_st;
+      ulGiLen = grtp->ulGiLen;
+      ulPiLen = grtp->ulPiLen;
+
+      /* Tildel plass for koordinatene */
+      l = Sys.pGrInfo->nko;
+      LC_InsKoL(til_linje,ko);
+      if (Sys.pGrInfo->nko > l) {   /* Har det blitt lagt inn flere linjer */
+         Sys.sGrEndra = (short)END_ENDRA;
+         Sys.sPibufStatus = LC_PIBUF_TOM;
+
+		   /* Alloker midlertidig buffer */
+		   pdAust   = (double*)UT_MALLOC(ko * sizeof(double));
+		   pdNord   = (double*)UT_MALLOC(ko * sizeof(double));
+		   pInfo    = (LB_INFO *)UT_MALLOC(ko * sizeof(LB_INFO));
+		   pszPinfo = (char*)UT_MALLOC(ulPiLen * sizeof(char));
+
+         /* Les fra buffer-filen */
+         LI_ReadCoordRb(pBgr->pFil, rb_st, ulGiLen,pdAust, pdNord, pInfo, ko,
+                   pszPinfo, ulPiLen);
+
+         /* Regn posisjoner */
+         til_pt = til_linje - 1;
+         if (retning == HENT_FORRFRA) {
+            fra_pt = 0;
+            retning = 1;
+         } else{
+            fra_pt = ko - 1;
+            retning = -1;
+         }
+
+         for (l = 0;  l < ko;  l++) {             /* Koordinater og PINFO */
+			   *(Sys.pdAust+til_pt) = *(pdAust+fra_pt);
+            *(Sys.pdNord+til_pt) = *(pdNord+fra_pt);
+            (Sys.pInfo+til_pt)->dHoyde = (pInfo+fra_pt)->dHoyde;
+            (Sys.pInfo+til_pt)->sKp = (pInfo+fra_pt)->sKp;
+            if ((pInfo+fra_pt)->ulPiOfset != LC_INGEN_PINFO) {
+               LC_PutPi(til_pt+1, pszPinfo+((pInfo+fra_pt)->ulPiOfset));
+            }
+
+            til_pt++;
+            fra_pt += retning;
+         }
+
+         Sys.pGrInfo->info |= in;
+
+		   /* Frigi midlertidig buffer */
+		   UT_FREE(pdAust);
+		   UT_FREE(pdNord);
+		   UT_FREE(pInfo);
+		   UT_FREE(pszPinfo);
+
+         // ----- Oppdater Kvalitet i de kopierte punktene
+         if (Sys.GrId.pFil->sSosiVer < 400)
+         {
+            // Husk kvalitet i GINFO p� aktuell gruppe
+            nivaa = 2;
+            pnr = 1;
+            LC_GetCurKvalitet(Sys.GrId.pFil,&nivaa,pnr,&gi_met,&gi_noy,&gi_syn,&gi_hmet,&gi_hnoy);
+
+            // Oppdater punktene
+            for (pnr=til_linje; ko>0; pnr++,ko--) {
+               nivaa = 3;
+               LC_GetCurKvalitet(Sys.GrId.pFil,&nivaa,pnr,&met,&noy,&syn,&hmet,&hnoy);
+               // Funnet punkt uten kvalitet i PINFO
+               if (nivaa < 3) {
+                  LC_UpdatePiKvalitet(Sys.GrId.pFil,pnr,
+                                      metode,noyaktighet,synbarhet,hoydemetode,hoydenoyaktighet);
+
+               // Funnet punkt med samme kvalitet som aktuell GINFO
+			      } else if (met == gi_met  &&  noy == gi_noy  &&  syn == gi_syn  &&
+                          hmet == gi_hmet  &&  hnoy == gi_hnoy) {
+                  LC_UpdatePiKvalitet(Sys.GrId.pFil,pnr,met,noy,syn,hmet,hnoy);
+               }
+            }
+         }
+
+         *ngi = Sys.pGrInfo->ngi;
+         *nko = Sys.pGrInfo->nko;
+         *info = Sys.pGrInfo->info;
+
+      } else {                  /* For mange koordinater */
+         sStatus = UT_FALSE;
+      }
+   }
+
+   return sStatus;
+}
+
+
+/*
+AR-940208
+CH LC_SnuGr                                                        Snu gruppe
+CD ===========================================================================
+CD Form�l:
+CD Snur en gruppe.
+CD Rutinen tilsvarer put fra brukerprogram inn i ringbufret.
+CD B�de koordinater, h�yde, KP og PINFO blir behandlet.
+CD For .BUE blir fortegnet p� radius endret.
+CD Fortegnet p� referanser til gruppen blir oppdatert.
+CD
+CD Parametre:
+CD Type    Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD
+CD Bruk:
+CD    LC_SnuGr();
+   =============================================================================
+*/
+SK_EntPnt_FYBA void LC_SnuGr(void)
+{
+   short ngi,sGiLin,Endret;
+   long fra_pt,til_pt;
+   long nko;
+   unsigned short info;
+   double *pdAust,*pdNord;
+   LB_INFO * pInfo;
+   char *pszPinfo,szRadius[30];
+   double nva,nvn,oha,ohn;
+   LC_GEO_STATUS GeoStat;
+   LC_BGR Bgr,FlateBgr;
+   LC_POLYGON Polygon;
+	LC_POL_ELEMENT * pPE;
+   LC_OY_ELEMENT * pOE;
+
+
+   /* Feil ==> Ingen aktuell gruppe */
+   if (Sys.GrId.lNr == INGEN_GRUPPE){
+      LC_Error(31,"(LC_CopyCoord)","");
+
+   /* Lovlig gruppe */
+   } else if (Sys.pGrInfo->nko > 1) {
+
+      /* Husk diverse opplysninger */
+      nko = Sys.pGrInfo->nko;
+
+      /* Tildel plass for koordinatene */
+      Sys.sGrEndra = (short)END_ENDRA;
+		Sys.sPibufStatus = LC_PIBUF_TOM;
+
+		/* Lag en midlertidig kopi av original-bufferet */
+		pdAust   = (double*)UT_MALLOC(nko * sizeof(double));
+		UT_memcpy(pdAust,nko * sizeof(double),Sys.pdAust,nko * sizeof(double));
+
+		pdNord   = (double*)UT_MALLOC(nko * sizeof(double));
+      UT_memcpy(pdNord,nko * sizeof(double),Sys.pdNord,nko * sizeof(double));
+
+		pInfo    = (LB_INFO *)UT_MALLOC(nko * sizeof(LB_INFO));
+      UT_memcpy(pInfo,nko * sizeof(LB_INFO),Sys.pInfo,nko * sizeof(LB_INFO));
+
+		pszPinfo = (char*)UT_MALLOC(Sys.pGrInfo->ulPiLen * sizeof(char));
+      UT_memcpy(pszPinfo,Sys.pGrInfo->ulPiLen * sizeof(char),Sys.pszPinfo,Sys.pGrInfo->ulPiLen * sizeof(char));
+
+      /* T�mmer gruppen for gammelt innhold */
+      LC_DelKoL(1,nko);
+      LC_InsKoL(1,nko);
+
+      /* Legger inn koordinater og PINFO */
+		for (til_pt=0,fra_pt=nko-1;  til_pt<nko; til_pt++,fra_pt--) {
+         *(Sys.pdAust+til_pt) = *(pdAust+fra_pt);
+			*(Sys.pdNord+til_pt) = *(pdNord+fra_pt);
+         (Sys.pInfo+til_pt)->dHoyde = (pInfo+fra_pt)->dHoyde;
+         (Sys.pInfo+til_pt)->sKp = (pInfo+fra_pt)->sKp;
+         if ((pInfo+fra_pt)->ulPiOfset != LC_INGEN_PINFO) {
+            LC_PutPi(til_pt+1, pszPinfo+((pInfo+fra_pt)->ulPiOfset));
+         }
+      }
+
+		/* Frigi midlertidig buffer */
+		UT_FREE(pdAust);
+		UT_FREE(pdNord);
+		UT_FREE(pInfo);
+		UT_FREE(pszPinfo);
+
+		/* ====== Hvis gruppen er .BUE ==> skift fortegn p� radius ==== */
+      if (Sys.pGrInfo->gnavn == L_BUE) {
+         sGiLin = 2;
+         pszPinfo = LC_GetGP("..RADIUS",&sGiLin,Sys.pGrInfo->ngi);
+
+         if (*pszPinfo == '-') {
+            UT_StrCopy(szRadius,pszPinfo+1,30);
+         } else {
+            szRadius[0] = '-';
+            UT_StrCopy(szRadius+1,pszPinfo,29);
+         }
+
+         LC_UpdateGP(sGiLin,"..RADIUS",szRadius);
+      }
+
+
+      /* ========= Oppdater referanser til gruppen */
+      /* Husk gruppen */
+      Bgr = Sys.GrId;
+
+      LC_POL_InitPolygon(&Polygon);
+
+		LC_GetGrWin(&Sys.GrId,&nva,&nvn,&oha,&ohn);
+      LC_SBFlate(&GeoStat,LC_FRAMGR,nva,nvn,oha,ohn);
+      if (LC_FFFlate(&GeoStat,&FlateBgr)) {
+         do {
+            if (FlateBgr.pFil == Bgr.pFil) {
+               /* Funnet flate i rett fil, sjekk referansene */
+               LC_RxGr(&FlateBgr,LES_OPTIMALT,&ngi,&nko,&info);
+               LC_POL_GetRef(&Polygon);
+               Endret = UT_FALSE;
+
+               /* Omkretsen */
+              for(pPE = Polygon.HovedPO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+                 if ((memcmp(&pPE->Bgr,&Bgr,sizeof(LC_BGR))) == 0) {
+                    pPE->sRetning = (pPE->sRetning == LC_MED_DIG)?
+                                                     LC_MOT_DIG  :  LC_MED_DIG;
+                    Endret = UT_TRUE;
+                 }
+              }
+
+              /* �yer */
+              for (pOE = Polygon.OyOA.pForsteOE; pOE != NULL; pOE = pOE->pNesteOE) {
+					  for (pPE = pOE->PO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+                    if ((memcmp(&pPE->Bgr,&Bgr,sizeof(LC_BGR))) == 0) {
+                       pPE->sRetning = (pPE->sRetning == LC_MED_DIG)?
+                                                     LC_MOT_DIG  :  LC_MED_DIG;
+                       Endret = UT_TRUE;
+                    }
+                 }
+              }
+
+              /* Lagre de oppdaterte referansene */
+              if (Endret) {
+                 LC_POL_PutRef(&Polygon);
+                 LC_WxGr(SKRIV_OPTIMALT);
+              }
+
+              /* Frigi allokerte kjeder */
+              LC_POL_FrigiPolygon(&Polygon);
+
+            }
+         } while (LC_FNFlate(&GeoStat,&FlateBgr));
+      }
+      LC_AvsluttSok(&GeoStat);
+
+
+		/* ========= Les inn igjen opprinnelig gruppe */
+      LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+   }
+}
+
+
+/*
+AR-911001
+CH LC_DelGr                                                     Slett gruppe
+CD ==========================================================================
+CD Form�l:
+CD Fjerner aktuell gruppe fra basen.
+CD Grupper som er tatt ut fra NGIS for oppdatering blir ikke sletta fra
+CD SOSI-filen, men de blir merka som sletta. (LC_SetNgisModus avgj�r da om
+CD disse kan leses.)
+CD Det er ikke mulig � slette grupper fra sekvensielle filer, eller grupper
+CD som er brukt i flater.
+CD
+CD Parametre:
+CD Type   Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD short  sStatus  r    Status:  UT_TRUE  = OK
+CD                               UT_FALSE = feil, ikke sletta
+CD
+CD Bruk:
+CD sStatus = LC_DelGr();
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_DelGr(void)
+{
+   UT_INT64 neste;
+   char *gp;
+   short gilin = 2;
+   short sStatus = UT_TRUE;
+   long lSnr = LC_GetSn();
+   char *pszNgisFlagg;
+
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {
+                                         /* Ikke filhode, eller kladdebase */
+      //if (Sys.pGrInfo->gnavn != L_HODE  &&  Sys.GrId.pFil->pBase->sType == LC_BASE) {
+      if (Sys.GrId.lNr != 0  &&  Sys.GrId.pFil->pBase->sType == LC_BASE) {
+         if ( ! (Sys.pGrInfo->info & GI_SLETTA)) {  /* Ikke sletta fra f�r */
+            if (Sys.GrId.pFil->usLag & LC_FRAMGR) { /* Har skriveaksess */
+
+               // Finn og ta vare p� NGIS-flagg
+               gp = LC_GetGP("..NGIS-FLAGG",&gilin,Sys.pGrInfo->ngi);
+               if (gp) {
+                  pszNgisFlagg = (char*)malloc(strlen(gp)+1);
+                  UT_StrCopy(pszNgisFlagg, gp, strlen(gp)+1);
+               } else {
+                  pszNgisFlagg = NULL;
+               }
+               
+               // Ny gruppe - ikke lagret til SOSI, eller
+               // ikke NGIS-oppdatering, eller
+               // ny NGIS-gruppe, eller
+               // vanlig NGIS-grupppe
+               if (Sys.pGrInfo->sosi_st == NY_SOSI_ST  || 
+                   pszNgisFlagg == NULL  ||
+                   *pszNgisFlagg == 'N'  ||
+                   *pszNgisFlagg == 'V'  ||
+                   *pszNgisFlagg == 'E'  ||
+                   *pszNgisFlagg == 'S' ) {
+
+                  if (Sys.pGrInfo->gnavn == L_LINJE    ||
+                      Sys.pGrInfo->gnavn == L_KURVE    ||
+                      Sys.pGrInfo->gnavn == L_BUE      ||
+                      Sys.pGrInfo->gnavn == L_BUEP     ||
+                      Sys.pGrInfo->gnavn == L_SIRKEL   ||
+                      Sys.pGrInfo->gnavn == L_SIRKELP  ||
+                      Sys.pGrInfo->gnavn == L_KLOTOIDE ||
+                      Sys.pGrInfo->gnavn == L_TRASE      ) {
+
+                     if (Sys.pGrInfo->nko > 0) {
+                        // Sjekk om det finnes referanser til gruppen
+                        if (LC_ErReferert())  sStatus = UT_FALSE;
+                     }
+                  }
+
+                  // Det finnes ikke referanser til gruppen
+                  if (sStatus == UT_TRUE) {
+
+                     /* Ikke NGIS-oppdatering, eller ny NGIS-gruppe, fjerner fysisk fra SOSI-filen */
+                     if (Sys.pGrInfo->sosi_st == NY_SOSI_ST  ||
+                         pszNgisFlagg == NULL  ||
+                         *pszNgisFlagg == 'N'  ) {  
+
+                        if (Sys.pGrInfo->sosi_st != NY_SOSI_ST) { /* Ikke ny gruppe */
+                           LB_Plass(Sys.GrId.pFil,Sys.pGrInfo->sosi_st,&neste);
+                           /* Posisjoner og blank ut omr�det */
+                           _fseeki64(Sys.GrId.pFil->pBase->pfSos,Sys.pGrInfo->sosi_st,SEEK_SET);
+							      LB_WriteBlank(Sys.GrId.pFil->pBase->pfSos,Sys.GrId.pFil->sTegnsett,neste);
+									fflush(Sys.GrId.pFil->pBase->pfSos);
+                        }
+                        Sys.pGrInfo->ngi = 0;
+                        Sys.pGrInfo->nko = 0;
+
+                      /* Vanlig NGIS-grupppe, merker som slettet */
+                     } else if (*pszNgisFlagg == 'V'  ||
+                                *pszNgisFlagg == 'E'  ||
+                                *pszNgisFlagg == 'S' ) {
+                        LC_OppdaterEndret(O_SLETTET);
+                        LC_WxGr(SKRIV_SOSI);
+                     }
+
+                     /* Fjerner fra snr.tab */
+                     LS_PutSn(Sys.GrId.pFil,INGEN_GRUPPE,lSnr);
+
+                     /* Fjerner fra geogr. s�ketabell */
+                     LR_R_Delete(Sys.pGrInfo->pRL);
+                     Sys.pGrInfo->pRL = NULL;
+
+
+                     Sys.pGrInfo->info |= GI_SLETTA;      /* Gruppen sletta */
+                     LI_PutBt(Sys.GrId.pFil,Sys.GrId.lNr,0L);  /* Fjerner all merking */
+
+					      Sys.GrId.lNr = INGEN_GRUPPE;       /* Ingen aktuell gruppe */
+                     Sys.sGrEndra = END_UENDRA;
+
+                  /* Brukt i flate */
+                  /*} else {
+                     LC_Error(44,"(LC_DelGr)","");*/
+                  }
+
+               /* Bare leseaksess */
+               } else if (*pszNgisFlagg == 'R'  ||  *pszNgisFlagg == 'H' ) {
+                  LC_Error(91,"(LC_DelGr)","");
+                  sStatus = UT_FALSE;
+
+               /* Ukjent NGIS endringsflagg */
+               } else {
+                  LC_Error(91,"(LC_DelGr)","");
+                  sStatus = UT_FALSE;
+               }
+
+               // Frigir alloker minne
+               if (pszNgisFlagg)  free(pszNgisFlagg);
+
+            } else {                          /* Ikke skriveaksess */
+               LC_Error(91,"(LC_DelGr)","");
+               sStatus = UT_FALSE;
+            }
+         }
+
+      } else {                         /* Filhode, eller kladdebase */
+         sStatus = UT_FALSE;
+
+         if (Sys.GrId.pFil->pBase->sType != LC_BASE) {
+            /* Slett gruppe ulovlig ved kladdebase */
+            LC_Error(95,"(LC_DelGr)","");
+         } else {
+            /* Kan ikke slette filhodet */
+            LC_Error(48,"(LC_DelGr)","");
+         }
+      }
+   }
+
+   return sStatus;
+}
+
+
+/*
+AR-920129
+CH LC_SplittGr                                                 Splitt gruppe
+CD ==========================================================================
+CD Form�l:
+CD Splitter aktuell gruppe i to deler.
+CD F�rste del av gruppen beholdes som aktuell gruppe. Denne blir ikke
+CD skrevet til SOSI-filen, men buffer er oppdatert.
+CD Siste del av gruppen legges som en ny gruppe p� samme fil som
+CD opprinnelig gruppe. Denne blir skrevet til basen.
+CD Den delen av gruppen som ligger mellom P1 og P2 blir fjernet.
+CD
+CD Hvis gruppen er BUEP og en av delene f�r bare to koordinater
+CD blir det lagt inn et nytt punkt midt p� buen.
+CD
+CD Parametre:
+CD Type     Navn   I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long    sP1     i    Punktnummer 1.   (M� v�re st�rre enn 1)
+CD long    sP2     i    Punktnummer 2.   (M� v�re mindre enn nko)
+CD LC_BGR *  pBgr2   u    Nytt gruppenummer for siste del av gruppen.
+CD short    sStatus r    Status: UT_TRUE  = OK
+CD                               UT_FALSE = feil, ikke splittet
+CD
+CD Bruk:
+CD sStatus = LC_SplittGr(sP1,sP2,&Bgr2);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_SplittGr (long sP1,long sP2,LC_BGR * pBgr2)
+{
+   short ngi,Endret,s;
+   long nko;
+   long l;
+   unsigned short info;
+   LC_FILADM *pFil;
+   LC_BGR Bgr,FlateBgr;
+   long lGmlSnr,lNyttSnr;
+   double nva,nvn,oha,ohn;
+   double a1,n1,a2,n2,as1,ns1,as2,ns2,r,fi,dfi,fi2,dfi2;
+   LC_GEO_STATUS GeoStat;
+   long lAntRef;
+   long lNyAntRef;
+   short sGiLin,sRefPos;
+   long *plRefArray,*plNyRefArray,*plRef,*plNyRef;
+   double fiNy,dfiNy,dA_ny,dN_ny;
+   double ax,nx;
+   bool bStorbue = false;   /* Viser om opprinnelig gruppe var OK storbue */
+   short sStatus = UT_FALSE;
+
+   /* Har aktuell gruppe med koordinater, og lovlige punktnummer */
+   if (Sys.GrId.lNr != INGEN_GRUPPE  &&
+       Sys.pGrInfo->nko > 0  &&
+		 sP1 > 1  &&
+       sP2 < Sys.pGrInfo->nko) {
+
+      /* Husk at beregning er utf�rt */
+      sStatus = UT_TRUE;
+
+      /* Husk gruppen */
+      pFil = Sys.GrId.pFil;
+      Bgr = Sys.GrId;
+      lGmlSnr = LC_GetSn();
+      LC_GetGrWin(&Bgr,&nva,&nvn,&oha,&ohn);
+
+
+      if (Sys.pGrInfo->gnavn == L_BUE  || 
+          Sys.pGrInfo->gnavn == L_BUEP ||
+          Sys.pGrInfo->gnavn == L_SIRKELP )
+      {
+         // Tar vare p� bueparametrene for opprinnelig "bue"
+         LC_GetBuePar(HENT_FORRFRA,&as1,&ns1,&r,&fi,&dfi,&s);
+         bStorbue = (fabs(dfi) > PI);
+      }
+
+      // ========= Lag ny gruppe, og kopier hele den opprinnelige gruppen
+      LC_NyGr(pFil,".LINJE",pBgr2,&lNyttSnr);
+      LC_CopyGr(&Bgr,OPPDATER_NGIS,&ngi,&nko,&info);
+
+      /* Samme brukttabell som opprinnelig gruppe */
+      for (s=BT_MIN_USER; s<=BT_MAX_USER; s++) {
+         if (LC_GetBt(&Bgr,s) != 0) {
+            LC_SetBt(pBgr2,s);
+         }
+      }
+
+      // SIRKELP konverteres til BUEP
+      if (Sys.pGrInfo->gnavn == L_SIRKELP )
+      {
+         LC_PutGi(1,".BUEP");
+         double a,n;
+         LC_GetTK(1,&a,&n);
+         nko = LC_AppKoL();
+         LC_PutTK(nko,a,n);
+         LC_PutKp(nko,LC_GetKp(1));
+      }
+
+      /* Fjern f�rste del av gruppen */
+      if (sP2 > sP1){
+         nko = LC_DelKoL(1, sP2-1);
+      } else if (nko > 1) {
+         nko = LC_DelKoL(1, sP1-1);
+      }
+
+      /* Sjekk om storbue er blitt liten bue */
+      if (Sys.pGrInfo->gnavn == L_BUE  &&  bStorbue)
+      {
+         LC_GetBue(HENT_FORRFRA,&a1,&n1,&a2,&n2,&r,&s);
+			GM_KonvBue(a1,n1,a2,n2,r,s,&as2,&ns2,&fi2,&dfi2);
+
+         /* Buen skal ikke v�re storbue lenger hvis sentrum er flyttet.
+          * Dette er tilfelle n�r linjen fra gammelt til nytt senter
+          * skj�rer linjen fra nytt start til sluttpunkt.
+          */
+         if (GM_sLinLin(a1,n1,a2,n2,as1,ns1,as2,ns2,&ax,&nx)) {
+            LC_PutGP("..STORBUE","0",&s);
+         }
+      }
+
+      // Sjekk at .BUEP har tre koordinater
+      if (Sys.pGrInfo->gnavn == L_BUEP)
+      {
+         if (nko == 2)
+         {
+            // --- Legger inn nytt punkt p� buen mellom de to endepunktene.
+            // �pningsvinkel til starten av den nye buen
+            LC_GetTK(1,&a1,&n1);
+            GM_PktBue(as1,ns1,fi,dfi,a1,n1,&dfiNy);
+
+            // Midtpunktet
+            fiNy = fi + (dfiNy+((dfi-dfiNy)/2.0));
+            dA_ny = as1 + fabs(r)*cos(fiNy);
+            dN_ny = ns1 + fabs(r)*sin(fiNy);
+
+            nko = LC_InsKoL(2,1);
+            LC_PutTK(2,dA_ny,dN_ny);
+         }
+
+         // Endre til .KURVE hvis buen blir ulovlig
+         LR_TestEndreBuepTilKurve(dfi);
+      }
+
+      // Lagre
+      LC_WxGr(SKRIV_OPTIMALT);
+
+      // ========= Oppdater referanser til gruppen
+      LC_SBFlate(&GeoStat,LC_FRAMGR,(double)nva,(double)nvn,
+                                    (double)oha,(double)ohn);
+      if (LC_FFFlate(&GeoStat,&FlateBgr)) {
+         do {
+            if (FlateBgr.pFil == pFil) {
+               /* Funnet flate i rett fil, sjekk referansene */
+               LC_RxGr(&FlateBgr,LES_OPTIMALT,&ngi,&nko,&info);
+					lAntRef = LC_InqAntRef();
+					plRefArray = (long *) UT_MALLOC(lAntRef * sizeof(long));
+					plNyRefArray = (long *) UT_MALLOC((lAntRef+2) * sizeof(long));
+					sGiLin = 2;
+					sRefPos = 0;
+					LC_GetRef(plRefArray,lAntRef,&sGiLin,&sRefPos);
+
+               lNyAntRef = lAntRef;
+               Endret = UT_FALSE;
+               plRef = plRefArray;
+               plNyRef = plNyRefArray;
+               for (l=0; l<lAntRef; l++) {
+                  if (labs(*plRef) == lGmlSnr) {
+                     if (*plRef > 0) {
+                        *plNyRef++ = *plRef++;
+                        *plNyRef++ = lNyttSnr;
+
+                     } else {
+                        *plNyRef++ = -lNyttSnr;
+                        *plNyRef++ = *plRef++;
+                     }
+                     Endret = UT_TRUE;
+                     lNyAntRef++;
+                     
+                  } else {
+                     *plNyRef++ = *plRef++;
+                  }
+               }
+
+               if (Endret) {
+                  LC_PutRef(plNyRefArray,lNyAntRef);
+                  LC_WxGr(SKRIV_OPTIMALT);
+               }
+					UT_FREE(plRefArray);
+					UT_FREE(plNyRefArray);
+				}
+			} while (LC_FNFlate(&GeoStat,&FlateBgr));
+      }
+      LC_AvsluttSok(&GeoStat);
+
+      // ========= Oppdater opprinnelig gruppe
+      LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+
+      /* Fjern siste del av gruppen */
+      if (nko > 1) {
+         nko = LC_DelKoL(sP1+1, nko-sP1);
+      }
+
+      // SIRKELP m� konverteres til BUEP
+      if (Sys.pGrInfo->gnavn == L_SIRKELP )
+      {
+         LC_PutGi(1,".BUEP");
+      }
+
+      /* Sjekk om storbue er blitt liten bue */
+      if (Sys.pGrInfo->gnavn == L_BUE  &&  bStorbue)
+      {
+         LC_GetBue(HENT_FORRFRA,&a1,&n1,&a2,&n2,&r,&s);
+         GM_KonvBue(a1,n1,a2,n2,r,s,&as2,&ns2,&fi2,&dfi2);
+
+         /* Buen skal ikke v�re storbue lenger hvis sentrum er flyttet.
+          * Dette er tilfelle n�r linjen fra gammelt til nytt senter
+			 * skj�rer linjen fra nytt start til sluttpunkt.
+          */
+         if (GM_sLinLin(a1,n1,a2,n2,as1,ns1,as2,ns2,&dA_ny,&dN_ny)) {
+            LC_PutGP("..STORBUE","0",&s);
+         }
+      }
+
+      // Sjekk at .BUEP har tre koordinater
+      if (Sys.pGrInfo->gnavn == L_BUEP)
+      {
+         if (nko == 2)
+         {
+            // --- Legger inn nytt punkt p� buen mellom de to endepunktene.
+            // �pningsvinkel til slutten av den nye buen
+            LC_GetTK(2,&a2,&n2);
+            GM_PktBue(as1,ns1,fi,dfi,a2,n2,&dfiNy);
+            // Midtpunktet
+            fiNy = fi + (dfiNy/2.0);
+            dA_ny = as1 + fabs(r)*cos(fiNy);
+            dN_ny = ns1 + fabs(r)*sin(fiNy);
+
+            LC_InsKoL(2,1);
+            LC_PutTK(2,dA_ny,dN_ny);
+         }
+
+         // Endre til .KURVE hvis buen blir ulovlig
+         LR_TestEndreBuepTilKurve(dfi);
+      }
+   }
+
+   return sStatus;
+}
+
+/*
+AR-930803
+CH LR_TestEndreBuepTilKurve                               Sammenf�y grupper
+CD ==========================================================================
+CD Form�l:
+CD Sjekk om BUEP blir ugyldeig etter splitting. 
+CD Konverterer eventuellt til .KURVE
+CD
+CD Parametre:
+CD Type    Navn      I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD double  dDeltaFi   i   �pningsvinkel for opprinnelig BUEP
+CD
+CD Bruk:
+CD LR_TestEndreBuepTilKurve(dDeltaFi);
+   =============================================================================
+*/
+static void LR_TestEndreBuepTilKurve(double dDeltaFi)
+{
+   double as,ns,r,fi,dfi;
+   double dAMidt,dNMidt,dAFotP,dNFotP;
+   double a1,n1,a2,n2;
+   short s;
+ 
+   // Avrund buffer til riktig enhet
+   LC_RoundKoord();
+
+   // Bueparametrene for oppdatert "bue"
+   if (LC_GetBuePar(HENT_FORRFRA,&as,&ns,&r,&fi,&dfi,&s) )
+   {
+      // Buen er snudd krumming (�pningsvinkelen har skiftet fortegn)
+      if (dDeltaFi * dfi  <  0.0)
+      {
+         LC_PutGi(1,".KURVE");
+      }
+      else
+      {
+         // Sjekk at buen ikke har blitt en rett linje etter avrunding til aktuell enhet.
+         LC_GetTK(1,&a1,&n1);
+         LC_GetTK((Sys.pGrInfo->nko+1)/2,&dAMidt,&dNMidt);
+         LC_GetTK(Sys.pGrInfo->nko,&a2,&n2);
+         GM_fotp(a1,n1,a2,n2,dAMidt,dNMidt,&dAFotP,&dNFotP);
+         // Avstand fra fotpunktet til punktet p� buen m� v�re minst en enhet
+         if(GM_Avstand(dAMidt,dNMidt,dAFotP,dNFotP) < Sys.pGrInfo->dEnhet) {
+            LC_PutGi(1,".KURVE");
+         }
+      }
+   }
+   else
+   {
+      LC_PutGi(1,".KURVE");
+   }
+}
+
+
+/*
+AR-930803
+CH LC_SammenfoyGr                                          Sammenf�y grupper
+CD ==========================================================================
+CD Form�l:
+CD Sammenf�ye to grupper.
+CD Kopierer koordinater fra gitt gruppe inn i aktuell gruppe.
+CD De kopierte koordinatene kommer som en utvidelse av gruppen.
+CD Rutinen tildeler selv n�dvendig plass i buffer.
+CD Kvalitet og enhet blir automatisk oppdatert slik at gruppene ikke 
+CD mister informasjon.
+CD Gruppen det kopieres fra blir slettet.
+CD Eventuelle referanser til gruppene blir oppdatert.
+CD
+CD
+CD Parametre:
+CD Type    Navn       I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_BGR * pFraBgr     i    Gruppenummer det skal kopieres fra.
+CD short   retning     i    Buffer-retning:
+CD                                HENT_FORRFRA ( 1) = vanlig,
+CD                                HENT_BAKFRA  (-1) = buffer skal snues.
+CD short   plassering  i    Forteller hvor pFraBgr skal plasseres i
+CD                          aktuell gruppe.
+CD                             LC_SG_FORRAN = Heng den andre gruppen inn
+CD                                            forran f�rste koordinat.
+CD                             LC_SG_BAK    = Heng den andre gruppen inn
+CD                                            etter siste koordinat.
+CD short   metode      i    Forteller hva som skal skje med sammenf�ingspunktene.
+CD                             LC_SG_BEHOLD = Begge punktene beholdes.
+CD                             LC_SG_FJERN  = Bare det ene av punktene beholdes.
+CD short   ngi         u    Antall GINFO-linjer
+CD long    nko         u    Antall koordinater
+CD unsigned short info u    Diverse informasjon. (Se under $LENKE<LC_RxGr>)
+CD short   sStatus     r    Status: UT_TRUE=OK, UT_FALSE=ikke utf�rt.
+CD
+CD Bruk:
+CD sStatus = LC_SammenfoyGr(bgr,retning,plassering,metode,&ngi,&nko,&info);
+   =============================================================================
+*/
+SK_EntPnt_FYBA short LC_SammenfoyGr(LC_BGR * pFraBgr,short retning,short plassering,short metode,
+                    short *ngi,long *nko,unsigned short *info)
+{
+   short Endret,gnavn;
+   long FraNko,sTilPkt;
+   LC_BGR AktBgr,FlateBgr;
+   long lAktSnr,lFraSnr;
+   double nva,nvn,oha,ohn;
+   LC_GEO_STATUS GeoStat;
+   LC_POLYGON Pol;
+   LC_OY_ELEMENT * pOE;
+   short sStatus = UT_TRUE;
+
+
+   if (Sys.GrId.lNr == INGEN_GRUPPE){        /* Feil ==> Ingen aktuell gruppe */
+      LC_Error(31,"(LC_SammenfoyGr)","");
+      sStatus = UT_FALSE;
+
+   } else {
+      /* Husk aktuell gruppe */
+      AktBgr = Sys.GrId;
+      lAktSnr = LC_GetSn();
+      sTilPkt = (plassering == LC_SG_FORRAN)?  1 : (Sys.pGrInfo->nko+1); 
+
+		/* ========= Kopier */
+      if (LC_CopyCoord(pFraBgr,retning,sTilPkt,ngi,nko,info)) {
+         LC_WxGr(SKRIV_OPTIMALT);
+
+         /* ========= Oppdater referanser */
+         LC_RxGr(pFraBgr,LES_OPTIMALT,ngi,&FraNko,info);
+         lFraSnr = LC_GetSn();
+      
+         LC_GetGrWin(&AktBgr,&nva,&nvn,&oha,&ohn);
+
+         LC_SBFlate(&GeoStat,LC_FRAMGR,(double)nva,(double)nvn,
+                                       (double)oha,(double)ohn);
+         if (LC_FFFlate(&GeoStat,&FlateBgr)) {
+            do {
+               if (FlateBgr.pFil == AktBgr.pFil) {  /* P� samme fil ? */
+   
+                  /* Funnet flate i rett fil, sjekk referansene */
+                  gnavn = LC_RxGr(&FlateBgr,LES_OPTIMALT,ngi,nko,info);
+
+                  if ( gnavn == L_FLATE) {
+                     /* Hent referansene */
+                     LC_POL_InitPolygon(&Pol);
+                     LC_POL_GetRef(&Pol);
+
+                     /* Ytre avgrensning */
+					      Endret = LB_RensOmkrets(&Pol.HovedPO,lAktSnr,lFraSnr);
+
+                     /* �yer */
+                     for (pOE = Pol.OyOA.pForsteOE; pOE != NULL; pOE = pOE->pNesteOE) {
+                        /* Sjkker en og en �y */
+					         Endret |= LB_RensOmkrets(&pOE->PO,lAktSnr,lFraSnr);
+                     }
+
+                     /* Lagre oppdatert referanse */
+                     if (Endret == UT_TRUE) {
+                        *ngi = LC_POL_PutRef(&Pol);
+                        LC_WxGr(SKRIV_OPTIMALT);
+                     }
+
+                     /* Frigi allokerte kjeder */
+                     LC_POL_FrigiPolygon(&Pol);
+                  }
+				   }
+			   } while (LC_FNFlate(&GeoStat,&FlateBgr));
+         }
+         LC_AvsluttSok(&GeoStat);
+
+         /* ========= Fjern den kopierte gruppen fra basen */
+         LC_RxGr(pFraBgr,LES_OPTIMALT,ngi,&FraNko,info);
+         lFraSnr = LC_GetSn();
+         LC_DelGr();
+      
+         /* ========= Les inn opprinnelig gruppe igjen */
+         LC_RxGr(&AktBgr,LES_OPTIMALT,ngi,nko,info);
+
+         /* ========= Fjerner punkt og fjerner KP fra koblingspunktet */
+         if (metode == LC_SG_FJERN) {
+            if (plassering == LC_SG_BAK) {
+               LC_PutKp(sTilPkt,0);
+               *nko = LC_DelKoL(sTilPkt-1,1);
+            } else {
+               LC_PutKp(FraNko,0);
+               *nko = LC_DelKoL(FraNko+1,1);
+            }
+
+         } else {
+            if (plassering == LC_SG_BAK) {
+               LC_PutKp(sTilPkt,0);
+               LC_PutKp(sTilPkt-1,0);
+            } else {
+               LC_PutKp(FraNko,0);
+               LC_PutKp(FraNko+1,0);
+            }
+         }
+
+      } else {                  /* For mange koordinater */
+         sStatus = UT_FALSE;
+      }
+   }
+
+   return sStatus;
+}
+
+
+/*
+AR-930803
+CH LB_RensOmkrets                             Fjerner overfl�dige referanser
+CD ==========================================================================
+CD Form�l:
+CD  Fjerner overfl�dige referanser ved sammenf�ining av to grupper.
+CD
+CD Parametre:
+CD Type    Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD
+CD
+CD
+CD Bruk:
+CD Endret = LB_RensOmkrets(&Pol.HovedPO,lAktSnr,lFraSnr);
+   =============================================================================
+*/
+static short LB_RensOmkrets(LC_POL_OMKR * pPO,long lAktSnr,long lFraSnr)
+{
+   LC_POL_ELEMENT * pPE;
+
+
+   if (pPO != NULL) {
+      /* Tilslag p� f�rste og siste gruppe */
+      if (pPO->pForstePE->lSnr  == lAktSnr  &&
+          pPO->pSistePE->lSnr  == lFraSnr) {
+         /* Overser siste referansen (kopiert gruppe) */
+         LC_POL_FjernGruppeOmkrets(pPO, pPO->pSistePE);
+		   return UT_TRUE;
+
+      } else if (pPO->pForstePE->lSnr  == lFraSnr  &&
+                 pPO->pSistePE->lSnr  == lAktSnr) {
+
+         /* Overser f�rste referansen (kopiert gruppe) */
+         LC_POL_FjernGruppeOmkrets(pPO, pPO->pForstePE);
+         return UT_TRUE;
+      }
+
+      /* Resten av referansene */
+      for(pPE = pPO->pForstePE; pPE->pNestePE != NULL; pPE = pPE->pNestePE) {
+
+         if (pPE->lSnr  == lAktSnr  &&
+             pPE->pNestePE->lSnr  == lFraSnr) {
+            /* Overser siste referansen (kopiert gruppe) */
+            LC_POL_FjernGruppeOmkrets(pPO, pPE->pNestePE);
+		      return UT_TRUE;
+
+         } else if (pPE->lSnr  == lFraSnr  &&
+                    pPE->pNestePE->lSnr  == lAktSnr) {
+
+            /* Overser f�rste referansen (kopiert gruppe) */
+            LC_POL_FjernGruppeOmkrets(pPO, pPE);
+            return UT_TRUE;
+         }
+      }
+   }
+
+   return UT_FALSE;
+}
+
+
+/*
+AR:2000-07-28
+CH LC_NyGr                                                 Ny gruppe i basen
+CD ==========================================================================
+CD Form�l:
+CD Lager en ny gruppe i basen, og tildeler serienummer.
+CD Sjekker at gruppenavnet er lovlig i denne versjon av FYBA.
+CD Ved feil navn vil ".LINJE" bli valgt.
+CD Legger inn gruppenavn i buffer.
+CD Gruppen blir "aktuell" gruppe.
+CD Sjekker ledig plass b�de for indeks-fil og sosi-fil.
+CD
+CD Parametre:
+CD Type       Navn    I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_FILADM  *pFil    i    Peker til FilAdm
+CD char       *sosi    i    Gruppenavn (Eks. ".KURVE")
+CD LC_BGR *     pBgr    iu   Tildelt gruppenummer i basen
+CD                          (Bgr.lNr=INGEN_GRUPPE = Feil, ikke oppretta)
+CD long        snr     u    Tildelt serienummer
+CD gnavn       short   r    Gruppenavn. (Se under $LENKE<LC_RxGr>)
+CD                          INGEN_GRUPPE hvis det ikke er opprettet noen ny gruppe.
+CD
+CD Bruk:
+CD gnavn = LC_NyGr (pFil,sosi,&Bgr,&snr);
+   =============================================================================
+*/
+SK_EntPnt_FYBA short LC_NyGr (LC_FILADM *pFil,char *sosi,LC_BGR * pBgr,long *snr)
+{
+   short navn_nr,gilin;
+   unsigned long ulLedigPlass;
+   char szTx[256];
+   char szSosiNavn[LC_MAX_SOSINAVN_LEN];
+   short sMetode, sSynbarhet, sHoydeMetode,sNivaa;
+   long lNoyaktighet, lHoydeNoyaktighet;
+
+
+   /* Test lovlig filpeker */
+   LO_TestFilpeker(pFil,"NyGr");
+
+   /* Preparer SOSI-navnet */
+   UT_StrCopy(szSosiNavn,sosi,LC_MAX_SOSINAVN_LEN);
+   UT_StrUpper(szSosiNavn);
+
+   /* Vanlig base */
+   if (pFil->pBase->sType == LC_BASE) {
+
+      // Har aktuell gruppe
+      if (Sys.GrId.lNr != INGEN_GRUPPE) {
+         // Er forrige gruppe endra?
+         if (Sys.sGrEndra != END_UENDRA) {
+            LC_WxGr(SKRIV_OPTIMALT);
+         }
+      }
+
+      /* Setter: 'ingen aktuell gruppe' */
+      pBgr->lNr = Sys.GrId.lNr = INGEN_GRUPPE;
+
+      /* Sjekk om lovlig filnummer */
+      if (pFil->usLag == LC_SEKV) {
+			LC_Error(37,"(LC_NyGr)","");
+         Sys.pGrInfo->gnavn = INGEN_GRUPPE;
+
+		/* Ikke skriveaksess */
+		//} else if (pFil->sAccess != UT_UPDATE  ||  pFil->lNgisLag == LC_NGIS_LES) {
+		//} else if (pFil->sAccess != UT_UPDATE  ||  strcmp(pFil->szNgisLag,"0") == 0 ) {  
+		} else if (pFil->sAccess != UT_UPDATE  ||
+                 ((Sys.sNGISmodus == NGIS_NORMAL) && (strcmp(pFil->szNgisLag,"0")) == 0) ) {  
+
+         LC_Error(38,"(LC_NyGr)","");
+         Sys.pGrInfo->gnavn = INGEN_GRUPPE;
+
+		} else {
+			if (pFil->lAntGr < LC_MAX_GRU) {
+				/* Sjekk ledig diskplass  for SOSI-filer */
+				UT_InqAvailSize(pFil->pszNavn,&ulLedigPlass);
+				if (ulLedigPlass < ((unsigned long)LC_MAX_KOORD * (unsigned long)120)) {
+               /* Disken er snart full */
+               LC_Error(93,"(LB_NyGr)",pFil->pszNavn);
+            }
+										 /* Sjekk om navnet finnes */
+				if (LN_FinnNavn(&pFil->SosiNavn,szSosiNavn,&navn_nr) != 1) {
+					navn_nr = L_LINJE;    /* Ukjent gruppenavn ==> Velg ".LINJE" */
+				}
+
+				pBgr->pFil = Sys.GrId.pFil = pFil;         /* Fil */
+				pBgr->lNr = Sys.GrId.lNr = pFil->lAntGr++; /* Ant. grupper i basen */
+
+				Sys.pGrInfo = LI_AppGrt(pBgr->pFil,pBgr->lNr);
+
+				LB_ClGr();
+				Sys.pGrInfo->gnavn = navn_nr;                /* Gruppenavn */
+				Sys.pGrInfo->sosi_st = NY_SOSI_ST;           /* Setter start SOSI til ny */
+				Sys.pGrInfo->rb_st = NY_RB_ST;
+				Sys.pGrInfo->dEnhet = pFil->TransPar.dEnhet;             /* Enhet */
+            Sys.pGrInfo->dEnhetHoyde = pFil->TransPar.dEnhet_h;   /* Enhet-H */
+            Sys.pGrInfo->dEnhetDybde = pFil->TransPar.dEnhet_d;   /* Enhet-D */
+            Sys.pGrInfo->ulPrior[0] = 0UL;              /* Prioritetstabell */
+            Sys.pGrInfo->ulPrior[1] = 0UL;
+            Sys.pGrInfo->ulPrior[2] = 0UL;
+            Sys.pGrInfo->ulPrior[3] = 0UL;
+
+            /* Nuller brukttabellen */
+            LI_PutBt(pFil,pBgr->lNr,0L);
+
+            /* Fjerner fra geogr. s�ketabell */
+            Sys.pGrInfo->pRL = NULL;
+
+            /* Nytt serienummer */
+            *snr = pFil->lMaxSnr + 1L;
+
+            /* Legg inn gruppenavn */
+            LC_AppGiL();
+            LC_PutGi(1,LN_GetNavn(&pFil->SosiNavn,navn_nr));
+            LC_PutSn(*snr);
+
+            /* NGIS-flagg */
+            //if (pFil->lNgisLag > 0) {
+            if (*pFil->szNgisLag != '\0'  &&  strcmp(pFil->szNgisLag,"0") != 0 ) {         
+
+               // Skriv navnet med hermetegn hvis det er blanke i navnet
+               if (strchr(Sys.GrId.pFil->szNgisLag,' ') != NULL) {
+                  UT_SNPRINTF(szTx,256,"..NGIS-FLAGG N \"%s\"",pFil->szNgisLag);
+               } else {
+                  UT_SNPRINTF(szTx,256,"..NGIS-FLAGG N %s",pFil->szNgisLag);
+               }
+
+               gilin = LC_AppGiL();
+               LC_PutGi(gilin,szTx);
+            }
+
+            /* ------------ Legg inn div. standardopplysninger */
+            if (*Sys.GrId.pFil->szNgisLag != '\0'  &&  strcmp(Sys.GrId.pFil->szNgisLag,"0") != 0 ) {         
+
+               /* ..KVALITET */
+               sNivaa = 1;
+               LC_GetCurKvalitet(pFil,&sNivaa,1,&sMetode,&lNoyaktighet,
+                                 &sSynbarhet,&sHoydeMetode,&lHoydeNoyaktighet);
+               UT_SNPRINTF(szTx,256,"..KVALITET %s",
+                       LC_FormatterKvalitet(sMetode,lNoyaktighet,sSynbarhet,
+                                            sHoydeMetode,lHoydeNoyaktighet) );
+               LC_PutGi(LC_AppGiL(),szTx);
+            
+               // ..DATO
+               if (*Sys.GrId.pFil->szDato != '\0'  &&  
+                   *Sys.GrId.pFil->szDato != '*'  &&  
+                   *Sys.GrId.pFil->szDato < '4')
+               { 
+                  UT_SNPRINTF(szTx,256,"..DATO %s",pFil->szDato);
+                  LC_PutGi(LC_AppGiL(),szTx);
+               }
+
+               // ..SOSI-VERSJON
+               //UT_SNPRINTF(szTx,256,"..SOSI-VERSJON %.2f",((double)(pFil->sSosiVer))/100.0);
+               //LC_PutGi(LC_AppGiL(),szTx);
+            }
+
+            /* PINFO-buffer */
+            Sys.sPibufStatus = LC_PIBUF_TOM;
+
+         } else{                     /* For mange grupper, tab. sprengt */
+            UT_SNPRINTF(err().tx,LC_ERR_LEN," %ld",pFil->lAntGr);
+            LC_Error(39,"(LC_NyGr)",err().tx);
+            Sys.pGrInfo->gnavn = INGEN_GRUPPE;
+         }
+      }
+
+   } else{                         /* Kladdebase */
+                               /* Rens bort gammelt innhold i buffergruppen */
+      LC_DelKoL(1,Sys.pGrInfo->nko);
+      LC_DelGiL(2,(short)(Sys.pGrInfo->ngi-1));
+   
+      /* Sjekk om navnet finnes */
+      if (LN_FinnNavn(&Sys.GrId.pFil->SosiNavn,sosi,&navn_nr) != 1) {
+         LC_PutGi(1,".LINJE");    /* Ukjent gruppenavn ==> Velg ".LINJE" */
+
+      } else {
+         LC_PutGi(1,szSosiNavn);
+      }
+
+      /* Nytt serienummer */
+      *snr = NYTT_SNR;
+
+      /* Nullstill info */
+      Sys.pGrInfo->info = 0;
+   }
+
+   return (Sys.pGrInfo->gnavn);
+}
+
+
+/*
+AR-911001
+CH LB_FormaterEnhet                                         Lag GINFO for enhet
+CD =============================================================================
+CD Form�l:
+CD Legger inn enhet med h�velig antall siffer.
+CD
+CD Parametre:
+CD Type     Navn   I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD char   *streng    i    Peker til streng hvor ginfo skal legges
+CD char   *sosi     i    SOSI-navn som skal legges f�rst i strengen
+CD double  enhet    i    Aktuell enhet
+CD char   *ginfo    r    Peker til oppbygd streng
+CD
+CD Bruk:
+CD LB_FormaterEnhet(streng,sStrengMaxLen,"..ENHET",enhet);
+   =============================================================================
+*/
+char *LB_FormaterEnhet(char *streng,short sStrengMaxLen,char *SosiNavn,double enhet)
+{
+   char enhet_buffer[20],*cp;
+   short sAntDes = max(1,UT_RoundDS(fabs(min(1.0,log10(enhet)))));
+
+   UT_StrCopy(streng,SosiNavn,sStrengMaxLen);
+   UT_StrCat(streng," ",sStrengMaxLen);
+
+   UT_DtoA(enhet,sAntDes,'.',20,enhet_buffer);
+
+   cp = enhet_buffer;
+   while (*cp == ' ')
+       cp++;
+
+   UT_StrCat(streng,cp,sStrengMaxLen);
+
+   return(streng);
+}
+
+
+/*
+AR-930611
+CH LC_InsGiL                                              Skyt inn GINFO-linjer
+CD =============================================================================
+CD Form�l:
+CD Skyter inn linjer GINFO-delen i en gruppe.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD short    linje    i    Linjenummer linjen skal skytes inn forran.
+CD                        (Lovlig: 1  til  ngi+1)
+CD short    antall   i    Antall linjer som skal skytest inn.
+CD short    ngi      r    Antall GINFO-linjer i gruppen etter innskuddet.
+CD
+CD Bruk:
+CD ngi = LC_InsGiL(linje, antall);
+   =============================================================================
+*/
+SK_EntPnt_FYBA short LC_InsGiL(short linje, short antall)
+{
+   short s,len;
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {            /* Aktuell gruppe OK */
+      if (linje > 0  &&  linje <= (Sys.pGrInfo->ngi + 1)) {
+
+         /* P� slutten av GINFO */
+         if (linje == (Sys.pGrInfo->ngi + 1)) {
+            for ( ; antall > 0; antall--) {
+               LC_AppGiL();
+            }
+
+         /* Inni GINFO */
+         } else {
+            Sys.sGrEndra = (short)END_ENDRA;
+            /* M� flytte resten av buffer for � gi plass til de nye linjene */
+            memmove(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[linje-1] + antall,
+                  Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[linje-1],
+                  Sys.pGrInfo->ulGiLen - Sys.Ginfo.ulOfset[linje-1]);
+
+            /* Ny total GINFO-lengde; */
+            Sys.pGrInfo->ulGiLen += antall;
+ 
+            /* Antall GINFO-linjer etter utvidelsen */
+            Sys.pGrInfo->ngi += antall;
+
+            /* Oppdater offset for resten av GINFO */
+            for (s=Sys.pGrInfo->ngi; s>=linje+antall; s--) {
+               Sys.Ginfo.ulOfset[s-1] = Sys.Ginfo.ulOfset[s-1-antall] + antall;
+            }
+
+            /* Blank ut de nye linjene */
+            for (s=0; s<antall; s++) {
+               /* Beregn ofset og blank ut linjen */
+               if (linje == 1) {
+                  Sys.Ginfo.ulOfset[0] = 0;
+                  *Sys.Ginfo.pszTx = '\0';
+               } else {
+                  /* F�rte posisjon etter forrige linje */
+                  len = (short)strlen(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[linje-2]);
+                  Sys.Ginfo.ulOfset[linje-1] = Sys.Ginfo.ulOfset[linje-2] + len + 1;
+                  *(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[linje-1]) = '\0';
+               }
+
+               linje++;
+            }
+         }
+
+      } else {
+         UT_SNPRINTF(err().tx,LC_ERR_LEN," %d",linje);
+         LC_Error(40,"(LC_InsGiL)",err().tx);
+      }
+
+   } else {                              /* Ingen aktuell gruppe */
+      LC_Error(49,"(LC_InsGiL)","");
+   }
+
+   return(Sys.pGrInfo->ngi);
+}
+
+
+/*
+AR-930610
+CH LC_AppGiL                                             Heng p� en GINFO-linje
+CD =============================================================================
+CD Form�l:
+CD Henger p� en linje i GINFO-delen i en gruppe.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD short    ngi      r    Antall GINFO-linjer i gruppen etter utvidelsen.
+CD                        (Linjenumret p� den tilf�yde linjen.)
+CD
+CD Bruk:
+CD ngi = LC_AppGiL();
+   =============================================================================
+*/
+SK_EntPnt_FYBA short LC_AppGiL()
+{
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {            /* Aktuell gruppe OK */
+      Sys.sGrEndra = (short)END_ENDRA;
+      Sys.pGrInfo->ngi++;  /* Antall GINFO-linjer etter utvidelsen */
+
+      /* Blank ut den nye linjen */
+      Sys.pGrInfo->ulGiLen++;
+      Sys.Ginfo.ulOfset[Sys.pGrInfo->ngi - 1] = Sys.pGrInfo->ulGiLen - 1;
+      *(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[Sys.pGrInfo->ngi - 1]) = '\0';
+
+   } else {                              /* Ingen aktuell gruppe */
+      LC_Error(49,"(LC_InsGiL)","");
+   }
+
+   return(Sys.pGrInfo->ngi);
+}
+
+
+/*
+AR-930611
+CH LC_InsKoL                                        Skyt inn koordinatlinjer
+CD ==========================================================================
+CD Form�l:
+CD Skyter inn linjer koordinatdelen i en gruppe.
+CD
+CD Parametre:
+CD Type    Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long    linje    i    Linjenummer linjen skal skytes inn forran.
+CD                        (Lovlig: 1  til  nko+1)
+CD long    antall   i    Antall linjer som skal skytest inn.
+CD long    nko      r    Antall koordinater i gruppen etter innskuddet.
+CD
+CD Bruk:
+CD nko = LC_InsKoL(linje, antall);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA long LC_InsKoL(long linje, long antall)
+{
+   double *pdAust = Sys.pdAust + linje - 1;
+   double *pdNord = Sys.pdNord + linje - 1;
+   LB_INFO * pInfo = Sys.pInfo + linje - 1;
+ 
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                  /* AKtuell gruppe OK */
+      if (Sys.pGrInfo->nko + antall < LC_MAX_KOORD) {
+         if (linje > 0  &&  linje <= (Sys.pGrInfo->nko + 1)) {
+            Sys.sGrEndra = (short)END_ENDRA;
+            if (linje <= Sys.lPibufPnr)  Sys.sPibufStatus = LC_PIBUF_TOM;
+
+            /* Utf�r flyttingen */
+            memmove(pdAust+antall, pdAust, (Sys.pGrInfo->nko-linje+1) * (sizeof(double)));
+            memmove(pdNord+antall, pdNord, (Sys.pGrInfo->nko-linje+1) * (sizeof(double)));
+            memmove(pInfo+antall,  pInfo,  (Sys.pGrInfo->nko-linje+1) * (sizeof(LB_INFO)));
+
+            /* Antall koordinater etter utvidelsen */
+            Sys.pGrInfo->nko += antall;
+
+            /* Blank ut det nye omr�det */
+            while (antall > 0) {
+               *pdAust = 0.0;
+               *pdNord = 0.0;
+               pInfo->dHoyde = HOYDE_MANGLER;
+               pInfo->sKp = 0;
+               pInfo->ulPiOfset = LC_INGEN_PINFO;
+               pdAust++;
+               pdNord++;
+               pInfo++;
+               antall--;
+            }
+
+         } else {
+            UT_SNPRINTF(err().tx,LC_ERR_LEN," %ld",linje);
+            LC_Error(41,"(LC_InsKoL)",err().tx);
+         }
+
+      } else {                           /* For mange koordinater */
+         LC_Error(162,"(LC_InsKoL)",LX_GetGi(1));
+      }
+         
+   } else {                              /* Ingen aktuell gruppe */
+      LC_Error(49,"(LC_InsKoL)","");
+   }
+
+   return(Sys.pGrInfo->nko);
+}
+
+
+/*
+AR-911001
+CH LC_AppKoL                                       Heng p� en koordinatlinje
+CD ==========================================================================
+CD Form�l:
+CD Henger p� en linje i koordinatdelen i en gruppe.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long    nko      r    Antall koordinater i gruppen etter utvidelsen.
+CD
+CD Bruk:
+CD nko = LC_AppKoL();
+   ==========================================================================
+*/
+SK_EntPnt_FYBA long LC_AppKoL()
+{
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                  /* AKtuell gruppe OK */
+      if (Sys.pGrInfo->nko + 1 < LC_MAX_KOORD) {
+         Sys.sGrEndra = (short)END_ENDRA;
+         Sys.pGrInfo->nko++;             /* Antall koordinater etter utvidelsen */
+
+         /* Blank ut den nye linjen */
+         *(Sys.pdAust+Sys.pGrInfo->nko - 1) = 0.0;
+         *(Sys.pdNord+Sys.pGrInfo->nko - 1) = 0.0;
+         (Sys.pInfo+Sys.pGrInfo->nko - 1)->dHoyde = HOYDE_MANGLER;
+         (Sys.pInfo+Sys.pGrInfo->nko - 1)->sKp = 0;
+         (Sys.pInfo+Sys.pGrInfo->nko - 1)->ulPiOfset = LC_INGEN_PINFO;
+
+      } else {                           /* For mange koordinater */
+         LC_Error(162,"(LC_AppKoL)",LX_GetGi(1));
+      }
+
+   } else {                              /* Ingen aktuell gruppe */
+      LC_Error(49,"(LC_AppKoL)","");
+   }
+
+   return(Sys.pGrInfo->nko);
+}
+
+
+
+
+/*
+AR-930611
+CH LC_DelGiL                                                 Fjern GINFO-linjer
+CD =============================================================================
+CD Form�l:
+CD Fjerner linjer i GINFO-delen i en gruppe.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD short    linje    i    F�rste linjenummer som skal fjernes.
+CD                        (Lovlig: 2  til  ngi)
+CD short    antall   i    Antall linjer som skal fjernes.
+CD short    ngi      r    Antall GINFO-linjer i gruppen etter setting.
+CD
+CD Bruk:
+CD ngi = LC_DelGiL(linje, antall);
+   =============================================================================
+*/
+SK_EntPnt_FYBA short LC_DelGiL(short linje, short antall)
+{
+   short start;
+   char *pszTil, *pszFra;
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                 /* AKtuell gruppe OK */
+      if (antall > 0) {
+         Sys.sGrEndra = (short)END_ENDRA;
+
+         start = max(linje,2);           /* 2 er f�rste lovlige linje */
+         antall -= (start-linje);        /* Juster antall tilsvarende */
+
+         /* Max antall er resten av GINFO */
+         antall = min(start+antall-1,Sys.pGrInfo->ngi) - start + 1;
+
+         if (start+antall <= Sys.pGrInfo->ngi) {
+            /* Beregn forflytting */
+            pszTil = Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[start-1];
+            pszFra = Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[start+antall-1];
+
+            /* Utf�r flyttingen */
+            memmove(pszTil, pszFra, Sys.pGrInfo->ulGiLen - Sys.Ginfo.ulOfset[start+antall-1] + 1);
+
+            /* Antall GINFO-linjer etter slettingen */
+            Sys.pGrInfo->ngi -= antall;
+
+            /* Ny total GINFO-lengde; */
+            Sys.pGrInfo->ulGiLen -= (unsigned long)(pszFra - pszTil);
+
+            /* Oppdater offset for resten av GINFO */
+            LX_CreGiPeker(&Sys.Ginfo,Sys.pGrInfo->ngi);
+
+         /* Fjerner fram til slutten av GINFO */
+         } else {
+            /* Antall GINFO-linjer etter slettingen */
+            Sys.pGrInfo->ngi -= antall;
+            /* Ny total GINFO-lengde; */
+            Sys.pGrInfo->ulGiLen = Sys.Ginfo.ulOfset[start-1];
+         }
+      }
+
+   } else {                              /* Ingen aktuell gruppe */
+      LC_Error(49,"(LC_DelGiL)","");
+   }
+
+   return (Sys.pGrInfo->ngi);
+}
+
+
+/*
+AR:2008-04-09
+CH LC_DelGiNavn                                   Fjerner egenskap fra GINFO
+CD ==========================================================================
+CD Form�l:
+CD Fjerner alle forekomster av gitt egenskap (SOSI-navn) fra GINFO.
+CD
+CD Parametre:
+CD Type     Navn             I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD char    *pszEgenskapNavn   i    SOSI-navn som skal slettes
+CD short    ngi               r    Antall GINFO-linjer i gruppen etter setting
+CD
+CD Bruk:
+CD ngi = LC_DelGiNavn("..RADIUS");
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_DelGiNavn(char *pszEgenskapNavn)
+{
+   short sGiLinje = 2;
+   while (LC_GetGP(pszEgenskapNavn,&sGiLinje,Sys.pGrInfo->ngi) != NULL)
+   {
+      LC_DelGiL(sGiLinje,1);  
+   }
+
+   return Sys.pGrInfo->ngi;
+}
+
+
+/*
+AR-930611
+CH LC_DelKoL                                              Fjern koordinatlinjer
+CD =============================================================================
+CD Form�l:
+CD Fjerner linjer koordinatdelen i en gruppe.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD long    linje    i    F�rste linje som skal fjernes.
+CD                        (Lovlig: 1  til  nko)
+CD long    antall   i    Antall linjer som skal fjernes.(Max resten av gruppen)
+CD long    nko      r    Antall koordinater i gruppen etter blanking.
+CD
+CD Bruk:
+CD nko = LC_DelKoL(linje, antall);
+   =============================================================================
+*/
+SK_EntPnt_FYBA long LC_DelKoL(long linje, long antall)
+{
+   long start,s;
+   double *pdAust, *pdNord;
+   LB_INFO * pInfo,*pI;
+   unsigned long ulP1,ulP2,ulDelta;
+ 
+
+   /* UT_FPRINTF(stderr,"DelKoL: %hd - %hd (%hd) \n",linje,antall,Sys.GrInfo.nko); */
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {              /* AKtuell gruppe OK */
+      Sys.sGrEndra = (short)END_ENDRA;
+      if (linje <= Sys.lPibufPnr)  Sys.sPibufStatus = LC_PIBUF_TOM;
+            
+      start = max(linje,1);             /* 1 er f�rste lovlige linje */
+      antall -= (start-linje);          /* Juster antall tilsvarende */
+
+                                        /* Max antall er resten av punktene */
+      antall = min(start+antall-1,Sys.pGrInfo->nko) - start + 1;
+
+      /* UT_FPRINTF(stderr," %hd - %hd\n",start,antall); */
+
+      if (antall > 0) {
+         pdAust = Sys.pdAust + start - 1;
+         pdNord = Sys.pdNord + start - 1;
+         pInfo = Sys.pInfo + start - 1;
+
+
+         /* Pakk PINFO-bufferet */
+
+         /* Har gruppen PINFO */
+         if (Sys.pGrInfo->ulPiLen > 0) {
+            /* Er det PINFO p� de punktene som er slettet? */
+            pI = pInfo;
+            ulP1 = LC_INGEN_PINFO;
+            for (s=0; s<antall && ulP1==LC_INGEN_PINFO; s++,pI++) {
+               if (pI->ulPiOfset != LC_INGEN_PINFO) {
+                  ulP1 = pI->ulPiOfset;
+               }
+            }
+
+            /* Er det funnet PINFO ? */
+            if (ulP1 != LC_INGEN_PINFO) {
+                /* Sjekk om det er PINFO i resten av gruppen */
+               pI = pInfo+antall;
+               ulP2 = LC_INGEN_PINFO;
+               for (s=start+antall; s<=Sys.pGrInfo->nko && ulP2==LC_INGEN_PINFO; s++,pI++) {
+                  if (pI->ulPiOfset != LC_INGEN_PINFO) {
+                     ulP2 = pI->ulPiOfset;
+                  }
+               }
+
+
+               /* Er det funnet PINFO ? */
+               if (ulP2 != LC_INGEN_PINFO) {
+                  /* Oppdater ofset */
+                  ulDelta = ulP2 - ulP1;
+                  pI = pInfo+antall;
+                  for (s=start+antall; s <= Sys.pGrInfo->nko; s++,pI++) {
+                     if (pI->ulPiOfset != LC_INGEN_PINFO) {
+                        pI->ulPiOfset -= ulDelta;
+                     }
+                  }
+ 
+                  /* Pakk buffer */
+                  memmove(Sys.pszPinfo+ulP1, Sys.pszPinfo+ulP2, (Sys.pGrInfo->ulPiLen-ulP2) * (sizeof(char)));
+                  Sys.pGrInfo->ulPiLen -= ulDelta;
+
+               /* Det er ikke PINFO i resten av gruppen */
+               } else {
+                  /* Oppdater total PINFO-lengde */
+                  Sys.pGrInfo->ulPiLen = ulP1;
+               }
+            }
+         }
+
+         /* Utf�r flyttingen */
+         memmove(pdAust, pdAust+antall, (Sys.pGrInfo->nko-start-antall+1) * (sizeof(double)));
+         memmove(pdNord, pdNord+antall, (Sys.pGrInfo->nko-start-antall+1) * (sizeof(double)));
+         memmove(pInfo,  pInfo+antall,  (Sys.pGrInfo->nko-start-antall+1) * (sizeof(LB_INFO)));
+ 
+         /* Antall koordinater etter sletting */
+         Sys.pGrInfo->nko -= antall;
+      }
+
+   } else {                              /* Ingen aktuell gruppe */
+      LC_Error(49,"(LC_DelKoL)","");
+   }
+
+   return(Sys.pGrInfo->nko);
+}
+       
+
+
+/*
+AR-930803
+CH LB_ClGr                                          Nullstill aktuell gruppe
+CD ==========================================================================
+CD Form�l:
+CD Nullstill aktuell gruppe.
+CD
+CD Parametre:
+CD Type             Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD
+CD Bruk:
+CD LB_ClGr ();
+   =============================================================================
+*/
+void LB_ClGr (void)
+{
+   Sys.pGrInfo->ngi = 0;
+   Sys.pGrInfo->nko = 0;
+   Sys.pGrInfo->info = 0;
+   Sys.pGrInfo->ulGiLen = 0;
+   Sys.pGrInfo->ulPiLen = 0;
+   Sys.pGrInfo->szObjtype[0] = '\0';
+}
+
+
+/*
+AR-930610
+CH LB_RGru                                                        Les gruppe
+CD ==========================================================================
+CD Form�l:
+CD Leser en datagruppe fra SOSI-fil inn i aktuell gruppe.
+CD Eventuelle gamle pekere m� v�re frgitt utenfor denne rutinen.
+CD
+CD Parametre:
+CD Type       Navn    I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil     i   Peker til FilAdm
+CD UT_INT64   start    i   Startposisjon p� SOSI-filen
+CD UT_INT64   slutt    u   Sluttposisjon p� SOSI-filen
+CD short      siste_gr r   Siste gruppe (0=ikke siste, 1=siste p� filen)
+CD
+CD Bruk:
+CD siste_gr = LB_RGru(pFil,start,&slutt);
+   ==========================================================================
+*/
+short LB_RGru(LC_FILADM *pFil,UT_INT64 start,UT_INT64 *slutt)
+{
+   short type,siste,npinf;
+   long snr;
+   char *cp,tx[LC_MAX_SOSI_LINJE_LEN];
+   LB_LESEBUFFER *pLb = &pFil->pBase->BufAdm;
+   LC_FILADM *pAktFil = Sys.GrId.pFil;
+   LB_INFO *pInfo = NULL;
+   double d;
+   short sLagreNavn;      /* Flagg som viser om sosi-navnet skal skrives til buffer */
+   short sRefFunnet = UT_FALSE; /* Flagg som viser om referanse av ny type (..REF) er funnet i gruppen */
+
+   double dEnhet = 0.0;
+   double dEnhet_h = 0.0;
+   double dEnhet_d = 0.0;
+   double dOrigoAust = pFil->TransPar.Origo.dAust;      /* Origo til lokale variabler */
+   double dOrigoNord = pFil->TransPar.Origo.dNord;
+
+
+   /* PINFO-buffer er �delagt */
+   Sys.sPibufStatus = LC_PIBUF_TOM;
+
+   /* Angi hvilket tegnsett som skal brukes */
+   pLb->sTegnsett = pFil->sTegnsett;
+
+      /* Sett filposisjon */
+   LO_ReopenSos(pFil);
+   _fseeki64(pFil->pBase->pfSos,start,SEEK_SET);
+   pLb->sStatus = LESEBUFFER_TOM;
+
+   type = LB_GetSet(pFil->pBase->pfSos,pLb,&(pAktFil->SosiNavn));
+
+   if (pLb->cur_navn[pLb->cur_niv-1] != L_SLUTT) {    /* Ikke lest ".SLUTT" */
+      /* Sjekk at gruppen har lovlig gruppenavn */
+      if (type < 0) {
+         UT_SNPRINTF(err().tx,LC_ERR_LEN," \"%s %s\"",LN_GetNavn(&(pAktFil->SosiNavn),
+                                 pLb->cur_navn[pLb->cur_niv-1]),pLb->pp);
+         LC_Error(47,"(LB_RGru)",err().tx);
+         exit (2);
+      }  
+      
+      siste = 0;
+
+      /* Nullstiller gruppen */
+      LB_ClGr();
+
+      /* Legg inn gruppenavnet med serienummer */
+      Sys.pGrInfo->gnavn = pLb->cur_navn[0];
+      Sys.pGrInfo->ngi = 1;                           
+      snr = strtol(pLb->pp,&cp,10); 
+      if (Sys.pGrInfo->gnavn != L_HODE) {
+         UT_SNPRINTF(tx,LC_MAX_SOSI_LINJE_LEN,"%s %ld:",LN_GetNavn(&pAktFil->SosiNavn,pLb->cur_navn[0]),snr);
+      } else {
+         UT_StrCopy(tx,LN_GetNavn(&pAktFil->SosiNavn,pLb->cur_navn[0]),LC_MAX_SOSI_LINJE_LEN);
+      }
+      UT_StrCopy(Sys.Ginfo.pszTx,tx,LC_MAX_SOSI_LINJE_LEN);
+      *Sys.Ginfo.ulOfset = 0;
+      Sys.pGrInfo->ulGiLen = (unsigned long)strlen(tx) + 1;
+
+      pLb->set_brukt = SET_BRUKT;
+
+      /* Leser resten av GINFO */
+      type = LB_GetSet(pFil->pBase->pfSos,pLb,&(pAktFil->SosiNavn));
+
+      while (type < LEST_KOORD  &&  pLb->cur_niv > 1) {
+         if (type != LEST_BLANK) {
+            sLagreNavn = UT_TRUE;
+
+            /* GINFO */
+            if (type == LEST_GINFO) {
+                  /* Referanse */
+               if (pLb->cur_navn[pLb->cur_niv-1] == L_REF1  ||
+                   pLb->cur_navn[pLb->cur_niv-1] == L_REF2) {
+                  Sys.pGrInfo->info |= GI_REF;               
+                  if (LN_TestOy(pLb->pp))  Sys.pGrInfo->info |= GI_OY_REF;
+
+                  /* ..REF skal skrives bare p� f�rste linje med referanser */ 
+                  if (pLb->cur_navn[pLb->cur_niv-1] == L_REF2  &&  sRefFunnet == UT_TRUE) {
+                     sLagreNavn = UT_FALSE;
+                  }
+
+#ifdef UTGAAR
+                  /* Gruppen har h�yde informasjon */
+               } else if (pLb->cur_navn[pLb->cur_niv-1] == L_HOYDE) {
+                  Sys.pGrInfo->info |= GI_NAH;   /* Husk at gruppen har h�yde */
+#endif
+
+                  /* Spesiell "..ENHET" */
+               } else if (pLb->cur_navn[pLb->cur_niv-1] == L_ENHET2) {
+                  dEnhet = strtod(pLb->pp,&cp);
+
+                  /* Spesiell "..ENHET-H" */
+               } else if (pLb->cur_navn[pLb->cur_niv-1] == L_ENHET2H) {
+                  dEnhet_h = strtod(pLb->pp,&cp);
+
+                  /* Spesiell "..ENHET-D" */
+               } else if (pLb->cur_navn[pLb->cur_niv-1] == L_ENHET2D) {
+                  dEnhet_d = strtod(pLb->pp,&cp);
+
+                  /* Spesiell "...ENHET" */
+               } else if (pLb->cur_navn[pLb->cur_niv-1] == L_ENHET3) {
+                  dEnhet = strtod(pLb->pp,&cp);
+
+                  /* Spesiell "...ENHET-H" */
+               } else if (pLb->cur_navn[pLb->cur_niv-1] == L_ENHET3H) {
+                  dEnhet_h = strtod(pLb->pp,&cp);
+
+                  /* Spesiell "...ENHET-D" */
+               } else if (pLb->cur_navn[pLb->cur_niv-1] == L_ENHET3D) {
+                  dEnhet_d = strtod(pLb->pp,&cp);
+               }
+
+               /* Bygg opp GINFO-strengen for denne linjen */
+               if (sLagreNavn == UT_TRUE) {
+                  UT_StrCopy(tx,LN_GetNavn(&pAktFil->SosiNavn,pLb->cur_navn[pLb->cur_niv-1]),LC_MAX_SOSI_LINJE_LEN);
+               } else {
+                  *tx = '\0';
+               }
+               if (sLagreNavn == UT_TRUE  &&  *(pLb->pp) != '\0') {
+                  UT_StrCat(tx," ",LC_MAX_SOSI_LINJE_LEN);
+               }
+               if (*(pLb->pp) != '\0') {
+                  UT_StrCat(tx,pLb->pp,LC_MAX_SOSI_LINJE_LEN);
+               }
+            
+               /* Husk at det er funnet ny type referanse */
+               if (pLb->cur_navn[pLb->cur_niv-1] == L_REF2) {
+                  sRefFunnet = UT_TRUE;     /* Viser at referanse av ny type (..REF) er funnet */
+               }
+
+               // Husk OBJTYPE
+               if (pLb->cur_navn[pLb->cur_niv-1] == L_OBJTYPE) {
+                  UT_StrCopy(Sys.pGrInfo->szObjtype,pLb->pp,LC_MAX_OBJTYPE_LEN);
+               }
+
+            /* Kommentar */
+            } else {
+               UT_StrCopy(tx,pLb->pp,LC_MAX_SOSI_LINJE_LEN);
+            }
+
+            /* GINFO og kommentar-linje lagres */
+            if (Sys.pGrInfo->ngi >= LC_MAX_GINFO) {
+               LC_Error(149,"(LB_RGru)",Sys.Ginfo.pszTx);
+
+            } else if ((Sys.pGrInfo->ulGiLen + strlen(tx) + 1) >= LC_MAX_GINFO_BUFFER) {
+               LC_Error(150,"(LB_RGru)",Sys.Ginfo.pszTx);
+
+            } else {
+               Sys.pGrInfo->ngi++;    
+               UT_StrCopy(Sys.Ginfo.pszTx + Sys.pGrInfo->ulGiLen, tx,LC_MAX_SOSI_LINJE_LEN);
+               Sys.Ginfo.ulOfset[Sys.pGrInfo->ngi - 1] = Sys.pGrInfo->ulGiLen;
+               Sys.pGrInfo->ulGiLen += (unsigned long)strlen(tx) + 1;
+            }
+         }
+
+         // Hent neste linje
+         pLb->set_brukt = SET_BRUKT;
+         type = LB_GetSet(pFil->pBase->pfSos,pLb,&(pAktFil->SosiNavn));
+      }
+
+      // Enhet er ikke gitt i GINFO, bruk filhodets enhet
+      if (dEnhet == 0.0)  dEnhet = pFil->TransPar.dEnhet;
+
+      // Enhet-H er ikke gitt i GINFO brukes enhet-H fra filhodet
+      if (dEnhet_h == 0.0)  dEnhet_h = pFil->TransPar.dEnhet_h;
+
+      // Enhet-D er ikke gitt i GINFO brukes enhet-D fra filhodet
+      if (dEnhet_d == 0.0)  dEnhet_d = pFil->TransPar.dEnhet_d;
+
+      /* Husk aktuell ENHET */
+      Sys.pGrInfo->dEnhet = dEnhet;
+      Sys.pGrInfo->dEnhetHoyde = dEnhet_h;
+      Sys.pGrInfo->dEnhetDybde = dEnhet_d;
+
+      /* Koordinatdelen */
+      while (pLb->cur_niv >= 2) {
+         if (type != LEST_BLANK  &&  type != LEST_KOM) {
+            /* Sjekk at det ikke kommer GINFO innimellom koordinatene */
+               /* Ikke N� eller N�H */
+            if (pLb->cur_niv == 2  &&
+                pLb->cur_navn[pLb->cur_niv-1] != L_NAH  &&
+                pLb->cur_navn[pLb->cur_niv-1] != L_NAD  &&
+                pLb->cur_navn[pLb->cur_niv-1] != L_NA)
+            {
+               char szMelding[256];
+               UT_SNPRINTF(szMelding,256,"Egenskap \"%s\" i \"%s\"",pLb->tx,Sys.Ginfo.pszTx);
+               LC_Error(144,"(LB_RGru)",szMelding);
+            }
+
+            /* Sjekk at det ikke blir for mange koordinater */
+            if (Sys.pGrInfo->nko >= LC_MAX_KOORD)
+            {
+               UT_SNPRINTF(err().tx,LC_ERR_LEN," \"%s %ld:\"",LN_GetNavn(&pAktFil->SosiNavn,pLb->cur_navn[0]),snr);
+               LC_Error(148,"(LB_RGru)",err().tx);
+            }
+
+            if (*pLb->pp != '\0')
+            {
+               Sys.pGrInfo->nko++;
+               pInfo = Sys.pInfo + Sys.pGrInfo->nko - 1;
+
+               /* Regn om til basekoordinater og legg inn i buffer */
+
+              /* Nord-koordinaten */
+               d = strtod(pLb->pp,&cp);
+               *(Sys.pdNord + Sys.pGrInfo->nko - 1) = dOrigoNord + (d * dEnhet);
+
+               /* �st-koordinaten */
+               d = strtod(cp,&cp);  
+               *(Sys.pdAust + Sys.pGrInfo->nko - 1) = dOrigoAust + (d * dEnhet);
+
+               /* ..N�H */
+               if (pLb->cur_navn[pLb->cur_niv-1] == L_NAH)
+               { 
+                  Sys.pGrInfo->info |= GI_NAH;   /* Husk at gruppen har h�yde */
+
+                  /* Regn om h�yden */
+                  d = strtod(cp,&cp);
+                  pInfo->dHoyde = d * dEnhet_h;
+               }
+
+               /* ..N�D */
+               else if (pLb->cur_navn[pLb->cur_niv-1] == L_NAD)
+               {
+                  Sys.pGrInfo->info |= GI_NAD;   /* Husk at gruppen har dybde */
+
+                  /* Regn om dybden (Lagres som terrengverdi i mm) */
+                  d = strtod(cp,&cp);
+                  pInfo->dHoyde = d * dEnhet_d;
+               }
+
+               else 
+               {
+                  pInfo->dHoyde = HOYDE_MANGLER;
+               }
+            }
+
+            pLb->set_brukt = SET_BRUKT;
+
+            /* Neste sett */
+            type = LB_GetSet(pFil->pBase->pfSos,pLb,&(pAktFil->SosiNavn));
+            
+
+                                 /* PINFO */
+            if (Sys.pGrInfo->nko > 0)
+            {
+               pInfo->sKp = 0;
+               pInfo->ulPiOfset = LC_INGEN_PINFO;
+               npinf = 0;
+               *tx = '\0';
+               while (pLb->cur_niv > 2)
+               {
+                  if (type != LEST_BLANK  &&  type != LEST_KOM)
+                  {
+                     if (pLb->cur_navn[pLb->cur_niv-1] == L_KP) 
+                     {    /* Knutepunkt */
+                        /* Sjekk om det er flere kp i samme punkt */
+                        if (pInfo->sKp != 0)
+                        {
+                           //UT_SNPRINTF(err().tx,LC_ERR_LEN," \"%s\"",pLb->pp);
+                           UT_SNPRINTF(err().tx,LC_ERR_LEN," \"%s\" pnr.: %ld ",LX_GetGi(1), Sys.pGrInfo->nko);
+                           LC_Error(145,"(LB_RGru)",err().tx);
+                        }
+                        else
+                        {
+                           pInfo->sKp = (short)strtol(pLb->pp,&cp,10);
+                           Sys.pGrInfo->info |= GI_KP;
+                        }
+
+                     } else {                                  /* Annen PINFO */
+                        npinf++;
+                        if (npinf > 1)  UT_StrCat(tx," ",LC_MAX_SOSI_LINJE_LEN);
+                        UT_StrCat(tx, LN_GetNavn(&(pAktFil->SosiNavn),pLb->cur_navn[pLb->cur_niv-1]),
+                                  LC_MAX_SOSI_LINJE_LEN);
+                        if (*(pLb->pp) != '\0'){
+                           UT_StrCat(tx," ",LC_MAX_SOSI_LINJE_LEN);
+                           UT_StrCat(tx,pLb->pp,LC_MAX_SOSI_LINJE_LEN);
+                        }
+                     
+                        if (strlen(tx) > LC_MAX_SOSI_LINJE_LEN) {
+                           tx[30] = '\0';
+                           LC_Error(143,"(LB_RGru)",tx);
+                           tx[0] = '\0';
+                           npinf = 0;
+                        }
+                     }
+                  }
+
+                  pLb->set_brukt = SET_BRUKT;
+
+                  /* Neste sett */
+                  type = LB_GetSet(pFil->pBase->pfSos,pLb,&(pAktFil->SosiNavn));
+               }
+
+               /* Lagre PINFO */
+               if (*tx != '\0') {
+                  if (Sys.pGrInfo->ulPiLen == 0) {
+                     pInfo->ulPiOfset = 0;
+                  } else {
+                     pInfo->ulPiOfset = Sys.pGrInfo->ulPiLen;
+                  }
+
+                  if ((Sys.pGrInfo->ulPiLen + strlen(tx) + 1) >= LC_MAX_PINFO_BUFFER) {
+                     LC_Error(161,"(LB_RGru)",Sys.Ginfo.pszTx);
+
+                  } else {
+                     UT_StrCopy(Sys.pszPinfo + pInfo->ulPiOfset, tx, LC_MAX_PINFO_BUFFER-pInfo->ulPiOfset);
+                     Sys.pGrInfo->ulPiLen += (unsigned long)strlen(tx) + 1;
+                  }
+
+                  Sys.pGrInfo->info |= GI_PINFO;
+               }
+            }         
+
+         } else {       /* Fyll-linje er lest */
+            pLb->set_brukt = SET_BRUKT;
+            /* Neste sett */
+            type = LB_GetSet(pFil->pBase->pfSos,pLb,&(pAktFil->SosiNavn));
+
+         }
+      }
+
+   } else {                                         /* ".SLUTT" */
+       siste = 1;
+   }
+
+   if (Sys.pGrInfo->gnavn == L_HODE  &&  !siste ) {  /* Oppdater filtabellen */
+       LO_BeFt(pFil);
+   }
+
+   *slutt = pLb->startpos;                         /* Slutt - filposisjon */
+   return(siste);
+}
+
+
+/*
+AR-911001
+CH LB_Save                                           T�m skrivek�a for 1 fil
+CD ==========================================================================
+CD Form�l:
+CD Skriver gruppene som ligger i skrivek� ut til SOSI-fil.
+CD
+CD Parametre:
+CD Type       Navn  I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil   i    Peker til FilAdm
+CD
+CD Bruk:
+CD LB_Save(pFil);
+   ==========================================================================
+*/
+void LB_Save(LC_FILADM *pFil)
+{
+   LC_BGR Bgr,AktBgr;
+   long lNr;
+   short ngi;
+   long  nko;
+   unsigned short info;
+
+   Bgr.pFil = pFil;
+
+   if (Sys.lAntSkriv > 0L) {                     /* Er det noen i k� ? */
+      AktBgr = Sys.GrId;
+      for (lNr=0L; lNr<pFil->lAntGr; lNr++) {
+         if (LI_InqBt(pFil,lNr,BT_SKRKO)) {           /* I k� ? */
+            Bgr.lNr = lNr;
+            LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+            LB_Swap();
+         }
+      }
+      if (AktBgr.lNr != INGEN_GRUPPE) { 
+         LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+      } else {
+         Sys.GrId = AktBgr;
+      }
+   }  
+}
+
+
+/*
+AR-911001
+CH LC_Save                                                     T�m skrivek�a
+CD ==========================================================================
+CD Form�l:
+CD Skriver gruppene som ligger i skrivek� ut til SOSI-fil.
+CD
+CD Parametre: ingen
+CD
+CD Bruk:
+CD LC_Save();
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_Save(void)
+{
+   LC_BASEADM * pBase;
+   LC_FILADM *pFil;
+
+   if (Sys.lAntSkriv > 0L) {                     /* Er det noen i k� ? */
+      /* Skanner alle baser og alle filer */
+      for (pBase=Sys.pForsteBase; pBase!=NULL; pBase=pBase->pNesteBase) {
+         for (pFil=pBase->pForsteFil; pFil!=NULL; pFil=pFil->pNesteFil) {
+            LB_Save(pFil);
+         }
+         LO_CloseSos(pBase);
+      }
+
+      Sys.lAntSkriv = 0L;
+   }
+}
+
+
+/*
+AR-930610
+CH LB_Swap                                  Dump gruppe fra buffer til SOSI
+CD ==========================================================================
+CD Form�l:
+CD Skriver en gruppe fra buffer tilbake til SOSI-fil. Ledig plass fram til
+CD neste gruppe blir blanket. Hvis det ikke er plass blir gruppen flyttet
+CD til slutten av filen. Fjerner gruppen fra skrivek�a.
+CD
+CD Parametre: ingen
+CD
+CD Bruk:
+CD LB_Swap()
+   ==========================================================================
+*/
+void LB_Swap(void)
+{
+   short siste;
+   long nko;
+   UT_INT64 start,neste;
+
+   /* Filnummer og posisjon */
+   start = Sys.pGrInfo->sosi_st;
+   nko = Sys.pGrInfo->nko;
+
+   if (start == NY_SOSI_ST){                       /* Ny gruppe? */
+      siste = 1;                                   /* P� slutten */
+      start = Sys.GrId.pFil->n64AktPos;
+   } else{
+      siste = LB_Plass(Sys.GrId.pFil,start,&neste);    /* Finn ledig plass */
+   }  
+
+   /* Ikke siste gruppe */
+   if ( ! siste ) {
+      /* Skriver */
+      if ( ! LB_WGru(SKRIV_VANLIG,1,nko,Sys.GrId.pFil,start,&neste)) {
+         /* For lite plass, blank ut "gammelt" omr�det p� SOSI-filen */
+         _fseeki64(Sys.GrId.pFil->pBase->pfSos,start,SEEK_SET);
+         Sys.GrId.pFil->pBase->BufAdm.sStatus = LESEBUFFER_TOM;
+         LB_WriteBlank(Sys.GrId.pFil->pBase->pfSos,Sys.GrId.pFil->sTegnsett,neste); /* Blank ut omr�det */
+
+         /* Gruppen skrives p� slutten av SOSI-filen */
+         siste = 1;
+         start = Sys.GrId.pFil->n64AktPos;
+      }
+   }
+
+   /* Siste gruppe p� SOSI-filen */
+   if ( siste ) {
+      Sys.pGrInfo->sosi_st = start;       /* Ny filposisjon */
+      neste = LLONG_MAX;
+      /* Skriver */
+      LB_WGru (SKRIV_SISTE,1,nko,Sys.GrId.pFil,start,&neste);
+
+      Sys.GrId.pFil->n64AktPos = neste;                    /* Ny slutt-posisjon */
+   }
+
+   LI_ClrBt(Sys.GrId.pFil,Sys.GrId.lNr,BT_SKRKO);       /* Fjern fra skrivek� */
+}
+
+
+/*
+AR-930610
+CH LB_WGru                                         Skriv gruppe til SOSI-fil
+CD ==========================================================================
+CD Form�l:
+CD Skriver aktuell gruppe fra buffer til en SOSI-fil.
+CD Sjekker ikke om buffer er endret i fht. SOSI. (Skriver alltid.)
+CD
+CD Parametre:
+CD Type       Navn     I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD short      strategi  i   Skrivestrategi: F�lgende konstanter er definert:
+CD                          KONTROLLER_PLASS = Bare kontroller plass,
+CD                                             (ikke skriv til SOSI).
+CD                          SKRIV_VANLIG     = Skriv til SOSI, vanlig.
+CD                          SKRIV_SISTE      = Skriv til SOSI, med .SLUTT
+CD                                             og sett filst�rrelse.
+CD long       fra_punkt i   Punktnummer for f�rste koordinat som skal skrives.
+CD                          (Lovlig:  1  <=  fra_punkt  <=  nko)
+CD long       antall    i   Antall koordinatlinjer som skal skrives.
+CD                          (Lovlig:  0  <=  antall  <=  nko)
+CD                          (Ved skriv av annet enn aktuell gruppe skrives
+CD                          alltid hele gruppen.)
+CD LC_FILADM *pFil      i   Peker til FilAdm for fil det skal skrives til
+CD UT_INT64   ffipos    i   Startposisjon p� SOSI-filen
+CD UT_INT64  *lfipos   iu   inn: F�rste pos i neste gruppe (m� ikke overskrives)
+CD                          ut : F�rste pos etter gruppen (etter event. utrop.)
+CD short      ist       r   Status: 1 = Skrevet OK
+CD                               0 = Ikke plass, m� flyttes til slutten
+CD
+CD Bruk:
+CD ok = LB_WGru (strategi,fra_punkt,antall,pFil,ffipos,&lfipos);
+=============================================================================
+*/
+short LB_WGru (short strategi,long fra_punkt,long antall,
+               LC_FILADM *pFil,UT_INT64 ffipos,UT_INT64 *lfipos)
+{
+   short i,gnavn,ngi,skriv_nah,nah,forrige_nah;
+   long pt,l;
+   unsigned long ulOfset;
+   char tx[LC_MAX_SOSI_LINJE_LEN],*cp,szOrd[60];
+   char szError[256];
+   double dN,dA;
+   short sFilMindre;
+   UT_INT64 Size;
+   char szKp[50];
+   FILE *pfSos = NULL;
+   double dEnhet = 0.0;
+   double dEnhetHoyde = 0.0;
+   double dEnhetDybde = 0.0;
+   double dOrigoNord = pFil->TransPar.Origo.dNord;
+   double dOrigoAust = pFil->TransPar.Origo.dAust;
+   UT_INT64 fpos;
+   UT_INT64 nfipos;                   /* Neste filposisjon (f�rste etter linjen) */
+   UT_INT64 afipos = ffipos;                 /* Aktuell filposisjon */
+
+
+#ifdef test
+   SH_OutTx(1,1,"WGru:");
+   SH_OutShort(0,1,1,strategi);
+   SH_OutShort(0,1,3,fra_punkt);
+   SH_OutShort(0,1,4,antall);
+   SH_OutLong(0,1,5,pBgr->lNr);
+   SH_OutTx(0,1,pBgr->pFil->pszNavn);
+   SH_OutTx(0,1,pFil->pszNavn);
+   SH_OutTx(2,1,"ffipos:");SH_OutLong(0,0,10,ffipos);
+   SH_OutTx(0,1,"lfipos:");SH_OutLong(0,0,10,*lfipos);
+   SH_WaitKb();
+   SH_ErLine(SH_SCR,1);
+   SH_ErLine(SH_SCR,2);
+#endif
+
+/* printf("\nWGru:fra: %s : %ld nko:%ld til %s",
+       strrchr(pBgr->pFil->pszNavn,'\\')+1,
+       pBgr->lNr,                                     
+       antall,                                     
+       strrchr(pFil->pszNavn,'\\')+1);           */
+
+   /* Hent diverse opplysninger om gruppen */
+   gnavn  = Sys.pGrInfo->gnavn;
+   ngi  = Sys.pGrInfo->ngi;
+   /* antall  = Sys.pGrInfo->nko;      (Ant.koord kommer inn i kallet)   */
+   /* info = Sys.pGrInfo->info; */
+
+   if (strategi != KONTROLLER_PLASS) {
+       LO_ReopenSos(pFil);                  /* Aktiviser SOSI-filen */
+       pfSos = pFil->pBase->pfSos;
+       _fseeki64 (pfSos, afipos, SEEK_SET);
+       pFil->pBase->BufAdm.sStatus = LESEBUFFER_TOM;
+   }
+
+                                     /* Skriv GINFO */
+   for (i = 1; i <= ngi; i++) {
+      UT_StrCopy(tx,LX_GetGi(i),LC_MAX_SOSI_LINJE_LEN);
+      UT_StrCat(tx,"\r\n",LC_MAX_SOSI_LINJE_LEN);
+
+      /* Spesiell ..ENHET */
+      if (LN_Enhet(&(Sys.GrId.pFil->SosiNavn),tx)) {
+         cp = tx;
+         while(!UT_IsSpace(*cp)){
+             cp++;
+         }
+         dEnhet = strtod(cp,&cp);
+      }
+
+      /* Spesiell ..ENHET-H */
+      if (LN_EnhetHoyde(&(Sys.GrId.pFil->SosiNavn),tx)) {
+         cp = tx;
+         while(!UT_IsSpace(*cp)){
+             cp++;
+         }
+         dEnhetHoyde = strtod(cp,&cp);
+      }
+
+      /* Spesiell ..ENHET-D */
+      if (LN_EnhetDybde(&(Sys.GrId.pFil->SosiNavn),tx)) {
+         cp = tx;
+         while(!UT_IsSpace(*cp)){
+             cp++;
+         }
+         dEnhetDybde = strtod(cp,&cp);
+      }
+
+      /* GINFO, og kommentar-linje lagres */
+      /*
+      * Sjekk om plassen er oppbrukt.
+      * (Overskriver neste guppe.)
+      */
+      nfipos = afipos + (long)strlen(tx);
+      while (nfipos > *lfipos) {
+         if (gnavn == L_HODE) {
+            /* Pr�ver � flytte gruppen til slutten */
+            if (!LB_FlyttGrTilSlutt(pFil,*lfipos,lfipos)) {
+               LC_Error(146,"(LB_WGru)",pFil->pszNavn);
+               return 1;
+            }
+
+         } else {
+            return 0;
+         }
+      }
+
+      /* Skriv til SOSI */
+      if (strategi != KONTROLLER_PLASS) {
+         LB_WriteLine(pfSos,pFil->sTegnsett,tx);
+      }
+      afipos = nfipos;
+   }
+
+   /* Enhet er ikke gitt i GINFO, bruk filhodets enhet */
+   if (dEnhet == 0.0)  dEnhet = pFil->TransPar.dEnhet;
+
+   // Enhet-H er ikke gitt i GINFO, bruk enhet-H fra filhodet
+   if (dEnhetHoyde == 0.0)  dEnhetHoyde = pFil->TransPar.dEnhet_h;
+
+   // Enhet-D er ikke gitt i GINFO, bruk enhet-D fra filhodet
+   if (dEnhetDybde == 0.0)  dEnhetDybde = pFil->TransPar.dEnhet_d;
+
+
+   /* Hopp fram til f�rste koordinat som skal skrives */
+   pt = fra_punkt - 1;
+
+   forrige_nah = -1;
+   skriv_nah = 1;         /* Skriv ..N�(H) f�r f�rste koordinat linje */
+
+   /* =====> Skriv koordinater og PINFO */
+   for (l=0; l<antall; l++,pt++) {
+      nah = ((Sys.pInfo + pt)->dHoyde != HOYDE_MANGLER);
+
+       /* M� skrive ..N� eller ..N�H ved skifte mellom disse */
+      if (forrige_nah != nah) {
+         skriv_nah = 1;
+      }
+
+      if (skriv_nah) {               /* Skriv ..N� / ..N�H / ..N�D */
+         if (nah) {
+
+            if ((Sys.pGrInfo->info & GI_NAH) != 0) {
+               UT_StrCopy(tx,"..N�H\r\n",LC_MAX_SOSI_LINJE_LEN);
+            } else {
+               UT_StrCopy(tx,"..N�D\r\n",LC_MAX_SOSI_LINJE_LEN);
+            }
+            nfipos = afipos + 7;
+         } else {
+            UT_StrCopy(tx,"..N�\r\n",LC_MAX_SOSI_LINJE_LEN);
+            nfipos = afipos + 6;
+         }
+         forrige_nah = nah;
+
+         if (nfipos > *lfipos) {            /* Sjekk om plassen er oppbrukt */
+            return(0);                      /* Overskriver neste guppe */
+         }
+
+         if (strategi != KONTROLLER_PLASS) {
+            LB_WriteLine(pfSos,pFil->sTegnsett,tx);    /* Skriv til SOSI */
+         }
+         afipos = nfipos;
+         skriv_nah = 0;
+      }
+
+      /* -----> Koordinater */
+      dN = UT_RoundDD((*(Sys.pdNord+pt) - dOrigoNord) / dEnhet);
+      dA = UT_RoundDD((*(Sys.pdAust+pt) - dOrigoAust) / dEnhet);
+      UT_SNPRINTF(tx,LC_MAX_SOSI_LINJE_LEN,"%.0f %.0f",dN,dA);
+
+      // ----- H�yde eller dybde
+      if (nah)
+      {
+         // N�H
+         if ((Sys.pGrInfo->info & GI_NAH) != 0)
+         {
+            dA = UT_RoundDD((Sys.pInfo+pt)->dHoyde / dEnhetHoyde);
+         }
+
+         // N�D
+         else
+         {
+            dA = UT_RoundDD((Sys.pInfo+pt)->dHoyde / dEnhetDybde);
+         }
+
+         UT_SNPRINTF(szOrd,60," %.0f",dA);
+         UT_StrCat(tx,szOrd,LC_MAX_SOSI_LINJE_LEN);
+      }
+
+      // ----- PINFO
+      ulOfset = (Sys.pInfo+pt)->ulPiOfset;
+
+      if (ulOfset != LC_INGEN_PINFO)
+      {
+         skriv_nah = 1;
+         UT_StrCat(tx," ",LC_MAX_SOSI_LINJE_LEN);
+         UT_StrCat(tx,Sys.pszPinfo+ulOfset,LC_MAX_SOSI_LINJE_LEN);
+      }
+
+      // ----- ...KP n
+      if ((Sys.pInfo+pt)->sKp != 0)
+      {
+         skriv_nah = 1;
+         UT_SNPRINTF(szKp,50," ...KP %hd",(Sys.pInfo+pt)->sKp);
+         UT_StrCat(tx,szKp,LC_MAX_SOSI_LINJE_LEN);
+      }
+
+      // Sjekk at linjen ikke er for lang
+      if (strlen(tx) > (LC_MAX_SOSI_LINJE_LEN - 10))
+      {
+         tx[LC_MAX_SOSI_LINJE_LEN -10] = '\0';
+         UT_StrCat(tx, " ?????", LC_MAX_SOSI_LINJE_LEN);
+         LC_Error(134,"(LB_WGru)",LX_GetGi(1));
+      }
+
+      // Legg p� linjeslutt
+      UT_StrCat(tx,"\r\n",LC_MAX_SOSI_LINJE_LEN);
+                                           
+      /* Sjekk om plassen er oppbrukt */
+      nfipos = afipos + (long)strlen(tx);
+      if (nfipos > *lfipos) {                /* Overskriver neste guppe */
+         /* printf(" (Overskriv)"); */
+         return(0);                        /* ===> RETUR */
+      }
+
+      if (strategi != KONTROLLER_PLASS){
+         LB_WriteLine(pfSos,pFil->sTegnsett,tx);               /* Skriver */
+      }
+
+      afipos = nfipos;
+   }
+
+   if (strategi == SKRIV_SISTE)                 /* P� slutten av filen */
+   {
+      /* Akt.pos + reserveplass */
+      *lfipos = _ftelli64(pfSos) + (UT_INT64)Sys.sResPlass;
+      /* Legg p� 200 ekstra etter filhodet */
+      if (ffipos == 0)  *lfipos += 200;
+      LB_WriteBlank(pfSos,pFil->sTegnsett,*lfipos);
+
+      /* Skriver .SLUTT */
+      UT_StrCopy(tx,".SLUTT\r\n",LC_MAX_SOSI_LINJE_LEN);                 
+      LB_WriteLine(pfSos,pFil->sTegnsett,tx);
+
+      /* Husk akt. filposisjon */
+      fpos = _ftelli64(pfSos);
+      if (fpos == -1) {
+         UT_strerror(szError,256,errno);
+         UT_SNPRINTF(tx,LC_MAX_SOSI_LINJE_LEN,"%s - %s",pFil->pszNavn,szError);
+         LC_Error(142,"(LB_WGru)",tx);
+      }
+
+      // Sjekk om filst�rrelsen er redusert
+      sFilMindre = UT_FALSE;
+      if (Sys.sUtvidModus != LC_UTVID_SIKKER) {
+         if (UT_InqPathSize_i64(pFil->pszNavn,&Size) == 0) {
+            if (fpos <= Size)  sFilMindre = UT_TRUE;
+         }
+      }
+
+      // Filst�rrelsen er redusert, eller sikker utvidingsmodus
+      if (sFilMindre == UT_TRUE  ||  Sys.sUtvidModus == LC_UTVID_SIKKER) {
+
+         /* Steng filen for � bevare byte-pekeren */
+         LO_CloseSos(pFil->pBase);
+
+         /* Sett filst�rrelse */
+         if (fpos != -1) {
+            if ((i = UT_SetPathSize_i64(pFil->pszNavn,fpos-1)) != 0) {
+               UT_SNPRINTF(tx,LC_MAX_SOSI_LINJE_LEN,"(%s, Posisjon:%lld, Se log-fil for detaljert beskrivelse)",pFil->pszNavn,fpos-1);
+               LC_Error(92,"(LB_WGru)",tx);
+            }
+         }
+      }
+   }
+
+   else
+   {
+      if (strategi != KONTROLLER_PLASS) {
+                            /* Blank fram til neste gruppe, og t�m buffer */
+         LB_WriteBlank(pfSos,pFil->sTegnsett,*lfipos);
+      }
+   }
+
+/* printf(" (OK)"); */
+
+   return(1);
+}
+
+
+/*
+AR-920309
+CH LB_FlyttGrTilSlutt                      Flytt gruppe til slutten av filen
+CD ==========================================================================
+CD Form�l:
+CD Flytt gruppe til slutten av filen
+CD
+CD Parametre:
+CD Type       Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil     i    Peker til FilAdm
+CD UT_INT64   start    i    Startposisjon p� SOSI-filen (f�rste pos. i gr.)
+CD UT_INT64  *neste    u    Startposisjon i neste gruppe (f�rste pos. etter gr.)
+CD short      status   r    Status:  UT_FALSE = Feil
+CD                                   UT_TRUE = OK
+CD
+CD Bruk:
+CD status = LB_FlyttGrTilSlutt(forste,&neste)
+   ==========================================================================
+*/
+static short LB_FlyttGrTilSlutt(LC_FILADM *pFil, UT_INT64 start, UT_INT64 *neste)
+{
+   UT_INT64 lCurFilpos;
+   long lAntTegn,lNr;
+   char *pszBuffer;
+   LC_GRTAB_LINJE * pGrInfo;
+
+   /* Husk aktuell filposisjon */
+   lCurFilpos = _ftelli64(pFil->pBase->pfSos);
+
+   /* Sjekk gruppetabellen for � finne hvilken gruppe */
+   /* som starter i start posisjonen. */
+   for (lNr=1L; lNr<pFil->lAntGr; lNr++) {
+      pGrInfo = LI_GetGrt(pFil,lNr);
+      if (pGrInfo->ngi != 0) {
+         if (pGrInfo->sosi_st == start) {
+            /* Oppdater startposisjon */
+            pGrInfo->sosi_st = pFil->n64AktPos;
+            break;
+         }
+      }
+   }
+
+   /* Finn starten av neste gruppe */
+   LB_Plass (pFil,start,neste);
+
+   /* Alloker buffer for flyttingen */
+	lAntTegn = (long)(*neste - start);
+	pszBuffer = (char*)UT_MALLOC((size_t)lAntTegn * sizeof(char));
+
+	/* Les inn gruppen */
+	_fseeki64(pFil->pBase->pfSos,start,SEEK_SET);
+	fread(pszBuffer,sizeof(char),(size_t)lAntTegn,pFil->pBase->pfSos);
+
+	/* Skriv gruppen */
+	_fseeki64(pFil->pBase->pfSos,pFil->n64AktPos,SEEK_SET);
+   fwrite(pszBuffer,sizeof(char),(size_t)lAntTegn,pFil->pBase->pfSos);
+
+   /* Ny sluttposisjon */
+   pFil->n64AktPos = _ftelli64(pFil->pBase->pfSos);
+
+   /* Skriver .SLUTT */
+   UT_StrCopy(pszBuffer,".SLUTT\r\n",lAntTegn);
+   LB_WriteLine(pFil->pBase->pfSos,pFil->sTegnsett,pszBuffer);
+	UT_FREE(pszBuffer);
+	/* Posisjoner tilbake til opprinnelig posisjon */
+   _fseeki64(pFil->pBase->pfSos,lCurFilpos,SEEK_SET);
+
+   return UT_TRUE;
+}
+
+
+/*
+AR-920309
+CH LB_Plass                                          Finn tilgjengelig plass
+CD ==========================================================================
+CD Form�l:
+CD Scanner SOSI-filen og finner hvor mye plass som er tilgjengelig for
+CD gruppen. (Uten flytting.)
+CD
+CD Parametre:
+CD Type       Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil     i    Peker til FilAdm
+CD UT_INT64      start    i    Startposisjon p� SOSI-filen (f�rste pos. i gr.)
+CD UT_INT64     *neste    u    Startposisjon i neste gruppe (f�rste pos. etter gr.)
+CD short      siste    r    Siste gruppe:  UT_FALSE = Ikke siste gruppe
+CD                                         UT_TRUE = Siste gruppe
+CD
+CD Bruk:
+CD siste = LB_Plass (pFil,start,&neste)
+   ==========================================================================
+*/
+short LB_Plass (LC_FILADM *pFil, UT_INT64 start, UT_INT64 *neste)
+{
+   LB_LESEBUFFER * pLb = &pFil->pBase->BufAdm;
+
+   LO_ReopenSos(pFil);      /* Aktiviser SOSI-filen */
+   _fseeki64(pFil->pBase->pfSos,start,SEEK_SET);
+   pLb->sStatus = LESEBUFFER_TOM;
+   
+   /* Gruppenavn p� egen gruppe */
+   LB_GetSet(pFil->pBase->pfSos,pLb,&(pFil->SosiNavn));
+
+   /* Scann gruppen sett for sett */
+   do {
+      pLb->set_brukt = SET_BRUKT;
+      LB_GetSet(pFil->pBase->pfSos,pLb,&(pFil->SosiNavn));
+   } while (pLb->cur_niv != 1);
+
+   *neste = pLb->startpos;
+
+   return ((pLb->cur_navn[0] == L_SLUTT)?  1 : 0 );  /* Siste gruppe? */
+}
+
+
+/*
+GL-880119
+AR-911001
+CH LB_WriteBlank                                        Fyller inn "!!!!!!!"
+CD ==========================================================================
+CD Form�l:
+CD Fyller omr�det FRA-OG-MED current-posisjon og fram TIL,
+CD (men ikke inklusiv) , ltilpos med !!!!!.
+CD Rutina takler fra 1 til mange posisjoner.
+CD
+CD        curr-pos                       ltilpos
+CD          +------------------------------+
+CD          !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+CD
+CD Parametre:
+CD Type     Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD FILE    *fil       i    Filpeker
+CD short    sTegnsett i    Tegnsett (Def fra fyut.h)
+CD long     ltilpos   i    Posisjon det skal blankes fram til
+CD
+CD Bruk:
+CD LB_WriteBlank(fil,sTegnsett,ltilpos);
+   ===================================================================
+*/
+static void LB_WriteBlank (FILE *fil,short sTegnsett,UT_INT64 ltilpos)
+{
+   UT_INT64 fpos;
+   long  iant;
+   short  i;
+   char buffer[LC_MAX_SOSI_LINJE_LEN] = "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n";
+
+   fpos = _ftelli64(fil);       /* Skriver fulle linjer */
+   if (ltilpos > fpos){
+      while (fpos < (ltilpos-40)){
+         LB_WriteLine(fil,sTegnsett,buffer);
+         fpos = _ftelli64(fil);  
+      }
+                                         /* Skriver resten */
+      iant = (long)(ltilpos-fpos);
+      if (iant > 2) {                /* ant fyll > 2  */
+         for (i=0 ;( i < (iant - 2)) ; i++) {
+            buffer[i] = '!';
+         }
+         buffer[iant-2] = '\r';
+         buffer[iant-1] = '\n';
+         buffer[iant]   = '\0';
+         LB_WriteLine(fil,sTegnsett,buffer);
+
+      }else {                          /* ant fyll = 1 eller 2 */
+                                      /* blank sist p� forrige linje */
+         _fseeki64(fil,-2L,SEEK_CUR);
+         if      (iant == 1)   UT_StrCopy(buffer, " \r\n", LC_MAX_SOSI_LINJE_LEN);
+         else if (iant == 2)   UT_StrCopy(buffer, "  \r\n", LC_MAX_SOSI_LINJE_LEN);
+         LB_WriteLine(fil,sTegnsett,buffer);
+      }
+   }
+}
+
+
+/*
+AR-911001
+CH LB_WriteLine                                    Lavniv� skriv tekst linje
+CD ==========================================================================
+CD Form�l:
+CD Lavniv� overbygning ove write i C-biblioteket for � skrive en linje.
+CD
+CD Parametre:
+CD Type     Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD FILE    *fil       i    Filpeker
+CD short    sTegnsett i    Tegnsett (Spesifisert i UT)
+CD char    *tx        i    Tekststreng som skal skrives.
+CD short    antall    r    Antall tegn skrevet, eller -1 ved feil.
+CD
+CD Bruk:
+CD antall = LB_WriteLine(fil,sTegnsett,tx);
+   ==========================================================================
+*/
+short LB_WriteLine (FILE *fil,short sTegnsett,char *tx)
+{
+   UT_KonverterTegnsett(LC_INTERNT_TEGNSETT,sTegnsett,(unsigned char*)tx);
+   return (short)fwrite(tx,strlen(tx),1,fil);
+}
+
+
+/*
+AR-920909
+CH LB_FyllBuffer                         Oppdater lesebuffer fra SOSI-filen
+CD ==========================================================================
+CD Form�l:
+CD Les neste linje fra SOSI-filen inn i lesebuffer.
+CD Konverterer til rett internt tegnsett.
+CD
+CD Parametre:
+CD Type            Navn   I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD FILE           *fil     i    Filpeker
+CD LB_LESEBUFFER  *plb     i    Peker til bufferstruktur
+CD
+CD Bruk:
+CD LB_FyllBuffer(fil,&lb);
+   ===================================================================
+*/
+void LB_FyllBuffer (FILE *fil,LB_LESEBUFFER *plb)
+{
+   short ierr;
+
+
+   /* Husk filposisjonen */
+   plb->filpos =  _ftelli64(fil);
+
+   /* Les */
+   if ((ierr = UT_ReadLine(fil,LC_MAX_SOSI_LINJE_LEN,plb->tx)) != UT_OK) {
+      /* Lesefeil */
+      if (ierr == UT_EOF) {
+         LC_Error(42,"(LB_FyllBuffer)","");   /* EOF */
+      } else {
+         LC_Error(43,"(LB_FyllBuffer)","");   /* Annen lesefeil */
+      }
+      exit(1);
+   }
+
+   /* Konverter til rett tegnsett */
+   UT_KonverterTegnsett(plb->sTegnsett,LC_INTERNT_TEGNSETT,(unsigned char*)plb->tx);
+
+   if (strlen(plb->tx) >= LC_MAX_SOSI_LINJE_LEN-2)
+   {
+      char szMelding[LC_MAX_SOSI_LINJE_LEN + 10];
+      UT_SNPRINTF(szMelding, LC_MAX_SOSI_LINJE_LEN + 10, "\"%s\"", plb->tx);
+      LC_Error(164,"(LB_FyllBuffer)",szMelding);
+      exit(1);
+   }
+
+   /* Nullstill pekere */
+   plb->cp = plb->np = plb->pp = plb->ep = plb->tx;
+   plb->set_brukt = SET_BRUKT;
+   plb->sStatus = LESEBUFFER_OK;
+}
+
+
+/*
+AR-920909
+CH LB_GetSet                               Hent SOSI-navn og verdi fra buffer
+CD =============================================================================
+CD Form�l:
+CD Hen ett SOSI-navn og tilh�rende verdi fra lesebuffer.
+CD Inn: Hvis buffer har gyldig innhold peker "plb->np" til posisjon
+CD      der tolking skal starte.
+CD
+CD Parametre:
+CD Type            Navn   I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD FILE           *fil     i    Filpeker
+CD LB_LESEBUFFER  *plb     i    Peker til bufferstruktur
+CD LC_NAVNETABELL * pNavn   i    Peker til navnetabell
+CD short           type    r    Hva er hentet: >= 0 : Gruppenavn,linjenr
+CD                                                   i navnetab.
+CD                                  LEST_KOORD (-1): Koordinatlinje
+CD                                  LEST_BLANK (-2): Fyll-linje
+CD                                  LEST_GINFO (-3): Annen GINFO
+CD                                  LEST_KOM   (-4): Kommentarlinje
+CD
+CD Bruk:
+CD type = LB_GetSet(fil,&lb,pNavn);
+   =============================================================================
+*/
+short LB_GetSet(FILE *fil,LB_LESEBUFFER *plb,LC_NAVNETABELL * pNavn)
+{
+   short navn_nr,gml_niv;
+   char cTmp;
+
+   /* Sjekk at buffer har rett innhold */
+   if (plb->sStatus != LESEBUFFER_OK) {
+      LB_FyllBuffer(fil,plb);
+   }
+
+   /* Henter nytt sett */
+   if (plb->set_brukt == SET_BRUKT) {
+      plb->cp = plb->np;
+
+      do {
+         /* Hopp over ledende blanke */
+         while (UT_IsSpace(*plb->cp)) {
+            (plb->cp)++;
+         }
+         /* Linjen er oppbrukt, les inn ny */
+         if (*plb->cp == '\0') {
+            LB_FyllBuffer(fil,plb);
+         }
+      } while (UT_IsSpace(*plb->cp)  ||  *plb->cp == '\0');
+
+      plb->np = plb->cp;
+   
+      if (*plb->cp == '.') {                  /* --------- SOSI-navn */
+         plb->startpos = plb->filpos + (plb->cp - plb->tx); /* Husk filposisjon */
+         /* Scann over navnet (Ikke \0, mellomrom eller filslutt) */
+         while (*plb->cp  &&  !UT_IsSpace(*plb->cp)  &&  *plb->cp != 26) {
+            (plb->cp)++;
+         }
+         cTmp = *plb->cp;
+         *plb->cp = '\0';
+
+         /* S�k i navnetabellen */
+         gml_niv = plb->cur_niv;
+         plb->cur_niv = LN_PakkNavn(pNavn,plb->np,&navn_nr,&(plb->cur_ant_par));
+         plb->cur_navn[plb->cur_niv - 1] = navn_nr;
+
+         *plb->cp = cTmp;
+
+         /* Sjekk mot sprang i prikkniv� */
+         if ((plb->cur_niv - gml_niv) > 1) {
+            LC_Error(147,"(LB_GetSet)",plb->np);
+         }
+
+         /* Handter parameter */
+         if (navn_nr != L_SLUTT) {
+            do {
+               /* Hopp over ledende blanke */
+               while (UT_IsSpace(*plb->cp)) {
+                  (plb->cp)++;
+               }
+               /* Linjen er oppbrukt, les inn ny */
+               if (*plb->cp == '\0') {
+                  LB_FyllBuffer(fil,plb);
+               }
+            } while (UT_IsSpace(*plb->cp)  ||  *plb->cp == '\0');
+            plb->np = plb->cp;
+
+            LB_GetParameter(plb);
+         }
+
+         if (plb->cur_niv == 1) {                           /* Gruppenavn */
+            plb->cur_type = navn_nr;
+
+         } else if (navn_nr == L_NA  ||
+                    navn_nr == L_NAH ||
+                    navn_nr == L_NAD ) {                    /* Koordinat */
+            plb->cur_type = LEST_KOORD;
+
+         } else {                                   /* Annen GINFO / PINFO */
+            plb->cur_type = LEST_GINFO;
+         }
+
+      } else {                       /* Parameter, kommentar eller fyll */
+         if (LB_TestFyll(plb->cp)) {    /* ------------------ Fyll */
+            /* Marker at linjen er oppbrukt */
+            *plb->cp = '\0';
+
+            plb->cur_type = LEST_BLANK;
+            plb->np = plb->cp;
+
+            /* Fyll er alltid niv� 2 eller 3 */
+            if (plb->cur_niv == 1) {
+               plb->cur_niv = 2; 
+            }
+
+         } else if (*plb->cp == '!') {     /* ------------------ Kommentar */
+            plb->pp = plb->np;
+            /* Resten av linjen er kommentar */
+            plb->np = strchr(plb->cp,'\0');
+            plb->cur_type = LEST_KOM;
+            //plb->cur_niv = 2;   /* Kommentar er bare lovlig i ginfo */  // Fjernet 24/7-02.   
+            if (plb->cur_niv < 2)  plb->cur_niv = 2;       // Endret 22/8-02. 
+
+         } else {                          /* ------------------ Parameter */
+            LB_GetParameter(plb);
+            if (plb->cur_navn[plb->cur_niv - 1] == L_NA  ||
+                plb->cur_navn[plb->cur_niv - 1] == L_NAH ||
+                plb->cur_navn[plb->cur_niv - 1] == L_NAD ) {  /* Koordinat */
+               plb->cur_type = LEST_KOORD;
+
+            } else {                                   /* Annen GINFO / PINFO */
+               plb->cur_type = LEST_GINFO;
+            }
+         }
+      }
+   }
+
+   plb->set_brukt = SET_UBRUKT;
+
+   return plb->cur_type;
+}
+
+
+/*
+AR-920909
+CH LB_GetParameter                                 Hent parameter fra buffer
+CD ==========================================================================
+CD Form�l:
+CD Hent parameter fra lesebuffer.
+CD Forutsetter at det ikke er blanke forran parameteren.
+CD Inn: "plb->np" peker til f�rste posisjon i parameteren. (Der tolking
+CD skal starte.
+CD
+CD Parametre:
+CD Type            Navn   I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LB_LESEBUFFER  *plb     i    Peker til bufferstruktur
+CD
+CD Bruk:
+CD param = LB_GetParameter(&lb)
+   ==========================================================================
+*/
+static char *LB_GetParameter(LB_LESEBUFFER *plb)
+{
+   short npar = (plb->cur_ant_par == LC_ANT_PAR_UKJENT)?  9999 : plb->cur_ant_par;
+
+   plb->pp = plb->cp = plb->ep = plb->np;
+
+   for ( ; npar > 0; npar--) {
+      /* Neste sett er funnet */
+      if (*plb->cp == '\0'  ||  *plb->cp == '.'  ||  *plb->cp == '!') {
+         break;
+
+      /* Vanlig ord */
+      } else if (*plb->cp != '"') {
+         while (*plb->cp  &&  !UT_IsSpace(*plb->cp)) {
+            (plb->cp)++;
+         }
+         plb->ep = plb->cp;
+
+      /* "Ord" i hermetegn */ 
+      } else {
+         (plb->cp)++;     /* Start-hermetegn */
+         while (*plb->cp  &&  *plb->cp != '"') {          /* "Ordet" */
+            (plb->cp)++;
+         }
+         if (*plb->cp == '"') {
+            (plb->cp)++;
+         }
+         plb->ep = plb->cp;
+      }
+
+      if (npar > 1) {      /* Skann fram til neste parameter */
+         while (UT_IsSpace(*plb->cp)) {
+            (plb->cp)++;
+         }
+      }
+   }
+
+   /* Avslutt strengen */
+   if (plb->ep > plb->pp) {     /* Vanlig */
+      plb->cp = plb->ep;
+      (plb->cp)++;
+      plb->np = plb->cp;
+      *plb->ep = '\0';
+   } else {                /* Tom parameter */
+      plb->np = plb->ep;
+      plb->pp = plb->ep - 1;
+      *plb->pp = '\0';
+   }
+
+   return  plb->pp;
+}
+
+
+/*
+AR-920626
+!-------------------------------------------------------------!
+! LB_TestFyll -  Tester om en streng er fyll-linje.           !
+!                                                             !
+! Retur:  UT_TRUE  = linjen er fyll                           !
+!         UT_FALSE = linjen inneholder annen informasjon      !
+!                                                             !
+!-------------------------------------------------------------!
+*/
+static short LB_TestFyll(const char *pszTx)
+{
+   for (; *pszTx; ++pszTx) {
+      if (!UT_IsSpace(*pszTx)  &&  *pszTx != '!')  return (UT_FALSE);
+   }
+
+   return (UT_TRUE);
+}
+
+
+/*
+AR/TU:2008-09-11
+CH LC_ErstattReferanse                                     Erstatt referanse 
+CD ==========================================================================
+CD Form�l:
+CD Erstatt referanse i alle grupper i gitt fil.
+CD 
+CD
+CD Parametre:
+CD Type       Navn          I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil           i   Fil som skal behandles
+CD long       lGmlSnr        i   Gruppe som skal byttes ut
+CD long       lNyttSnr       i   Ny gruppe
+CD                               Verdien 0 f�rer til gammelt serienummer 
+CD                               fjernes uten at det legges inn noe nytt.
+CD bool       bSammeRetning  i   Gruppene er digitalisert i samme retning
+CD
+CD Bruk:
+CD sStatus = LC_ErstattReferanse(pFil, lGmlSnr, lNyttSnr, bSammeRetning);
+==========================================================================
+*/
+SK_EntPnt_FYBA void LC_ErstattReferanse (LC_FILADM *pFil,long lGmlSnr,long lNyttSnr, bool bSammeRetning)
+{
+   short ngi;
+   long nko;
+   unsigned short info;
+   LC_BGR BgrGml,Bgr;
+   long lAntRef;
+   short sGiLin,sRefPos;
+   long *plRefArray,*plRef,l;
+   bool bEndret;
+
+
+   // Husk gruppen
+   BgrGml = Sys.GrId;
+
+
+   lGmlSnr = labs(lGmlSnr);
+   lNyttSnr = labs(lNyttSnr);
+
+
+   LC_InitNextBgr(&Bgr);
+   Bgr.pFil = pFil;
+   while (LC_NextBgr(&Bgr,LC_FRAMGR))
+   {
+      if (Bgr.pFil == pFil)
+      {
+         LC_GetGrParaBgr(&Bgr,&ngi,&nko,&info);
+         if ((info&GI_REF) != 0)
+         {
+            // Gruppen er p� rett fil og har referanser, Bytt serienummer 
+            LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+            lAntRef = LC_InqAntRef();
+            plRefArray = (long *) UT_MALLOC(lAntRef * sizeof(long));
+            sGiLin = 2;
+            sRefPos = 0;
+            LC_GetRef(plRefArray,lAntRef,&sGiLin,&sRefPos);
+
+            bEndret = false;
+            plRef = plRefArray;
+            for (l=0; l<lAntRef; ++l,++plRef) 
+            {
+               if (labs(*plRef) == lGmlSnr)
+               {
+                  // Skal bytte serienummer
+                  if (lNyttSnr != 0)
+                  {
+                     if (*plRef > 0  && bSammeRetning)
+                     {
+                        *plRef = lNyttSnr;
+                     }
+                     else if (*plRef > 0  && !bSammeRetning)
+                     {
+                        *plRef = -lNyttSnr;
+                     }
+                     else if (*plRef < 0  && bSammeRetning)
+                     {
+                        *plRef = -lNyttSnr;
+                     }
+                     else if (*plRef < 0  && !bSammeRetning)
+                     {
+                        *plRef = lNyttSnr;
+                     }
+                  }
+
+                  // Skal fjerne serienummer
+                  else
+                  {
+                     memmove(plRef, plRef+1, (lAntRef-l-1) * sizeof(long));
+
+                     --l;
+                     --plRef;
+                     --lAntRef;
+                  }
+
+                  bEndret = true;
+               }
+            }
+
+            if (bEndret) {
+               LC_PutRef(plRefArray,lAntRef);
+               LC_WxGr(SKRIV_OPTIMALT);
+            }
+            UT_FREE(plRefArray);
+         }
+      }
+   }
+
+   // ========= Leser inn opprinnelig gruppe
+   LC_RxGr(&BgrGml,LES_OPTIMALT,&ngi,&nko,&info);
+}
diff --git a/FYBA/FYLD.cpp b/FYBA/FYLD.cpp
new file mode 100644
index 0000000..57eacfd
--- /dev/null
+++ b/FYBA/FYLD.cpp
@@ -0,0 +1,111 @@
+/* === 920413 ============================================================= */
+/*  STATENS KARTVERK  -  FYSAK-PC                                           */
+/*  Fil: fyld.c                                                             */
+/*  Innhold: Lagring og henting av indekstabeller                           */
+/* ======================================================================== */
+
+#include "stdafx.h"
+
+#include <stdlib.h>
+
+
+
+
+/* Globale strukturer for fyba */
+extern LC_SYSTEMADM    Sys;
+
+
+
+/*
+AR:2004-05-04
+CH LC_DelIdx                                            Sletter indeksfilene
+CD ==========================================================================
+CD Form�l:
+CD Sletter indeksfilene for gitt SOSI-fil.
+CD
+CD Parametre:
+CD Type  Navn     I/U Forklaring
+CD --------------------------------------------------------------------------
+CD char *szSosFil  i  SOSI-filnavn
+CD
+CD Bruk:
+CD LC_DelIdx(szSosFil);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_DelIdx(char *szSosFil)
+{
+   char fil[_MAX_PATH],sdir[_MAX_PATH];
+   char drive1[_MAX_DRIVE],dir1[_MAX_DIR],fname1[_MAX_FNAME],ext1[_MAX_EXT];
+   char drive2[_MAX_DRIVE],dir2[_MAX_DIR],fname2[_MAX_FNAME],ext2[_MAX_EXT];
+
+
+   // Bygg opp fullstendig filnavn
+   UT_FullPath(fil,szSosFil,_MAX_PATH);
+
+   // Splitt filnavnet
+   UT_splitpath(fil,drive1,dir1,fname1,ext1);
+
+   // Lag subdirectory navn
+   if ( *Sys.szIdxPath != 0) {
+      // Gitt sti for indeksfilene
+      UT_splitpath(Sys.szIdxPath,drive2,dir2,fname2,ext2);
+      UT_makepath(sdir,drive2,dir2,fname1,"");
+   } else {
+      // Ikke gitt sti.
+      UT_makepath(sdir,drive1,dir1,fname1,"");
+   }
+
+   /* Lag sti til filer p� sub-directory */
+   UT_splitpath(sdir,drive2,dir2,fname2,ext2);
+   UT_StrCat(dir2,fname1,_MAX_DIR);
+   UT_StrCat(dir2,UT_STR_SLASH,_MAX_DIR);
+
+   //
+   // Fjern indeks filene
+   //
+
+   // Administrasjonstabeller
+   UT_makepath(fil,drive2,dir2,"Adm",".Idx");
+   UT_DeleteFile(fil);
+   UT_makepath(fil,drive2,dir2,"admin",".idx");       /* FYBA - C */
+   UT_DeleteFile(fil);
+
+   // Ringbuffer
+   UT_makepath(fil,drive2,dir2,"Rb",".Idx"); 
+   UT_DeleteFile(fil);
+   
+   // Inf
+   UT_makepath(fil,drive2,dir2,"Inf",".Idx");         /* FYBA - D */
+   UT_DeleteFile(fil);
+   UT_makepath(fil,drive2,dir2,"info",".idx");        /* FYBA - C */
+   UT_DeleteFile(fil);
+   
+   // Gruppetabell
+   UT_makepath(fil,drive2,dir2,"Grt",".Idx");
+   UT_DeleteFile(fil);
+   UT_makepath(fil,drive2,dir2,"grtab",".idx");       /* FYBA - C */
+   UT_DeleteFile(fil);
+   
+   // Serienummer-tabell */
+   UT_makepath(fil,drive2,dir2,"Snr",".Idx");
+   UT_DeleteFile(fil);
+   
+   // Brukt-tabell
+   UT_makepath(fil,drive2,dir2,"Bt",".Idx");
+   UT_DeleteFile(fil);
+   UT_makepath(fil,drive2,dir2,"btab",".idx");        /* FYBA - C */
+   UT_DeleteFile(fil);
+
+   // Geografisk s�ketabell
+   UT_makepath(fil,drive2,dir2,"Geo",".Idx");
+   UT_DeleteFile(fil);
+
+   // Flate geografisk s�ketabell
+   UT_makepath(fil,drive2,dir2,"flate",".idx");       /* FYBA - C */
+   UT_DeleteFile(fil);
+
+   //
+   // Fjern subdirectory
+   //
+   UT_DeleteDir(sdir);
+}
diff --git a/FYBA/FYLE.cpp b/FYBA/FYLE.cpp
new file mode 100644
index 0000000..51a50fe
--- /dev/null
+++ b/FYBA/FYLE.cpp
@@ -0,0 +1,490 @@
+#include "stdafx.h"
+#include "fyba_strings.h"
+
+/*
+AR-940110
+CH LC_StrError                                             Feilmeldingstekst
+CD ==========================================================================
+CD Form�l:
+CD Henter feilmeldingstekst og niv� for et feilmeldingsnummer.
+CD Strengen legges i en egen feilmeldingsstruktur for feil-rutiner i fyba.
+CD Dette blir �delagt ved neste kall til en "feil-rutine". For � ta vare p�
+CD strengen m� den kopieres over til egen streng. (Bruk UT_StrCopy).
+CD
+CD Parametre:
+CD Type     Navn        I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD short    feil_nr      i   Feilmeldingsnummer
+CD char   **feilmelding  u   Peker til feilmeldingstekst avslutta med '\0'.
+CD short   *strategi     r   Feilniv� (0-4)
+CD                           0 = Ikke i bruk. (Utkoblet, testmeldinger mm.)
+CD                           1 = Lite alvorlig. Vises kort.
+CD                           2 = Normal feilmelding. Vises ca. 1 sekund.
+CD                           3 = Alvorlig. Krev tastetrykk for � fortsette.
+CD                           4 = Sv�rt alvorlig. Programmet b�r avbrytes.
+CD
+CD Bruk:
+CD strategi = LC_StrError(ckap,feil_nr,&feilmeldingspeker);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_StrError(short feil_nr,char **feilmelding)
+{
+#define MAX_FEIL_LEN  200
+   static char feil[MAX_FEIL_LEN];      /* Feilmeldings-streng */
+   short strategi = 0;
+
+
+   switch(feil_nr) {                           /* Finn riktig melding */
+/* --------------------- LO --------------------------- */
+      case 1:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_BASE_UNKNOWN_TYPE,MAX_FEIL_LEN);
+         break;
+      case 2:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_BASE_TOO_MANY_GROUPS,MAX_FEIL_LEN);
+         break;
+      case 3:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_FILE_NOT_FOUND,MAX_FEIL_LEN);
+         break;
+      case 4:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_BASE_FYBA_NOT_INITD,MAX_FEIL_LEN);
+         break;
+      case 5:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_BASE_NOT_OPEN,MAX_FEIL_LEN);
+         break;
+      case 6:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_FILE_OPEN_FAILED,MAX_FEIL_LEN);
+         break;
+      case 7:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_FILE_OMRAADE_MISSING,MAX_FEIL_LEN);
+         break;
+      case 8:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_FILE_MIN_NOE_MISSING,MAX_FEIL_LEN);
+         break;
+      case 9:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_FILE_MAX_NOE_MISSING,MAX_FEIL_LEN);
+         break;
+      case 10:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_BASE_INDEX_ABORTED,MAX_FEIL_LEN);
+         break;
+      case 101:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_BASE_OPEN_FAILED,MAX_FEIL_LEN);
+         break;
+      case 102:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_FILE_NEW_HEADER,MAX_FEIL_LEN);
+         break;
+      case 103:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_FILE_NOT_SOSI,MAX_FEIL_LEN);
+         break;
+      case 104:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_FILE_OMRAADE_INVALID,MAX_FEIL_LEN);
+         break;
+
+      case 105:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_SAVE_INVALID_FILEPTR,MAX_FEIL_LEN);
+         break;
+
+      case 106:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_OPEN_BASE_IS_KLADDE,MAX_FEIL_LEN);
+         break;
+
+/* --------------------- HO --------------------------- */
+      case 12:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_FILE_READ_ERROR_HODE,MAX_FEIL_LEN);
+         break;
+      case 14:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_FILE_TRANSPAR_MISSING,MAX_FEIL_LEN);
+         break;
+      case 15:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_FILE_KOORDSYS_MISSING,MAX_FEIL_LEN);
+         break;
+      case 16:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_FILE_ORIGO_MISSING,MAX_FEIL_LEN);
+         break;
+      case 17:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_FILE_ENHET_MISSING,MAX_FEIL_LEN);
+         break;
+/* --------------------- LN --------------------------- */
+      case 21:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_NAME_TABLE_FULL,MAX_FEIL_LEN);
+         break;
+
+      case 22:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_INVALID_GROUP_NAME,MAX_FEIL_LEN);
+         break;
+
+/* --------------------- LB --------------------------- */
+      case 31:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_FILE_NO_CURRENT_GROUP,MAX_FEIL_LEN);
+         break;
+      case 32:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_OPEN_INVALID_EXTERN,MAX_FEIL_LEN);
+         break;
+      case 33:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_SAVE_INVALID_EXTERN,MAX_FEIL_LEN);
+         break;
+      case 34:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_SAVE_NO_WRITE_ACCESS,MAX_FEIL_LEN);
+         break;
+      case 35:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_GROUP_DELETED,MAX_FEIL_LEN);
+         break;
+      case 36:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_FILE_INVALID_GROUP_NR,MAX_FEIL_LEN);
+         break;
+      case 37:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_NEW_INVALID_FILE,MAX_FEIL_LEN);
+         break;
+      case 38:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_NEW_NO_WRITE_ACCESS,MAX_FEIL_LEN);
+         break;
+      case 39:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_NEW_TOO_MANY_GROUPS,MAX_FEIL_LEN);
+         break;
+      case 40:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_NEW_INVALID_LINE_GI,MAX_FEIL_LEN);
+         break;
+      case 41:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_NEW_INVALID_LINE_COO,MAX_FEIL_LEN);
+         break;
+      case 42:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_SLUTT_MISSING,MAX_FEIL_LEN);
+         break;
+      case 43:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_READ_ERROR,MAX_FEIL_LEN);
+         break;
+      case 44:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_GROUP_REFERRED_TO,MAX_FEIL_LEN);
+         break;
+      case 47:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_INVALID_GI_LINE_1,MAX_FEIL_LEN);
+         break;
+      case 48:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_CANT_REMOVE_HEADER,MAX_FEIL_LEN);
+         break;
+      case 49:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_NO_CURRENT_GROUP,MAX_FEIL_LEN);
+         break;
+      case 50:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_DEL_UNKNOWN_FLAG,MAX_FEIL_LEN);
+         break;
+      case 91:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_DEL_NO_WRITE_ACCESS,MAX_FEIL_LEN);
+         break;
+      case 92:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_ERR_FILESIZE_CHANGE,MAX_FEIL_LEN);
+         break;
+      case 93:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_DISK_SOON_FULL,MAX_FEIL_LEN);
+         break;
+      case 94:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_NOT_A_HEADER,MAX_FEIL_LEN);
+         break;
+      case 95:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_DEL_NOT_SEQUENTIAL,MAX_FEIL_LEN);
+         break;
+      case 96:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_NO_CHANGE_HEADERS,MAX_FEIL_LEN);
+         break;
+      case 97:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_CANT_REWRITE_HEADER,MAX_FEIL_LEN);
+         break;
+      case 98:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_SAVE_NOT_A_HEADER,MAX_FEIL_LEN);
+         break;
+      case 99:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_CANT_COPY_COORD,MAX_FEIL_LEN);
+         break;
+      case 100:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_CANT_COPY_COORD_ROOM,MAX_FEIL_LEN);
+         break;
+      case 141:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_ENHET_NOT_SET,MAX_FEIL_LEN);
+         break;
+      case 142:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_CANT_READ_FILE_SIZE,MAX_FEIL_LEN);
+         break;
+      case 143:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_PINFO_LONG_OR_NO_NOE,MAX_FEIL_LEN);
+         break;
+      case 144:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_LOGIC_FAIL,MAX_FEIL_LEN);
+         break;
+      case 145:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_MAX_1_KP_OR_NO_NOE,MAX_FEIL_LEN);
+         break;
+      case 146:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_NO_ROOM_IN_HEADER,MAX_FEIL_LEN);
+         break;
+      case 147:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_INVALID_GAP,MAX_FEIL_LEN);
+         break;
+      case 148:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_TOO_MANY_COORDINATES,MAX_FEIL_LEN);
+         break;
+      case 149:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_TOO_MANY_GINFO,MAX_FEIL_LEN);
+         break;
+      case 150:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_TOO_MUCH_GINFO,MAX_FEIL_LEN);
+         break;
+      case 161:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_TOO_MUCH_PINFO,MAX_FEIL_LEN);
+         break;
+      case 162:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_CANT_EXTEND_GROUP,MAX_FEIL_LEN);
+         break;
+      case 163:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_READ_NO_WRITE_ACCESS,MAX_FEIL_LEN);
+      case 164:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_READ_LINE_TOO_LONG,MAX_FEIL_LEN);
+         break;
+
+
+/* --------------------- LX --------------------------- */
+      case 51:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_INVALID_POINT,MAX_FEIL_LEN);
+         break;
+      case 52:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_INVALID_GINFO,MAX_FEIL_LEN);
+         break;
+      case 53:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_INVALID_NODE,MAX_FEIL_LEN);
+         break;
+      case 54:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_INVALID_GROUP_NAME,MAX_FEIL_LEN);
+         break;
+      case 55:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_PINFO_TOO_LONG,MAX_FEIL_LEN);
+         break;
+      case 56:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_INVALID_REF,MAX_FEIL_LEN);
+         break;
+      case 57:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_CANT_CHANGE_ENHET ,MAX_FEIL_LEN);
+         break;
+      case 58:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_CANT_CHANGE_NGIS_LAG,MAX_FEIL_LEN);
+         break;
+      case 59:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_INVALID_BUE,MAX_FEIL_LEN);
+         break;
+      case 60:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_CANT_CHANGE_ORIGO_NOE,MAX_FEIL_LEN);
+         break;
+      case 131:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_PROB_TOO_LONG_PINFO,MAX_FEIL_LEN);
+         break;
+      case 132:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_NO_HOEYDE_WITH_NAD,MAX_FEIL_LEN);
+         break;
+      case 133:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_NO_HOEYDE_WITH_NAH,MAX_FEIL_LEN);
+         break;
+      case 134:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_LINE_TOO_LONG,MAX_FEIL_LEN);
+         break;
+
+ 
+/* --------------------- LS --------------------------- */
+      case 61:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_INVALID_SERIAL,MAX_FEIL_LEN);
+         break;
+
+/* --------------------- LI --------------------------- */
+      case 71:
+         strategi = 2;
+         UT_StrCopy(feil,FYBA_STRING_INVALID_LINE_NR,MAX_FEIL_LEN);
+         break;
+      case 72:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_INVALID_GROUP_NR,MAX_FEIL_LEN);
+         break;
+      case 73:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_ERR_READING_BUFFER,MAX_FEIL_LEN);
+         break;
+      case 74:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_ERR_WRITING_BUFFER,MAX_FEIL_LEN);
+         break;
+      case 75:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_MUST_INIT_INDEX,MAX_FEIL_LEN);
+         break;
+      case 79:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_ERR_READING_SEARCHT,MAX_FEIL_LEN);
+         break;
+      case 80:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_ERR_WRITING_SEARCHT,MAX_FEIL_LEN);
+         break;
+      case 111:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_ERR_READING_GROUPT,MAX_FEIL_LEN);
+         break;
+      case 112:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_ERR_WRITING_GROUPT,MAX_FEIL_LEN);
+         break;
+      case 113:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_ERR_READING_SERIALT,MAX_FEIL_LEN);
+         break;
+      case 114:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_ERR_WRITING_SERIALT,MAX_FEIL_LEN);
+         break;
+      case 115:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_ERR_READING_INFOT,MAX_FEIL_LEN);
+         break;
+      case 116:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_ERR_WRITING_INFOT,MAX_FEIL_LEN);
+         break;
+      case 117:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_ERR_INFOT_FULL,MAX_FEIL_LEN);
+         break;
+      case 118:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_ERR_READING_BRUKT,MAX_FEIL_LEN);
+         break;
+      case 119:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_ERR_WRITING_BRUKT,MAX_FEIL_LEN);
+         break;
+      case 120:
+         strategi = 4;
+         UT_StrCopy(feil,FYBA_STRING_NO_BLANKS_FILENAME,MAX_FEIL_LEN);
+         break;
+
+
+/* --------------------- LR --------------------------- */
+
+/* --------------------- LU --------------------------- */
+      case 121:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_TOO_MANY_CHOICES,MAX_FEIL_LEN);
+         break;
+      case 122:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_MISPLACED_CHOICE,MAX_FEIL_LEN);
+         break;
+      case 123:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_GROUP_CHOICE_MISSING,MAX_FEIL_LEN);
+         break;
+      case 124:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_INVALID_CHOICE,MAX_FEIL_LEN);
+         break;
+      case 125:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_NO_COMPLEX_CHOICE,MAX_FEIL_LEN);
+         break;
+      case 126:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_GAP_IN_LEVEL,MAX_FEIL_LEN);
+         break;
+      case 127:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_TOO_MANY_PRIORITIES,MAX_FEIL_LEN);
+         break;
+      case 128:
+         strategi = 3;
+         UT_StrCopy(feil,FYBA_STRING_DUPLICATE_DEFINITION,MAX_FEIL_LEN);
+         break;
+
+/* --------- Standard melding ved ukjent nr. ------------------- */
+      default:
+         strategi = 3;
+         UT_SNPRINTF(feil,MAX_FEIL_LEN,FYBA_STRING_UNKNOWN_ERROR,feil_nr);
+         break;
+   }
+
+   *feilmelding = feil;
+
+   return strategi;
+}
diff --git a/FYBA/FYLH.cpp b/FYBA/FYLH.cpp
new file mode 100644
index 0000000..93fafd5
--- /dev/null
+++ b/FYBA/FYLH.cpp
@@ -0,0 +1,1035 @@
+/*
+CH FYLH        AR-900503                                  BIBLIOTEK
+CD =================================================================
+CD
+CD Eier.......: STATENS KARTVERK / FYSAK-prosjektet
+CD Ansvarlig..: Georg Langerak / Andreas R�stad
+CD
+CD Rutiner for � handtere hodet p� SOSI-filer n�r dette ligger
+CD som ginfo i RB.
+CD  ==============================================================
+*/
+
+#include "stdafx.h"
+
+#include <math.h>
+#include <time.h>
+#include <ctype.h>
+#include <fcntl.h>
+
+/* Globale variabler */
+extern LC_SYSTEMADM Sys;
+
+
+
+/*
+AR:2000-10-07
+CH LC_PutTransEx                                 Legger inn ..TRANSPAR i hodet
+CD ==========================================================================
+CD Form�l:
+CD Legger inn innholdet under ..TRANSPAR i ginfo i aktuell gruppe.
+CD OBS! Forutsetter at aktuell gruppe er et SOSI-filhode versjon 3.x.
+CD
+CD M� velge mellom KOORDSYS, TRANSSYS eller GEOSYS.
+CD Kun en av disse kan benyttes i filhodet. 
+CD KOORDSYS er den mest vanlige m�te � definere referansesystem. 
+CD 
+CD GEOKOORD skal benyttes for GEOSYS og for TRANSSYS 
+CD
+CD M� velge mellom VERT-DATUM eller VERT-INT.
+CD VERT-DATUM er den mest vanlige beskrivelsesm�ten. 
+CD
+CD F�lgende kompaktifisering brukes:
+CD     ..TRANSPAR 
+CD     ...KOORDSYS <SYSKODE> <DATUM> <PROJEK> 
+CD     ...TRANSSYS <TILSYS> <KONSTA1> <KONSTB1> <KONSTA2> <KONSTB2> <KONSTC1> <KONSTC2> 
+CD     ...GEOSYS <GEO-DATUM> <GEO-PROJ> <GEO-SONE> 
+CD     ...GEOKOORD <GEOKOORD> 
+CD     ...ORIGO-N� <ORIGO-N> <ORIGO-�> 
+CD     ...ENHET <ENHET> 
+CD     ...ENHET-H <ENHET-H> 
+CD     ...ENHET-D <ENHET-D> 
+CD     ...VERT-DATUM <H�YDE-REF> <DYBDE-REF> <FRISEIL-REF> <H�YDE-TYPE> 
+CD     ...VERT-INT <H-REF-INT> <D-REF-INT> <F-REF-INT> 
+CD     ...VERT-DELTA <V-DELTA-MIN> <V-DELTA-MAX>
+CD
+CD
+CD Parametre:
+CD Type           Navn    I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD unsigned short usMaske  i   Maske som styrer hvilke deler av TRANSPAR som brukt
+CD                             F�lgende konstanter er definert:       
+CD                              LC_TR_KOORDSYS - Koordsys             
+CD                              LC_TR_TRANSSYS - Transsys             
+CD                              LC_TR_GEOSYS - Geosys                 
+CD                              LC_TR_GEOKOORD - Geokoord             
+CD                              LC_TR_ORIGO - Origo-n�                
+CD                              LC_TR_ENHET - Enhet                   
+CD                              LC_TR_ENHETH - Enhet-h                
+CD                              LC_TR_ENHETD - Enhet-d                
+CD                              LC_TR_VERTDATUM - Vert-datum          
+CD                              LC_TR_VERTINT - Vert-int              
+CD                              LC_TR_VERTDELTA - Vert-delta          
+CD
+CD LC_TRANSPAR *   pTrans   i   Peker til struktur med ..TRANSPAR informasjonen.
+CD short          ngi      r   Antall GINFO-linjer etter oppdateringen.
+CD
+CD Bruk:
+CD LC_TRANSPAR Trans;
+CD unsigned short usMaske = LC_TR_KOORDSYS | LC_TR_ORIGO | LC_TR_ENHET;
+CD Trans.sKoordsys = 32;
+CD Trans.dOrigoAust = 0.0;
+CD Trans.dOrigoNord = 0.0;
+CD Trans.dEnhet = 1.0;
+CD ngi = LC_PutTransEx(usMaske,&Trans);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_PutTransEx(unsigned short usMaske, LC_TRANSPAR * pTrans)
+{
+   short i,lin,ngi;
+   long nko;
+   unsigned short info;
+   char *cp = NULL;
+   char szGiLin[LC_MAX_SOSI_LINJE_LEN];
+
+
+   /* Ingen aktuell gruppe */
+   if (Sys.GrId.lNr == INGEN_GRUPPE) {
+      LC_Error(49,"(LC_PutTrans)","");
+      return Sys.pGrInfo->ngi;
+   }
+
+   /* Aktuell gruppe er ikke .HODE */
+   if (Sys.pGrInfo->gnavn != L_HODE) { 
+      LC_Error(94,"(LC_PutTrans)","");
+      return Sys.pGrInfo->ngi;
+   }
+
+
+   /* ----- Fjerner gammel transpar ----- */
+   LC_GetGrPara(&ngi,&nko,&info);
+   lin=2;
+   if (LC_GetGP("..TRANSPAR",&lin,ngi) != NULL) {      
+      i = lin;
+      do {
+         i++;
+         if (i <= ngi)  cp = LC_GetGi(i);
+      } while ( i <= ngi  &&  cp[2] == '.' );
+      /* i peker n� til f�rste linje etter hele ..TRANSPAR med underniv�er */
+
+      LC_DelGiL(lin,(short)(i-lin));
+   }
+
+   /* ----- Legger inn ny transpar ----- */
+   LC_PutGi(LC_AppGiL(),"..TRANSPAR");
+
+   /* Koordsys */
+   if ((usMaske & LC_TR_KOORDSYS) != 0) {
+      UT_SNPRINTF(szGiLin, LC_MAX_SOSI_LINJE_LEN, "...KOORDSYS %hd %s %s",pTrans->sKoordsys,pTrans->szKoordsysDatum,pTrans->szKoordsysProjek);
+      LC_PutGi(LC_AppGiL(),szGiLin);
+   }
+
+   /* Transsys */
+   if ((usMaske & LC_TR_TRANSSYS) != 0) {
+      UT_SNPRINTF(szGiLin, LC_MAX_SOSI_LINJE_LEN, "...TRANSSYS %hd %f %f %f %f %f %f", pTrans->sTranssysTilsys,
+              pTrans->dTranssysKonstA1, pTrans->dTranssysKonstB1,
+              pTrans->dTranssysKonstA2, pTrans->dTranssysKonstB2,
+              pTrans->dTranssysKonstC1, pTrans->dTranssysKonstC2);
+      LC_PutGi(LC_AppGiL(),szGiLin);
+   }
+
+   /* Geosys */
+   if ((usMaske & LC_TR_GEOSYS) != 0) {
+      if (pTrans->sGeosysProj  != LC_TR_GEOSYS_INGEN_VERDI)
+      {
+         UT_SNPRINTF(szGiLin, LC_MAX_SOSI_LINJE_LEN, "...GEOSYS %hd %hd %hd", pTrans->sGeosysDatum,
+                 pTrans->sGeosysProj, pTrans->sGeosysSone);
+      }
+      else
+      {
+         UT_SNPRINTF(szGiLin, LC_MAX_SOSI_LINJE_LEN, "...GEOSYS %hd", pTrans->sGeosysDatum);
+      }
+     
+      LC_PutGi(LC_AppGiL(),szGiLin);
+   }
+
+   /* Geokoord */ 
+   if ((usMaske & LC_TR_GEOKOORD) != 0) {
+      UT_SNPRINTF(szGiLin, LC_MAX_SOSI_LINJE_LEN, "...GEOKOORD %hd", pTrans->sGeoKoord);
+      LC_PutGi(LC_AppGiL(),szGiLin);
+   }
+
+   /* Origo */
+   if ((usMaske & LC_TR_ORIGO) != 0) {
+      UT_SNPRINTF(szGiLin, LC_MAX_SOSI_LINJE_LEN, "...ORIGO-N� %.0f  %.0f", pTrans->Origo.dNord, pTrans->Origo.dAust);
+      LC_PutGi(LC_AppGiL(),szGiLin);
+   }
+
+   /* Enhet */
+   if ((usMaske & LC_TR_ENHET) != 0) {
+      LC_PutGi(LC_AppGiL(),LB_FormaterEnhet(szGiLin,LC_MAX_SOSI_LINJE_LEN, "...ENHET", pTrans->dEnhet));
+   }
+
+   /* Enhet-h */
+   if ((usMaske & LC_TR_ENHETH) != 0) {
+      /*
+      * Hvis enhet og enhet_h er like
+      * skal det ikke legges inn ENHET-H
+      */
+      if (fabs(pTrans->dEnhet-pTrans->dEnhet_h) > 0.0000001) {
+         LC_PutGi(LC_AppGiL(),LB_FormaterEnhet(szGiLin,LC_MAX_SOSI_LINJE_LEN,"...ENHET-H",pTrans->dEnhet_h));
+      }
+   }
+
+   /* Enhet-d */
+   if ((usMaske & LC_TR_ENHETD) != 0) {
+      /*
+      * Hvis enhet og enhet_d er like
+      * skal det ikke legges inn ENHET-D
+      */
+      if (fabs(pTrans->dEnhet-pTrans->dEnhet_d) > 0.0000001) {
+         LC_PutGi(LC_AppGiL(),LB_FormaterEnhet(szGiLin,LC_MAX_SOSI_LINJE_LEN,"...ENHET-D",pTrans->dEnhet_d));
+      }
+   }
+
+   /* Vert-datum */
+   if ((usMaske & LC_TR_VERTDATUM) != 0) {
+      UT_SNPRINTF(szGiLin, LC_MAX_SOSI_LINJE_LEN, "...VERT-DATUM %s %s %s %s", pTrans->szVertdatHref,
+              pTrans->szVertdatDref, pTrans->szVertdatFref, pTrans->szVertdatHtyp);
+      LC_PutGi(LC_AppGiL(),szGiLin);
+   }
+      
+   /* Vert-int */
+   if ((usMaske & LC_TR_VERTINT) != 0) {
+      UT_SNPRINTF(szGiLin, LC_MAX_SOSI_LINJE_LEN, "...VERT-INT %hd %hd %hd", pTrans->sVertintHref,
+              pTrans->sVertintDref, pTrans->sVertintFref);
+      LC_PutGi(LC_AppGiL(),szGiLin);
+   }
+
+   /* Vert-delta */
+   if ((usMaske & LC_TR_VERTDELTA) != 0) {
+      UT_SNPRINTF(szGiLin, LC_MAX_SOSI_LINJE_LEN, "...VERT-DELTA %hd %hd", pTrans->sVdeltaMin, pTrans->sVdeltaMax);
+      LC_PutGi(LC_AppGiL(),szGiLin);
+   }
+
+   return Sys.pGrInfo->ngi;
+}
+
+
+/*
+AR-910920
+CH LC_PutTrans                                 Legger inn ..TRANSPAR i hodet
+CD ==========================================================================
+CD Form�l:
+CD Legger inn transformasjonsparametrene i ginfo i aktuell gruppe.
+CD Forutsetter at aktuell gruppe er et SOSI-filhode versjon 3.x.
+CD
+CD OBS! Denne rutinen opprettholdes bare for bakoverkompatibilitet.
+CD      For nye programmer b�r LC_PutTransEx benyttes. LC_PutTransEx er
+CD      kompatibel med nye versjoner av SOSI.
+CD
+CD Parametre:
+CD Type     Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD short    koosys     i    Koordinatsystem
+CD double   origo_a    i    Origo �st
+CD double   origo_n    i    Origo nord
+CD double   enhet      i    Enhet
+CD double   enhet_h    i    Enhet-H
+CD double   enhet_d    i    Enhet-D
+CD short    ngi        r    Antall GINFO-linjer etter oppdateringen.
+CD
+CD Bruk:
+CD     ngi = LC_PutTrans(koosys,origo_a,origo_n,enhet,enhet_h,enhet_d);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_PutTrans(short koosys,double origo_a,double origo_n,
+                  double enhet,double enhet_h,double enhet_d)
+{
+   short i,ngi,linje_enhet;
+   char c[80];
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {           /* Aktuell gruppe OK */
+       if (Sys.pGrInfo->gnavn == L_HODE) {        /* Aktuell gruppe .HODE */
+           UT_SNPRINTF(c,80,"%d",koosys);
+           ngi = LC_PutGP("...KOORDSYS",c,&i);
+           UT_SNPRINTF(c,80," %.0f  %.0f",origo_n,origo_a);
+           ngi = LC_PutGP("...ORIGO-N�",c,&i);
+           linje_enhet = 2;              
+           LC_GetGP("...ENHET",&linje_enhet,ngi);
+           LC_PutGi(linje_enhet,LB_FormaterEnhet(c,80,"...ENHET",enhet));
+        
+           /*
+            * Hvis enhet og enhet_h er like
+            * skal det ikke legges inn ENHET-H,
+            * eventuell gammel linje fjernes.
+            */
+
+           if (fabs(enhet-enhet_h) < 0.0000001) {
+              i = 2;
+              if (LC_GetGP("...ENHET-H",&i,ngi) != NULL) {
+                 LC_DelGiL(i,1);
+              }
+
+           } else {
+            
+              i = 2;              
+              if (LC_GetGP("...ENHET-H",&i,ngi) == NULL) {
+                i = linje_enhet + 1;
+                ngi = LC_InsGiL(i,1);         /* Ikke funnet, tildel ny linje */
+              }
+              LC_PutGi(i,LB_FormaterEnhet(c,80,"...ENHET-H",enhet_h));
+           }
+
+           /*
+            * Hvis enhet og enhet_d er like
+            * skal det ikke legges inn ENHET-D,
+            * eventuell gammel linje fjernes.
+            */
+           if (fabs(enhet-enhet_d) < 0.000001) {
+              i = 2;
+              if (LC_GetGP("...ENHET-D",&i,ngi) != NULL) {
+                 LC_DelGiL(i,1);
+              }
+
+           } else {
+              i = 2;              
+              if (LC_GetGP("...ENHET-D",&i,ngi) == NULL) {
+                i = linje_enhet + 1;
+                ngi = LC_InsGiL(i,1);         /* Ikke funnet, tildel ny linje */
+             }
+             LC_PutGi(i,LB_FormaterEnhet(c,80,"...ENHET-D",enhet_d));
+
+           }
+
+       } else{                              /* Gruppen er ikke filhode */
+           LC_Error(94,"(LC_PutTrans)","");
+       }
+
+   } else{                              /* Ingen aktuell gruppe */
+       LC_Error(49,"(LC_PutTrans)","");
+   }
+
+   return Sys.pGrInfo->ngi;
+}
+
+
+/*
+AR:2000-10-07
+CH LC_GetTransEx                                 Henter ..TRANSPAR fra hodet
+CD ==========================================================================
+CD Form�l:
+CD Henter ut innholdet under ..TRANSPAR fra ginfo i aktuell gruppe.
+CD OBS! Forutsetter at aktuell gruppe er et SOSI-filhode.
+CD
+CD M� velge mellom KOORDSYS, TRANSSYS eller GEOSYS. Kun en av disse kan benyttes i filhodet. 
+CD KOORDSYS er den mest vanlige m�te � definere referansesystem. 
+CD 
+CD GEOKOORD skal benyttes for GEOSYS og for TRANSSYS 
+CD
+CD M� velge mellom VERT-DATUM eller VERT-INT.
+CD VERT-DATUM er den mest vanlige beskrivelsesm�ten. 
+CD
+
+CD Parametre:
+CD Type            Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD unsigned short *pusMaske  iu   [Inn] Styrer hvilke deler av TRANSPAR som skal hentes
+CD                                [Ut]  Viser hvilke deler av TRANSPAR som er funnet/hentet.
+CD                                F�lgende konstanter er definert:
+CD                                  LC_TR_ALLT - Alle deler av ..TRANSPAR hentes
+CD                                  LC_TR_KOORDSYS - Koordsys
+CD                                  LC_TR_TRANSSYS - Transsys
+CD                                  LC_TR_GEOSYS - Geosys
+CD                                  LC_TR_GEOKOORD - Geokoord
+CD                                  LC_TR_ORIGO - Origo-n�
+CD                                  LC_TR_ENHET - Enhet
+CD                                  LC_TR_ENHETH - Enhet-h
+CD                                  LC_TR_ENHETD - Enhet-d
+CD                                  LC_TR_VERTDATUM - Vert-datum
+CD                                  LC_TR_VERTINT - Vert-int
+CD                                  LC_TR_VERTDELTA - Vert-delta
+CD
+CD LC_TRANSPAR *    pTrans    iu   Peker til struktur som skal motta ..TRANSPAR informasjonen.
+CD short           sStatus   r    Status: UT_TRUE=OK, UT_FALSE=feil (ikke funnet).
+CD
+CD Bruk:
+CD unsigned short usMaske = LC_TR_ALLT;
+CD LC_TRANSPAR Trans;
+CD ist = LC_GetTransEx(&usMaske,&Trans);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetTransEx(unsigned short *pusMaske, LC_TRANSPAR * pTrans)
+{
+   short lin,ngi,itxi;
+   long nko;
+   unsigned short us;
+   char *cp;
+   short ist = UT_TRUE;
+   unsigned short usMaskeInn = *pusMaske;
+
+
+   /* Nullstiller pTrans */
+   memset(pTrans,0,sizeof(LC_TRANSPAR));
+
+   /* Nullstiller masken */
+   *pusMaske = 0;
+
+   LC_GetGrPara(&ngi,&nko,&us);
+
+
+   /* ----- Div. kontroller ----- */
+
+   /* Ingen aktuell gruppe */
+   if (Sys.GrId.lNr == INGEN_GRUPPE) {
+      LC_Error(49,"(LC_GetTransEx)","");
+      return  UT_FALSE;
+   }
+   /* Gruppen er ikke filhode */
+   if (Sys.pGrInfo->gnavn != L_HODE) {        
+      LC_Error(94,"(LC_GetTransEx)","");
+      return  UT_FALSE;
+   }
+   /* Transpar */
+   lin=2;
+   if (LC_GetGP("..TRANSPAR",&lin,ngi) == NULL) {      
+      LC_Error(14,"(LC_GetTransEx)","");
+      return  UT_FALSE;
+   }
+
+
+   /* ----- Henter verdier ----- */
+
+   /* Koordsys */
+   if ((usMaskeInn & LC_TR_KOORDSYS) != 0) {
+      lin = 2;
+      cp = LC_GetGP("...KOORDSYS",&lin,ngi);
+      if (cp == NULL) {
+          lin=2;
+          cp = LC_GetGP("..KOORDSYS",&lin,ngi);
+      }
+      if (cp != NULL) {
+         *pusMaske |= LC_TR_KOORDSYS;
+         UT_StrShort(cp,0,&itxi,&pTrans->sKoordsys);
+         UT_StrToken(cp,itxi,&itxi,36,pTrans->szKoordsysDatum);
+         UT_StrToken(cp,itxi,&itxi,36,pTrans->szKoordsysProjek);
+      }
+   }
+
+   /* Transsys */
+   if ((usMaskeInn & LC_TR_TRANSSYS) != 0) {
+      lin = 2;
+      if ((cp = LC_GetGP("...TRANSSYS",&lin,ngi)) != NULL) {
+         *pusMaske |= LC_TR_TRANSSYS;
+         UT_StrShort(cp,0,&itxi,&pTrans->sTranssysTilsys);
+         UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstA1);
+         UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstB1);
+         UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstA2);
+         UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstB2);
+         UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstC1);
+         UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstC2);
+      }
+   }
+
+   /* Geosys */
+   if ((usMaskeInn & LC_TR_GEOSYS) != 0) {
+      lin = 2;
+      if ((cp = LC_GetGP("...GEOSYS",&lin,ngi)) != NULL) {
+         *pusMaske |= LC_TR_GEOSYS;
+         UT_StrShort(cp,0,&itxi,&pTrans->sGeosysDatum);
+         UT_StrShort(cp,itxi,&itxi,&pTrans->sGeosysProj);
+         UT_StrShort(cp,itxi,&itxi,&pTrans->sGeosysSone);
+      }
+   }
+
+   /* Geokoord */ 
+   if ((usMaskeInn & LC_TR_GEOKOORD) != 0) {
+      lin = 2;
+      if ((cp = LC_GetGP("...GEOKOORD",&lin,ngi)) != NULL) {
+         *pusMaske |= LC_TR_GEOKOORD;
+         UT_StrShort(cp,0,&itxi,&pTrans->sGeoKoord);
+      }
+   }
+
+   /* Origo */
+   if ((usMaskeInn & LC_TR_ORIGO) != 0) {
+      //pTrans->dOrigoAust = 0.0;                           
+      //pTrans->dOrigoNord = 0.0;                           
+      lin = 2;
+      if ((cp = LC_GetGP("...ORIGO-N�",&lin,ngi)) != NULL) {
+         *pusMaske |= LC_TR_ORIGO;
+         UT_StrDbl(cp,0,&itxi,'.',&pTrans->Origo.dNord);
+         UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->Origo.dAust);
+      }
+   }
+
+   /* Enhet */
+   if ((usMaskeInn & LC_TR_ENHET) != 0) {
+      lin = 2;
+      if ((cp = LC_GetGP("...ENHET",&lin,ngi)) != NULL) {
+         *pusMaske |= LC_TR_ENHET;
+         pTrans->dEnhet = strtod(cp,&cp);
+      }
+   }
+
+   /* Enhet-h */
+   if ((usMaskeInn & LC_TR_ENHETH) != 0) {
+      lin=2;
+      if ((cp = LC_GetGP("...ENHET-H",&lin,ngi)) == NULL) {
+        pTrans->dEnhet_h = pTrans->dEnhet;
+      } else {
+        *pusMaske |= LC_TR_ENHETH;
+        pTrans->dEnhet_h = strtod(cp,&cp);
+      }
+   }
+
+   /* Enhet-d */
+   if ((usMaskeInn & LC_TR_ENHETD) != 0) {
+      lin=2;
+      if ((cp = LC_GetGP("...ENHET-D",&lin,ngi)) == NULL) {
+        pTrans->dEnhet_d = pTrans->dEnhet;
+      } else {
+        *pusMaske |= LC_TR_ENHETD;
+        pTrans->dEnhet_d = strtod(cp,&cp);
+      }
+   }
+
+   /* Vert-datum */
+   if ((usMaskeInn & LC_TR_VERTDATUM) != 0) {
+      lin = 2;
+      if ((cp = LC_GetGP("...VERT-DATUM",&lin,ngi)) != NULL) {
+         *pusMaske |= LC_TR_VERTDATUM;
+         UT_StrToken(cp,0,&itxi,7,pTrans->szVertdatHref);
+         UT_StrToken(cp,itxi,&itxi,6,pTrans->szVertdatDref);
+         UT_StrToken(cp,itxi,&itxi,6,pTrans->szVertdatFref);
+         UT_StrToken(cp,itxi,&itxi,2,pTrans->szVertdatHtyp);
+      }
+   }
+   
+   /* Vert-int */
+   if ((usMaskeInn & LC_TR_VERTINT) != 0) {
+      lin = 2;
+      if ((cp = LC_GetGP("...VERT-INT",&lin,ngi)) != NULL) {
+         *pusMaske |= LC_TR_VERTINT;
+         UT_StrShort(cp,0,&itxi,&pTrans->sVertintHref);
+         UT_StrShort(cp,itxi,&itxi,&pTrans->sVertintDref);
+         UT_StrShort(cp,itxi,&itxi,&pTrans->sVertintFref);
+      }
+   }
+
+   /* Vert-delta */
+   if ((usMaskeInn & LC_TR_VERTDELTA) != 0) {
+      lin = 2;
+      if ((cp = LC_GetGP("...VERT-DELTA",&lin,ngi)) != NULL) {
+         *pusMaske |= LC_TR_VERTDELTA;
+         UT_StrShort(cp,0,&itxi,&pTrans->sVdeltaMin);
+         UT_StrShort(cp,itxi,&itxi,&pTrans->sVdeltaMax);
+      }
+   }
+
+
+   /* ----- Div. sluttkontroll ----- */
+
+   /* Kontroller at det er funnet Koordsys, Transsys eller Geosys */
+   if ((usMaskeInn & LC_TR_KOORDSYS) != 0  ||
+       (usMaskeInn & LC_TR_TRANSSYS) != 0  ||
+       (usMaskeInn & LC_TR_GEOSYS) != 0      ) {
+      if ((*pusMaske & LC_TR_KOORDSYS) == 0  &&
+          (*pusMaske & LC_TR_TRANSSYS) == 0  &&
+          (*pusMaske & LC_TR_GEOSYS) == 0  ) {
+         /* Ikke noe koordinatsystem funnet */
+         LC_Error(15,"(LC_GetTransEx)","");
+         ist = UT_FALSE;
+      }
+   }
+
+   /* Kontroller at det er funnet Origo */
+   if ((usMaskeInn & LC_TR_ORIGO) != 0  &&  
+       (*pusMaske & LC_TR_ORIGO) == 0  ) {
+      /* Origo mangler */
+      LC_Error(16,"(LC_GetTransEx)","");
+      ist = UT_FALSE;
+   }
+
+   /* Kontroller at det er funnet Enhet */
+   if ((usMaskeInn & LC_TR_ENHET) != 0  &&  
+       (*pusMaske & LC_TR_ENHET) == 0 ) {
+      /* Enhet mangler */
+      LC_Error(17,"(LC_GetTransEx)","");
+      ist = UT_FALSE;
+   }
+
+   return ist;
+}
+
+
+/*
+GL-880427
+AR-910920
+CH LC_GetTrans                                     Finner ..TRANSPAR i hodet
+CD ==========================================================================
+CD Form�l:
+CD Henter ut transformasjonsparametrene fra ginfo i aktuell gruppe.
+CD Forutsetter at aktuell gruppe er et SOSI-filhode.
+CD
+CD OBS! Denne rutinen opprettholdes bare for bakoverkompatibilitet.
+CD      For nye programmer b�r LC_GetTransEx benyttes. LC_GetTransEx er
+CD      kompatibel med nye versjoner av SOSI.
+CD
+CD
+CD Parametre:
+CD Type     Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD short   *koosys     u    Koordinatsystem
+CD double  *origo_a    u    Origo �st
+CD double  *origo_n    u    Origo nord
+CD double  *enhet      u    Enhet
+CD double  *enhet_h    u    ...ENHET-H
+CD double  *enhet_d    u    ...ENHET-D
+CD short    ist        r    status: UT_TRUE=OK, UT_FALSE=feil (navn er ikke funnet)
+CD
+CD Bruk:
+CD     ist = LC_GetTrans(&koosys,&origo_a,&origo_n,&enhet,&enhet_h,&enhet_d);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetTrans(short *koosys,double *origo_a,double *origo_n,double *enhet,
+					 double *enhet_h,double *enhet_d)
+{
+
+   short lin,ngi;
+   long nko;
+   unsigned short us;
+   char *cp;
+   short ist = UT_TRUE;
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {           /* Aktuell gruppe OK */
+       if (Sys.pGrInfo->gnavn == L_HODE) {        /* Aktuell gruppe .HODE */
+           LC_GetGrPara(&ngi,&nko,&us);
+
+           lin=2;
+           if (LC_GetGP("..TRANSPAR",&lin,ngi) == NULL) {      /* Transpar */
+               LC_Error(14,"(LC_GetTrans)","");
+               ist = UT_FALSE;
+           } else{
+               *koosys=0;                                      /* Koordsys */
+               lin=2;
+               cp = LC_GetGP("...KOORDSYS",&lin,ngi);
+               if (cp == NULL){
+                   lin=2;
+                   cp = LC_GetGP("..KOORDSYS",&lin,ngi);
+               }
+               if (cp == NULL){
+                   LC_Error(15,"(LC_GetTrans)","");
+                   ist = UT_FALSE;
+               } else{
+                   *koosys = atoi(cp);
+                   *origo_a = 0.0;                            /* Origo */
+                   *origo_n = 0.0;
+                   lin = 2;
+                   cp = LC_GetGP("...ORIGO-N�",&lin,ngi);
+                   if (cp == NULL) {
+                       LC_Error(16,"(LC_GetTrans)","");
+                       ist = UT_FALSE;
+                   } else{
+                       *origo_n=strtod(cp,&cp);
+                       *origo_a=strtod(cp,&cp);
+
+                       *enhet  = 1.0;                         /* Enhet */
+                       lin = 2;
+                       cp = LC_GetGP("...ENHET",&lin,ngi);
+                       if (cp == NULL){
+                           LC_Error(17,"(LC_GetTrans)","");
+                           ist = UT_FALSE;
+                       } else{
+                           *enhet  = strtod(cp,&cp);
+                       }
+                       lin=2;
+                       cp = LC_GetGP("...ENHET-H",&lin,ngi);
+                       if (cp == NULL){
+                          *enhet_h = *enhet;
+                       } else {
+                          *enhet_h = strtod(cp,&cp);
+                       }
+                       lin=2;
+                       cp = LC_GetGP("...ENHET-D",&lin,ngi);
+                       if (cp == NULL){
+                          *enhet_d = *enhet;
+                       } else{
+                          *enhet_d = strtod(cp,&cp);
+                       }
+                   }
+               }
+           }
+
+       } else{                              /* Gruppen er ikke filhode */
+           LC_Error(94,"(LC_GetTrans)","");
+           ist = UT_FALSE;
+       }
+
+   } else{                              /* Ingen aktuell gruppe */
+       LC_Error(49,"(LC_GetTrans)","");
+       ist = UT_FALSE;
+   }
+
+   return ist;
+}
+
+/*
+AR-920401
+CH LC_GetTegnsett                                            Finner tegnsett
+CD ==========================================================================
+CD Form�l:
+CD Finne tegnsett i ginfo i aktuell gruppe.
+CD OBS! Forutsetter at aktuell gruppe er et SOSI-filhode.
+CD
+CD Parametre:
+CD Type    Navn       I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD short  *psTegnsett  u   Tegnsett, konstanter definert:
+CD                            TS_DOSN8   = DOS norsk 8-bits(standardverdi)
+CD                            TS_ND7     = Norsk Data 7-bits
+CD                            TS_ISO8859 = ISO8859-10 norsk/samisk
+CD                            TS_DECM8   = DEC multinasjonal 8-bits
+CD                            TS_DECN7   = DEC norsk 7-bits
+CD short   sStatus     r   Status: UT_TRUE  = Funnet
+CD                                  UT_FALSE = Ikke funnet
+CD
+CD Bruk:
+CD      sStatus = LC_GetTegnsett(&sTegnsett);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetTegnsett(short *psTegnsett)
+{
+   short lin,ngi;
+   long nko;
+   unsigned short us;
+   char *cp;
+   short ist = UT_FALSE;
+
+   *psTegnsett = TS_DOSN8;
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {           /* Aktuell gruppe OK */
+      if (Sys.pGrInfo->gnavn == L_HODE) {        /* Aktuell gruppe .HODE */
+         LC_GetGrPara(&ngi,&nko,&us);
+         lin=2;
+         if ((cp = LC_GetGP("..TEGNSETT",&lin,ngi)) != NULL) {  /* Tegnsett */
+            ist = UT_TRUE;
+            UT_StrUpper(cp);
+            if (strcmp(cp,"ISO8859-10") == 0) {
+               *psTegnsett = TS_ISO8859;
+
+            } else if (strcmp(cp,"ISO8859-1") == 0) {
+               *psTegnsett = TS_ISO8859;
+
+            } else if (strcmp(cp,"ANSI") == 0) {
+               *psTegnsett = TS_ISO8859;
+
+            } else if (strcmp(cp,"ND7") == 0) {
+               *psTegnsett = TS_ND7;
+
+            } else if (strcmp(cp,"DECN7") == 0) {
+               *psTegnsett = TS_DECN7;
+
+            } else if (strcmp(cp,"DECM8") == 0) {
+               *psTegnsett = TS_DECM8;
+            }
+         }
+
+      } else {                              /* Gruppen er ikke filhode */
+         LC_Error(94,"(LC_GetTegnsett)","");
+         ist = UT_FALSE;
+      }
+
+   } else {                              /* Ingen aktuell gruppe */
+       LC_Error(49,"(LC_GetTegnsett)","");
+       ist = UT_FALSE;
+   }
+
+   return ist;
+}
+
+
+/*
+AR-920401
+CH LH_GetNgisLag                                           Finner NGIS-LAG
+CD ==========================================================================
+CD Form�l:
+CD Finne NGIS-LAG i ginfo i aktuell gruppe.
+CD OBS! Forutsetter at aktuell gruppe er et SOSI-filhode.
+CD
+CD Parametre:
+CD Type   Navn        I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD char*  pszNgisLag   r   NGIS-lag. 
+CD                           Tom streng = ..NGIS-LAG er ikke funnet eller parameter mangler
+CD                           ..NGIS-LAG 0 = Bare leseaksess
+CD
+CD Bruk:
+CD      pszNgisLag = LH_GetNgisLag();
+CD ==========================================================================
+*/
+char* LH_GetNgisLag(void)
+{
+   char *cp;
+   short lin = 2;
+
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {           /* Aktuell gruppe OK */
+      if (Sys.pGrInfo->gnavn == L_HODE) {        /* Aktuell gruppe .HODE */
+         if ((cp = LC_GetGP("..NGIS-LAG",&lin,Sys.pGrInfo->ngi)) != NULL) {
+            return cp; 
+         } else {
+            return  "";
+         }
+
+      } else {                              /* Gruppen er ikke filhode */
+         LC_Error(94,"(LH_GetNgisLag)","");
+      }
+
+   } else {                              /* Ingen aktuell gruppe */
+       LC_Error(49,"(LH_GetNgisLag)","");
+   }
+
+   return  "";
+}
+
+
+/*
+AR-910920
+CH LC_PutOmr                                     Legger inn ..OMR�DE i hodet
+CD ==========================================================================
+CD Form�l:
+CD Legger inn omr�de i ginfo i aktuell gruppe.
+CD Hvis omr�de ikke har noen utstrekning justeres
+CD dette med 1 meter i hver retning. 
+CD OBS! Forutsetter at aktuell gruppe er et SOSI-filhode av ny type.
+CD
+CD Parametre:
+CD Type     Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   nv_a       i    Omr�de
+CD double   nv_n       i
+CD double   oh_a       i
+CD double   oh_n       i
+CD short    ist        r    status: UT_TRUE=OK, UT_FALSE=feil
+CD
+CD Bruk:
+CD     ist = LC_PutOmr(nv_a,nv_n,oh_a,oh_n);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_PutOmr(double nv_a,double nv_n,double oh_a,double oh_n)
+{
+   short i;
+   char c[80];
+   short ist = UT_FALSE;
+   double dNV_N, dNV_A, dOH_A, dOH_N;
+
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {           /* Aktuell gruppe OK */
+       if (Sys.pGrInfo->gnavn == L_HODE) {        /* Aktuell gruppe .HODE */
+
+           //UT_SNPRINTF(c,80," %ld     %ld",UT_RoundDL(floor(nv_n)),UT_RoundDL(floor(nv_a)));
+           dNV_N = UT_RoundDD(floor(nv_n));
+           dNV_A = UT_RoundDD(floor(nv_a));
+ 
+           dOH_N = UT_RoundDD(ceil(oh_n));
+           dOH_A = UT_RoundDD(ceil(oh_a));
+
+           // Hvis n�dvendig justeres omr�de
+           if (fabs(dOH_N-dNV_N) < 0.00000001) {
+               dNV_N -= 1.0;
+               dOH_N += 1.0;
+           }
+           if (fabs(dOH_A-dOH_A) < 0.00000001) {
+               dNV_A -= 1.0;
+               dOH_A += 1.0;
+           }
+
+           UT_SNPRINTF( c,80, " %.0f  %.0f", dNV_N, dNV_A );
+           if (LC_PutGP("...MIN-N�",c,&i)) {
+
+               UT_SNPRINTF( c, 80, " %.0f  %.0f", dOH_N, dOH_A );
+               if (LC_PutGP("...MAX-N�",c,&i)){
+                   ist = UT_TRUE;
+               }
+           }
+
+       } else{                              /* Gruppen er ikke filhode */
+           LC_Error(94,"(LC_PutOmr)","");
+       }
+
+   } else{                              /* Ingen aktuell gruppe */
+       LC_Error(49,"(LC_PutOmr)","");
+   }
+
+   return ist;
+}
+
+
+/*
+AR-910920
+CH LC_GetOmr                                         Finner ..OMR�DE i hodet
+CD ==========================================================================
+CD Form�l:
+CD Henter ut omr�de fra ginfo i aktuell gruppe.
+CD OBS! Forutsetter at aktuell gruppe er et SOSI-filhode.
+CD
+CD Parametre:
+CD Type     Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double  *nv_a       u    Omr�de
+CD double  *nv_n       u
+CD double  *oh_a       u
+CD double  *oh_n       u
+CD short    ist        r    status: UT_TRUE=OK, UT_FALSE=feil (navn er ikke funnet)
+CD
+CD Bruk:
+CD     ist = LC_GetOmr(&nv_a,&nv_n,&oh_a,&oh_n);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetOmr(double *nv_a,double *nv_n,double *oh_a,double *oh_n)
+{
+   short lin,i,ngi;
+   long nko;
+   unsigned short info;
+   char *cp;
+   short ist = UT_TRUE;
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {           /* Aktuell gruppe OK */
+       if (Sys.pGrInfo->gnavn == L_HODE) {        /* Aktuell gruppe .HODE */
+           LC_GetGrPara(&ngi,&nko,&info);
+           lin=2;
+           if (LC_GetGP("..OMR�DE",&lin,ngi) == NULL) { 
+               LC_Error(7,"(LC_GetOmr)","");
+               *nv_n = -9999999.0;
+               *nv_a = -9999999.0;
+               *oh_n =  9999999.0;
+               *oh_a =  9999999.0;
+               ist = UT_FALSE;
+           } else {
+               /* Min-N� */
+               i = lin;
+               cp = LC_GetGP("...MIN-N�",&i,ngi);
+               if (cp == NULL){
+                  LC_Error(8,"(LC_GetOmr)","");
+                  ist = UT_FALSE;
+                  *nv_n = -9999999.0;
+                  *nv_a = -9999999.0;
+               } else{
+                   *nv_n = strtod(cp,&cp);
+                   *nv_a = strtod(cp,&cp);
+                   /* Max-N� */
+                   i = lin;
+                   cp = LC_GetGP("...MAX-N�",&i,ngi);
+                   if (cp == NULL){
+                      LC_Error(9,"(LC_GetOmr)","");
+                      ist = UT_FALSE;
+                      *oh_n = 9999999.0;
+                      *oh_a = 9999999.0;
+
+                   } else{
+                      *oh_n = strtod(cp,&cp);
+                      *oh_a = strtod(cp,&cp);
+                   }
+               }
+           }
+
+       } else{                              /* Gruppen er ikke filhode */
+           LC_Error(94,"(LC_GetOmr)","");
+           ist = UT_FALSE;
+       }
+
+   } else{                              /* Ingen aktuell gruppe */
+       LC_Error(49,"(LC_GetOmr)","");
+       ist = UT_FALSE;
+   }
+
+   return ist;
+}
+
+
+/*
+AR-910920
+CH LC_NyttHode                                               Lager nytt hode
+CD ==========================================================================
+CD Form�l:
+CD Legger inn et standard SOSI-filhode i ginfo i aktuell gruppe.
+CD
+CD Parametre:
+CD     ingen
+CD
+CD Bruk:
+CD     LC_NyttHode();
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_NyttHode(void)
+{
+   short ngi;
+   long nko;
+   unsigned short us;
+   char szTx[100];
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {           /* Aktuell gruppe OK */
+                                           /* Tildel plass */
+       LC_GetGrPara(&ngi,&nko,&us);
+       if (ngi < 10){
+           LC_InsGiL((short)(ngi+1),(short)(10-ngi));
+       } else if (ngi > 10){
+           LC_DelGiL(11,(short)(ngi-10));
+       }
+
+       Sys.pGrInfo->gnavn = L_HODE;       /* Aktuell gruppe .HODE */
+
+                                           /* Generer nytt hode */
+       LC_PutGi(1,".HODE");
+       LC_PutGi(2,"..TEGNSETT ISO8859-10");
+       LC_PutGi(3,"..TRANSPAR");
+       LC_PutGi(4,"...KOORDSYS 0");
+       LC_PutGi(5,"...ORIGO-N�  0  0");
+       LC_PutGi(6,"...ENHET 0.01");
+       LC_PutGi(7,"..OMR�DE");
+       LC_PutGi(8,"...MIN-N�   -99999   -99999");
+       LC_PutGi(9,"...MAX-N�  1999999  1999999");
+
+       //LC_PutGi(10,"..SOSI-VERSJON  3.0");
+       UT_SNPRINTF(szTx,100,"..SOSI-VERSJON %.2f",((double)FYBA_SOSI_VERSJON)/100.0);
+       LC_PutGi(10,szTx);
+
+       LC_PutSn(0L);          /* Standard serienummer 0 for hodet*/
+   }
+}
+
+
+/*
+AR-910920
+CH LC_TestHode                                             Tester SOSI-hodet
+CD ==========================================================================
+CD Form�l:
+CD Sjekker at ginfo i aktuell gruppe er et lovlig SOSI-filhode.
+CD
+CD Parametre:
+CD  Type    Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD  short   ist      r    status: UT_TRUE=OK, UT_FALSE=feil
+CD
+CD Bruk:
+CD     ist = LC_TestHode();
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_TestHode(void)
+{
+   double d;
+   short ist;
+   unsigned short usMaske = LC_TR_ALLT;
+   LC_TRANSPAR Trans;
+
+
+   ist = LC_GetTransEx(&usMaske,&Trans);
+
+   if (ist == UT_TRUE) {
+       ist =  LC_GetOmr(&d,&d,&d,&d);
+   }
+
+   return ist;
+}
+
diff --git a/FYBA/FYLI.cpp b/FYBA/FYLI.cpp
new file mode 100644
index 0000000..0bc7c26
--- /dev/null
+++ b/FYBA/FYLI.cpp
@@ -0,0 +1,2293 @@
+/* === 910828 ============================================================= */
+/*  STATENS KARTVERK  -  FYSAK-PC                                           */
+/*  Fil: fyli.c                                                             */
+/*  Innhold: Lagring og henting av indekstabeller                           */
+/* ======================================================================== */
+
+#include "stdafx.h"
+
+#include <limits.h>
+
+#ifdef WIN32
+#   include <process.h>
+#endif
+
+/* Div. styrevariabler */
+
+/* Konstanter for ModusXxx */
+#define NY    0
+#define LES   1
+#define SKRIV 2
+
+
+/* Globale strukturer for fyba */
+extern LC_SYSTEMADM    Sys;
+
+
+/* Lokale rutiner */
+static FILE *LI_OpenIdxFil(LC_FILADM *pFil, const char *pszNavn, const char *pszType);
+static FILE *LI_OpenAdm(LC_FILADM *pFil);
+static FILE *LI_OpenGrt(LC_FILADM *pFil);
+static FILE *LI_OpenGeo(LC_FILADM *pFil);
+static FILE *LI_OpenSnr(LC_FILADM *pFil);
+static FILE *LI_OpenBt(LC_FILADM *pFil);
+static void  LI_OpenRb(LC_FILADM *pFil,UT_INT64 n64FilPos,short sModus);
+static short LI_ReadAdm(LC_FILADM *pFil);
+static void  LI_CreateIdx(LC_FILADM *pFil);
+static void  LI_FrigiIdx(LC_FILADM *pFil);
+
+
+/*
+AR-910928
+CH LI_TestIdx                               Sjekk at indeksfilene eksisterer
+CD ==========================================================================
+CD Form�l:
+CD Sjekk at indeksfilene eksisterer.
+CD
+CD Parametre:
+CD Type    Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD char   *szSosFil   i    SOSI-fil
+CD short   status     r    Status
+CD                          UT_TRUE = OK
+CD                          UT_FALSE = Fil mangler
+CD
+CD Bruk:
+CD status = LI_TestIdx(szSosFil);
+   ==========================================================================
+*/
+short LI_TestIdx(char *szSosFil)
+{
+   UT_INT64 Size;
+   char fil[_MAX_PATH];
+   char drive[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
+
+
+   // Hvis det er valgt spesiell indekskatalog skal indeksen alltid bygges opp p� nytt
+   if (*Sys.szIdxPath != '\0')  return UT_FALSE;
+
+   /*
+    *  Lag sti til indeksfilene
+    */
+   UT_splitpath(szSosFil,drive,dir,fname,ext);
+   /* Lag navn p� sub-directory */
+   UT_StrCat(dir,fname,_MAX_DIR);
+   UT_StrCat(dir,UT_STR_SLASH,_MAX_DIR);
+
+   /* Sjekk at indeksfilene finnes */
+   /* -------------- Adm ------------- */
+   UT_makepath(fil,drive,dir,"Adm",".Idx");
+   if (UT_InqPathSize_i64(fil,&Size) != 0)  return UT_FALSE;
+
+   /* -------------- Gruppetabell ------------- */
+   UT_makepath(fil,drive,dir,"Grt",".Idx");
+   if (UT_InqPathSize_i64(fil,&Size) != 0)  return UT_FALSE;
+
+   /* -------------- RB ------------- */
+   UT_makepath(fil,drive,dir,"Rb",".Idx");
+   if (UT_InqPathSize_i64(fil,&Size) != 0)  return UT_FALSE;
+
+   /* -------------- SNR ------------- */
+   UT_makepath(fil,drive,dir,"Snr",".Idx");
+   if (UT_InqPathSize_i64(fil,&Size) != 0)  return UT_FALSE;
+   
+   /* -------------- BT -------------- */
+   UT_makepath(fil,drive,dir,"Bt",".Idx");
+   if (UT_InqPathSize_i64(fil,&Size) != 0)  return UT_FALSE;
+   
+   /* -------------- GEO ------------- */
+   UT_makepath(fil,drive,dir,"Geo",".Idx");
+   if (UT_InqPathSize_i64(fil,&Size) != 0)  return UT_FALSE;
+
+   /* printf("\nIndeksfilene finnes."); */
+   return UT_TRUE;
+}
+
+
+/*
+AR-910929
+CH LI_OpenInit                              �pner og nullstiller indeksfilene
+CD ==========================================================================
+CD Form�l:
+CD �pner indeksfilene og nullstiller tabellene.
+CD
+CD Parametre:
+CD Type       Navn  I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil   i    Peker til FilAdm
+CD short      status r    Status
+CD                          UT_TRUE = OK
+CD                          UT_FALSE = Ikke �pnet OK
+CD
+CD Bruk:
+CD status = LI_OpenInit(pFil);
+   ==========================================================================
+*/
+short LI_OpenInit(LC_FILADM *pFil)
+{
+   char fil[_MAX_PATH];
+   char drive1[_MAX_DRIVE],dir1[_MAX_DIR],fname1[_MAX_FNAME],ext1[_MAX_EXT];
+   char drive2[_MAX_DRIVE],dir2[_MAX_DIR],fname2[_MAX_FNAME],ext2[_MAX_EXT];
+   FILE *pF;
+
+
+   // ----- Alloker overordnet struktur for indekstabeller
+   LI_CreateIdx(pFil);
+
+   // ----- Splitt filnavnet
+   UT_splitpath(pFil->pszNavn,drive1,dir1,fname1,ext1);
+
+   // Gitt sti for indeksfilene
+   if ( *Sys.szIdxPath != 0) {
+      UT_splitpath(Sys.szIdxPath,drive2,dir2,fname2,ext2);
+      UT_makepath(fil,drive2,dir2,fname1,"");
+
+   } else {
+      UT_makepath(fil,drive1,dir1,fname1,"");
+   }
+
+   // ----- Lag subdirectory hvis det ikke finnes fra f�r
+   // Sjekk at navnet er lovlig (ikke blanke siste i navnet)
+   if (fil[strlen(fil)-1] == ' ')
+   {
+      LC_Error(120,"(LI_OpenInit)",pFil->pszNavn);
+      exit(99);
+   }
+
+   // Opprett katalogen
+   UT_CreateDir(fil);
+
+
+   // ----- �pner indeksfilene
+
+   /* -------------- Adm ------------- */
+   pF = LI_OpenAdm(pFil);
+
+   /* Marker at basen er �pnet */       
+   UT_StrCopy(pFil->szBaseVer, FYBA_IDENT, LC_BASEVER_LEN);
+   UT_StrCopy(pFil->szIdxVer, FYBA_INDEKS_VERSJON, 5);
+   pFil->ulPid = 0;
+   pFil->sIdxOpen = UT_TRUE;
+   pFil->ulPid = UT_GETPID();
+   //pFil->ulPid = GetCurrentProcessId();   // Bruke _getpid() i stede?
+
+   if (fwrite(pFil,sizeof(*pFil),1,pF) != 1) {
+      LC_Error(112,"(LI_OpenInit)","");
+      exit(99);
+   }
+
+   fclose(pF);
+
+   /* -------------- Gruppetabell ------------- */
+   pF = LI_OpenGrt(pFil);
+   fclose(pF);
+
+   /* -------------- RB ------------- */
+   LI_OpenRb(pFil,0L,SKRIV);
+   pFil->pBase->n64FilPosRb = 0L;
+
+   /* -------------- SNR ------------- */
+   pF = LI_OpenSnr(pFil);
+   fclose(pF);
+
+   /* -------------- BT -------------- */
+   pF = LI_OpenBt(pFil);
+   fclose(pF);
+
+   /* -------------- GEO ------------- */
+   /* (Geografisk s�k er uaktuellt ved kladdebase)  ?????? */
+   pF = LI_OpenGeo(pFil);
+   fclose(pF);
+
+   return UT_TRUE;
+}
+
+
+/*
+AR-910930
+CH LI_OpenRead                                   �pner og leser indeksfilene
+CD ==========================================================================
+CD Form�l:
+CD �pner indeksfilene og leser inn tabellene.
+CD
+CD Parametre:
+CD Type       Navn  I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil   i  Peker til FilAdm
+CD short      status r  Status
+CD                         UT_OK (0): Lest OK
+CD                         LI_LESEFEIL: Feil ved les fra Adm.idx
+CD                         LI_OPPTATT: Filen er �pen i et annet program
+CD                         LI_FEIL_INDEKSVERSJON: Feil indeksversjon
+CD                         LI_FEIL_STORRELSE: Feil st�rrelse p� SOSI-filen
+CD                         LI_FEIL_OPPDATTID: Feil oppdateringstid p� SOSI-filen
+CD
+CD Bruk:
+CD status = LI_OpenRead(pFil);
+   ==========================================================================
+*/
+short LI_OpenRead(LC_FILADM *pFil)
+{
+   FILE *pF;
+   long linje;
+   long lSnr;
+   long lGrNr;
+   unsigned long bt;
+   LC_GRTAB_LINJE * pGrt;
+   LC_BOKS Boks;
+   short sStatus;
+
+
+   /* -------------- Admin ------------- */
+   // Her sjekkes det ogs� mot feil versjon, lesefeil
+   // og om filen er �pen i annet program.
+   if ((sStatus = LI_ReadAdm(pFil)) != UT_OK)
+   {
+      return sStatus;
+   }
+
+   // Alloker overordnet struktur for indekstabeller
+   LI_CreateIdx(pFil);
+
+   /* -------------- RB ------------- */
+   LI_OpenRb(pFil,0L,SKRIV);
+   pFil->pBase->n64FilPosRb = 0L;
+
+   /* -------------- Gruppetabell ------------- */
+   pF = LI_OpenGrt(pFil);
+   for (linje = 0; linje<pFil->lAntGr; linje++) {
+      pGrt = LI_AppGrt(pFil,linje);
+      if (fread(pGrt,sizeof(*pGrt),1,pF) != 1) { /* Les */
+         UT_SNPRINTF(err().tx,LC_ERR_LEN," %s : %ld",pFil->pszNavn,linje);
+         LC_Error(111,"(LI_OpenRead): ",err().tx);
+         exit(99);
+      }
+   }
+   fclose(pF);
+   
+   /* -------------- SNR ------------- */
+   pF = LI_OpenSnr(pFil);
+   lSnr = 0;
+   while (fread(&lGrNr,sizeof(lGrNr),1,pF) == 1) {
+      if (lGrNr != INGEN_GRUPPE)  LI_PutSnr(pFil,lSnr,lGrNr);
+      lSnr++;
+   }
+   if (! feof(pF)) {
+      UT_SNPRINTF(err().tx,LC_ERR_LEN," %ld",lSnr);
+      LC_Error(111,"(LI_OpenRead): ",err().tx);
+      exit(99);
+   }
+   fclose(pF);
+
+
+   /* -------------- BT -------------- */
+   pF = LI_OpenBt(pFil);
+   for (linje = 0; linje<pFil->lAntGr; linje++) {
+      if (fread(&bt,sizeof(bt),1,pF) != 1) {   /* Les */
+         UT_SNPRINTF(err().tx,LC_ERR_LEN," %s : %ld",pFil->pszNavn,linje);
+         LC_Error(111,"(LI_OpenRead): ",err().tx);
+         exit(99);
+      }
+      LI_PutBt(pFil,linje,bt);
+   }
+   fclose(pF);
+
+   /* -------------- GEO ------------- */
+   pF = LI_OpenGeo(pFil);
+   for (linje = 0; linje<pFil->lAntGr; linje++) {
+      if (fread(&Boks,sizeof(Boks),1,pF) != 1) { /* Les */
+         UT_SNPRINTF(err().tx,LC_ERR_LEN," %s : %ld",pFil->pszNavn,linje);
+         LC_Error(111,"(LI_OpenRead): ",err().tx);
+         exit(99);
+      }
+
+      if (Boks.dMaxAust != (double)LONG_MAX) {
+         /* Lagre omskrevet boks i s�ketreet */
+         pGrt = LI_GetGrt(pFil,linje);
+         pGrt->pRL = LR_InsertGeo(pFil,linje,&Boks);
+      }
+   }
+   fclose(pF);
+
+   return UT_OK;
+}
+
+
+/*
+AR-930809
+CH LI_CreateIdx                               Allokerer Idx struktur i minne
+CD ==========================================================================
+CD Form�l:
+CD Allokerer Idx struktur i minne
+CD
+CD Parametre:
+CD Type       Navn  I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil   i    Peker til FilAdm
+CD
+CD Bruk:
+CD LI_CreateIdx(pFil);
+   ==========================================================================
+*/
+static void LI_CreateIdx(LC_FILADM *pFil)
+{
+	pFil->pIdx = (LC_IDX_TABELL *) UT_MALLOC(sizeof(LC_IDX_TABELL));
+	memset(pFil->pIdx,'\0',sizeof(LC_IDX_TABELL));
+}
+
+
+/*
+AR-930809
+CH LI_FrigiIdx                                   Frigi Idx struktur i minne
+CD ==========================================================================
+CD Form�l:
+CD Frigi Idx struktur i minne
+CD
+CD Parametre:
+CD Type       Navn  I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil   i    Peker til FilAdm
+CD
+CD Bruk:
+CD LI_FrigiIdx(pFil);
+   ==========================================================================
+*/
+static void LI_FrigiIdx(LC_FILADM *pFil)
+{
+   int i;
+   LC_GRTAB_LINJE * *ppGt = pFil->pIdx->GtAdm;
+   long **pplSnr;
+   unsigned long **ppulBt;
+
+
+   if (pFil->pIdx != NULL) {
+      ppGt = pFil->pIdx->GtAdm;
+      pplSnr = pFil->pIdx->SnrAdm;
+      ppulBt = pFil->pIdx->BtAdm;
+
+      for (i=0; i<LC_ANT_IDX_BLOKK; i++) {
+         /* Gruppetabellen */
+			if (*ppGt != NULL) {
+				UT_FREE(*ppGt);
+			}
+         ppGt++;
+
+         /* SNR-tabellen */
+			if (*pplSnr != NULL) {
+				UT_FREE(*pplSnr);
+         }
+         pplSnr++;
+
+         /* Brukt-tabellen */
+			if (*ppulBt != NULL) {
+				UT_FREE(*ppulBt);
+         }
+         ppulBt++;
+
+      }
+
+      /* Frigi GEO-tabellen */
+      if (pFil->pGeoRN != NULL) {
+         LR_R_FrigiGren(pFil->pGeoRN);
+      }
+		
+      /* Frigir topp-blokken */
+		UT_FREE(pFil->pIdx);
+
+		pFil->pIdx = NULL;
+	}
+}
+
+
+/*
+AR-910830
+CH LI_Close                                             Stenger indeksfilene
+CD ==========================================================================
+CD Form�l:
+CD Skriver adm. opplysning og stenger indeksfilene.
+CD
+CD Parametre:
+CD Type       Navn  I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil   i  Peker til FilAdm
+CD short      s_stat i  Slutt-status (brukes forel�pig ikke)
+CD                         (RESET_IDX) = Fjern indeksfilene
+CD                         (SAVE_IDX ) = Lagrer indeksfilene
+CD
+CD Bruk:
+CD LI_Close(pFil,SAVE_IDX);
+   ==========================================================================
+*/
+void LI_Close(LC_FILADM *pFil,short s_stat)
+{
+   long lGrNr,lSnr;
+   unsigned long flag;
+   FILE *pF;
+   LC_R_LEAF * pRL;
+   LC_BOKS Boks;
+
+
+   /* RB */
+   if (pFil->pBase->pCurRb != NULL) {
+      fclose(pFil->pBase->pfRb);
+      pFil->pBase->pCurRb = NULL;
+   }
+
+   if (s_stat == SAVE_IDX  &&  pFil->pIdx != NULL  &&  *Sys.szIdxPath == '\0') {
+
+      /* Gruppetabellen */
+      pF = LI_OpenGrt(pFil);     /* �pne og posisjoner */
+      for (lGrNr=0; lGrNr<pFil->lAntGr; lGrNr++) {
+			if (fwrite(LI_GetGrt(pFil,lGrNr),sizeof (LC_GRTAB_LINJE),1,pF) != 1) {
+            LC_Error(112,"(LI_Close)","");
+            exit(99);
+         }
+      }
+      fclose(pF);
+
+      /* Brukttabellen */
+      pF = LI_OpenBt(pFil);     /* �pne og posisjoner */
+      for (lGrNr=0; lGrNr<pFil->lAntGr; lGrNr++) {
+         flag = LI_GetBt(pFil,lGrNr);
+         if (fwrite(&flag,sizeof flag,1,pF) != 1) {
+				LC_Error(112,"(LI_Close)","");
+            exit(99);
+         }
+      }
+      fclose(pF);
+
+      /*Serienummertabellen */
+      pF = LI_OpenSnr(pFil);     /* �pne og posisjoner */
+      for (lSnr=0; lSnr<=pFil->lMaxSnr; lSnr++) {
+         lGrNr = LI_GetSnr(pFil,lSnr);
+         if (fwrite(&lGrNr,sizeof lGrNr,1,pF) != 1) {
+            LC_Error(112,"(LI_Close)","");
+				exit(99);
+         }
+      }
+      fclose(pF);
+
+      /* Geografisk s�ketabell */
+      pF = LI_OpenGeo(pFil);     /* �pne og posisjoner */
+      for (lGrNr=0; lGrNr<pFil->lAntGr; lGrNr++) {
+         pRL = LI_GetGeo(pFil,lGrNr);
+
+         if (pRL == NULL) {
+            Boks.dMaxAust = (double)LONG_MAX;
+            if (fwrite(&Boks,sizeof (LC_BOKS),1,pF) != 1) {
+               LC_Error(112,"(LI_Close)","");
+               exit(99);
+            }
+
+         } else {
+            if (fwrite(&(pRL->Boks),sizeof (LC_BOKS),1,pF) != 1) {
+               LC_Error(112,"(LI_Close)","");
+               exit(99);
+            }
+         }
+		}
+      fclose(pF);
+
+      /* Lagre adm. blokken */
+      LI_SaveAdm(pFil);
+
+   } else {
+      /* Fjern indeks filene */
+      LC_DelIdx(pFil->pszNavn);
+   }
+
+   /*
+	 *  Frigi overordnet struktur for indekstabeller
+    */
+   LI_FrigiIdx(pFil);
+
+}
+
+
+/*
+AR-910929
+CH LI_OpenIdxFil                                              �pne indeksfil
+CD ==========================================================================
+CD Form�l:
+CD �pner indeksfil p� rett katalog
+CD
+CD Parametre:
+CD Type        Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM  *pFil     i    Peker til FilAdm
+CD const char *pszNavn  i    Filnavn
+CD const char *pszType  i    Filtype
+CD
+CD Bruk:
+CD pF = LI_OpenIdxFil(pFil,"Adm",".Idx");
+   ==========================================================================
+*/
+static FILE *LI_OpenIdxFil(LC_FILADM *pFil, const char *pszNavn, const char *pszType)
+{
+   short ierr;
+   char fil[_MAX_PATH];
+   char drive1[_MAX_DRIVE],dir1[_MAX_DIR],fname1[_MAX_FNAME],ext1[_MAX_EXT];
+   char drive2[_MAX_DRIVE],dir2[_MAX_DIR],fname2[_MAX_FNAME],ext2[_MAX_EXT];
+
+   FILE *pF;
+
+   // ----- Bygg opp fullt filnavn til filen
+   //  Splitt SOSI-filnavnet
+   UT_splitpath(pFil->pszNavn,drive1,dir1,fname1,ext1);
+
+   // Gitt sti for indeksfilene
+   if ( *Sys.szIdxPath != 0) {
+      UT_splitpath(Sys.szIdxPath,drive2,dir2,fname2,ext2);
+      UT_StrCat(dir2,fname1,_MAX_DIR);
+      UT_StrCat(dir2,UT_STR_SLASH,_MAX_DIR);
+      // Bygg opp filnavn
+      UT_makepath(fil,drive2,dir2,pszNavn,pszType);
+
+   } else {
+      UT_StrCat(dir1,fname1,_MAX_DIR);
+      UT_StrCat(dir1,UT_STR_SLASH,_MAX_DIR);
+      // Bygg opp filnavn
+      UT_makepath(fil,drive1,dir1,pszNavn,pszType);
+   }
+
+	// �ner filen
+   pF = UT_OpenFile(fil,"",UT_UPDATE,UT_UNKNOWN,&ierr);
+   if (ierr != UT_OK){
+      char szError[256];
+      UT_strerror(szError,256,ierr);
+      UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",fil,szError);
+      LC_Error(6,"(LI_OpenIdxFil)",err().tx);
+      exit(2);
+   }
+
+   /* Posisjoner hvis n�dvendig */
+   //fseek(pF,0L,SEEK_SET);   // OBS!  Er denne n�dvendig? AR:2004-05-14  Fjernet
+
+   return pF;
+}
+
+
+/*
+AR-910929
+CH LI_OpenAdm                                     �pne og posisjoner, Adm
+CD ==========================================================================
+CD Form�l:
+CD Sjekker at rett Adm-fil er �pen, og posisjoner
+CD
+CD Parametre:
+CD Type       Navn  I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil   i    Peker til FilAdm
+CD
+CD Bruk:
+CD pF = LI_OpenAdm(pFil);
+   ==========================================================================
+*/
+static FILE *LI_OpenAdm(LC_FILADM *pFil)
+{
+   FILE *fi = LI_OpenIdxFil(pFil,"Adm",".Idx");
+   fseek(fi,0L,SEEK_SET);
+
+   return fi;
+}
+
+
+/*
+AR-910929
+CH LI_OpenGrt                                     �pne og posisjoner, Grt
+CD ==========================================================================
+CD Form�l:
+CD Sjekker at rett Grt-fil er �pen, og posisjoner
+CD
+CD Parametre:
+CD Type       Navn  I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil   i    Peker til FilAdm
+CD
+CD Bruk:
+CD pF = LI_OpenGrt(pFil);
+   ==========================================================================
+*/
+static FILE *LI_OpenGrt(LC_FILADM *pFil)
+{
+   FILE *fi = LI_OpenIdxFil(pFil,"Grt",".Idx");
+   fseek(fi,0L,SEEK_SET);
+
+   return fi;
+}
+
+
+/*
+AR-910929
+CH LI_OpenGeo                                     �pne og posisjoner, Geo
+CD ==========================================================================
+CD Form�l:
+CD Sjekker at rett Geo-fil er �pen, og posisjoner
+CD
+CD Parametre:
+CD Type       Navn  I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil   i    Peker til FilAdm
+CD
+CD Bruk:
+CD pF = LI_OpenGeo(pFil);
+   ==========================================================================
+*/
+static FILE *LI_OpenGeo(LC_FILADM *pFil)
+{
+   FILE *fi = LI_OpenIdxFil(pFil,"Geo",".Idx");
+   fseek(fi,0L,SEEK_SET);
+
+   return fi;
+}
+
+
+/*
+AR-910929
+CH LI_OpenSnr                                     �pne og posisjoner, Snr
+CD ==========================================================================
+CD Form�l:
+CD Sjekker at rett Snr-fil er �pen, og posisjoner
+CD
+CD Parametre:
+CD Type       Navn  I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil   i    Peker til FilAdm
+CD
+CD Bruk:
+CD pF = LI_OpenSnr(pFil);
+   ==========================================================================
+*/
+static FILE *LI_OpenSnr(LC_FILADM *pFil)
+{
+   FILE *fi = LI_OpenIdxFil(pFil,"Snr",".Idx");
+   fseek(fi,0L,SEEK_SET);
+
+   return fi;
+}
+
+
+/*
+AR-910929
+CH LI_OpenBt                                     �pne og posisjoner, Bt
+CD ==========================================================================
+CD Form�l:
+CD �pne Bt-fil, og posisjoner
+CD
+CD Parametre:
+CD Type       Navn  I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil   i    Peker til FilAdm
+CD
+CD Bruk:
+CD pF = LI_OpenBt(pFil);
+   ==========================================================================
+*/
+static FILE *LI_OpenBt(LC_FILADM *pFil)
+{
+   FILE *fi = LI_OpenIdxFil(pFil,"Bt",".Idx");
+   fseek(fi,0L,SEEK_SET);
+
+   return fi;
+}
+
+
+/*
+AR-930810
+CH LI_GetGeo                                                   Get geo-linje
+CD ==========================================================================
+CD Form�l:
+CD Henter en linje fra geografisk s�ketabell.
+CD
+CD Parametre:
+CD Type          Navn  I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM    *pFil   i    Peker til FilAdm
+CD long          linje  i    Linjenummer i geo-tabellen (gruppenummer)
+CD LC_GEOTABELL *geop   r    Peker til geo-tabell-struktur
+CD
+CD Bruk:
+CD geop = LI_GetGeo(pFil,linje);
+   ==========================================================================
+*/
+LC_R_LEAF * LI_GetGeo(LC_FILADM *pFil,long linje)
+{
+   LC_GRTAB_LINJE * pGT;
+
+   pGT = LI_GetGrt(pFil,linje);
+
+   return pGT->pRL; /* Peker til element s�ketreet */
+}
+
+
+/*
+AR-930810
+CH LI_GetSnr                                                   Get snr-linje
+CD ==========================================================================
+CD Form�l:
+CD Henter en linje fra serienummer-tabellen.
+CD
+CD Parametre:
+CD Type             Navn  I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM       *pFil   i    Peker til FilAdm
+CD long             lSnr   i    Serienummer
+CD long             lGrNr  r    Gruppenummer
+CD
+CD Bruk:
+CD lGrNr = LI_GetSnr(pFil,lSnr);
+   ==========================================================================
+*/
+long LI_GetSnr(LC_FILADM *pFil,long lSnr)
+{
+   long **pplGrNr;
+
+   if (pFil->pIdx != NULL) {
+      /* Lovlig serienummer? */
+      if (lSnr <= pFil->lMaxSnr) {
+         /* Finner starten av aktuell blokk */
+			pplGrNr = pFil->pIdx->SnrAdm + (lSnr / LC_IDX_LIN_BLOKK);
+         /* Er denne blokken brukt? */
+         if (*pplGrNr != NULL) {
+            /* Hent aktuell linje i denne blokken */
+            return  *(*pplGrNr + (lSnr % LC_IDX_LIN_BLOKK));
+         }
+      }
+   }
+
+   return  INGEN_GRUPPE;
+}
+
+
+/*
+AR-930810
+CH LI_PutSnr                                                   Put snr-linje
+CD ==========================================================================
+CD Form�l:
+CD Legger inn en linje i serienummer-tabellen.
+CD
+CD Parametre:
+CD Type          Navn  I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM    *pFil   i    Peker til FilAdm
+CD long          lSnr   i    Serienummer
+CD long          lGrNr  i    Gruppenummer
+CD
+CD Bruk:
+CD LI_PutSnr(pFil,lSnr,lGrNr);
+   ==========================================================================
+*/
+void LI_PutSnr(LC_FILADM *pFil,long lSnr,long lGrNr)
+{
+   long **pplGrNr,*pL;
+   int antall;
+
+	if (pFil->pBase->sType == LC_BASE) {
+      if (pFil->pIdx != NULL) {
+         if (lSnr < LC_MAX_GRU) {
+            /* Finner starten av aktuell blokk */
+            pplGrNr = pFil->pIdx->SnrAdm + (lSnr / LC_IDX_LIN_BLOKK);
+
+            /* Blokken finnes ikke, lag ny blokk */ 
+				if (*pplGrNr == NULL)
+				{
+					*pplGrNr = (long *) UT_MALLOC(sizeof(long)*LC_IDX_LIN_BLOKK);
+
+               for (pL=*pplGrNr,antall=0; antall<LC_IDX_LIN_BLOKK; pL++,antall++) {
+						*pL = INGEN_GRUPPE;
+					}
+				}
+
+            /* Legg inn aktuell linje i blokken */
+            *(*pplGrNr + (lSnr % LC_IDX_LIN_BLOKK)) = lGrNr;
+
+         } else {
+				UT_SNPRINTF(err().tx,LC_ERR_LEN,"%ld",lSnr);
+            LC_Error(61,"(LI_PutSnr): ",err().tx);
+            exit(99);
+         }
+
+      } else {
+         LC_Error(75,"(LI_PutSnr): ","");
+         exit(99);
+      }
+   }
+}
+
+
+/*
+AR-930810
+CH LI_GetGrt                                                   Get grt-linje
+CD ==========================================================================
+CD Form�l:
+CD Henter en linje fra gruppetabellen. 
+CD
+CD Parametre:
+CD Type            Navn  I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM      *pFil   i   Peker til FilAdm
+CD long            linje  i   Linjenummer i grt-tabellen (gruppenummer)
+CD LC_GRTAB_LINJE *grtp   r   Peker til grt-tabell-linje
+CD
+CD Bruk:
+CD grtp = LI_GetGrt(pFil,linje);
+   ==========================================================================
+*/
+LC_GRTAB_LINJE * LI_GetGrt(LC_FILADM *pFil,long linje)
+{
+   LC_GRTAB_LINJE * *ppGt;
+
+   if (pFil->pIdx != NULL) {
+		/* Finner starten av aktuell blokk */
+      ppGt = pFil->pIdx->GtAdm + (linje / LC_IDX_LIN_BLOKK);
+      /* Er denne blokken brukt? */
+      if (*ppGt != NULL) {
+         /* Hent aktuell linje i denne blokken */
+         return  (*ppGt + (linje % LC_IDX_LIN_BLOKK));
+      }
+   }
+
+   UT_SNPRINTF(err().tx,LC_ERR_LEN," %s : %ld",pFil->pszNavn,linje);
+   LC_Error(111,"(LI_GetGrt): ",err().tx);
+   exit(99);
+
+   return  NULL;
+}
+
+
+/*
+AR-930810
+CH LI_AppGrt                                                    Ny grt-linje
+CD ==========================================================================
+CD Form�l:
+CD Legger inn en NY linje i gruppetabell.
+CD
+CD Parametre:
+CD Type          Navn  I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM    *pFil   i    Peker til FilAdm
+CD long          linje  i    Linjenummer i grt-tabellen (gruppenummer)
+CD LC_GEOTABELL *grtp   r    Peker til grt-tabell-struktur
+CD
+CD Bruk:
+CD pgrt = LI_AppGrt(pFil,linje,geop);
+   ==========================================================================
+*/
+LC_GRTAB_LINJE * LI_AppGrt(LC_FILADM *pFil,long linje)
+{
+   LC_GRTAB_LINJE * *ppGt;
+
+   if (pFil->pIdx != NULL) {
+      /* Finner starten av aktuell blokk */
+      ppGt = pFil->pIdx->GtAdm + (linje / LC_IDX_LIN_BLOKK);
+      if (*ppGt == NULL) {
+			/* Blokken finnes ikke, lag ny blokk */
+			*ppGt = (LC_GRTAB_LINJE *)UT_MALLOC(sizeof(LC_GRTAB_LINJE)*LC_IDX_LIN_BLOKK);
+			memset(*ppGt,'\0',sizeof(LC_GRTAB_LINJE)*LC_IDX_LIN_BLOKK);
+		}
+
+		/* Finn aktuell linje i blokken */
+      return  (*ppGt + (linje % LC_IDX_LIN_BLOKK));    /* Funnet ===> */
+
+   } else {
+      LC_Error(75,"(LI_PutGrt): ",err().tx);
+      exit(99);
+   }
+
+   return  NULL;
+}
+
+
+/*
+AR-930810
+CH LI_GetBt                                                     Get bt-linje
+CD ==========================================================================
+CD Form�l:
+CD Henter en linje fra brukt-tabellen.
+CD
+CD Parametre:
+CD Type          Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM    *pFil     i    Peker til FilAdm
+CD long          linje    i    Linjenummer i bt-tabellen (gruppenummer)
+CD unsigned long bt_val   r    Hentet bit-m�nster
+CD
+CD Bruk:
+CD bt_val = LI_GetBt(pFil,linje);
+   ==========================================================================
+*/
+unsigned long LI_GetBt(LC_FILADM *pFil,long linje)
+{
+   unsigned long **ppulFlag;
+
+   if (pFil->pIdx != NULL) {
+      /* Finner starten av aktuell blokk */
+      ppulFlag = pFil->pIdx->BtAdm + (linje / LC_IDX_LIN_BLOKK);
+      /* Er denne blokken brukt? */
+      if (*ppulFlag != NULL) {
+         /* Hent aktuell linje i denne blokken */
+         return  *(*ppulFlag + (linje % LC_IDX_LIN_BLOKK));
+      }
+   }
+
+   UT_SNPRINTF(err().tx,LC_ERR_LEN," %s : %ld",pFil->pszNavn,linje);
+   LC_Error(111,"(LI_GetBt): ",err().tx);
+   exit(99);
+
+   return  0L;
+}
+
+
+/*
+AR-930810
+CH LI_PutBt                                                     Put bt-linje
+CD ==========================================================================
+CD Form�l:
+CD Legger inn en linje i brukt-tabell.
+CD
+CD Parametre:
+CD Type              Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil   i    Peker til FilAdm
+CD long              linje     i    Linjenummer i bt-tabellen (gruppenummer)
+CD unsigned long     bt_val    i    Bit m�nster som skal lagres
+CD
+CD Bruk:
+CD LI_PutBt(pFil,linje,bt_val);
+   ==========================================================================
+*/
+void LI_PutBt(LC_FILADM *pFil,long linje,unsigned long bt_val)
+{
+   unsigned long **ppulFlag;
+
+   if (pFil->pIdx != NULL) {
+      /* Finner starten av aktuell blokk */
+      ppulFlag = pFil->pIdx->BtAdm + (linje / LC_IDX_LIN_BLOKK);
+
+      /* Blokken finnes ikke, lag ny blokk */ 
+		if (*ppulFlag == NULL)
+		{
+			*ppulFlag =	(unsigned long *) UT_MALLOC(sizeof(unsigned long)*LC_IDX_LIN_BLOKK);
+			memset(*ppulFlag,'\0',sizeof(unsigned long)*LC_IDX_LIN_BLOKK);
+		}
+
+      /* Legg inn aktuell linje i blokken */
+      *(*ppulFlag + (linje % LC_IDX_LIN_BLOKK)) = bt_val;
+
+   } else {
+      LC_Error(75,"(LI_PutBt): ",err().tx);
+      exit(99);
+   }
+}
+
+
+/*
+AR-881123
+CH LC_SetBt                                       Sett merke i brukttabellen
+CD ==========================================================================
+CD Form�l:
+CD Legg inn merke i brukttabellen.
+CD
+CD Parametre:
+CD Type    Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR * pGr       i    Gruppenummer
+CD short   kolonne   i    Kolonne som skal merkes.
+CD                        (Lovlig BT_MIN_USER - BT_MAX_USER)
+CD
+CD Bruk:
+CD LC_SetBt(pGr,kolonne);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_SetBt(LC_BGR * pGr,short kolonne)
+{
+   /* LO_TestFilpeker(pGr->pFil,"LC_SetBt"); */
+   LO_TestFilpeker(pGr->pFil,"SetBt");
+
+                                           /* Lovlig gruppe */
+   if (pGr->lNr >= 0L && pGr->lNr < pGr->pFil->lAntGr) {
+                                           /* Lovlig kolonne */
+       if (kolonne >= BT_MIN_USER  &&  kolonne <= BT_MAX_USER) {
+                                           /* Merk */
+           LI_SetBt(pGr->pFil,pGr->lNr,kolonne);
+       }
+
+   } else{                                 /* Ulovlig gruppe */
+      char errtx[50];
+      UT_SNPRINTF(errtx,50," %ld",pGr->lNr);
+      LC_Error(72,"(LC_SetBt)",errtx);
+   }
+}
+
+
+/*
+AR-881123
+CH LC_ClrBt                                      Slett merke i brukttabellen
+CD ==========================================================================
+CD Form�l:
+CD Fjern merke i brukttabellen.
+CD
+CD Parametre:
+CD Navn     Type    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR *  pGr      i    Gruppenummer
+CD kolonne  short    i    Kolonne som skal merkes.
+CD                        (Lovlig BT_MIN_USER - BT_MAX_USER)
+CD
+CD Bruk:
+CD LC_ClrBt(pGr,kolonne);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_ClrBt(LC_BGR * pGr,short kolonne)
+{
+   /* LO_TestFilpeker(pGr->pFil,"LC_ClrBt"); */
+   LO_TestFilpeker(pGr->pFil,"ClrBt");
+
+                                           /* Lovlig gruppe */
+   if (pGr->lNr >= 0L && pGr->lNr < pGr->pFil->lAntGr) {
+                                           /* Lovlig kolonne */
+       if (kolonne >= BT_MIN_USER  &&  kolonne <= BT_MAX_USER) {
+                                           /* Fjern merkingen */
+           LI_ClrBt(pGr->pFil,pGr->lNr,kolonne);
+       }
+
+   } else{                                 /* Ulovlig gruppe */
+      char errtx[50];
+      UT_SNPRINTF(errtx,50," %ld",pGr->lNr);
+      LC_Error(72,"(LC_ClrBt)",errtx);
+   }
+}
+
+
+/*
+AR-881123
+CH LC_GetBt                                       Hent merke i brukttabellen
+CD ==========================================================================
+CD Form�l:
+CD Hent merke i brukttabellen.
+CD
+CD Parametre:
+CD Navn     Type    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR *  pGr      i    Gruppenummer
+CD kolonne  short    i    Kolonne som skal brukes.
+CD                        (Lovlig BT_MIN_BT - BT_MAX_BT)
+CD merke    short    r    UT_FALSE = ikke marka,  UT_TRUE = merka
+CD
+CD Bruk:
+CD merke = LC_GetBt(pGr,kolonne);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetBt(LC_BGR * pGr,short kolonne)
+{
+   /* LO_TestFilpeker(pGr->pFil,"LC_GetBt"); */
+   LO_TestFilpeker(pGr->pFil,"GetBt");
+
+                                           /* Lovlig gruppe */
+   if (pGr->lNr >= 0L && pGr->lNr < pGr->pFil->lAntGr) {
+                                           /* Lovlig kolonne */
+       if (kolonne >= BT_MIN_BT  &&  kolonne <= BT_MAX_BT) {
+                                           /* Returner verdi */
+           return (LI_InqBt(pGr->pFil,pGr->lNr,kolonne));
+       }
+
+   } else{                                 /* Ulovlig gruppe */
+      char errtx[50];
+      UT_SNPRINTF(errtx,50," %ld",pGr->lNr);
+      LC_Error(72,"(LC_GetBt)",errtx);
+   }
+
+   return UT_FALSE;                            /* Retur ved feil */
+}
+
+
+/*
+AR-881123
+CH LC_EraseBt                                   Slett omr�de i brukttabellen
+CD ==========================================================================
+CD Form�l:
+CD Blanker en eller flere kolonner i brukttabellen i aktuell base.
+CD
+CD Parametre:
+CD Navn     Type    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD fra_kol  short    i    F�rste kolonne som skal blankes.
+CD                        (Lovlig BT_MIN_USER - BT_MAX_USER)
+CD til_kol  short    i    Siste kolonne som skall blankes.
+CD                        (Lovlig BT_MIN_USER - BT_MAX_USER)
+CD
+CD Bruk:
+CD LC_EraseBt(fra_kol,til_kol);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_EraseBt(short fra_kol,short til_kol)
+{
+                       /* Beregner lovlige kolonner */
+   fra_kol = max(fra_kol,BT_MIN_USER);
+   til_kol = min(til_kol,BT_MAX_USER);
+
+   LI_EraseBt(fra_kol,til_kol);
+}
+
+
+/*
+AR-891120
+CH LI_SetBt                                       Sett merke i brukttabellen
+CD ==========================================================================
+CD Form�l:
+CD Legg inn merke i brukttabellen.
+CD
+CD Parametre:
+CD Navn     Type    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil   i    Peker til FilAdm
+CD long       lGrNr  i    Gruppenummer
+CD kolonne    short  i    Kolonne som skal merkes.
+CD                        (Lovlig BT_MIN_BT - BT_MAX_BT)
+CD
+CD Bruk:
+CD LI_SetBt(pFil,lGrNr,kolonne);
+   ==========================================================================
+*/
+void LI_SetBt(LC_FILADM *pFil,long lGrNr,short kolonne)
+{
+   LI_PutBt (pFil,lGrNr,LI_GetBt(pFil,lGrNr) | (0x1UL << kolonne));
+}
+
+
+/*
+AR-891120
+CH LI_ClrBt                                      Slett merke i brukttabellen
+CD ==========================================================================
+CD Form�l:
+CD Fjern merke i brukttabellen.
+CD
+CD Parametre:
+CD Type       Navn  I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil   i    Peker til FilAdm
+CD long       lGrNr  i    Gruppenummer
+CD kolonne    short  i    Kolonne som skal merkes.
+CD                        (Lovlig BT_MIN_BT - BT_MAX_BT)
+CD
+CD Bruk:
+CD LI_ClrBt(pFil,lGrNr,kolonne);
+   ==========================================================================
+*/
+void LI_ClrBt(LC_FILADM *pFil,long lGrNr,short kolonne)
+{
+   LI_PutBt(pFil,lGrNr,LI_GetBt(pFil,lGrNr) & (~ (0x1UL << kolonne) ));
+}
+
+
+/*
+AR-910828
+CH LI_InqBt                                       Hent merke i brukttabellen
+CD ==========================================================================
+CD Form�l:
+CD Hent merke i brukttabellen.
+CD
+CD Parametre:
+CD Type       Navn  I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil   i    Peker til FilAdm
+CD long       lGrNr  i    Gruppenummer
+CD kolonne    short  i    Kolonne som skal brukes.
+CD                        (Lovlig BT_MIN_BT - BT_MAX_BT)
+CD merke      short  r    UT_TRUE = marka,  UT_FALSE = ikke merka.
+CD
+CD Bruk:
+CD merke = LI_InqBt(pFil,lGrNr,kolonne);
+   ==========================================================================
+*/
+short LI_InqBt(LC_FILADM *pFil,long lGrNr,short kolonne)
+{
+   return ((LI_GetBt(pFil,lGrNr) & (0x1UL << kolonne)) == 0)?  UT_FALSE : UT_TRUE;
+}
+
+
+/*
+AR-910827
+CH LI_EraseBt                                   Slett omr�de i brukttabellen
+CD ==========================================================================
+CD Form�l:
+CD Blanker en eller flere kolonner i brukttabellen i aktuell base.
+CD
+CD Parametre:
+CD Type   Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD short  fra_kol    i    F�rste kolonne som skal blankes. (Lovlig 0 - BT_MAX_BT)
+CD short  til_kol    i    Siste kolonne som skal blankes. (Lovlig 0 - BT_MAX_BT)
+CD
+CD Bruk:
+CD LI_EraseBt(fra_kol,til_kol);
+   ==========================================================================
+*/
+void LI_EraseBt(short fra_kol,short til_kol)
+{
+   long lNr;
+   unsigned long maske;
+   LC_FILADM *pFil;
+
+                                               /* Beregner lovlige omr�der */
+   fra_kol = max(fra_kol,BT_MIN_BT);
+   til_kol = min(til_kol,BT_MAX_BT);
+
+   maske = 0x0000;                             /* Lager slettemaske */
+   for ( ; fra_kol <= til_kol; fra_kol++){
+       maske |= (0x1UL << fra_kol);   /* Merker bit som skal blankes */
+   }
+   maske = ~ maske;                            /* Inverterer masken */
+
+   /*
+    * Fjerner merkingen
+    */
+   for (pFil=Sys.pAktBase->pForsteFil; pFil != NULL; pFil=pFil->pNesteFil) {
+      for (lNr=0L; lNr<pFil->lAntGr; lNr++) {
+         LI_PutBt(pFil,lNr,(maske & LI_GetBt(pFil,lNr)));
+      }
+   }
+}
+
+
+/*
+AR-910827
+CH LC_CopyBt                                  Kopier kolonne i brukttabellen
+CD ==========================================================================
+CD Form�l:
+CD Kopier kolonne i brukttabellen.
+CD Samtidig er det mulig � utf�re logiske operasjoner mellom de to kolonnene.
+CD
+CD Parametre:
+CD Type   Navn        I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD short  fra_kol      i    Kolonne det skal kopieres fra. (Lovlig 0 - BT_MAX_BT)
+CD short  til_kol      i    Kolonne det skal kopieres til. (Lovlig 1 - BT_MAX_USER)
+CD short  operasjon    i    Logisk operasjon mellom kolonnene.
+CD                           BC_COPY     = Overskriv gammelt innhold.
+CD                           BC_AND      = Logisk AND mellom de to kolonnene.               
+CD                           BC_OR       = Logisk OR mellom de to kolonnene.               
+CD                           BC_INVERT   = Overskriv gammelt innhold med
+CD                                         invertert verdi.
+CD                           BC_EXCHANGE = Bytter innholdet i de to kolonnene.
+CD                                           
+CD Bruk:
+CD LC_CopyBt(fra_kol,til_kol,operasjon);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_CopyBt(short fra_kol,short til_kol,short operasjon)
+{
+   long lNr;
+   unsigned long maske_fra,maske_til;
+   LC_FILADM *pFil = Sys.pAktBase->pForsteFil;
+   unsigned long merke;
+   unsigned long ul;
+
+                                           /* Beregner lovlige omr�der */
+   fra_kol = min(max(fra_kol,0),BT_MAX_BT);
+   til_kol = min(max(til_kol,0),BT_MAX_USER);
+
+                                           /* Returner verdi */
+   maske_fra = 0x00000001UL << fra_kol;
+   maske_til = 0x00000001UL << til_kol;
+
+
+                                           /* G�r gjennom alle grupper */
+   for (; pFil != NULL; pFil=pFil->pNesteFil) {
+      for (lNr=1L; lNr<pFil->lAntGr; lNr++) {
+         merke = LI_GetBt(pFil,lNr);
+         switch (operasjon){
+            case BC_AND:                                        /* AND */
+               if ((merke & maske_fra)  &&  (merke & maske_til)){
+                  merke |= maske_til;             /* Sett */
+               } else{
+                  merke &= ( ~ maske_til);        /* Blank */
+               }
+               break;
+
+            case BC_OR:                                         /* OR */
+               if ((merke & maske_fra)  ||  (merke & maske_til)){
+                  merke |= maske_til;             /* Sett */
+               } else{
+                  merke &= ( ~ maske_til);        /* Blank */
+               }
+               break;
+
+            case BC_INVERT:                    /* INVERT  (Invertert kopi)*/
+               if (merke & maske_fra) {
+                  merke &= ( ~ maske_til);        /* Blank */
+               } else{
+                  merke |= maske_til;             /* Sett */
+               }
+               break;
+
+            case BC_EXCHANGE:                                       /* BYTT */
+               /* Husk innholdet i "til-kolonnen" */
+               ul = merke & maske_til;
+               /* Oppdater "til-kolonnen" */
+               if (merke & maske_fra) {
+                   merke |= maske_til;             /* Sett */
+               } else{
+                   merke &= ( ~ maske_til);        /* Blank */
+               }
+               /* Oppdater "fra-kolonnen" */
+               if (ul) {
+                   merke |= maske_fra;             /* Sett */
+               } else{
+                   merke &= ( ~ maske_fra);        /* Blank */
+               }
+               break;
+
+            default:
+            case BC_COPY:                                       /* COPY */
+               if (merke & maske_fra) {
+                   merke |= maske_til;             /* Sett */
+               } else{
+                   merke &= ( ~ maske_til);        /* Blank */
+               }
+               break;
+         }
+
+            /* Skriv tilbake */
+      LI_PutBt(pFil,lNr,merke);
+      }
+   }
+}
+
+
+/*
+AR-891120
+CH LI_SaveAdm                          Skriv globale variabler til indeksfil
+CD ==========================================================================
+CD Form�l:
+CD Skriver globale variabler til indeksfilen.
+CD
+CD Parametre:
+CD Type   Navn        I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil   i    Peker til FilAdm
+CD
+CD Bruk:
+CD LI_SaveAdm(pFil);
+   ==========================================================================
+*/
+void LI_SaveAdm(LC_FILADM *pFil)
+{
+   UT_INT64 Size;
+   FTID FilTid;
+   FILE *pF;
+
+   /* �pner Adm-fil, og posisjonerer */
+   pF = LI_OpenAdm(pFil);
+
+   /* Filst�rrelse for SOSI-filen */
+   UT_InqPathSize_i64(pFil->pszNavn,&Size);
+   pFil->SosiBytes = Size;
+
+   /* Oppdateringstid for SOSI-filen */
+   UT_InqPathTid(pFil->pszNavn,&FilTid);
+   pFil->SosiTid.usAar  = FilTid.usAar;
+   pFil->SosiTid.usMnd  = FilTid.usMnd;
+   pFil->SosiTid.usDag  = FilTid.usDag;
+   pFil->SosiTid.usTime = FilTid.usTime;
+   pFil->SosiTid.usMin  = FilTid.usMin;
+   pFil->SosiTid.usSek  = FilTid.usSek;
+
+
+   pFil->sIdxOpen = UT_FALSE;
+   pFil->ulPid = 0;
+   if (fwrite(pFil,sizeof(*pFil),1,pF) != 1) {
+      LC_Error(112,"(LI_SaveAdm)","");
+      exit(99);
+   }
+
+   fclose(pF);
+}
+
+
+/*
+AR-891120
+CH LI_ReadAdm                            Les globale variabler fra indeksfil
+CD ==========================================================================
+CD Form�l:
+CD �pner Adm-filen, og henter "globale" variabler fra indeksfilen.
+CD
+CD Parametre: ingen
+CD Type       Navn   I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil    i    Peker til FilAdm
+CD short      status  r    Status:
+CD                         UT_OK (0): Lest OK
+CD                         LI_LESEFEIL: Feil ved lesing av 
+CD                         LI_OPPTATT: Filen er �pen i et annet program
+CD                         LI_FEIL_INDEKSVERSJON: Feil indeksversjon
+CD                         LI_FEIL_STORRELSE: Feil st�rrelse p� SOSI-filen
+CD                         LI_FEIL_OPPDATTID: Feil oppdateringstid p� SOSI-filen
+CD
+CD Bruk:
+CD sStatus = LI_ReadAdm(pFil);
+   ==========================================================================
+*/
+static short LI_ReadAdm(LC_FILADM *pFil)
+{
+   unsigned short  usLag;
+   FTID SosiTid;
+   UT_INT64 SosiSize;
+   short  sAccess;         
+   short sTegnsett;
+   char  *pszNavn;
+   LC_IDX_TABELL *pIdx;
+   LC_FILADM *pNesteFil;
+   LC_BASEADM *pBase;   
+   FILE *pF;
+   LC_R_NODE *pGeoRN;
+   short  sStatus = UT_OK;         
+
+
+   /* �pner Adm-fil, og posisjonerer */
+   pF = LI_OpenAdm(pFil);
+
+   /* Tar vare p� div. adm som ikke m� bli overskrevet av adm fra filen */
+   pszNavn   = pFil->pszNavn;
+   sAccess   = pFil->sAccess;
+   usLag     = pFil->usLag;
+   pBase     = pFil->pBase;
+   pIdx      = pFil->pIdx;
+   pGeoRN    = pFil->pGeoRN;
+   pNesteFil = pFil->pNesteFil;
+   pBase     = pFil->pBase;
+   sTegnsett = pFil->sTegnsett;
+
+   /* Hent div. opplysninger om SOSI-filen */
+   UT_InqPathSize_i64(pszNavn,&SosiSize);
+   UT_InqPathTid(pszNavn,&SosiTid);
+
+   /* Leser adm */
+   if (fread(pFil,sizeof(*pFil),1,pF) != 1)
+   {
+      /* printf("\nFeil lengde lest."); */
+      sStatus = LI_LESEFEIL;
+   }
+   
+   // lest OK
+   else
+   { 
+      /*
+      // Sjekk om filen er �pen i et annet program
+      if (pFil->sIdxOpen == UT_TRUE)
+      {
+         // Sjekk om dette programmet er aktivt n�, eller om det har krasjet
+         // (ulPid er prosessID for programmet som �pnet filen)
+         if (pFil->ulPid != 0)
+         {
+            HANDLE hProgram = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, pFil->ulPid );
+            if (hProgram != NULL)
+            {
+               // Programmet finnes / er aktivt n�
+               CloseHandle(hProgram);
+               // printf("\nFilen er �pen i et annet program.");
+               sStatus = LI_OPPTATT;
+            }
+         }
+      }
+      */
+
+      // Ikke �pen i annet program som er aktivt n�
+      if (sStatus == UT_OK)
+      {
+         /* Sjekk versjonsnummer */
+         if (strcmp(FYBA_INDEKS_VERSJON,pFil->szIdxVer) != 0) {
+            /* printf("\nFeil indeksversjon"); */
+            sStatus = LI_FEIL_INDEKSVERSJON;
+
+         /* Sjekk st�rrelse for SOSI-filen */
+         } else if (pFil->SosiBytes != SosiSize) {
+            /* printf("\nFeil st�rrelse p� SOSI-filen."); */
+            sStatus = LI_FEIL_STORRELSE;
+
+         /* Sjekk oppdateringstid for SOSI-filen */
+         } else if (memcmp(&pFil->SosiTid,&SosiTid,sizeof(FTID)) != 0) {
+            /* printf("\nFeil oppdateringstid"); */
+            sStatus = LI_FEIL_OPPDATTID;
+         }
+      }
+   }
+
+   /* Legg inn igjen diverse  adm. */
+   pFil->pszNavn   = pszNavn;
+   pFil->sAccess   = sAccess;
+   pFil->usLag     = usLag;
+   pFil->pBase     = pBase;
+   pFil->pIdx      = pIdx;
+   pFil->pGeoRN    = pGeoRN;
+   pFil->pNesteFil = pNesteFil;
+   pFil->pBase     = pBase;
+   pFil->sTegnsett = sTegnsett;
+   UT_StrCopy(pFil->szBaseVer,FYBA_IDENT,LC_BASEVER_LEN);
+   UT_StrCopy(pFil->szIdxVer,FYBA_INDEKS_VERSJON,5);
+      
+
+   // Retur hvis feil
+   if (sStatus != UT_OK)
+   {
+      fclose(pF);
+      return sStatus;
+   }
+
+   // Marker at basen er �pnet
+   pFil->sIdxOpen = UT_TRUE;
+   pFil->ulPid = getpid();
+
+   // Skriv
+   fseek(pF,0L,SEEK_SET);
+   if (fwrite(pFil,sizeof(*pFil),1,pF) != 1) 
+   {
+      LC_Error(112,"(LI_ReadAdm)","");
+      exit(99);
+   }
+
+   // Stenger filen
+   fclose(pF);
+
+   return sStatus;
+}
+
+
+/*
+AR-930824
+CH LI_WriteRb                                     Skriv gruppe til bufferfil
+CD ==========================================================================
+CD Form�l:
+CD Skriv gruppe fra buffer i minne til buffer-fil.
+CD
+CD Parametre:
+CD Type            Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM      *pFil      i    Peker til FilAdm
+CD UT_INT64        n64FilPos i    Startposisjon i buffer-filen.
+CD char           *pszGi     iu   Ginfo-buffer
+CD unsigned long   ulGiLen   i    Ant tegn som skal skrives
+CD double         *pdAust    iu   Koord
+CD double         *pdNord    iu   Koord
+CD LB_INFO *        pInfo     iu   H�yde, KP og PINFO-ofsett
+CD long            lNko      i    Ant koord
+CD char           *pszPi     iu   Pinfo-buffer
+CD unsigned long   ulPiLen   i    Ant tegn som skal skrives
+CD
+CD Bruk:
+CD LI_WriteRb(pFil,lFilPos,Sys.Ginfo.pszTx,Sys.pGrInfo->ulGiLen,
+CD            Sys.pdAust, Sys.pdNord, Sys.pInfo, Sys.pGrInfo->nko,
+CD            Sys.pszPinfo, Sys.pGrInfo->ulPiLen);
+   ==========================================================================
+*/
+void LI_WriteRb(LC_FILADM *pFil, UT_INT64 n64FilPos,
+                char *pszGi, unsigned long ulGiLen,
+                double *pdAust, double *pdNord,
+                LB_INFO * pInfo, long lNko,
+                char *pszPi, unsigned long ulPiLen)
+{
+   short sSkrivefeil = UT_FALSE;
+   FILE *pF;
+
+   /* �pner RB-fil, og posisjonerer */
+   LI_OpenRb(pFil,n64FilPos,SKRIV);
+   pF = pFil->pBase->pfRb;
+
+   /* GINFO */
+   if (ulGiLen > 0) {
+      if (fwrite(pszGi,(sizeof(char))*ulGiLen,1,pF) != 1) {
+         sSkrivefeil = UT_TRUE;
+      }
+   }
+
+   if (lNko > 0) {
+      /* �st koordinat */
+      if (fwrite(pdAust,(sizeof(double))*lNko,1,pF) != 1) {
+         sSkrivefeil = UT_TRUE;
+      }
+
+      /* Nord koordinat */
+      if (fwrite(pdNord,(sizeof(double))*lNko,1,pF) != 1) {
+         sSkrivefeil = UT_TRUE;
+      }
+
+      /* H�yde, KP mm. */
+      if (fwrite(pInfo,(sizeof(LB_INFO)) * lNko,1,pF) != 1) {
+         sSkrivefeil = UT_TRUE;
+      }
+
+      /* PINFO */
+      if (ulPiLen > 0) {
+         if (fwrite(pszPi,(sizeof(char))*ulPiLen,1,pF) != 1) {
+            sSkrivefeil = UT_TRUE;
+         }
+      }
+   }
+
+   if (sSkrivefeil == UT_TRUE) {
+      UT_SNPRINTF(err().tx,LC_ERR_LEN," %s : %lld",pFil->pszNavn,n64FilPos);
+      LC_Error(74,"(LI_WriteRb): ",err().tx);
+      exit(99);
+   }
+
+   pFil->pBase->n64FilPosRb = _ftelli64(pF);
+}
+
+
+/*
+AR-930823
+CH LI_ReadRb                                       Les gruppe fra buffer-fil
+CD ==========================================================================
+CD Form�l:
+CD Les gruppe fra buffer-fil til buffer i minne.
+CD
+CD Parametre:
+CD Type            Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM      *pFil      i    Peker til FilAdm for filen det skal leses fra.
+CD UT_INT64        n64FilPos i    Startposisjon i buffer-filen.
+CD char           *pszGi     iu   Ginfo-buffer
+CD unsigned long   ulGiLen   i    Ant tegn som skal leses til buffer
+CD double         *pdAust    iu   Koord
+CD double         *pdNord    iu   Koord
+CD LB_INFO *        pInfo     iu   H�yde, KP og PINFO-ofsett
+CD long            lNko      i    Ant koord
+CD char           *pszPi     iu   Pinfo-buffer
+CD unsigned long   ulPiLen   i    Ant tegn som skal leses til buffer
+CD
+CD Bruk:
+CD LI_ReadRb(pFil,lFilPos,Sys.Ginfo.pszTx,Sys.pGrInfo->ulGiLen,
+CD           Sys.pdAust, Sys.pdNord, Sys.pInfo, Sys.pGrInfo->nko,
+CD           Sys.pszPinfo, Sys.pGrInfo->ulPiLen);
+   ==========================================================================
+*/
+void LI_ReadRb(LC_FILADM *pFil, UT_INT64 n64FilPos,
+               char *pszGi, unsigned long ulGiLen,
+               double *pdAust, double *pdNord,
+               LB_INFO * pInfo, long lNko,
+               char *pszPi, unsigned long ulPiLen)
+{
+   short sLesefeil = UT_FALSE;
+   FILE *pF;
+
+   /* �pner RB-fil, og posisjonerer */
+   LI_OpenRb(pFil,n64FilPos,LES);
+   pF = pFil->pBase->pfRb;
+
+   /* Leser GINFO */
+   if (ulGiLen > 0) {
+      if (fread(pszGi,(sizeof(char))*ulGiLen,1,pF) != 1) {
+         sLesefeil = UT_TRUE;
+      }
+      // AR:2004-05-14 - Test
+      /*
+      int antall = fread(pszGi,(sizeof(char))*ulGiLen,1,pF);
+      if (antall != 1) {
+         sLesefeil = UT_TRUE;
+         // Bygger streng for feilvisning
+         char szError[256];
+         strerror_s(szError,256,errno);
+         UT_SNPRINTF(err().tx,LC_ERR_LEN,"%s",szError);
+         if (feof(pF)) {
+            UT_SNPRINTF(err().tx,LC_ERR_LEN,"Filslutt");
+         }
+      }
+      */
+   }
+
+   if (lNko > 0) {
+      /* Leser �st koordinat */
+      if (fread(pdAust,(sizeof(double))*lNko,1,pF) != 1) {
+         sLesefeil = UT_TRUE;
+      }
+
+      /* Leser nord koordinat */
+      if (fread(pdNord,(sizeof(double))*lNko,1,pF) != 1) {
+         sLesefeil = UT_TRUE;
+      }
+
+      /* Leser h�yde, KP mm. */
+      if (fread(pInfo,(sizeof(LB_INFO)) * lNko,1,pF) != 1) {
+         sLesefeil = UT_TRUE;
+      }
+
+      /* Leser PINFO */
+      if (ulPiLen > 0) {
+         if (fread(pszPi,(sizeof(char))*ulPiLen,1,pF) != 1) {
+            sLesefeil = UT_TRUE;
+         }
+      }
+   }
+
+   if (sLesefeil == UT_TRUE) {
+      UT_SNPRINTF(err().tx,LC_ERR_LEN," %s : %lld",pFil->pszNavn,n64FilPos);
+
+      LC_Error(73,"(LI_ReadRb): ",err().tx);
+      exit(99);
+   }
+
+   pFil->pBase->n64FilPosRb = _ftelli64(pF);
+}
+
+
+/*
+AR-930825
+CH LI_ReadCoordRb                            Les koordinater fra buffer-fil
+CD ==========================================================================
+CD Form�l:
+CD Les koordinatene for en gruppe fra buffer-fil til buffer i minne.
+CD
+CD Parametre:
+CD Type            Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM      *pFil      i    Peker til FilAdm for filen det skal leses fra.
+CD UT_INT64        n64FilPos i    Startposisjon for gruppen i buffer-filen.
+CD unsigned long   ulGiLen   i    Ant tegn GINFO
+CD double         *pdAust    iu   Koord
+CD double         *pdNord    iu   Koord
+CD LB_INFO *        pInfo     iu   H�yde, KP og PINFO-ofsett
+CD long            lNko      i    Ant koord
+CD char           *pszPi     iu   Pinfo-buffer
+CD unsigned long   ulPiLen   i    Ant tegn som skal leses til buffer
+CD
+CD Bruk:
+CD LI_ReadCoordRb(pFil,lFilPos,Sys.pGrInfo->ulGiLen,
+CD           Sys.pdAust, Sys.pdNord, Sys.pInfo, Sys.pGrInfo->nko,
+CD           Sys.pszPinfo, Sys.pGrInfo->ulPiLen);
+   ==========================================================================
+*/
+void LI_ReadCoordRb(LC_FILADM *pFil, UT_INT64 n64FilPos, unsigned long ulGiLen,
+               double *pdAust, double *pdNord,
+               LB_INFO * pInfo, long lNko,
+               char *pszPi, unsigned long ulPiLen)
+{
+   short sLesefeil = UT_FALSE;
+   FILE *pF;
+
+   /* �pner RB-fil, og posisjonerer */
+   LI_OpenRb(pFil,n64FilPos+(UT_INT64)ulGiLen,LES);
+   pF = pFil->pBase->pfRb;
+
+   if (lNko > 0) {
+      /* Leser �st koordinat */
+      if (fread(pdAust,(sizeof(double))*lNko,1,pF) != 1) {
+         sLesefeil = UT_TRUE;
+      }
+
+      /* Leser nord koordinat */
+      if (fread(pdNord,(sizeof(double))*lNko,1,pF) != 1) {
+         sLesefeil = UT_TRUE;
+      }
+
+      /* Leser h�yde, KP mm. */
+      if (fread(pInfo,(sizeof(LB_INFO))*lNko,1,pF) != 1) {
+         sLesefeil = UT_TRUE;
+      }
+
+      /* Leser PINFO */
+      if (ulPiLen > 0) {
+         if (fread(pszPi,(sizeof(char))*ulPiLen,1,pF) != 1) {
+            sLesefeil = UT_TRUE;
+         }
+      }
+   }
+
+   if (sLesefeil == UT_TRUE) {
+      UT_SNPRINTF(err().tx,LC_ERR_LEN," %s : %lld",pFil->pszNavn,n64FilPos);
+      LC_Error(73,"(LI_ReadCoordRb): ",err().tx);
+      exit(99);
+   }
+
+   pFil->pBase->n64FilPosRb = _ftelli64(pF);
+}
+
+
+
+/*
+AR-930823
+CH LI_BerBufferLen                                      Beregn bufferlengde
+CD ==========================================================================
+CD Form�l:
+CD Beregn n�dvendig plass for � skrive gitt gruppe til RB.
+CD
+CD Parametre:
+CD Type            Navn   I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD unsigned long   ulGiLen i    Ant tegn som skal leses til buffer
+CD long            lNko    i    Ant koord
+CD unsigned long   ulPiLen i    Ant tegn som skal leses til buffer
+CD long            lLen    r    Ant byte for � lagre gruppen
+CD
+CD Bruk:
+CD lLen = LI_BerBufferLen(Sys.pGrInfo->ulGiLen,Sys.pGrInfo->nko,
+CD                        Sys.pGrInfo->ulPiLen);
+   ==========================================================================
+*/
+long LI_BerBufferLen(unsigned long ulGiLen,long lNko,unsigned long ulPiLen)
+{
+            /* GINFO */
+            /* Koordinat � og N */
+            /* H�yde, KP og PINFO-ofsett */
+            /* PINFO */
+   return  ((long)sizeof(char) * (long)ulGiLen) +
+           (2L * (long)sizeof(double) * lNko) +
+           ((long)sizeof(LB_INFO) * lNko) +
+           ((long)sizeof(char) * (long)ulPiLen);
+
+
+#ifdef TEST
+   long lLen;
+
+   /* GINFO */
+   lLen = (sizeof(char)) * ulGiLen;
+
+   /* Koordinat � og N */
+   lLen += 2L * (sizeof(double)) * lNko;
+
+   /* H�yde, KP og PINFO-ofsett */
+   lLen += (sizeof(LB_INFO)) * lNko;
+
+   /* PINFO */
+   lLen += (sizeof(char)) * ulPiLen;
+
+   return lLen;
+#endif
+}
+
+
+/*
+AR-910929
+CH LI_OpenRb                                         �pne og posisjoner, Rb
+CD ==========================================================================
+CD Form�l:
+CD Sjekker at rett Rb-fil er �pen, og posisjoner
+CD
+CD Parametre:
+CD Type       Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil      i    Peker til FilAdm
+CD UT_INT64   n64FilPos i    Filposisjon i byte fra filstart
+CD short      sModus    i    Modus (LES / SKRIV)
+CD
+CD Bruk:
+CD void LI_OpenRb(pFil,lFilPos);
+   ==========================================================================
+*/
+static void LI_OpenRb(LC_FILADM *pFil,UT_INT64 n64FilPos,short sModus)
+{
+   if (pFil->pBase->pCurRb != pFil) {
+      // ----- Feil fil er �pen, stenger denne og �pner rett fil
+
+      // Stenger forrige fil
+      if (pFil->pBase->pCurRb != NULL) {
+         fclose(pFil->pBase->pfRb);
+      }
+
+      // Byggr opp fullt filnavn til Rb-filen og �pner filen
+      pFil->pBase->pfRb = LI_OpenIdxFil(pFil, "Rb", ".Idx");
+
+      // Husk current filnummer
+      pFil->pBase->pCurRb = pFil;
+      pFil->pBase->sModusRb = NY;
+   }
+
+   // Posisjoner hvis n�dvendig
+   if (pFil->pBase->sModusRb == NY  ||  sModus != pFil->pBase->sModusRb  ||  n64FilPos != pFil->pBase->n64FilPosRb) {
+      //_fseeki64(pFil->pBase->pfRb,n64FilPos,SEEK_SET);
+      UT_SetPos_i64(pFil->pBase->pfRb,n64FilPos);
+
+      pFil->pBase->sModusRb = sModus;
+   }
+}
+
+
+
+/*
+AR-930927
+CH LC_SetModusMerk                Setter flag for merking av referert gruppe.
+CD ==========================================================================
+CD Form�l:
+CD Setter flag for merking av referert gruppe.
+CD Har innvirkning for virkem�ten til:
+CD LC_FAGeo, LC_FASn, og LC_FAGiQuery
+CD
+CD Parametre:
+CD Type           Navn   I/U  Forklaring
+CD -----------------------------------------------------------------------
+CD unsigned short modus   i   0 = Ikke merk referert gruppe.
+CD                            1 = Merk referert gruppe.
+CD
+CD Bruk:
+CD LC_SetModusMerk(1);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_SetModusMerk(unsigned short usModus)
+{
+   Sys.usMerkRefGr = usModus;
+}
+
+
+/*
+AR-881123
+CH LC_MerkGr                                    Merk en gruppe brukttabellen
+CD ==========================================================================
+CD Form�l:
+CH Merk aktuell gruppe i brukttabellen. Hvis flag for merking av referert
+CD gruppe er satt, blir ogs� eventuelle refererte grupper merket.
+CD
+CD Parametre:
+CD Type    Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD short   sKolonne   i    Kolonne som skal merkes.
+CD                         (Lovlig BT_MIN_USER - BT_MAX_USER)
+CD short   sBryter    i    Bryter   1=p�, 0=av
+CD long    lAntall    r    Antall grupper merket.
+CD
+CD Bruk:
+CD lAntall = LC_MerkGr(sKolonne,sBryter);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA long LC_MerkGr(short sKolonne,short sBryter)
+{
+   LC_BGR AktBgr,Bgr;
+   long lAntRef;
+   short sGiLin,sRefPos;
+   long l;
+   short ngi;
+   long nko;
+   unsigned short info;
+   long *plRefArr;
+   long lAntall = 0L;
+
+
+   /* Lovlig gruppe */
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {
+      /* Lovlig kolonne */
+      if (sKolonne >= BT_MIN_BT  &&  sKolonne <= BT_MAX_BT) {
+         /* Merk denne gruppen */
+         if (sBryter) {
+            LI_SetBt(Sys.GrId.pFil,Sys.GrId.lNr,sKolonne);
+
+         } else {
+            LI_ClrBt(Sys.GrId.pFil,Sys.GrId.lNr,sKolonne);
+         }
+         lAntall++;
+
+         /* Er det referanser p� gruppen og rekursiv merking er aktivisert? */
+         if ((Sys.pGrInfo->info & GI_REF)  &&  Sys.usMerkRefGr) {
+            /* Husk aktuell gruppe */
+            AktBgr = Sys.GrId;
+
+            /* Hent og merk refererte grupper */
+				lAntRef = LC_InqAntRef();
+				plRefArr = (long *) UT_MALLOC(lAntRef * sizeof(long));
+				sGiLin = 2;
+				sRefPos = 0;
+				LC_GetRef(plRefArr,lAntRef,&sGiLin,&sRefPos);
+				for (l=0; l<lAntRef; l++) {
+               if (plRefArr[l] != START_OY  &&  plRefArr[l] != SLUTT_OY) {
+                  if (LC_FiSn(AktBgr.pFil,labs(plRefArr[l]),&Bgr)) {
+                     LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+                     lAntall += LC_MerkGr(sKolonne,sBryter);
+                  }
+               }
+            }
+				UT_FREE(plRefArr);
+
+            /* Les tilbake aktuell gruppe */
+            LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+         }
+      }
+   }
+
+   return lAntall;
+}
+
+
+/*
+AR-931101
+CH LC_ClrPrioritet                                      Slett prioritets-bit
+CD ==========================================================================
+CD Form�l:
+CD Slett prioritets-bit.
+CD
+CD Parametre:
+CD Navn     Type    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR *  pGr      i    Gruppenummer
+CD kolonne  short    i    Kolonne som skal merkes.
+CD                        (Lovlig 0 til LC_MAX_ANT_PRIOR-1)
+CD
+CD Bruk:
+CD LC_ClrPrioritet(pGr,kolonne);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_ClrPrioritet(LC_BGR * pGr,short kolonne)
+{
+   short s;
+   LC_GRTAB_LINJE * pGrt;
+
+   LO_TestFilpeker(pGr->pFil,"ClrPrioritet");
+
+   /* Lovlig gruppe */
+   if (pGr->lNr >= 0L && pGr->lNr < pGr->pFil->lAntGr) {
+      /* Lovlig kolonne */
+      if (kolonne >= 0  &&  kolonne < LC_MAX_ANT_PRIOR) {
+
+         pGrt = LI_GetGrt(pGr->pFil,pGr->lNr);
+
+         /* Fjern merkingen */
+         s = kolonne / 32;
+         pGrt->ulPrior[s]  &=  (~ (0x1UL << (kolonne % 32)) );
+
+      }
+
+   } else{                                 /* Ulovlig gruppe */
+      char errtx[50];
+      UT_SNPRINTF(errtx,50," %ld",pGr->lNr);
+      LC_Error(72,"(LC_ClrPrioritet)",errtx);
+   }
+}
+
+
+/*
+AR-931101
+CH LC_SetPrioritet                                      Sett prioritets-bit
+CD ==========================================================================
+CD Form�l:
+CD Sett prioritets-bit.
+CD
+CD Parametre:
+CD Navn     Type    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR *  pGr      i    Gruppenummer
+CD kolonne  short    i    Kolonne som skal merkes.
+CD                        (Lovlig 0 til LC_MAX_ANT_PRIOR-1)
+CD
+CD Bruk:
+CD LC_SetPrioritet(pGr,kolonne);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_SetPrioritet(LC_BGR * pGr,short kolonne)
+{
+   short s;
+   LC_GRTAB_LINJE * pGrt;
+
+   LO_TestFilpeker(pGr->pFil,"SetPrioritet");
+
+   /* Lovlig gruppe */
+   if (pGr->lNr >= 0L && pGr->lNr < pGr->pFil->lAntGr) {
+      /* Lovlig kolonne */
+      if (kolonne >= 0  &&  kolonne < LC_MAX_ANT_PRIOR) {
+
+         pGrt = LI_GetGrt(pGr->pFil,pGr->lNr);
+
+         /* Fjern merkingen */
+         s = kolonne / 32;
+         pGrt->ulPrior[s]  |=  (0x1UL << (kolonne % 32));
+      }
+
+   } else {                                 /* Ulovlig gruppe */
+      char errtx[50];
+      UT_SNPRINTF(errtx,50," %ld",pGr->lNr);
+      LC_Error(72,"(LC_SetPrioritet)",errtx);
+   }
+}
+
+
+/*
+AR-931101
+CH LC_InqPrioritet                                       Hent prioritets-bit
+CD ==========================================================================
+CD Form�l:
+CD Hent prioritets-bit.
+CD
+CD Parametre:
+CD Navn     Type    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR *  pGr      i    Gruppenummer
+CD kolonne  short    i    Kolonne som skal hentes.
+CD                        (Lovlig 0 til LC_MAX_ANT_PRIOR-1)
+CD short    sAvPaa   r    Av eller P�  (UT_TRUE = P�, UT_FALSE = Av)
+CD
+CD Bruk:
+CD sAvPaa = LC_InqPrioritet(pGr,kolonne);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_InqPrioritet(LC_BGR * pGr,short kolonne)
+{
+   short s;
+   LC_GRTAB_LINJE * pGrt;
+
+   LO_TestFilpeker(pGr->pFil,"InqPrioritet");
+
+   /* Lovlig gruppe */
+   if (pGr->lNr >= 0L && pGr->lNr < pGr->pFil->lAntGr) {
+      /* Lovlig kolonne */
+      if (kolonne >= 0  &&  kolonne < LC_MAX_ANT_PRIOR) {
+
+         pGrt = LI_GetGrt(pGr->pFil,pGr->lNr);
+
+         /* Returner aktuellt bit */
+         s = kolonne / 32;
+         return ((pGrt->ulPrior[s] & (0x1UL << (kolonne % 32))) == 0UL)?  UT_FALSE : UT_TRUE;
+      }
+
+   } else {                                 /* Ulovlig gruppe */
+      char errtx[50];
+      UT_SNPRINTF(errtx,50," %ld",pGr->lNr);
+      LC_Error(72,"(LC_SetPrioritet)",errtx);
+   }
+
+   return UT_FALSE;
+}
+
+
+/*
+AR-931101
+CH LC_ErasePrioritet                                 Blank ut prioritets-bit
+CD ==========================================================================
+CD Form�l:
+CD Blank ut prioritets-bit.
+CD
+CD Parametre:
+CD Navn     Type    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR *  pGr      i    Gruppenummer
+CD
+CD Bruk:
+CD LC_ErasePrioritet(pGr);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_ErasePrioritet(LC_BGR * pGr)
+{
+   LC_GRTAB_LINJE * pGrt;
+
+   LO_TestFilpeker(pGr->pFil,"ErasePrioritet");
+
+   /* Lovlig gruppe */
+   if (pGr->lNr >= 0L && pGr->lNr < pGr->pFil->lAntGr) {
+
+      pGrt = LI_GetGrt(pGr->pFil,pGr->lNr);
+
+      /* Blank ut alle bit */
+      pGrt->ulPrior[0] = 0x0UL;
+      pGrt->ulPrior[1] = 0x0UL;
+      pGrt->ulPrior[2] = 0x0UL;
+      pGrt->ulPrior[3] = 0x0UL;
+
+   } else {                                 /* Ulovlig gruppe */
+      char errtx[50];
+      UT_SNPRINTF(errtx,50," %ld",pGr->lNr);
+      LC_Error(72,"(LC_SetPrioritet)",errtx);
+   }
+}
+
+
+/*
+AR-931101
+CH LC_EraseAllPrioritet                        Blank ut ALLE prioritets-bit
+CD ==========================================================================
+CD Form�l:
+CD Blank ut alle prioritets-bit p� alle gruppene i denne filen.
+CD
+CD Parametre:
+CD Navn        Type    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM  *pFil     i    Filpeker
+CD
+CD Bruk:
+CD LC_EraseAllPrioritet(pFil);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_EraseAllPrioritet(LC_FILADM *pFil)
+{
+   LC_GRTAB_LINJE * pGrt;
+   long lNr;
+
+   LO_TestFilpeker(pFil,"EraseAllPrioritet");
+
+   for (lNr=0L; lNr<pFil->lAntGr; lNr++) {
+
+      pGrt = LI_GetGrt(pFil,lNr);
+
+      /* Blank ut alle bit */
+      pGrt->ulPrior[0] = 0x0UL;
+      pGrt->ulPrior[1] = 0x0UL;
+      pGrt->ulPrior[2] = 0x0UL;
+      pGrt->ulPrior[3] = 0x0UL;
+
+   } /* endfor */
+}
+                                       
+/*
+AR:2005-06-20
+CH LC_DumpBt                                   Dump brukttabellen til stderr
+CD ==========================================================================
+CD Form�l:
+CD Dump brukttabellen til stderr
+CD
+CD Parametre:
+CD Type     Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD
+CD Bruk:
+CD LC_DumpBt();
+   =============================================================================
+*/
+SK_EntPnt_FYBA void LC_DumpBt(const char *pszMelding)
+{
+   short ngi,s;
+   long nko;
+   unsigned short info;
+   LC_BGR Bgr,AktBgr;
+   char szTx[1024],szOrd[30];
+   LC_FILADM *pAktuellFil = NULL;
+
+
+   LC_GetGrNr(&AktBgr);
+
+   UT_FPRINTF(stderr,"\n=================================================\n");
+   UT_FPRINTF(stderr,"Dump av brukt-tabellen i FYBA: %s\n", pszMelding);
+   UT_FPRINTF(stderr,"=================================================\n");
+
+   UT_StrCopy(szTx,"\n    Snr  ",1024);
+
+   for (s=BT_MIN_BT; s<=BT_MAX_BT; ++s)
+   {
+      UT_SNPRINTF(szOrd,30,"%3hd",s);
+      UT_StrCat(szTx,szOrd,1024);
+   }
+   UT_FPRINTF(stderr,"%s\n",szTx);
+
+   UT_FPRINTF(stderr,"---------------------------------------------------------------------------------------------------------\n");
+
+   LC_InitNextBgr(&Bgr);
+
+   /* Alle gruppene i framgrunn */
+   while (LC_NextBgr(&Bgr,LC_FRAMGR)) {
+      LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+      // Filnavn
+      if (Bgr.pFil != pAktuellFil)
+      {
+         UT_FPRINTF(stderr,"%s\n",Bgr.pFil->pszNavn);
+         pAktuellFil = Bgr.pFil;
+      }
+      // Snr
+      UT_SNPRINTF(szTx,1024,"%7ld: ", LC_GetSn());
+
+      for (s=BT_MIN_BT; s<=BT_MAX_BT; ++s)
+      {
+         UT_SNPRINTF(szOrd,30,"%3hd",LC_GetBt(&Bgr,s));
+         UT_StrCat(szTx,szOrd,1024);
+      }
+
+      UT_FPRINTF(stderr,"%s\n",szTx);
+   }
+
+   UT_FPRINTF(stderr,"\n=================================================\n");
+
+   if (AktBgr.lNr != INGEN_GRUPPE) {
+      LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+   }
+}
diff --git a/FYBA/FYLO.cpp b/FYBA/FYLO.cpp
new file mode 100644
index 0000000..eafbda7
--- /dev/null
+++ b/FYBA/FYLO.cpp
@@ -0,0 +1,2529 @@
+/* === AR-920210 ========================================================= */
+/*  STATENS KARTVERK  -  FYSAK-PC                                          */
+/*  Fil: fylo.c                                                            */
+/*  Innhold: �pningsrutiner for FYSAK-PC                                   */
+/* ======================================================================= */
+
+#include "stdafx.h"
+
+#include <math.h>
+#include <fcntl.h>
+
+#include <errno.h>
+#include <ctype.h>
+#include <limits.h>
+
+
+/* --- Lokale rutiner -------------------------- */
+static LC_BASEADM * LO_AppBaseAdm(void);
+static short       LO_DelBaseAdm(LC_BASEADM * pBase);
+static LC_FILADM * LO_AppFilAdm(LC_BASEADM * pBase);
+static void        LO_DelFilAdm(LC_FILADM *pFil);
+static short       LO_OpenKladd(LC_BASEADM * pBase);
+static short       LO_InklSos(LC_FILADM *pFil,short vising);
+
+/* --- Globale strukturer ---------------------- */
+LC_SYSTEMADM Sys;
+
+LC_FEILMELDING& err() { /* Feilmeldingsstruktur - construct on first use to prevent */
+					    /* it from being uninitialized */
+  static LC_FEILMELDING* err = new LC_FEILMELDING;
+  return *err;
+}                       
+char retur_str[LC_MAX_SOSI_LINJE_LEN];          /* Returstreng */
+
+volatile short fyba_initiert = 0;    /* Bryter for � vise at LC_Init er utf�rt */
+
+
+void  (*LC_ErrorAdr)(short ifeilnr, const char* logtx, const char* vartx) = NULL;
+void  (*LC_StartMessageAdr)(const char *cfil) = NULL;
+void  (*LC_ShowMessageAdr)(double prosent) = NULL;
+void  (*LC_EndMessageAdr)(void) = NULL;
+short (*LC_CancelAdr)(void) = NULL;
+
+
+
+/*
+AR-910920
+CH LC_Init                                                       Initierer FYBA
+CD =============================================================================
+CD Form�l:
+CD Initierer FYBA.
+CD
+CD Parametre:
+CD Type     Navn      I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD
+CD Bruk:
+CD LC_Init();
+   =============================================================================
+*/
+SK_EntPnt_FYBA void LC_Init(void)
+{
+   fyba_initiert = 1;                  /* FYBA er initiert */
+
+   /* Husker aktuelle versjonsnummer */
+   UT_StrCopy(Sys.szBaseVer,FYBA_IDENT,LC_BASEVER_LEN);
+   UT_StrCopy(Sys.szIdxVer,FYBA_INDEKS_VERSJON,5);
+
+	/* Ingen aktuell gruppe */
+   Sys.GrId.lNr = INGEN_GRUPPE;
+   Sys.sGrEndra = END_UENDRA;
+
+   Sys.sResPlass = 0;
+   Sys.lMaxSkriv = 0L;
+   Sys.lAntSkriv = 0L;
+   Sys.sNGISmodus = NGIS_NORMAL;
+   Sys.sUtvidModus = LC_UTVID_SIKKER;
+
+	/* Allokerer buffer */
+	Sys.Hode.pszTx  = (char*)UT_MALLOC(LC_MAX_GINFO_BUFFER * sizeof(char));
+	Sys.Ginfo.pszTx = (char*)UT_MALLOC(LC_MAX_GINFO_BUFFER * sizeof(char));
+	Sys.pszPinfo    = (char*)UT_MALLOC(LC_MAX_PINFO_BUFFER * sizeof(char));
+	Sys.pdAust      = (double *)UT_MALLOC(LC_MAX_KOORD * sizeof(double));
+	Sys.pdNord      = (double *)UT_MALLOC(LC_MAX_KOORD * sizeof(double));
+	Sys.pInfo       = (LB_INFO *)UT_MALLOC(LC_MAX_KOORD * sizeof(LB_INFO));
+
+	/* Initierer lesebuffer for HO-rutinene */
+	Sys.BufAdm.sStatus = LESEBUFFER_TOM;
+
+	/* Initierer navnetabell for HO-rutinene */
+	LN_InitTab(&(Sys.SosiNavn));
+
+   Sys.usMerkRefGr = 0;
+
+   /* Ingen base er �pnet */
+   Sys.pForsteBase = NULL;
+   Sys.pAktBase = NULL;
+}
+
+
+/*
+AR-910920
+CH LC_Close                                                    Stenger ned FYBA
+CD =============================================================================
+CD Form�l:
+CD Stenger ned FYBA.
+CD
+CD Parametre:
+CD Type     Navn      I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD
+CD Bruk:
+CD LC_Close();
+	=============================================================================
+*/
+SK_EntPnt_FYBA void LC_Close(void)
+{
+   LC_BASEADM *pBase, *pNesteBase;
+
+   /* Ingen aktuell gruppe */
+   Sys.GrId.lNr = INGEN_GRUPPE;
+
+   if (fyba_initiert != 0) {
+      fyba_initiert = 0;       /* FYBA er ikke initiert */
+
+		/* Frigir buffer */
+		UT_FREE(Sys.Hode.pszTx);
+		UT_FREE(Sys.Ginfo.pszTx);
+		UT_FREE(Sys.pszPinfo);
+		UT_FREE(Sys.pdAust);
+		UT_FREE(Sys.pdNord);
+		UT_FREE(Sys.pInfo);
+
+      /* Initierer navnetabell for HO-rutinene */
+		LN_InitTab(&(Sys.SosiNavn));
+
+      /* Stenger eventuelle �pne baser. */
+      for (pBase=Sys.pForsteBase; pBase!=NULL; pBase=pNesteBase) {
+         pNesteBase = pBase->pNesteBase;
+         LC_CloseBase(pBase,RESET_IDX);
+      }
+    
+      /* Ingen base er �pnet */
+      Sys.pForsteBase = NULL;
+      Sys.pAktBase = NULL;
+
+   }
+}
+
+
+
+
+
+/*
+AR-910920
+CH LC_SetDefLpfi                                  Ledig plass mellom grupper
+CD ==========================================================================
+CD Form�l:
+CD Legger inn standardverdi for antall tegn ledig plass bak gruppe
+CD p� .SOS-fil.
+CD
+CD Parametre:
+CD Type     Navn      I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD short    ant_tegn   i    Antall tegn ledig plass.
+CD
+CD Bruk:
+CD LC_SetDefLpfi(ant_tegn);
+   =============================================================================
+*/
+SK_EntPnt_FYBA void LC_SetDefLpfi(short ant_tegn)
+{
+   Sys.sResPlass = ant_tegn;
+}
+
+
+/*
+AR-911003
+CH LC_InqDefLpfi                             Hent ledig plass mellom grupper
+CD ==========================================================================
+CD Form�l:
+CD Henter ut standardverdi for antall tegn ledig plass bak gruppe
+CD p� .SOS-fil.
+CD
+CD Parametre:
+CD Type     Navn      I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD short    ant_tegn   r    Antall tegn ledig plass.
+CD
+CD Bruk:
+CD ant_tegn = LC_InqDefLpfi();
+   =============================================================================
+*/
+SK_EntPnt_FYBA short LC_InqDefLpfi(void)
+{
+   return  Sys.sResPlass;
+}
+
+
+/*
+AR-911021
+CH LC_InqLag                          Finn hvilet lag aktuell gruppe tilh�rer
+CD ==========================================================================
+CD Form�l:
+CD Finn hvilket lag aktuell gruppe tilh�rer.
+CD
+CD Parametre:
+CD Type            Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD unsigned short *usLag    u    "Lag":  LC_FRAMGR eller LC_BAKGR
+CD short           status   r    UT_TRUE = OK, UT_FALSE = Ingen aktuell gruppe
+CD
+CD Bruk:
+CD     status = LC_InqLag(&usLag);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_InqLag(unsigned short *usLag)
+{
+   /* Er det noen aktuell gruppe? */
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {
+		*usLag = Sys.GrId.pFil->usLag;
+		return UT_TRUE;
+   }
+
+   /* Ingen aktuell gruppe */
+   return UT_FALSE;
+}
+
+
+/*
+AR-920221
+CH LC_InqFilLag                              Finn hvilet lag en fil tilh�rer
+CD ==========================================================================
+CD Form�l:
+CD Finn hvilket lag en fil tilh�rer.
+CD
+CD Parametre:
+CD Type            Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM      *pFil     i    Filpeker
+CD unsigned short  usLag    r    "Lag":  LC_FRAMGR eller LC_BAKGR
+CD
+CD Bruk:
+CD     usLag = LC_InqFilLag(pFil);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA unsigned short LC_InqFilLag(LC_FILADM *pFil)
+{
+   /* LO_TestFilpeker(pFil,"LC_InqFilLag"); */
+   LO_TestFilpeker(pFil,"InqFilLag");
+   return pFil->usLag;
+}
+
+
+/*
+AR-920221
+CH LC_SetFilLag                             Velg hvilet lag en fil tilh�rer
+CD ==========================================================================
+CD Form�l:
+CD Velg hvilket lag en fil tilh�rer.
+CD
+CD Parametre:
+CD Type            Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM      *pFil     i    Filpeker
+CD unsigned short  usLag    i    "Lag":  LC_FRAMGR eller LC_BAKGR
+CD
+CD Bruk:
+CD     LC_SetFilLag(pFil,LC_FRAMGR);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_SetFilLag(LC_FILADM *pFil,unsigned short usLag)
+{
+   short ostat;
+   
+   LO_TestFilpeker(pFil,"SetFilLag");
+
+   /* M� lagre aktuell gruppe hvis den er p� denne filen og er endret */
+   //if (pFil == Sys.GrId.pFil  &&  Sys.sGrEndra != END_UENDRA) {
+   if (pFil == Sys.GrId.pFil  &&  Sys.GrId.lNr != INGEN_GRUPPE  &&  Sys.sGrEndra != END_UENDRA) {
+		LC_WxGr(SKRIV_OPTIMALT);
+      Sys.sGrEndra = END_UENDRA;
+   }
+
+   /* T�mmer skrivek�a for denne filen */
+   LB_Save(pFil);
+
+   /* Steng eventuell �pen fil */
+   LO_CloseSos(pFil->pBase);
+
+   if ( usLag == LC_FRAMGR) {
+      /* Sjekk at filen kan �pnes med den �nskede aksessen */   
+		pFil->pBase->pfSos = UT_OpenFile(pFil->pszNavn,"",UT_UPDATE,UT_OLD,&ostat);
+
+      /* �pningsfeil */
+      if (ostat != UT_OK) {
+         char szError[256];
+         UT_strerror(szError,256,ostat);
+         UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pFil->pszNavn,szError);
+         LC_Error(101,"(LC_SetFilLag)",err().tx);
+
+      } else {
+         // Husk current filnummer mm
+         pFil->pBase->pCurSos = pFil;
+         pFil->sAccess = UT_UPDATE;
+         pFil->usLag = LC_FRAMGR;
+
+         // Husk antall filer i framgrunn/bakgrunn
+         pFil->pBase->sAntFramgrFil++;
+         pFil->pBase->sAntBakgrFil--;
+      }
+   
+   } else {
+      pFil->sAccess = UT_READ;
+      pFil->usLag = LC_BAKGR;
+     
+      // Husk antall filer i framgrunn/bakgrunn
+      pFil->pBase->sAntBakgrFil++;
+      pFil->pBase->sAntFramgrFil--;
+   }
+}
+
+
+/*
+AR-971114
+CH LC_Backup                                     Lag backup av gitt SOSI-fil
+CD ==========================================================================
+CD Form�l:
+CD Lag backup av gitt SOSI-fil.
+CD Kopien legges p� en underkatlog med navn "Backup" under den katalogen
+CD SOSI-filen ligger p�. Kopien navnes "Filnavn.nnn" der nnn er et
+CD fortl�pende nummer fra 000 og oppover. Det f�rste ledige numret blir brukt.
+CD
+CD Parametre:
+CD Type         Navn          I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM   *pFil           i   Filpeker
+CD char        *pszBackupPath  i   Katalognavn for lagring av backup.
+CD short        sStatus        r   UT_TRUE = OK
+CD                                 UT_FALSE = Feil.
+CD
+CD Bruk:
+CD     sStatus = LC_Backup(pFil, szBackupPath);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_Backup(LC_FILADM *pFil, const char *pszBackupPath)
+{
+   char drive[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
+	char szBakFil[_MAX_PATH];
+	char szBakKatalog[_MAX_PATH];
+   short sIdx;
+   UT_INT64 Size;
+   
+   LO_TestFilpeker(pFil,"Backup");
+
+   /* M� lagre aktuell gruppe hvis den er p� denne filen og er endret */
+   //if (pFil == Sys.GrId.pFil  &&  Sys.sGrEndra != END_UENDRA) {
+   if (pFil == Sys.GrId.pFil  &&  Sys.GrId.lNr != INGEN_GRUPPE  &&  Sys.sGrEndra != END_UENDRA) {
+		LC_WxGr(SKRIV_OPTIMALT);
+      Sys.sGrEndra = END_UENDRA;
+   }
+
+   /* T�mmer skrivek�a for denne filen */
+   LB_Save(pFil);
+
+   /* Steng eventuell �pen fil */
+   LO_CloseSos(pFil->pBase);
+   
+
+   UT_splitpath(pFil->pszNavn,drive,dir,fname,ext);
+
+   /* Opprett katalogen */
+   if (pszBackupPath != NULL  &&  *pszBackupPath != '\0') {
+      UT_StrCopy(szBakKatalog,pszBackupPath,_MAX_PATH);
+   } else {
+      UT_makepath(szBakKatalog,drive,dir,"Backup","");
+   }
+   UT_CreateDir(szBakKatalog);
+
+   /* Lag standard navn */
+   for (sIdx=0; sIdx<100; sIdx++) {
+
+      UT_SNPRINTF(ext,_MAX_EXT,".b%02hd",sIdx);
+      UT_makepath(szBakFil,"",szBakKatalog,fname,ext);
+
+      /* Kontroller om filen finnes fra f�r */
+      /* (Gj�res ved � pr�ve � sp�rre om filens st�rrelse) */
+      if (UT_InqPathSize_i64(szBakFil,&Size) != 0) {
+         break;  /* Har funnet et ubrukt navn */
+      }
+   }
+
+   /* Kopier */
+   return UT_CopyFile(pFil->pszNavn,szBakFil, UT_FALSE);
+}
+
+
+/*
+AR-910920
+CH LC_MaxSkriv                                         Max skriv f�r lagring
+CD ==========================================================================
+CD Form�l:
+CD Setter max antall skriv uten lagring til SOSI-filen.
+CD (0 = allt skrives direkte til SOSI-filen.)
+CD
+CD Parametre:
+CD Type     Navn      I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD long     antall     i    Max antall skriv uten lagring til SOSI-filen
+CD
+CD Bruk:
+CD LC_MaxSkriv(antall);
+   =============================================================================
+*/
+SK_EntPnt_FYBA void LC_MaxSkriv(long antall)
+{
+   Sys.lMaxSkriv = labs(antall);
+}
+
+
+/*
+AR-910920
+CH LC_InqMaxSkriv                                       Max skriv f�r lagring
+CD ==========================================================================
+CD Form�l:
+CD Sp�rr etter max antall skriv uten lagring til SOSI-filen.
+CD (0 = allt skrives direkte til SOSI-filen.)
+CD
+CD Parametre:
+CD Type     Navn      I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD long     antall     i    Max antall skriv uten lagring til SOSI-filen
+CD
+CD Bruk:
+CD antall = LC_InqMaxSkriv();
+   =============================================================================
+*/
+SK_EntPnt_FYBA long LC_InqMaxSkriv(void)
+{
+   return Sys.lMaxSkriv;
+}
+
+
+/*	
+AR-900924
+CH LC_SetNgisModus                                            Velg NGIS modus
+CD ==========================================================================
+CD Form�l:
+CD Velger handteringsm�te for grupper som er merket for oppdatering av NGIS.
+CD	Standardverdi fra LC_Init er NGIS_NORMAL.
+CD
+CD Parametre:
+CD Type   Navn  I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD short  modus  i   Behandlingsm�te:
+CD						    NGIS_NORMAL  (0) = Vanlig handtering
+CD							 NGIS_SPESIAL (1) = Spesialmodus der det er mulig � lese
+CD                                       grupper som er merka som sletta.
+CD
+CD Bruk:
+CD LC_SetNgisModus(NGIS_NORMAL);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_SetNgisModus(short modus)
+{
+   if (modus == NGIS_SPESIAL){
+		 Sys.sNGISmodus = NGIS_SPESIAL;
+	} else{
+       Sys.sNGISmodus = NGIS_NORMAL;
+	}
+}
+
+
+/*	
+AR-2003-03-31
+CH LC_GetNgisModus                                            Hent NGIS modus
+CD ==========================================================================
+CD Form�l:
+CD Henter handteringsm�te for grupper som er merket for oppdatering av NGIS.
+CD	Standardverdi fra LC_Init er NGIS_NORMAL.
+CD
+CD Parametre:
+CD Type   Navn  I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD short  modus  r   Behandlingsm�te:
+CD						    NGIS_NORMAL  (0) = Vanlig handtering
+CD							 NGIS_SPESIAL (1) = Spesialmodus der det er mulig � lese
+CD                                       grupper som er merka som sletta.
+CD
+CD Bruk:
+CD modus = LC_GetNgisModus();
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetNgisModus(void)
+{
+   return Sys.sNGISmodus;
+}
+
+
+/*	
+AR-900924
+CH LC_GetNgisLag                                               Hent NGIS-LAG 
+CD ==========================================================================
+CD Form�l:
+CD Henter NGIS-LAG for gitt fil.
+CD Strengen ligger i et felles "returbuffer" for alle get-rutiner i fyba.
+CD Dette blir �delagt ved neste kall til en "get-rutine". For � ta vare p�
+CD strengen m� den kopieres over til egen streng. (Bruk strcpy).
+CD
+CD Parametre:
+CD Type       Navn    I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil     i   Fil det �nskes opplsninger om.
+CD char*  pszNgisLag   r   NGIS-lag. 
+CD                           Tom streng = ..NGIS-LAG er ikke funnet
+CD                           "0"  = Bare leseaksess (..NGIS-LAG 0)
+CD
+CD
+CD Bruk:
+CD pszNgisLag = LC_GetNgisLag(pFil);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA char* LC_GetNgisLag(LC_FILADM *pFil)
+{
+	LO_TestFilpeker(pFil,"LC_GetNgisLag");
+   
+   UT_StrCopy(retur_str,pFil->szNgisLag,LC_MAX_SOSI_LINJE_LEN);
+
+   return retur_str;
+}
+
+
+/*	
+AR-970109
+CH LC_SetUtvidModus                                         Velg utvis modus
+CD ==========================================================================
+CD Form�l:
+CD Velger handteringsm�te for utvidelse av SOSI-filer.
+CD	Standardverdi fra LC_Init er LC_UTVID_SIKKER.
+CD
+CD Parametre:
+CD Type   Navn  I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD short  modus  i   Behandlingsm�te:
+CD						    LC_UTVID_SIKKER (0) = SOSI-filen stenges og filst�rrelsen
+CD                                          oppdateres etter hver gruppe som er
+CD                                          skrevet p� slutten av filen.
+CD							 LC_UTVID_RASK   (1) = SOSI-filen stenges IKKE etter hver
+CD                                          gruppe som er skrevet p� slutten
+CD                                          av filen.
+CD                                          (M� bare brukes i spesielle tilfeller.)
+CD
+CD Bruk:
+CD LC_SetUtvidModus(LC_UTVID_SIKKER);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_SetUtvidModus(short modus)
+{
+   if (modus == LC_UTVID_SIKKER) {
+      Sys.sUtvidModus = LC_UTVID_SIKKER;
+   } else{
+      Sys.sUtvidModus = LC_UTVID_RASK;
+   }
+}
+
+
+/*	
+AR-970109
+CH LC_GetUtvidModus                                         Hent utvis modus
+CD ==========================================================================
+CD Form�l:
+CD Henter valgt handteringsm�te for utvidelse av SOSI-filer.
+CD
+CD Parametre:
+CD Type   Navn  I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD short  modus  r   Behandlingsm�te:
+CD						    LC_UTVID_SIKKER (0) = SOSI-filen stenges og filst�rrelsen
+CD                                          oppdateres etter hver gruppe som er
+CD                                          skrevet p� slutten av filen.
+CD							 LC_UTVID_RASK   (1) = SOSI-filen stenges IKKE etter hver
+CD                                          gruppe som er skrevet p� slutten
+CD                                          av filen.
+CD                                          (M� bare brukes i spesielle tilfeller.)
+CD
+CD Bruk:
+CD short sModus = LC_GetUtvidModus();
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetUtvidModus(void)
+{
+   return Sys.sUtvidModus;
+}
+
+
+/*
+AR-910922
+CH LO_AppBaseAdm                                         Legg til ny BaseAdm
+CD ==========================================================================
+CD Form�l:
+CD Allokerer en ny BasAdm-tabell.
+CD Legger tabellen inn i kjeden av base-adm-tabeller.
+CD Velg basen som aktuell base.
+CD
+CD Parametre:
+CD Type        Navn      I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BASEADM * pBase      r   Basepeker.
+CD
+CD Bruk:
+CD pBase = LO_AppBaseAdm();
+   =============================================================================
+*/
+static LC_BASEADM * LO_AppBaseAdm(void)
+{
+   LC_BASEADM * pBase;
+
+   /*
+    * Allokerer og nullstiller minne til blokken
+	 */
+	pBase = (LC_BASEADM *) UT_MALLOC(sizeof(LC_BASEADM));
+	memset(pBase,'\0',sizeof(LC_BASEADM));
+
+	/*
+	 * Legger blokken inn i kjeden av baser
+	 */
+	pBase->pNesteBase = Sys.pForsteBase;
+   Sys.pForsteBase = pBase;
+
+   /* Velg basen som aktuell base */
+	Sys.pAktBase = pBase;
+
+   return pBase;
+}
+
+
+/*
+AR-931110
+CH LC_InqCurBase                                              Aktuell base
+CD ==========================================================================
+CD Form�l:
+CD Sp�rr etter aktuell base.
+CD
+CD Parametre:
+CD Type        Navn      I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BASEADM * pBase      r   Basepeker.
+CD
+CD Bruk:
+CD pBase = LC_InqCurBase();
+   =============================================================================
+*/
+SK_EntPnt_FYBA LC_BASEADM * LC_InqCurBase(void)
+{
+   return  Sys.pAktBase;
+}
+
+
+/*
+AR-910924
+CH LO_DelBaseAdm                                            Fjern en BaseAdm
+CD ==========================================================================
+CD Form�l:
+CD Fjerner tabellen fra kjeden av base-adm-tabeller og frigir minnet.
+CD OBS! All aktivitet mot basen m� v�re avsluttet f�r dette kallet.
+CD (Alle sosi-filer m� v�re stengt!)
+CD
+CD Parametre:
+CD Type        Navn     I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BASEADM * pBase     i   Peker til baseadministrasjonsblokk.
+CD short       sStatus   r   UT_TRUE=OK, UT_FALSE=Basen har �pne filer.
+CD
+CD Bruk:
+CD sStatus = LO_DelBaseAdm(pBase);
+   =============================================================================
+*/
+static short LO_DelBaseAdm(LC_BASEADM * pBase)
+{
+   LC_BASEADM * pB;
+
+   /*
+    * Sjekk at basen er tom
+    */
+   if (pBase->pForsteFil != NULL)  return UT_FALSE;
+
+   /*
+	 * Sjekk at alle filer er stengt
+    */
+   if (pBase->pCurSos != NULL)  fclose(pBase->pfSos);
+   if (pBase->pCurRb != NULL)  fclose(pBase->pfRb);
+
+	/*
+    * Fjern blokken fra kjeden av Baser
+    */
+
+   /* F�rste base i systemet */   
+   if (Sys.pForsteBase != NULL) {
+     if (Sys.pForsteBase == pBase) {
+        Sys.pForsteBase = pBase->pNesteBase;
+
+     } else {
+        /* Skanner til basen forran den aktuelle */
+		  pB = Sys.pForsteBase;
+        while ((pB->pNesteBase != pBase) && (pB->pNesteBase != NULL)) {
+           pB = pB->pNesteBase;
+        }
+
+        /* Heng sammen kjeden */
+        pB->pNesteBase = pBase->pNesteBase;
+     }
+   }
+   
+   /*
+    * Frigi minne som var brukt av blokken
+	 */
+	UT_FREE(pBase);
+
+	return UT_TRUE;
+}
+
+
+/*
+AR-910922
+CH LC_OpenBase                                                 �pner ny base
+CD ==========================================================================
+CD Form�l:
+CD �pner en base, nullstiller tabellene.
+CD
+CD Hvis basen er kladdebase opprettes en SOSI-fil med en gruppe i basen,
+CD denne brukes som buffer for les / skriv.
+CD Kladdefilen legges p� current directory.
+CD Kladdebase brukes bare n�r alle SOSI-filer �pnes med sekvensiell les/skriv.
+CD  
+CD Den nye basen velges som aktuell base.
+CD
+CD Parametre:
+CD Type        Navn      I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD short       sBaseType  i   Basetype. Konstanter definert:
+CD                             LC_BASE  = Vanlig base.
+CD                             LC_KLADD = Kladdebase. Brukes bare i spesielle
+CD                                        tilfeller hvis ingen fil �pnes
+CD                                        som LC_BASE_xx.
+CD LC_BASEADM * pBase      r   Basepeker.
+CD
+CD Bruk:
+CD pBase = LC_OpenBase(sBaseType);
+	==========================================================================
+*/
+SK_EntPnt_FYBA LC_BASEADM * LC_OpenBase(short sBaseType)
+{
+	LC_BASEADM * pBase;
+
+	/*
+	 * Sjekk at FYBA er initiert og at det er gitt lovlig sBaseType
+	 */
+	if (fyba_initiert != 1){
+		LC_Error(4,"(LC_OpenBase)","");
+		exit(2);
+	}
+	if (sBaseType != LC_BASE  &&  sBaseType != LC_KLADD) {
+		LC_Error(1,"(LC_OpenBase)","");
+		exit(2);
+	}
+
+	/*
+	 * Legg til ny baseadm og sett denne som aktuell base
+	 */
+	pBase = LO_AppBaseAdm();
+
+	/*
+	 * Initierer
+	 */
+	pBase->sType = sBaseType;
+	pBase->lAntGr = 0L;
+   pBase->sAntFramgrFil = 0;
+   pBase->sAntBakgrFil = 0;
+	pBase->pForsteFil = NULL;
+	pBase->pCurSos = NULL;
+   pBase->pfSos = NULL;
+
+	/* Initierer lesebuffer for les mot SOSI-fil */
+	pBase->BufAdm.sStatus = LESEBUFFER_TOM;
+
+	/*
+	 * Kladdebase ==> Opprett kladde-SOSI-fil og opprett en gruppe i denne
+	 */
+	if (sBaseType == LC_KLADD) {
+		if (! LO_OpenKladd(pBase)) {
+
+         /*
+          * Frigir BaseAdm og returnerer hvis det ikke kan �pnes kladdebase.
+          */
+         LO_DelBaseAdm(pBase);
+         return NULL;
+      }
+	}
+
+   return pBase;
+}
+
+
+/*
+AR-911003
+CH LC_SelectBase                                           Velg aktuell base
+CD ==========================================================================
+CD Form�l:
+CD Velger ny aktuell base.
+CD
+CD Parametre:
+CD Type        Navn      I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BASEADM * pBase      i   Peker til BasAdm.
+CD
+CD Bruk:
+CD LC_SelectBase(pBase);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_SelectBase(LC_BASEADM * pBase)
+{
+   Sys.pAktBase = pBase;
+}
+
+
+/*
+AR-910922
+CH LO_OpenKladd                                              �pne kladdebase
+CD ==========================================================================
+CD Form�l:
+CD Initierer en base for bruk som kladdebase for bare sekvensielle filer,
+CD Nullstiller tabellene.
+CD Oppretter en gruppe i basen, denne brukes som buffer for les / skriv.
+CD Kladdefilen legges p� samme directory som indeksfilene.
+CD
+CD Parametre:
+CD Type        Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BASEADM * pBase      i    Basepeker.
+CD short       status     r    Status. UT_TRUE=OK, UT_FALSE=Feil ved �pning
+CD
+CD Bruk:
+CD status = LO_OpenKladd(pBase);
+   ==========================================================================
+*/
+static short LO_OpenKladd(LC_BASEADM * pBase)
+{
+   short status = UT_TRUE;
+   short o_stat;
+   long snr;
+   FILE *kladdefil;
+   LC_BGR Bgr;
+   char fil[] = "FyKladd.Sos";
+
+	/*
+    * �pner kladde-sosi-filen
+    */
+   kladdefil = UT_OpenFile(fil,"",UT_UPDATE,UT_UNKNOWN,&o_stat);
+
+                                           /* �pnet OK */
+   if (o_stat == UT_OK){
+      ho_New(kladdefil,0,0.0,0.0,0.001,0.001,0.001,-199999.0,-199999.0,1999999.0,1999999.0);
+      fclose(kladdefil);
+                        /* Nuller styrevariablene */
+      pBase->sType = LC_BASE;    /* �pner midlertidig som base */
+
+      /* �pner kladde filen */
+      if (LC_OpenSos(fil,LC_BASE_FRAMGR,LC_NY_IDX,LC_INGEN_STATUS,
+           &(Bgr.pFil),&o_stat)) {
+
+         LC_NyGr(Bgr.pFil,".LINJE",&Bgr,&snr);
+
+         /* Merke for at dette er �pen kladdebase */
+			pBase->sType = LC_KLADD;
+      
+      /* �pningsfeil */
+      } else {   
+         UT_DeleteFile(fil);
+         char szError[256];
+         UT_strerror(szError,256,o_stat);
+         UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",fil,szError);
+         LC_Error(101,"(LC_OpenKladd)",err().tx);
+         status = UT_FALSE;
+      }
+
+	/* �pningsfeil p� kladdefilen */
+   } else {
+      char szError[256];
+      UT_strerror(szError,256,o_stat);
+      UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",fil,szError);
+      LC_Error(101,"(LO_OpenKladd)",err().tx);
+      status = UT_FALSE;
+   }
+
+	return  status;
+}
+
+
+/*
+AR-891204
+CH LC_CloseBase                                                   Steng base
+CD ==========================================================================
+CD Form�l:
+CD Stenger alle filer i basen, og frigir baseadministrasjonsblokken.
+CD Hvis aktuell base blir stengt blir f�rste base i systemet valgt som ny
+CD aktuell base.
+CD
+CD Parametre:
+CD Type       Navn   I/U Forklaring
+CD --------------------------------------------------------------------------
+CD PLCBASEADM pBase   i  Peker tilBaseAdm
+CD short      s_stat  i  Slutt-status
+CD                       RESET_IDX = Fjern indeksfilene
+CD                       SAVE_IDX  = Lagrer indeksfilene.
+CD                       ABORT     = Fjerner indeksfilene (ved avbrutt
+CD                                   indeks oppbygging).  
+CD
+CD Bruk:
+CD LC_CloseBase(pBase,s_stat);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_CloseBase(LC_BASEADM * pBase,short s_stat)
+{
+	short sAktBaseSletta = (pBase == Sys.pAktBase);
+	
+    if (pBase == NULL) {
+      LC_Error(101,"(LC_CloseBase)","LC_CloseBase fikk NULL-peker");
+      return;
+	}
+
+	/*
+    * Steng SOSI-filene
+    */
+   while (pBase->pForsteFil != NULL) {
+      LC_CloseSos(pBase->pForsteFil,s_stat);
+   }
+
+	/*
+	 * Kladdebase ==>  Slett kladdefilen
+    */
+   if (pBase->sType == LC_KLADD) {
+      UT_DeleteFile("FyKladd.Sos");
+   }
+
+   /*
+    * Frigi base-administrasjonsblokken
+    */
+   LO_DelBaseAdm(pBase);
+
+	/* Aktuell base er sletta, velg f�rste base som ny aktuell base */
+   if (sAktBaseSletta) {
+      Sys.pAktBase = Sys.pForsteBase;
+   }
+}
+
+
+/*
+AR-910922
+CH LO_AppFilAdm                                           Legg til ny FilAdm
+CD ==========================================================================
+CD Form�l:
+CD Allokerer en ny FilAdm-tabell.
+CD Legger tabellen inn i kjeden av fil-adm-tabeller.
+CD
+CD Parametre:
+CD Type        Navn     I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BASEADM * pBase     i   Base der filen skal ligge.
+CD LC_FILADM  *pFil      r   Peker til filadministrasjonsblokk.
+CD
+CD Bruk:
+CD pFil = LO_AppFilAdm();
+   =============================================================================
+*/
+static LC_FILADM *LO_AppFilAdm(LC_BASEADM * pBase)
+{
+	LC_FILADM *pFil;
+
+   /*
+    * Allokerer minne til blokken
+	 */
+	pFil = (LC_FILADM *) UT_MALLOC(sizeof(LC_FILADM));
+	memset(pFil,'\0',sizeof(LC_FILADM));
+
+	/*
+    * Legger blokken inn i kjeden av filer
+    */
+   if (pBase->pForsteFil == NULL) {
+      pBase->pForsteFil = pFil;
+   } else {
+		pBase->pSisteFil->pNesteFil = pFil;
+   }
+
+	pBase->pSisteFil = pFil;
+   pFil->pNesteFil = NULL;
+
+   /*
+    * Husker hvilken base filen tilh�rer
+    */
+   pFil->pBase = pBase;
+
+   return pFil;
+}
+
+
+/*
+AR-910924
+CH LO_DelFilAdm                                              Fjern en FilAdm
+CD ==========================================================================
+CD Form�l:
+CD Fjerner en fil fra kjeden av fil-adm-tabeller og frigir minnet.
+CD OBS! All aktivitet mot filen og indeksfilene m� v�re avsluttet f�r dette
+CD kallet.
+CD szBaseVer settes til '\0', slik at dette kan brukes for � sjekke om en
+CD filpeker er lovlig.
+CD
+CD Parametre:
+CD Type        Navn     I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM  *pFil      i   Peker til filadministrasjonsblokk.
+CD
+CD Bruk:
+CD LO_DelFilAdm(pFil);
+   =============================================================================
+*/
+static void LO_DelFilAdm(LC_FILADM *pFil)
+{
+   LC_FILADM *pF;
+	LC_BASEADM * pBase = pFil->pBase;
+
+
+   /*
+    * Fjern blokken fra kjeden av filer
+    */
+
+   /* F�rste fil i basen */   
+   if (pBase->pForsteFil == pFil) {
+		pBase->pForsteFil = pFil->pNesteFil;
+      if (pBase->pSisteFil == pFil) {
+         pBase->pSisteFil = NULL;
+      }
+
+   } else {
+      /* Skanner til filen forran den aktuelle */
+      pF = pBase->pForsteFil;
+      while (pF->pNesteFil != pFil) {
+         pF = pF->pNesteFil;
+		}
+
+      /* Heng sammen kjeden */
+      pF->pNesteFil = pFil->pNesteFil;
+      if (pBase->pSisteFil == pFil) {
+         pBase->pSisteFil = pF;
+      }
+   }
+
+   /*
+    * Marker at blokken er frigitt.
+    */
+	pFil->szBaseVer[0] = '\0';
+
+   
+   //UT_FPRINTF(stderr,"Frigir minne til FilAdm for: %s\n",pFil->pszNavn);
+
+   /*
+    * Frigi minne som var brukt av blokken
+	 */
+	if (pFil->pszNavn != NULL)
+   {
+      UT_FREE(pFil->pszNavn);
+      pFil->pszNavn = NULL;
+   }
+
+   // OBS! midlertidig?  AR:2004-05-19 
+   //memset(pFil,'\0',sizeof(LC_FILADM));
+
+	UT_FREE(pFil);
+}
+
+
+/*
+AR-920508
+CH LC_OpenSos                                      �pner og sjekker SOSI-fil
+CD ==========================================================================
+CD Form�l:
+CD �pner en ny fil i aktuell base.
+CD Allokerer minne til ny filadministrasjonsblokk og initierer denne.
+CD �pner SOSI-filen og legger navn mm. inn i fil-adm.
+CD Leser hodet og tolker det inn i filtabellen.
+CD Hode blir ikke generert for nye filer. Dette kan lages med LC_PutGi, eller
+CD LC_NyttHode eller kopieres fra annen fil, og skrives med LC_WsGr
+CD eller LC_WxGr.
+CD
+CD Parametre:
+CD Type    Navn   I/U  Forklaring
+CD --------------------------------------------------------------------
+CD char   *fil        i   Filnavn inkl. sti og fil-type
+CD                        (Hvis fil-type mangler forutsettes  .SOS)
+CD short   sModus     i   Filmodus
+CD                        LC_BASE_FRAMGR = Framgrunnsfil
+CD                        LC_BASE_BAKGR  = Bakgrunnsfil (Bare les)
+CD                        LC_SEKV_LES    = Sekvensiell, les
+CD                        LC_SEKV_SKRIV  = Sekvensiell, skriv
+CD                        LC_SEKV_UTVID  = Sekvensiell, utvid gammel fil
+CD short   sNyIdx     i   Indeksgenerering:
+CD                        LC_NY_IDX  = Tvungen nygenerering 
+CD                        LC_GML_IDX = Bruk gammel .idx hvis den er OK
+CD short   sVisStatus i  Vis indeksoppbygging
+CD                        LC_VIS_STATUS   = Vis status
+CD                        LC_INGEN_STATUS = Ikke vis status
+CD LC_FILADM **pFil   u  Peker til FilAdm blokk. 
+CD short  *o_stat     u  Detaljert �pningsstatus:
+CD                          0: �pning og hode OK
+CD                         >0: �pningsfeil feilmelding
+CD                         -1: �pning OK, tom fil / ikke SOSI-fil
+CD                         -2: Ikke �pnet, kan ikke bruke append p�
+CD                             tom fil / ikke sosi-fil
+CD                         -3: (LC_CANCEL): Ikke �pnet,
+CD                             indeksoppbygging avbrutt med [Esc],
+CD                             eller feil p� filen.
+CD                         -4: (LC_DUBLIKAT): Filen er i basen fra f�r (pFil)
+CD                         -5: (LC_OPPTATT): Filen er �pen i annet program 
+CD short   status     r  �pningsstatus: UT_TRUE = OK
+CD                                      UT_FALSE = Feil, (o_stat gir detalj)
+CD
+CD Bruk:
+CD ist=LC_OpenSos(fil,LC_BASE_FRAMGR,LC_NY_IDX,LC_VIS_STATUS,&pFil,&o_stat);
+CD ist=LC_OpenSos(fil,LC_SEKV_LES,LC_NY_IDX,LC_INGEN_STATUS,&pFil,&o_stat);
+   ==========================================================================
+*/
+
+/// <summary><c>LC_OpenSos</c> �pner og sjekker SOSI-fil <c>FYBA</c> biblioteket.
+/// </summary>
+/// <param name="fil">Filnavn inkl. sti og fil-type (Hvis fil-type mangler forutsettes  .SOS)</param>
+SK_EntPnt_FYBA short LC_OpenSos(const char *fil,short sModus,short sNyIdx,short sVisStatus,
+                                LC_FILADM **pFil, short *o_stat)
+{
+   short sAccess;
+   UT_INT64 sluttpos;
+   double nv_a,nv_n,oh_a,oh_n;
+   char drive[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
+	char szSosFil[_MAX_PATH];
+   LC_FILADM *pFi;
+   UT_INT64 Size;
+   short sStatus;
+
+   /*
+    * Sjekk at FYBA er initiert
+    */
+   if (fyba_initiert != 1) {
+      LC_Error(4,"(LC_OpenSos)","");
+      exit(2);
+   }
+   if (Sys.pForsteBase == NULL) {
+		LC_Error(5,"(LC_OpenSos)","");
+      exit(2);
+   }
+
+   if (Sys.pAktBase->sType == LC_KLADD) {
+      if (sModus == LC_BASE_FRAMGR  || sModus == LC_BASE_BAKGR) {
+   		LC_Error(106,"(LC_OpenSos)",fil);
+         exit(2);
+      }
+   }
+
+   *o_stat = 0;
+   LO_CloseSos(Sys.pAktBase);            /* Steng eventuell �pen fil */
+
+   /*
+    * Bygg opp fullstendig filnavn
+    */
+	UT_FullPath(szSosFil,fil,_MAX_PATH);
+   UT_splitpath(szSosFil,drive,dir,fname,ext);
+   if (*ext == '\0')  UT_StrCopy(ext, ".sos",_MAX_EXT);
+   UT_makepath(szSosFil,drive,dir,fname,ext);
+   /* UT_StrUpper(szSosFil); */
+
+   /* UT_FPRINTF(stderr,"�pner: %s\n",szSosFil); */
+
+   /* Sjekk om filen er i basen fra f�r */
+	if ((*pFil = LC_GetFiNr(szSosFil)) != NULL) {
+      *o_stat = LC_DUBLIKAT;
+      return UT_FALSE;
+   }
+
+   /*
+    * Tolk aksess for UT_OpenFile
+    */
+   if (sModus == LC_BASE_BAKGR  ||  sModus == LC_SEKV_LES) {
+      sAccess = UT_READ;
+   } else {
+      sAccess = UT_UPDATE;
+   }
+
+   /*
+    * Fil som bare skal leses m� finnes fra f�r.
+    */
+   if (sModus == LC_SEKV_LES  ||  sModus == LC_BASE_BAKGR) {
+      if (UT_InqPathSize_i64(szSosFil,&Size) != UT_OK) {
+			*o_stat=-2;
+         return UT_FALSE;
+      }
+   }
+   
+   /*
+    * Sekvensiell utvid krever at filen finnes og at det er lov � skrive.
+    */
+   if (sModus == LC_SEKV_UTVID) {
+      if (UT_InqPathSize_i64(szSosFil,&Size) != UT_OK) {
+         *o_stat=-2;
+         return UT_FALSE;
+      }
+   }
+
+   /*
+	 * Basefil og gammel indeks, krever at filene finnes.
+    */
+   if ((sModus == LC_BASE_FRAMGR  &&  sNyIdx == LC_GML_IDX) ||
+		 (sModus == LC_BASE_BAKGR   &&  sNyIdx == LC_GML_IDX)) {
+      /* M� ogs� sjekke lovlig aksess ? */
+      if (UT_InqPathSize_i64(szSosFil,&Size) != UT_OK) {
+         sNyIdx = LC_NY_IDX;
+      } else {
+         if (! LI_TestIdx(szSosFil)) {
+            sNyIdx = LC_NY_IDX;
+         }
+      }
+   }
+
+   /*
+    * Legg til ny Filadm
+    */
+   pFi = *pFil = LO_AppFilAdm(Sys.pAktBase);
+
+   /*
+    * Initierer
+    */
+   UT_StrCopy(pFi->szBaseVer,FYBA_IDENT,LC_BASEVER_LEN);
+   UT_StrCopy(pFi->szIdxVer,FYBA_INDEKS_VERSJON,5);
+	pFi->sSosiVer = FYBA_SOSI_VERSJON;
+   UT_StrCopy(pFi->szDato,"*",LC_DATO_LEN);
+	pFi->SosiNiv[0] = 0;
+	pFi->SosiNiv[1] = 0;
+	pFi->pszNavn = (char*)UT_MALLOC(strlen(szSosFil)+1);
+	UT_StrCopy(pFi->pszNavn,szSosFil,strlen(szSosFil)+1);
+	pFi->sAccess = sAccess;
+	pFi->lMaxSnr = NYTT_SNR;   /* Ikke noe akt. snr */
+	pFi->lAntGr = 0L;
+	pFi->sTegnsett = TS_DOSN8; /* Standard n�r ikke annet er gitt */
+	pFi->n64NesteLedigRbPos = 0;
+   *pFi->szNgisLag = '\0';
+
+   pFi->pIdx = NULL;
+   pFi->pGeoRN=NULL;
+
+   if (sModus == LC_BASE_FRAMGR) {
+      pFi->usLag = LC_FRAMGR;
+	} else if (sModus == LC_BASE_BAKGR) {
+      pFi->usLag = LC_BAKGR;
+   } else {
+      pFi->usLag = LC_SEKV;
+   }
+
+                                           /* �pner .SOS-filen */
+	pFi->pBase->pfSos = UT_OpenFile(pFi->pszNavn,"",sAccess,UT_OLD,o_stat);
+
+                 /* Ukjent fil med skriveaksess ==> opprett filen */
+   if (*o_stat == ENOENT  &&  sAccess == UT_UPDATE){
+      pFi->pBase->pfSos = UT_OpenFile(pFi->pszNavn,"",sAccess,UT_UNKNOWN,o_stat);
+   }
+   pFi->pBase->pCurSos = pFi;
+
+   
+   if (*o_stat == UT_OK) {      /* Gammel file er �pnet OK */
+                           /* Sjekk at SOSI-filen er OK */
+		if (ho_TestSOSI(pFi->pBase->pfSos,&sluttpos) == UT_FALSE){
+            *o_stat = -1;                  /* Tom fil */
+      }
+   
+   } else {
+      /* �pningsfeil p� SOSI-filen  ==>  avbryter */
+      char szError[256];
+      UT_strerror(szError,256,*o_stat);
+      UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pFi->pszNavn,szError);
+      LC_Error(101,"(LC_OpenSos)",err().tx);
+      pFi->pBase->pCurSos = NULL;
+      LO_DelFilAdm(pFi);
+      *pFil = NULL;
+      return UT_FALSE;
+   }
+
+
+   /* Eksisterende fil er �pnet OK, hent tegnsett */
+   if (*o_stat == UT_OK) {
+      ho_GetTegnsett(pFi->pBase->pfSos,&(pFi->sTegnsett));
+
+   /* Tom fil, pr. def. DOSN8 n�r ikke gitt annet tegnsett */ 
+   } else if (*o_stat == -1) {
+		pFi->sTegnsett = TS_DOSN8;
+   }
+
+   /* Omr�de */
+   if (*o_stat == UT_OK) {
+      /* Eksisterende fil er �pnet OK, hent omr�de */
+      ho_GetOmr(pFi->pBase->pfSos,&nv_a,&nv_n,&oh_a,&oh_n);
+      pFi->Omraade.dMinAust = nv_a;
+      pFi->Omraade.dMinNord = nv_n;
+      pFi->Omraade.dMaxAust = oh_a;
+      pFi->Omraade.dMaxNord = oh_n;
+
+   } else {
+      /* Tom fil, pr. def. ingen utstrekning */ 
+      pFi->Omraade.dMinAust = pFi->Omraade.dMinNord = (double)LONG_MAX;
+      pFi->Omraade.dMaxAust = pFi->Omraade.dMaxNord = (double)LONG_MIN;
+   }
+   
+   /* Filen er �pnet OK */
+   if (*o_stat == UT_OK || *o_stat == -1) {
+
+               /* Sett aktuell filposisjon mm. */
+      if (sModus == LC_SEKV_UTVID) {
+			if (*o_stat == -1) {         /* Kan ikke utvide tom fil */
+            *o_stat=-2;
+            return UT_FALSE;
+         }
+
+         /* Aktuell posisjon settes til slutten av filen */
+         pFi->n64AktPos = sluttpos;
+
+         /* ----- Oppdater filtabellen ----- */
+
+         /* ..TRANSPAR */
+         pFi->TransMaske = LC_TR_ALLT;
+         ho_GetTransEx(pFi->pBase->pfSos,&(pFi->TransMaske),&(pFi->TransPar));
+ 
+         /* Ikke noe akt. snr */
+         pFi->lMaxSnr = NYTT_SNR;
+         
+         /* Kvalitet */
+         ho_GetKvalitet(pFi->pBase->pfSos,&(pFi->Kvalitet.sMetode),
+                                         &(pFi->Kvalitet.lNoyaktighet),
+                                         &(pFi->Kvalitet.sSynbarhet),
+                                         &(pFi->Kvalitet.sHoydeMetode),
+                                         &(pFi->Kvalitet.lHoydeNoyaktighet));
+
+
+		} else {                    /* Annen aksess */
+                  /* Aktuell posisjon settes til starten av filen */
+			pFi->n64AktPos = 0L;
+                     /* I dette tilfellet oppdateres filtabellen   */
+                     /* n�r hodet leses/skrives fra/til SOSI-filen */
+         /* Denne brukes senere for � sjekke at hode er skrevet til filen */
+         pFi->TransPar.dEnhet = 0.0;  
+      }
+   }
+
+   /*
+    * Basefil, handter indeks.
+    */
+   if (sModus == LC_BASE_FRAMGR  ||  sModus == LC_BASE_BAKGR) {
+      
+      if (sNyIdx == LC_GML_IDX) {
+         // Lagret indeks, les inn indeksfilene
+         sStatus = LI_OpenRead(pFi);
+
+         if (sStatus == UT_OK) {
+            // �pnet OK, nullstill prioritetstabellen
+            LC_EraseAllPrioritet(pFi);
+
+         } else if (sStatus == LI_OPPTATT) {
+            // Filen er �pen i et annet program
+            LO_CloseSos(Sys.pAktBase);  // Steng eventuell �pen fil
+            LO_DelFilAdm(*pFil);         // Frigir filadministrasjonsblokken
+            *pFil = NULL;
+            *o_stat = LC_OPPTATT;
+            return UT_FALSE;
+
+			} else {
+            // Feil indeksversjon, st�rrelse eller oppdateringstid p� SOSI-filen
+				// - M� bygge ny indeks
+            LI_Close(pFi,RESET_IDX);
+            sNyIdx = LC_NY_IDX;
+
+            /*
+            * M� initiere deler av fil-adm p� nytt.
+            */
+            pFi->lAntGr = 0L;
+            pFi->n64NesteLedigRbPos = 0;
+            pFi->lMaxSnr = NYTT_SNR;   /* Ikke noe akt. snr */
+           	pFi->SosiNiv[0] = 0;
+           	pFi->SosiNiv[1] = 0;
+         }
+      }
+
+
+      if (sNyIdx == LC_NY_IDX) {
+         LI_OpenInit(pFi);                  /* Initierer LI-systemet */
+         LN_InitTab(&(pFi->SosiNavn));      /* Initierer navne-systemet */
+
+			if (*o_stat != -1) {       /* Filen har innhold */
+            /* Bygg indekser for filen, m. vising av status */
+            pFi->usDataFeil = 0;
+            if (! LO_InklSos(pFi,sVisStatus)) {
+					/* Indeksoppbygging er avbrutt */
+               /* Steng filen */
+               LC_CloseSos(pFi,RESET_IDX);
+               *pFil = NULL;
+               *o_stat = LC_CANCEL;
+               return UT_FALSE;
+            }
+
+            /* Gi melding om ulovlig referanse */
+            if ((pFi->usDataFeil & LC_DATAFEIL_REF) != 0) {
+               LC_Error(56,"(LC_OpenSos)",pFi->pszNavn);
+            }
+
+            /* Gi melding om ulovlig bue */
+            if ((pFi->usDataFeil & LC_DATAFEIL_BUE) != 0) {
+               LC_Error(59,"(LC_OpenSos)",pFi->pszNavn);
+            }
+         }
+      }
+
+   /*
+    * Sekvensiell fil, initier navnesystemet.
+    */
+   } else {
+      LN_InitTab(&(pFi->SosiNavn));
+   }
+
+
+   // Husk antall filer i framgrunn/bakgrunn
+   if (pFi->usLag & LC_FRAMGR)     pFi->pBase->sAntFramgrFil++;
+   else if (pFi->usLag & LC_BAKGR) pFi->pBase->sAntBakgrFil++;
+
+
+   // Initierer filtype
+   LC_SetFilType(pFi,LC_FILTYPE_UKJENT);
+   return  UT_TRUE;
+}
+
+
+/*
+AR-910925
+CH LO_ReopenSos                                              Re�pne SOSI-fil
+CD ==========================================================================
+CD Form�l:
+CD �pner p� nytt en av filene i filtabellen.
+CD
+CD Parametre:
+CD Type         Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM   *pFil     i    Peker til FilAdm-blokk
+CD
+CD Bruk:
+CD LO_ReopenSos(pFil);
+   ==========================================================================
+*/
+void LO_ReopenSos(LC_FILADM *pFil)
+{
+   short ostat;
+
+   if (pFil->pBase->pCurSos != pFil) {
+      if (pFil->pBase->pCurSos != NULL){     /* Stenger forrige fil */
+         fclose(pFil->pBase->pfSos);
+      }
+
+      /* �ner filen */
+		pFil->pBase->pfSos = UT_OpenFile(pFil->pszNavn,"",pFil->sAccess,UT_OLD,&ostat);
+
+      /* �pningsfeil */
+      if (ostat != UT_OK) {
+         LC_Error(6,"(LO_ReopenSos)",pFil->pszNavn);
+         exit(2);
+      }
+
+      /* Husk current filnummer */
+      pFil->pBase->pCurSos = pFil;
+   }
+}
+
+
+/*
+AR-881027
+CH LC_CloseSos                                                Steng SOSI-fil
+CD ==========================================================================
+CD Form�l:
+CD Stenger en SOSI-fil, og fjerner den fra basen.
+CD
+CD Parametre:
+CD Type        Navn   I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM  *pFil     i   Peker til FilAdm-blokk
+CD short       s_stat  i   Slutt-status
+CD                         RESET_IDX = Fjern indeksfilene
+CD                         SAVE_IDX  = Lagrer indeksfilene.
+CD
+CD Bruk:
+CD LC_CloseSos(pFil,SAVE_IDX);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_CloseSos(LC_FILADM *pFil,short s_stat)
+{
+   LC_BGR Bgr,AktBgr;
+   short ngi,linje_nr;
+   long nko;
+   unsigned short info;
+   char szSosiNiv[10];
+   LC_BOKS * pB;
+
+
+   /* LO_TestFilpeker(pFil,"LC_CloseSos"); */
+	LO_TestFilpeker(pFil,"CloseSos");
+
+	/*
+    * Hvis aktuell gruppe er p� denne filen
+    */
+   if (Sys.GrId.lNr != INGEN_GRUPPE  &&  Sys.GrId.pFil == pFil) {
+
+      if (pFil->pBase->sType == LC_BASE) {
+         /* Hvis gruppen er endra, skriv den til filen */
+         if (Sys.sGrEndra != END_UENDRA) {
+            if (LC_WxGr(SKRIV_SOSI) == UT_FALSE) {
+               // Indeksfilene ikke er brukbare
+               s_stat = RESET_IDX;
+            }
+         }
+      }
+      /* Vis at det ikke er noen aktuell gruppe lenger */
+      Sys.GrId.lNr = INGEN_GRUPPE;
+   }
+
+   // Husk antall filer i framgrunn/bakgrunn
+   if (pFil->usLag & LC_FRAMGR)     pFil->pBase->sAntFramgrFil--;
+   else if (pFil->usLag & LC_BAKGR) pFil->pBase->sAntBakgrFil--;
+
+   /*
+	 * Sikrer oppdatering av sosi-filen
+    */
+   if (pFil->pBase->sType == LC_BASE) {
+      LB_Save(pFil);
+   }
+   
+   /* Oppdater ..SOSI-NIV� i fil-hodet */
+	if (pFil->SosiNiv[1] > pFil->SosiNiv[0]) {
+      AktBgr = Sys.GrId;
+      Bgr.pFil = pFil;
+      Bgr.lNr = 0;
+      LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+
+      UT_SNPRINTF (szSosiNiv, 10, "%d", (int)pFil->SosiNiv[1]);
+      ngi = LC_PutGP("..SOSI-NIV�", szSosiNiv, &linje_nr);
+      LC_WxGr(SKRIV_SOSI);
+
+      if (AktBgr.lNr != INGEN_GRUPPE) { 
+         LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+      } else {
+         Sys.GrId = AktBgr;
+      }
+   }
+   
+   /* UT_FPRINTF(stderr,"Stenger: %s\n",pFil->pszNavn); */
+   LO_CloseSos(pFil->pBase);
+
+   /*
+   * Indeks skal alltid fjernes for kladdefilen i kladdebase
+   */
+   if (pFil->pBase->sType == LC_KLADD  &&  (pFil->usLag & LC_FRAMGR)) {
+      s_stat = RESET_IDX;
+   }
+
+   /*
+    * Fjern indeksfilene / lagre indeks og steng filer
+    */
+   if (pFil->usLag != LC_SEKV) {
+		LI_Close(pFil,s_stat);
+   }
+
+   /*
+    * Frigi fil-administrasjonsblokken
+    */
+   LO_DelFilAdm(pFil);
+
+   /* Oppdaterer omskrevet boks for basen */
+   if (Sys.pAktBase != NULL) { /* er basen fortsatt aapent? */
+     pFil = Sys.pAktBase->pForsteFil;
+     pB = &(Sys.pAktBase->Omraade);
+     pB->dMinAust = pB->dMinNord = (double)LONG_MAX;
+     pB->dMaxAust = pB->dMaxNord = (double)LONG_MIN;
+     while (pFil != NULL) {
+        /* Er filen i rett lag? (Hoper over sekvensielle filer) */
+        if (pFil->usLag & (LC_FRAMGR | LC_BAKGR)) {
+           /* Filen inneholder data */
+           if (pFil->pGeoRN != NULL) {
+              pB->dMinAust = min(pB->dMinAust,pFil->Omraade.dMinAust);
+              pB->dMinNord = min(pB->dMinNord,pFil->Omraade.dMinNord);
+              pB->dMaxAust = max(pB->dMaxAust,pFil->Omraade.dMaxAust);
+              pB->dMaxNord = max(pB->dMaxNord,pFil->Omraade.dMaxNord);
+           }
+        }
+        pFil = pFil->pNesteFil;
+     }
+   }
+}
+
+
+/*
+AR:2009-03-20
+CH LC_FcloseSos                             Steng �pen SOSI-fil i filsystemet
+CD ==========================================================================
+CD Form�l:
+CD Denne rutinen brukes til � sikre at en fil er oppdatert og stengt i filsystemet,
+CD slik at SOSI-filen kan leses fra andre program.
+CD 
+CD OBS!
+CD Stenger bare filen i filsystemet.
+CD Filen er fortsatt �pen i basen.
+CD FYBA �pner automatisk filen p� nytt n�r det er behov for dette.
+CD
+CD Parametre:
+CD Type        Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM  *pFil     i   Peker til FilAdm-blokk
+CD
+CD Bruk:
+CD LC_FcloseSos(pFil);
+==========================================================================
+*/
+SK_EntPnt_FYBA void LC_FcloseSos(LC_FILADM *pFil)
+{
+   LO_TestFilpeker(pFil,"LC_FcloseSos");
+
+   // M� lagre aktuell gruppe hvis den er p� denne filen og er endret
+   if (pFil == Sys.GrId.pFil  &&  Sys.GrId.lNr != INGEN_GRUPPE  &&  Sys.sGrEndra != END_UENDRA) {
+      LC_WxGr(SKRIV_OPTIMALT);
+      Sys.sGrEndra = END_UENDRA;
+   }
+
+   // T�mmer skrivek�a for denne filen
+   LB_Save(pFil);
+
+   // Steng eventuell �pen fil
+   LO_CloseSos(pFil->pBase);
+}
+
+
+/*
+AR-911001
+CH LO_CloseSos                                        Steng current SOSI-fil
+CD ==========================================================================
+CD Form�l:
+CD Stenger current SOSI-fil i basen.
+CD
+CD Parametre:
+CD Type         Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BASEADM *  pBase    i    Peker til BaseAdm-blokk
+CD
+CD Bruk:
+CD LO_CloseSos(pBase);
+	==========================================================================
+*/
+void LO_CloseSos(LC_BASEADM * pBase)
+{
+   if (pBase->pCurSos != NULL) {
+      fclose(pBase->pfSos);     
+      pBase->pCurSos = NULL;
+   }
+}
+
+
+/*
+AR-890510
+CH LO_BeFt                                       Beregn omregnings-parametre
+CD ==========================================================================
+CD Form�l:
+CD Oppdaterer filtabellen med hodeinformasjoner fra aktuell gruppe,
+CD som m� v�re SOSI-filens hode.
+CD
+CD Parametre:
+CD Type         Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM   *pFil     i    Peker til FilAdm-blokk
+CD
+CD Bruk:
+CD LO_BeFt(pFil);
+   ==========================================================================
+*/
+void LO_BeFt(LC_FILADM *pFil)
+{
+   double nva,nvn,oha,ohn;
+   short lin;
+   char *cp;
+
+
+   /* Transformasjonsparametre */
+   pFil->TransMaske = LC_TR_ALLT;
+   LC_GetTransEx(&(pFil->TransMaske),&(pFil->TransPar));
+
+   /* Omr�de */
+   LC_GetOmr(&nva,&nvn,&oha,&ohn);
+   pFil->Omr.dMinAust = nva;
+   pFil->Omr.dMinNord = nvn;
+   pFil->Omr.dMaxAust = oha;
+   pFil->Omr.dMaxNord = ohn;
+
+	/* Kvalitet */
+   LC_GetKvalitet(&(pFil->Kvalitet.sMetode),
+                  &(pFil->Kvalitet.lNoyaktighet),
+                  &(pFil->Kvalitet.sSynbarhet),
+                  &(pFil->Kvalitet.sHoydeMetode),
+						&(pFil->Kvalitet.lHoydeNoyaktighet));
+
+   /* Tegnsett */
+   LC_GetTegnsett(&(pFil->sTegnsett));
+
+   /* SOSI-VERSJON */
+   lin=2;
+   if ((cp = LC_GetGP("..SOSI-VERSJON",&lin,Sys.pGrInfo->ngi)) != NULL) {
+      pFil->sSosiVer = (short)(strtod(cp,&cp)*100.0);
+   } else {
+      pFil->sSosiVer = FYBA_SOSI_VERSJON;
+   }
+
+   // DATO
+   lin=2;
+   if ((cp = LC_GetGP("..DATO",&lin,Sys.pGrInfo->ngi)) != NULL) {
+      UT_StrCopy(pFil->szDato,cp,LC_DATO_LEN);
+   } else {
+      UT_StrCopy(pFil->szDato,"*",LC_DATO_LEN);
+   }
+
+   /* SOSI-NIV� */
+   lin=2;
+   if ((cp = LC_GetGP("..SOSI-NIV�",&lin,Sys.pGrInfo->ngi)) != NULL) {
+      pFil->SosiNiv[0] = (char)(strtol(cp,&cp,10));
+   } else {
+      pFil->SosiNiv[0] = 0;
+   }
+
+   /* ..NGIS-LAG */
+   UT_StrCopy(pFil->szNgisLag,LH_GetNgisLag(),LC_NGISLAG_LEN);
+}
+
+
+/*
+AR-911003
+CH LC_GetBaOm                                                Hent baseomr�de
+CD ==========================================================================
+CD Form�l:
+CD Henter baseomr�det for aktuell base (Sum av filhodene).
+CD Sekvensielle filer regnes ikke med.
+CD
+CD Parametre:
+CD Type           Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD unsigned short usLag    i   Velg hvilke "lag" det skal s�kes i.
+CD                               LC_FRAMGR og /eller LC_BAKGR
+CD                               (Bruk "|" for � kombinere.)
+CD double        *nva      u    Nedre venstre �st
+CD double        *nvn      u    Nedre venstre nord
+CD double        *oha      u    �vre h�yre �st
+CD double        *ohn      u    �vre h�yre nord
+CD short          sStatus  r    UT_TRUE=OK, UT_FALSE=ingen fil
+CD
+CD Bruk:
+CD sStatus = LC_GetBaOm(LC_FRAMGR,&nva,&nvn,&oha,&ohn);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetBaOm(unsigned short usLag,double *nva,double *nvn,double *oha,
+                 double *ohn)
+{
+   double na,nn,oa,on;
+   LC_FILADM *pFil;
+	short sAntall = 0;
+
+   *nvn = LONG_MAX; 
+   *nva = LONG_MAX;
+   *ohn = LONG_MIN;
+   *oha = LONG_MIN;
+
+   LC_InitNextFil(&pFil);
+	while (LC_NextFil(&pFil,usLag)) {
+      sAntall++;
+      if (LC_GetFiOm(pFil,&na,&nn,&oa,&on)) {
+         *nva = min (*nva, na);
+         *nvn = min (*nvn, nn);
+         *oha = max (*oha, oa);
+         *ohn = max (*ohn, on);
+      }
+   }
+   
+   return (sAntall > 0);
+}
+
+
+/*
+AR-910928
+CH LC_GetFiOm                                       Hent omr�de fra fil-hode
+CD ==========================================================================
+CD Form�l:
+CD Hent omr�de for en SOSI-fil i basen.
+CD Fungerer ikke mot sekvensielle filer.
+CD
+CD Parametre:
+CD Type       Navn  I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil   i   Peker til FilAdm
+CD double     nva    u   Nedre venstre �st
+CD double     nvn    u   Nedre venstre nord
+CD double     oha    u   �vre h�yre �st
+CD double     ohn    u   �vre h�yre nord
+CD short      ist    r   Status (UT_TRUE=OK, UT_FALSE=sekvensiell fil)
+CD
+CD Bruk:
+CD ist = LC_GetFiOm(pFil,&nva,&nvn,&oha,&ohn);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetFiOm(LC_FILADM *pFil,double *nva,double *nvn,double *oha,double *ohn)
+{
+	/* LO_TestFilpeker(pFil,"LC_GetFiOm"); */
+   LO_TestFilpeker(pFil,"LC_GetFiOm");
+
+   if (pFil->usLag != LC_SEKV) {
+      *nva = pFil->Omr.dMinAust;
+      *nvn = pFil->Omr.dMinNord;
+      *oha = pFil->Omr.dMaxAust;
+      *ohn = pFil->Omr.dMaxNord;
+      return UT_TRUE;
+   }
+
+   return UT_FALSE;
+}
+
+
+/*
+AR-911001
+CH LO_InklSos                                       Inkluder SOSI-fil i base
+CD ==========================================================================
+CD Form�l:
+CD Hjelperutine for LC_OpenSos.
+CD Bygger indeks og klargj�r filen for basen.
+CD Prosessen kan avbrytes med <ESC>, og rutinen returnerer da UT_FALSE.
+CD Aktuell gruppe blir brukt under prosessen, og etterp� er det ingen
+CD aktuell gruppe tilgjengelig.
+CD
+CD Parametre:
+CD Type       Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil        i   Peker til FilAdm
+CD short      sVisStatus  i   Vis indeksoppbygging
+CD                               LC_VIS_STATUS   = Vis status
+CD                               LC_INGEN_STATUS = Ikke vis status
+CD short      sStatus     r   Status: UT_TRUE=OK, UT_FALSE=avbrutt eller feil 
+CD
+CD Bruk:
+CD ant_bgr = LO_InklSos(pFil,LC_VIS_STATUS);
+   ==========================================================================
+*/
+static short LO_InklSos(LC_FILADM *pFil,short sVisStatus)
+{
+   unsigned long ulLedigPlass;
+   short siste,ngi,nivaa;
+   long nko;
+	unsigned short info;
+   UT_INT64 pos,fpos;
+   long lGrNr;
+   LC_BGR Bgr;
+   LC_GRTAB_LINJE *pForrigeGrInfo,*pGrInfo;
+   LC_BOKS * pB;
+   short avbrutt = 0;
+   double lengde_faktor = 0.0;
+   short sStatus = UT_TRUE;
+   short pnr = 1;
+
+   // Hvis aktuell gruppe er endret, skriv den
+   if (Sys.GrId.lNr != INGEN_GRUPPE  &&  Sys.sGrEndra != END_UENDRA) {
+      LC_WxGr(SKRIV_OPTIMALT);
+   }
+
+   LO_ReopenSos(pFil);    // Sikkrer at filen er �pen - Kan ha blitt stengt i LC_WxGr
+
+   Sys.GrId.pFil = pFil;
+  
+   // ----- S�k fram til .HODE
+   if (ho_FinnHode(pFil->pBase->pfSos, &pos) == UT_TRUE) {
+
+      // ----- Bygg indeks
+      /* Sikkrer at ny lesing startes */
+      _fseeki64(pFil->pBase->pfSos,pos,SEEK_SET);
+
+      /* Ledetekst */
+      if (sVisStatus == LC_VIS_STATUS) {
+         LC_StartMessage(pFil->pszNavn);
+		   fpos = _ftelli64(pFil->pBase->pfSos);
+         _fseeki64(pFil->pBase->pfSos,-1,SEEK_END);
+         lengde_faktor = 100.0 / (double)_ftelli64(pFil->pBase->pfSos);
+         _fseeki64(pFil->pBase->pfSos,fpos,SEEK_SET);
+      }
+
+      pForrigeGrInfo = NULL;
+
+      do {
+         if (pFil->lAntGr < LC_MAX_GRU) {        /* Klargj�r for lesing */
+
+			   /* Sjekk ledig diskplass  for SOSI-filer */
+
+            if (pFil->sAccess == UT_UPDATE) {
+			      UT_InqAvailSize(pFil->pszNavn,&ulLedigPlass);
+			      if (ulLedigPlass < ((unsigned long)LC_MAX_KOORD * (unsigned long)120)) {
+                  /* Disken er snart full */
+                  LC_Error(93,"(LO_InklSos)",pFil->pszNavn);
+               }
+            }
+
+            Sys.GrId.lNr = pFil->lAntGr++;   /* (Nr er 1 mindre enn antall) */
+
+			   Sys.pGrInfo = LI_AppGrt(pFil,Sys.GrId.lNr);
+
+
+            Sys.pGrInfo->sosi_st = pos;
+
+
+
+            /* Les gruppen */
+            siste = LB_RGru(pFil,pos,&pos);
+
+            /* Buffer for GetPP er �delagt */
+            Sys.sPibufStatus = LC_PIBUF_TOM;
+      
+			   /* Grafisk vising av mengde lest */
+            if (sVisStatus == LC_VIS_STATUS) {
+               LC_ShowMessage((double)pos * lengde_faktor);
+            }
+
+            /* Gruppe lest OK */
+            if ( ! siste) {
+               LC_OppdaterEndret(O_GINFO);
+               nivaa = 2;
+				   LC_GetCurKvalitet(Sys.GrId.pFil,&nivaa,pnr,
+                              &Sys.pGrInfo->Kvalitet.sMetode,
+                              &Sys.pGrInfo->Kvalitet.lNoyaktighet,
+                              &Sys.pGrInfo->Kvalitet.sSynbarhet,
+                              &Sys.pGrInfo->Kvalitet.sHoydeMetode,
+                              &Sys.pGrInfo->Kvalitet.lHoydeNoyaktighet);
+
+               /* Oppdater buffer-fil */
+               Sys.GrId.pFil->lSisteGrRb = Sys.GrId.lNr;
+               Sys.pGrInfo->rb_st = Sys.GrId.pFil->n64NesteLedigRbPos;
+               Sys.pGrInfo->rb_forrige_gr = Sys.GrId.lNr - 1L;
+               Sys.pGrInfo->rb_neste_gr = INGEN_GRUPPE;
+               Sys.pGrInfo->ulPrior[0] = 0UL;
+				   Sys.pGrInfo->ulPrior[1] = 0UL;
+				   Sys.pGrInfo->ulPrior[2] = 0UL;
+				   Sys.pGrInfo->ulPrior[3] = 0UL;
+
+               if (pForrigeGrInfo != NULL) {
+                  pForrigeGrInfo->rb_neste_gr = Sys.GrId.lNr;
+               }
+
+				   LI_WriteRb(Sys.GrId.pFil,Sys.pGrInfo->rb_st,Sys.Ginfo.pszTx,Sys.pGrInfo->ulGiLen,
+                          Sys.pdAust, Sys.pdNord, Sys.pInfo, Sys.pGrInfo->nko,
+                          Sys.pszPinfo, Sys.pGrInfo->ulPiLen);
+ 
+               Sys.GrId.pFil->n64NesteLedigRbPos +=
+                     (UT_INT64)LI_BerBufferLen(Sys.pGrInfo->ulGiLen,Sys.pGrInfo->nko,Sys.pGrInfo->ulPiLen);
+
+               pForrigeGrInfo = Sys.pGrInfo;
+
+              /* Nuller merking */
+               LI_PutBt(pFil,Sys.GrId.lNr,0L);
+
+               LS_Indx();          /* Serienummer tabeller */
+               LR_Indx();          /* Geografisk indeks */
+
+            /* ".SLUTT" er lest */
+			   } else {
+               pFil->n64AktPos = pos;
+               pFil->lAntGr--;
+			   }
+
+         } else {                     /* For mange grupper, tab. sprengt */
+            UT_SNPRINTF(err().tx,LC_ERR_LEN," %ld",pFil->lAntGr+1L);
+            LC_Error(2,"(LO_InklSos)",err().tx);
+            exit(99);
+         }
+
+         avbrutt = LC_Cancel();     /* <ESC> avbryter lesing */
+      } while ( !siste  &&  !avbrutt);
+
+
+                     /* Bygg indeks for grupper med referanser */
+      if (! avbrutt) {          /* Lesing er avbrutt */
+         lengde_faktor = 100.0 / (double)pFil->lAntGr;
+
+         Bgr.pFil = pFil;
+         for (lGrNr=0; lGrNr<pFil->lAntGr && !avbrutt; lGrNr++) {
+            if (sVisStatus == LC_VIS_STATUS) {
+				   LC_ShowMessage((double)lGrNr * lengde_faktor);
+            }
+
+            /* Sjekk om gruppen har referanser */
+            pGrInfo = LI_GetGrt(pFil,lGrNr);
+            if ((pGrInfo->info & GI_REF) != 0) {
+               /* Les inn og beregn omskreven boks medregnet refererte grupper */
+               Bgr.lNr = lGrNr;
+               if (LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info) != INGEN_GRUPPE) { 
+                  LR_IndxFlate();
+               }
+            }
+
+            avbrutt = LC_Cancel();     /* <ESC> avbryter lesing */
+         }
+      }
+
+      Sys.GrId.lNr = INGEN_GRUPPE;               /* Ingen aktuell gruppe */
+      Sys.sGrEndra = END_UENDRA;
+
+      /* Oppdaterer omskrevet boks for basen */
+      if ( ! avbrutt) {          /* Lesing er avbrutt */
+         pFil = Sys.pAktBase->pForsteFil;
+         pB = &(Sys.pAktBase->Omraade);
+         pB->dMinAust = pB->dMinNord = (double)LONG_MAX;
+         pB->dMaxAust = pB->dMaxNord = (double)LONG_MIN;
+         while (pFil != NULL) {
+            /* Er filen i rett lag? (Hoper over sekvensielle filer) */
+            if (pFil->usLag & (LC_FRAMGR | LC_BAKGR)) {
+               /* Filen inneholder data */
+               if (pFil->pGeoRN != NULL) {
+                  pB->dMinAust = min(pB->dMinAust,pFil->Omraade.dMinAust);
+                  pB->dMinNord = min(pB->dMinNord,pFil->Omraade.dMinNord);
+                  pB->dMaxAust = max(pB->dMaxAust,pFil->Omraade.dMaxAust);
+                  pB->dMaxNord = max(pB->dMaxNord,pFil->Omraade.dMaxNord);
+               }
+            }
+            pFil = pFil->pNesteFil;
+         }
+      }
+
+      if (avbrutt) {          /* Lesing er avbrutt */
+         LC_Error(10,"(LO_InklSos)","");
+		   pFil->lAntGr = 0L;
+         sStatus = UT_FALSE;
+      }
+
+      if (sVisStatus == LC_VIS_STATUS) {
+         LC_EndMessage();
+      }
+   }
+
+   return sStatus;
+}
+
+
+/*
+AR-911001
+CH LC_GetFiNr                                                 Get fil nummer
+CD ==========================================================================
+CD Form�l:
+CD Sjekker alle filer i aktuell base om noen av den har det gitte filnavnet.
+CD
+CD Parametre:
+CD Type        Navn     I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD char        fil_navn  i   Filnavn
+CD LC_FILADM  *pFil      r   Peker til FilAdm for filen. (NULL = ukjent fil)
+CD
+CD Bruk:
+CD pFil = LC_GetFiNr(fil_navn);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA LC_FILADM *LC_GetFiNr(const char *fil_navn)
+{
+   LC_FILADM *pFil;
+   char drive[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
+   char szSosFil[_MAX_PATH];
+
+
+   /*
+    * Bygg opp fullstendig filnavn
+    */
+   UT_FullPath(szSosFil,fil_navn,_MAX_PATH);
+   UT_splitpath(szSosFil,drive,dir,fname,ext);
+   if (*ext == '\0')  UT_StrCopy(ext,".sos",_MAX_EXT);
+	UT_makepath(szSosFil,drive,dir,fname,ext);
+
+   for (pFil=Sys.pAktBase->pForsteFil; pFil!=NULL; pFil=pFil->pNesteFil) {
+      /* Rett filnavn? ==> */
+      if (UT_FilnavnCmp(pFil->pszNavn,szSosFil) == 0)   return pFil;
+   }
+
+   return  NULL;
+}
+
+
+/*
+AR-911001
+CH LC_GetFiNa                                                   Hent filnavn
+CD ==========================================================================
+CD Form�l:
+CD Henter filnavnet for en fil i basen. Fungerer b�de for basefiler
+CD og for sekvensielle filer.
+CD OBS! Hvis du skal endre p� filnavnet m� du f�rst kopiere det 
+CD      til en lokale varialel.
+CD
+CD Parametre:
+CD Type        Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM  *pFil       i    Peker til FilAdm
+CD char       *fil_navn   r    Peker til filnavn 
+CD
+CD Bruk:
+CD fil_navn = LC_GetFiNa(pFil);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA char *LC_GetFiNa(LC_FILADM *pFil)
+{
+   /* LO_TestFilpeker(pFil,"LC_GetFiNa"); */
+   LO_TestFilpeker(pFil,"GetFiNa");
+
+   return pFil->pszNavn;
+}
+
+
+/*
+AR-920729
+CH LO_TestFilpeker                            Sjekk at en filpeker er gyldig
+CD ==========================================================================
+CD Form�l:
+CD Sjekk at en filpeker er gyldig.
+CD
+CD Parametre:
+CD Type        Navn         I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM * pFil          i    Peker til FilAdm
+CD char       *pszRutineNavn i    Melding (rutinenavnet for kallende rutine)
+CD
+CD Bruk:
+CD LO_TestFilpeker(pFil,"LC_OpenBase");
+   ==========================================================================
+*/
+void LO_TestFilpeker(LC_FILADM *pFil,char *pszRutineNavn)
+{
+   char szTx[100];
+
+
+   if (pFil == NULL  ||  *(pFil->szBaseVer) != 'F') { 
+
+      UT_SNPRINTF(szTx,100," %s,  (Filpeker: %p)",pszRutineNavn,pFil); 
+      LC_Error(105,"(TestFilpeker)",szTx);
+   }
+}
+
+
+/*
+AR-921008
+CH LC_ErFilBase                                 Sjekker om en fil er i basen
+CD ==========================================================================
+CD Form�l:
+CD Sjekker om en fil er i basen.
+CD
+CD Parametre:
+CD Type    Navn   I/U  Forklaring
+CD --------------------------------------------------------------------
+CD char   *fil     i   Filnavn inkl. sti og fil-type
+CD                     (Hvis fil-type mangler forutsettes  .SOS)
+CD short   status  r   Status: UT_TRUE = Filen er med i basen.
+CD                             UT_FALSE = Filen er IKKE med i basen.
+CD
+CD Bruk:
+CD ist = LC_ErFilBase(fil);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_ErFilBase(const char *fil)
+{
+   char drive[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
+   char szSosFil[_MAX_PATH];
+
+   /*
+    * Bygg opp fullstendig filnavn
+    */
+   UT_FullPath(szSosFil,fil,_MAX_PATH);
+   UT_splitpath(szSosFil,drive,dir,fname,ext);
+   if (*ext == '\0')  UT_StrCopy(ext,".sos",_MAX_EXT);
+   UT_makepath(szSosFil,drive,dir,fname,ext);
+
+   /* Sjekk om filen er i basen fra f�r */
+   if (LC_GetFiNr(szSosFil) != NULL)  return UT_TRUE;  /* Er i basen */
+
+   return UT_FALSE;  /* Er ikke i basen */
+}
+ 
+
+
+/*
+AR-940923
+CH LC_ErKoordsysLik                                      Sjekker KOORDSYS
+CD =======================================================================
+CD Form�l:
+CD Sjekk at alle filene i basen har samme koordinatsystem.
+CD
+CD Parametre:
+CD Type    Navn   I/U  Forklaring
+CD -----------------------------------------------------------------------
+CD short   status  r   Status: UT_TRUE = KOORDSYS er lik.
+CD                             UT_FALSE = KOORDSYS er IKKE lik.
+CD
+CD Bruk:
+CD ist = LC_ErKoordsysLik();
+	=======================================================================
+*/
+SK_EntPnt_FYBA short LC_ErKoordsysLik(void)
+{
+   short sKoSys = 0;
+   short sFilNr = 0;
+   LC_FILADM *pFil;
+
+   /* Sjekk at alle filene i basen har samme koordinatsystem */
+   LC_InitNextFil(&pFil);
+
+   while (LC_NextFil(&pFil,LC_FRAMGR | LC_BAKGR))
+   {
+      sFilNr++;
+      if (sFilNr == 1)
+      {
+         sKoSys = pFil->TransPar.sKoordsys;
+      } 
+
+      else if (pFil->TransPar.sKoordsys != sKoSys)
+      {
+         LC_FILADM *pF;
+
+         // Skriv filnavn og koordinatsystem til loggfilen
+
+         UT_FPRINTF(stderr,"Det er funnet filer med ulikt koordinatsystem:\n");
+
+         LC_InitNextFil(&pF);
+         while (LC_NextFil(&pF,LC_FRAMGR | LC_BAKGR))
+         {
+            UT_FPRINTF(stderr,"   \"%s\" : %hd\n",pF->pszNavn,pF->TransPar.sKoordsys);
+         }
+         return  UT_FALSE;
+      }
+   }
+
+   return  UT_TRUE;
+}
+
+
+
+/*
+AR-940923
+CH LC_ErVertdatumLik                                   Sjekker VERT-DATUM
+CD =======================================================================
+CD Form�l:
+CD Sjekk at alle filene i basen har samme VERT-DATUM.
+CD
+CD Parametre:
+CD Type    Navn   I/U  Forklaring
+CD -----------------------------------------------------------------------
+CD short   status  r   Status: UT_TRUE = VERT-DATUM er lik.
+CD                             UT_FALSE = VERT-DATUM er IKKE lik.
+CD
+CD Bruk:
+CD ist = LC_ErVertdatumLik();
+	=======================================================================
+*/
+SK_EntPnt_FYBA short LC_ErVertdatumLik(void)
+{
+   char szVertdatHref[7];
+   char szVertdatDref[6];
+   char szVertdatFref[6];
+   char szVertdatHtyp[2];
+
+   bool bForsteFil = true;
+   LC_FILADM *pFil;
+
+   /* Sjekk at alle filene i basen har samme VERT-DATUM */
+   LC_InitNextFil(&pFil);
+
+   while (LC_NextFil(&pFil,LC_FRAMGR | LC_BAKGR))
+   {
+      // Sjekker bare filer med VERT-DATUM gitt i filhodet
+      // (Overser standardverdien)
+      if (strlen(pFil->TransPar.szVertdatHref) > 0)
+      {
+         if ( bForsteFil)
+         {
+            UT_StrCopy(szVertdatHref, pFil->TransPar.szVertdatHref, 7);
+            UT_StrCopy(szVertdatDref, pFil->TransPar.szVertdatDref, 6);
+            UT_StrCopy(szVertdatFref, pFil->TransPar.szVertdatFref, 6);
+            UT_StrCopy(szVertdatHtyp, pFil->TransPar.szVertdatHtyp, 2);
+            bForsteFil = false;
+         } 
+
+         else if (UT_StrCmpi(pFil->TransPar.szVertdatHref,szVertdatHref) != 0  ||
+                  UT_StrCmpi(pFil->TransPar.szVertdatDref,szVertdatDref) != 0  ||
+                  UT_StrCmpi(pFil->TransPar.szVertdatFref,szVertdatFref) != 0  ||
+                  UT_StrCmpi(pFil->TransPar.szVertdatHtyp,szVertdatHtyp) != 0    )
+         {
+            LC_FILADM *pF;
+
+            // Skriv filnavn og VERT-DATUM til loggfilen
+
+            UT_FPRINTF(stderr,"Det er funnet filer med ulikt VERT-DATUM:\n");
+
+            LC_InitNextFil(&pF);
+            while (LC_NextFil(&pF,LC_FRAMGR | LC_BAKGR))
+            {
+               UT_FPRINTF(stderr,"   \"%s\" : \"%s %s %s %s\"\n",
+                         pF->pszNavn,
+                         pF->TransPar.szVertdatHref,
+                         pF->TransPar.szVertdatDref,
+                         pF->TransPar.szVertdatFref,
+                         pF->TransPar.szVertdatHtyp);
+            }
+            return  UT_FALSE;
+         }
+      }
+   }
+
+   return  UT_TRUE;
+}
+
+
+/*
+AR:2000-11-30
+CH LC_SetEndringsstatus             Setter endringsstatus for aktuell gruppe
+CD ==========================================================================
+CD Form�l:
+CD Setter endringsstatus for aktuell gruppe.
+CD
+CD NB! Denne rutinen b�r normalt ikke brukes av vanlige klient-program!
+CD
+CD
+CD Parametre:
+CD Type   Navn      I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD short  sStatus    i   Kode for endring:
+CD                         END_UENDRA  0   Ikke endra
+CD                         END_KOPI    1   Endra ved totalkopi fra annen gruppe
+CD                         END_ENDRA   2   Endra ved normal Put fra program
+CD
+CD Bruk:
+CD LC_dg_SetEndringsstatus(END_KOPI);
+=============================================================================
+*/
+SK_EntPnt_FYBA void LC_SetEndringsstatus(short sStatus)
+{
+   Sys.sGrEndra = sStatus;
+}
+
+/*
+JA�:2001-03-06
+CH LC_SetFilType								Setter filtype for en sosifil
+CD ==========================================================================
+CD Form�l:
+CD Setter filtype for en fil.
+CD
+CD Denne rutinen er prim�rt tenkt brukt i GabEdit hvor det er behov for � 
+CD definere flere typer arbeidsfil.
+CD
+CD Parametre:
+CD Type         Navn   I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *  pFil	   i   Peker til filen
+CD short        type    i   Filtypen som skal settes
+CD                             LC_FILTYPE_UKJENT
+CD                             LC_FILTYPE_INAKTIV
+CD                             LC_FILTYPE_GAB_EIENDOM
+CD                             LC_FILTYPE_GAB_ADRESSE
+CD                             LC_FILTYPE_GAB_BYGNING
+CD                             LC_FILTYPE_BYGG
+CD                             LC_FILTYPE_DEK
+CD                             LC_FILTYPE_DEK_ENDRING
+CD                             LC_FILTYPE_GRUNNKRETS
+CD                             LC_FILTYPE_POSTKRETS
+CD                             LC_FILTYPE_SKOLEKRETS
+CD                             LC_FILTYPE_KIRKESOGN
+CD                             LC_FILTYPE_TETTSTED
+CD                             LC_FILTYPE_VALGKRETS
+CD
+CD Bruk:
+CD LC_SetFilType(pFil,type);
+=============================================================================
+*/
+SK_EntPnt_FYBA void LC_SetFilType(LC_FILADM *pFil, short sType)
+{  
+   LO_TestFilpeker(pFil,"SetFilType");
+	pFil->sFilType = sType;
+}
+
+/*
+JA�:2001-03-06
+CH LC_GetFilType                               Henter filtype for en sosifil
+CD ==========================================================================
+CD Form�l:
+CD Finner filtypen for en fil.
+CD
+CD Parametre:
+CD Type         Navn   I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *  pFil	   i   Peker til filen
+CD short        type    r   Filtypen som skal settes
+CD                             LC_FILTYPE_UKJENT
+CD                             LC_FILTYPE_INAKTIV
+CD                             LC_FILTYPE_GAB_EIENDOM
+CD                             LC_FILTYPE_GAB_ADRESSE
+CD                             LC_FILTYPE_GAB_BYGNING
+CD                             LC_FILTYPE_BYGG
+CD                             LC_FILTYPE_DEK
+CD                             LC_FILTYPE_DEK_ENDRING
+CD                             LC_FILTYPE_GRUNNKRETS
+CD                             LC_FILTYPE_POSTKRETS
+CD                             LC_FILTYPE_SKOLEKRETS
+CD                             LC_FILTYPE_KIRKESOGN
+CD                             LC_FILTYPE_TETTSTED
+CD                             LC_FILTYPE_VALGKRETS
+CD
+CD Bruk:
+CD type = LC_GetFilType(pFil);
+=============================================================================
+*/
+SK_EntPnt_FYBA short LC_GetFilType(LC_FILADM *pFil)
+{
+   LO_TestFilpeker(pFil,"GetFilType");
+	return pFil->sFilType;
+}
+
+
+/*
+AR:2004-05-03
+CH LC_GetIdxPath                               Hent katalog for ny indeksfil
+CD ==========================================================================
+CD Form�l:
+CD Hent katalognavn for ny indeks. For detaljer se under LC_SetIdxPath.
+CD
+CD Parametre:
+CD Type         Navn        I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD const char  *pszIdxPath   r    Katalog for indeks
+CD
+CD Bruk:
+CD const char *pszIdxPath = LC_GetIdxPath();
+   ==========================================================================
+*/
+SK_EntPnt_FYBA const char *LC_GetIdxPath(void)
+{
+   return Sys.szIdxPath;
+}
+
+
+/*
+AR:2011-05-31
+CH LC_SetIdxPath                               Velg katalog for ny indeksfil
+CD ==========================================================================
+CD Form�l:
+CD Velg katalognavn for ny indeks. Indeksfilene for en SOSI-fil legges som
+CD en underkatalog under den gitte katalogen. Underkatalogen har samme navn
+CD som SOSI-filen. Hvis det er valgt spesiell plassering av indeksfilene blir
+CD disse alltid slettet n�r SOSI-filen stenges.
+CD OBS! Ingen SOSI-filer kan v�re �pne n�r indekskatalog velges.
+CD
+CD Parametre:
+CD Type        Navn       I/U Forklaring
+CD --------------------------------------------------------------------------
+CD const char *pszIdxPath  i  Katalog for indeks
+CD                            "" = Tom streng betyr at indeksfilene legges p� en
+CD                                 underkatalog under katalogen der SOSI-filen ligger
+CD                                 (default).
+CD                            "katalognavn" = Indeksfilene legges p� en
+CD                                            underkatalog under denne katalogen.
+CD short       status      r  Status: UT_TRUE = OK
+CD                                    UT_FALSE = Feil, feilmelding er gitt.
+CD
+CD Bruk:
+CD status = LC_SetIdxPath("C:\\kart\\test");
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_SetIdxPath(const char *pszIdxPath)
+{
+   if (LC_InqAntFiler(LC_FRAMGR|LC_BAKGR) == 0)
+   {
+      // Handter TEMP spesielt
+      /*
+      CD "TEMP" = Indeksfilene legges p� brukerens temp-katalog.
+      // 2011-05-31: Handtering av "TEMP" er fjernet.
+      if (_strcmpi(pszIdxPath,"TEMP") == 0)
+      {
+         char szBuffer[_MAX_PATH];
+         size_t returnValue;
+        // Hent katalognavn fra environment
+         getenv_s( &returnValue, szBuffer, _MAX_PATH, "TEMP");
+         if(returnValue == 0)
+         {
+            getenv_s( &returnValue, szBuffer, _MAX_PATH, "TMP");
+         }
+         if(returnValue == 0)
+         {
+            Sys.szIdxPath[0] = '\0';
+            return UT_FALSE;
+         }
+         else
+         {
+            UT_StrCopy(Sys.szIdxPath,szBuffer,_MAX_PATH);
+            if (Sys.szIdxPath[strlen(Sys.szIdxPath)-1] != UT_SLASH)  UT_StrCat(Sys.szIdxPath,UT_STR_SLASH,_MAX_PATH);
+         }
+      }
+      else 
+      */
+      if (*pszIdxPath == '\0')
+      {
+         Sys.szIdxPath[0] = '\0';
+      }
+
+      else
+      {
+         UT_StrCopy(Sys.szIdxPath,pszIdxPath,_MAX_PATH);
+         if (Sys.szIdxPath[strlen(Sys.szIdxPath)-1] != UT_SLASH)  UT_StrCat(Sys.szIdxPath,UT_STR_SLASH,_MAX_PATH);
+
+         // Opprett katalogen hvis den ikke finnes fra f�r
+         UT_CreateDir(Sys.szIdxPath);
+      }
+
+      return UT_TRUE;
+   }
+
+   return UT_FALSE;
+}
diff --git a/FYBA/FYLP.cpp b/FYBA/FYLP.cpp
new file mode 100644
index 0000000..a5ecf76
--- /dev/null
+++ b/FYBA/FYLP.cpp
@@ -0,0 +1,1169 @@
+/* === AR-970929 ========================================================= */
+/*  STATENS KARTVERK  -  FYSAK-PC                                          */
+/*  Fil: fylp.c                                                            */
+/*  Innhold: Polygonhandtering for FYSAK-PC                                */
+/* ======================================================================= */
+
+#include "stdafx.h"
+
+#include <ctype.h>
+#include <memory.h>
+#include <limits.h>
+
+
+/* Globale variabler for FYBA */
+extern LC_SYSTEMADM Sys;             /* Systemadministrasjon */
+
+
+/*
+AR-970929
+CH LC_POL_LeggTilGruppeOmkrets                       Legg til eit element
+CD =======================================================================
+CD Bruk:
+CD LC_POL_OMKR  YtrePolygon;
+CD pElement = LC_POL_LeggTilGruppeOmkrets(YtrePolygon,pBgr,sRetning,lSnr);
+CD
+CD parametere:
+CD Type            Navn     I/U    Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POL_OMKR *    pPO      I/U    Peikar til polygonadministrasjonsblokka
+CD LC_BGR *         pBgr      I     Gruppenummer
+CD short           sRetning  I     N�steretning (LC_MED_DIG eller LC_MOT_DIG)
+CD long            lSnr      I     Serienummer
+CD LC_POL_ELEMENT * pElement  R     Peker til innlagt element
+CD
+CD Legg til eit element i kjeden av polygonelement.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA LC_POL_ELEMENT * LC_POL_LeggTilGruppeOmkrets(LC_POL_OMKR *pPO,LC_BGR *pBgr,
+                                                short sRetning, long lSnr)
+{
+  LC_POL_ELEMENT * pPE;
+  pPE = (LC_POL_ELEMENT *) UT_MALLOC(sizeof(LC_POL_ELEMENT));
+  pPE->pForrigePE = pPO->pSistePE;
+  pPE->pNestePE = NULL;
+
+  if(pPO->pForstePE == NULL) {
+    pPO->pForstePE = pPE;
+
+  } else {
+    pPO->pSistePE->pNestePE = pPE;
+
+  }
+
+  pPO->pSistePE = pPE;
+
+  pPE->Bgr = *pBgr;
+  pPE->sRetning = sRetning;
+  pPE->lSnr = lSnr;
+
+  return pPE;
+}
+
+
+/*
+SJM-930921
+CH LC_POL_FjernSisteGruppeOmkrets                   Fjernar siste element
+CD =======================================================================
+CD Bruk:
+CD LC_POL_OMKR  YtrePolygon;
+CD LC_POL_FjernSisteGruppeOmkrets(&YtrePolygon);
+CD
+CD parametere:
+CD Type         Navn     I/U    Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POL_OMKR *  pPO      I/U    Peikar til polygonadministrasjonsblokka
+CD
+CD Fjernar siste element i kjeden av polygonelement.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_FjernSisteGruppeOmkrets(LC_POL_OMKR *pPO)
+{
+   LC_POL_ELEMENT *pPE = pPO->pSistePE;
+
+   if (pPE != NULL) {
+      pPO->pSistePE = pPE->pForrigePE;
+      if(pPE->pForrigePE == NULL) {
+         pPO->pForstePE = NULL;
+
+      } else {
+         pPE->pForrigePE->pNestePE = NULL;
+      }
+		UT_FREE(pPE);
+   }
+}
+
+
+/*
+AR-971112
+CH LC_POL_FjernGruppeOmkrets                              Fjernar element
+CD =======================================================================
+CD Bruk:
+CD LC_POL_OMKR  YtrePolygon;
+CD LC_POL_FjernGruppeOmkrets(&YtrePolygon,);
+CD
+CD parametere:
+CD Type            Navn     I/U    Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POL_OMKR    *pPO      I/U    Peikar til polygonadministrasjonsblokka
+CD LC_POL_ELEMENT *pPE       I      Peker til element som skal fjernes
+CD
+CD Fjernar et element i kjeden av polygonelement.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_FjernGruppeOmkrets(LC_POL_OMKR *pPO, LC_POL_ELEMENT *pPE)
+{
+   /* Oppdaterer pekeren til neste element */
+   if (pPE->pForrigePE != NULL) {
+      /* Inne i kjeden */
+      pPE->pForrigePE->pNestePE = pPE->pNestePE;
+   } else {
+      /* Starten av kjeden */
+      pPO->pForstePE = pPE->pNestePE;
+   }
+
+   /* Oppdaterer pekeren til forrige element */
+   if (pPE->pNestePE != NULL) {
+      /* Inne i kjeden */
+      pPE->pNestePE->pForrigePE = pPE->pForrigePE;
+   } else {
+      /* Slutten av kjeden */
+      pPO->pSistePE = pPE->pForrigePE;
+   }
+	UT_FREE(pPE);
+}
+
+
+/*
+SJM-930921
+CH LC_POL_FrigiAlleOyer    Frigjer minne som er allokert til kjede av �yelement
+CD =======================================================================
+CD Bruk:                           
+CD LC_OY_ADM  OyKjede;
+CD LC_POL_FrigiAlleOyer(OyKjede);
+CD
+CD parametere:
+CD Type       Navn     I/U    Forklaring
+CD -----------------------------------------------------------------------
+CD LC_OY_ADM *pOA      I/U    Peikar til �yadministrasjonsblokka
+CD
+CD Frigjer minne som er allokert til kjede av �y (i polygon) - element.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_FrigiAlleOyer(LC_OY_ADM *pOA)
+{
+  LC_OY_ELEMENT *pOE,*pNesteOE;
+
+  pOE = pOA->pForsteOE;
+
+  /* Frigir omkretsen av hver �y */
+  while(pOE != NULL) {
+    LC_POL_FrigiOmkrets(&(pOE->PO));
+	 pNesteOE = pOE->pNesteOE;
+	 UT_FREE(pOE);
+	 pOE = pNesteOE;
+  }
+  pOA->pForsteOE = NULL;
+  pOA->pSisteOE = NULL;
+}
+
+
+/*
+SJM-931003
+CH LC_POL_FjernOy                    Fjernar ei oy fr� kjede av �yelement
+CD =======================================================================
+CD Bruk:
+CD LC_OY_ADM  OyKjede;
+CD LC_POL_FjernOy(OyKjede,OyElement);
+CD
+CD parametere:
+CD Type           Navn     I/U    Forklaring
+CD -----------------------------------------------------------------------
+CD LC_OY_ADM     *pOA      I/U    Peikar til �yadministrasjonsblokka
+CD LC_OY_ELEMENT *pOE      I/U    Peikar til kjede av oyar
+CD
+CD Frigjer minne som er allokert til kjede av �y (i polygon) - element.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_FjernOy(LC_OY_ADM *pOA,LC_OY_ELEMENT *pOE)
+{
+   /* UT_FPRINTF(stderr,"LC_POL_FjernOy: Kallar LC_POL_Frigi()\n"); */
+   LC_POL_FrigiOmkrets(&(pOE->PO));
+
+   /* Frigir �ykjeda */
+   if (pOE->pForrigeOE != NULL) {
+      pOE->pForrigeOE->pNesteOE = pOE->pNesteOE;
+   } else {
+      pOA->pForsteOE = pOE->pNesteOE;
+   }
+
+   if (pOE->pNesteOE != NULL) {
+      pOE->pNesteOE->pForrigeOE = pOE->pForrigeOE;
+   } else {
+      pOA->pSisteOE = pOE->pForrigeOE;
+   }
+	UT_FREE(pOE);
+}
+
+
+/*
+SJM-930921
+CH LC_POL_LeggTilOy                                  Legg til eit element
+CD =======================================================================
+CD Bruk:
+CD LC_OY_ADM  OyKjede;
+CD LC_POL_LeggTilOy(&OyKjede,pPO);
+CD
+CD Parametere:
+CD Type         Navn     I/U    Forklaring
+CD -----------------------------------------------------------------------
+CD LC_OY_ADM   *pOyKjede I/U    Peikar til kjede av �yelement
+CD LC_POL_OMKR *pPO       I     Peikar til polygonadministrasjonsblokka
+CD
+CD Legg til eit element i kjeden av �yar (i polygon) - element.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_LeggTilOy(LC_OY_ADM *pOA,LC_POL_OMKR *pPO)
+{
+  LC_OY_ELEMENT *pOE;
+  pOE = (LC_OY_ELEMENT *) UT_MALLOC(sizeof(LC_OY_ELEMENT));
+  pOE->pForrigeOE = pOA->pSisteOE;
+  pOE->pNesteOE = NULL;
+  pOE->PO = *pPO;
+
+  if(pOA->pForsteOE == NULL) {
+    pOA->pForsteOE = pOE;
+
+  } else {
+    pOA->pSisteOE->pNesteOE = pOE;
+
+  }
+
+  pOA->pSisteOE = pOE;
+  /* *********************************************
+  UT_FPRINTF(stderr,"LC_POL_LeggTilOy: Aktuell OE %p\n",pOE);
+  UT_FPRINTF(stderr,"LC_POL_LeggTilOy: OA->f�rsteOE %p\n" ,pOA->pForsteOE);
+  UT_FPRINTF(stderr,"LC_POL_LeggTilOy: SisteOE->nesteOE %p\n",pOA->pSisteOE->pNesteOE);
+  UT_FPRINTF(stderr,"LC_POL_LeggTilOy: SisteOE %p\n",pOA->pSisteOE);
+   ********************************************* */
+}
+
+
+/*
+SJM-930921
+CH LC_POL_FrigiOmkrets     Frigjer minne som er allokert til kjede av polygonelement
+CD =======================================================================
+CD Bruk:
+CD
+CD parametere:
+CD Type         Navn     I/U    Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POL_OMKR *pPO      I/U    Peikar til polygonadministrasjonsblokka
+CD
+CD Frigir minne som er allokert til kjede av polygonelement.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_FrigiOmkrets(LC_POL_OMKR *pPO)
+{
+  LC_POL_ELEMENT *pPE,*pNestePE;
+
+  pPE = pPO->pForstePE;
+
+  while(pPE != NULL) {
+    /* UT_FPRINTF(stderr,"LC_POL_FrigiOmkrets: pPE = %p\n",pPE); */
+	 pNestePE = pPE->pNestePE;
+	 UT_FREE(pPE);
+	 pPE = pNestePE;
+  }
+  pPO->pForstePE = NULL;
+  pPO->pSistePE = NULL;
+}
+
+
+/*
+AR-931208
+CH LC_POL_FrigiPolygon            Frigi minne som er allokert til polygon
+CD =======================================================================
+CD Form�l:
+CD Frigir minne som er allokert til polygon. (B�de omkrets og hull.)
+CD
+CD Parametere:
+CD Type        Navn     I/U    Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POLYGON *pPolygon  I     Peikar til polygonbeskrivelse
+CD
+CD Bruk:
+CD LC_POLYGON  Polygon;
+CD LC_POL_FrigiPolygon(&Polygon);
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_FrigiPolygon(LC_POLYGON *pPolygon)
+{
+   /* Frigir �y-kjeden */
+   LC_POL_FrigiAlleOyer(&(pPolygon->OyOA));
+
+   /* Frigir omkretsen */
+   LC_POL_FrigiOmkrets(&(pPolygon->HovedPO));
+}
+
+
+/*
+SJM-930921  
+CH LC_POL_InitOmkrets                           Initierer polygon-omkrets
+CD =======================================================================
+CD Bruk:
+CD POL_OMKR  YtrePolygon;
+CD LC_POL_InitOmkrets(YtrePolygon);
+CD
+CD parametere:
+CD Type         Navn     I/U    Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POL_OMKR *pPO      I/U    Peikar til polygonadministrasjonsblokka
+CD
+CD Initierer administrasjonsblokka for polygonelement
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_InitOmkrets(LC_POL_OMKR *pPO)
+{
+  pPO->pForstePE = NULL;
+  pPO->pSistePE = NULL;
+}
+
+
+/*
+SJM-930921 
+CH LC_POL_InitOy                                      Initierer �y-kjeden
+CD =======================================================================
+CD Bruk:
+CD LC_OY_ADM  OyKjede;
+CD LC_POL_InitOy(OyKjede);
+CD
+CD parametere:
+CD Type       Navn     I/U    Forklaring
+CD -----------------------------------------------------------------------
+CD LC_OY_ADM *pOA      I/U    Peikar til �yadministrasjonsblokka
+CD
+CD Initierer �y-kjeden.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_InitOy(LC_OY_ADM *pOA)
+{
+  pOA->pForsteOE = NULL;
+  pOA->pSisteOE = NULL;
+}
+
+
+/*
+AR-931208
+CH LC_POL_InitPolygon                          Initierer polygon-struktur
+CD =======================================================================
+CD Form�l:
+CD Initierer polygon-struktur.
+CD
+CD Parametere:
+CD Type        Navn     I/U    Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POLYGON *pPolygon  I     Peikar til polygonbeskrivelse
+CD
+CD Bruk:
+CD LC_POLYGON  Polygon;
+CD LC_POL_InitPolygon(&Polygon);
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_InitPolygon(LC_POLYGON *pPolygon)
+{
+   LC_POL_InitOmkrets(&(pPolygon->HovedPO));
+   LC_POL_InitOy(&(pPolygon->OyOA));
+}
+
+
+/*
+AR-931208
+CH LC_POL_PutRef                            Legger inn referanser i GINFO
+CD =======================================================================
+CD Form�l:
+CD Legger inn referanser i GINFO, ut fra beskrivelse i struktur.
+CD
+CD Parametere:
+CD Type        Navn     I/U    Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POLYGON *pPolygon  I     Polygonbeskrivelse
+CD short       ngi       r     Antall linjer GINFO
+CD
+CD Bruk:
+CD ngi = LC_POL_PutRef(pPolygon);
+CD =======================================================================
+*/
+SK_EntPnt_FYBA short LC_POL_PutRef(LC_POLYGON *pPolygon)
+{
+   #define MAX_LEN  66   /* Ginfolinjen skrives ut n�r den er lengre en 70 tegn */
+   LC_POL_ELEMENT *pPE;
+   LC_OY_ELEMENT *pOE;
+   short gilin;
+   char temp[LC_MAX_SOSI_LINJE_LEN],*ginfo,*cp;
+   char szOrd[50];
+   short ledig_linje = -1;
+
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE){                  /* Aktuell gruppe OK */
+      /* Pakker gammel GINFO */
+      for (gilin=2; gilin <= Sys.pGrInfo->ngi; gilin++) {
+         ginfo = LX_GetGi(gilin);
+
+         /* Gammel type referanse er funnet */
+         if (strncmp(ginfo,".. ",3) == 0) {
+            if (ledig_linje == -1) {        /* F�rste linje med referanse */
+               ledig_linje = gilin;
+            }
+
+         /* Ny type referanse er funnet */
+         } else if (strncmp(ginfo,"..REF ",6) == 0) {
+            if (ledig_linje == -1) {        /* F�rste linje med referanse */
+               ledig_linje = gilin;
+            }
+            /* S�k over resten av referansene */
+            for (gilin++; gilin <= Sys.pGrInfo->ngi; gilin++) {
+               ginfo = LX_GetGi(gilin);
+               if (strncmp(ginfo,"..",2) == 0) { /* Annen GINFO er funnet */
+                  gilin--;
+                  break;      /* Avbryt, alle referanser er funnet*/
+               }
+            }
+         
+         /* Annen GINFO */
+         } else {
+            if (ledig_linje != -1) {
+               /* Funnet linje som skal flyttes opp */
+               LC_PutGi(ledig_linje,ginfo);
+               ledig_linje++;
+            }
+         }
+
+      
+      }
+
+      if (ledig_linje == -1)  ledig_linje = Sys.pGrInfo->ngi + 1;
+
+
+      /* Legger inn referanser */
+      if (pPolygon->HovedPO.pForstePE != NULL) {
+         /* Husk at det finnes flate i filen */
+         if ( Sys.GrId.pFil->SosiNiv[1] < 4) {
+            Sys.GrId.pFil->SosiNiv[1] = 4;
+         }
+
+
+         if (Sys.GrId.pFil->sSosiVer >= 220) {
+            UT_StrCopy(temp,"..REF ",LC_MAX_SOSI_LINJE_LEN);
+            cp = temp + 6;
+         } else {   
+            UT_StrCopy(temp,".. ",LC_MAX_SOSI_LINJE_LEN);
+            cp = temp + 3;
+         }
+
+         /* Legger ut hovedpolygonet */
+         for (pPE = pPolygon->HovedPO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+
+            /* Strengen er full, skriver ut */
+            if(strlen(temp) > MAX_LEN) {
+               if (ledig_linje > Sys.pGrInfo->ngi) {
+                  ledig_linje = LC_AppGiL();
+               }
+               LC_PutGi(ledig_linje,temp);
+               ledig_linje ++;
+
+               if (Sys.GrId.pFil->sSosiVer >= 220) {
+                  *temp = '\0';
+                  cp = temp;
+               } else {   
+                  UT_StrCopy(temp,".. ",LC_MAX_SOSI_LINJE_LEN);
+                  cp = temp + 3;
+               }
+            }
+
+            /* Skriv ut referansen */
+            if (cp > temp) {
+               if (! UT_IsSpace(*(cp-1))  &&  *(cp-1) != '(') {
+                  *cp++ = ' ';
+                  *cp = '\0';
+               }
+            }    
+            UT_SNPRINTF(szOrd, 50, ":%ld", ((pPE->sRetning == LC_MED_DIG)?  pPE->lSnr : -pPE->lSnr));
+            UT_StrCat(temp, szOrd, LC_MAX_SOSI_LINJE_LEN);
+            cp = strchr(temp,'\0');
+         }
+
+
+         /* Legger ut �yer */
+         for (pOE = pPolygon->OyOA.pForsteOE; pOE != NULL; pOE = pOE->pNesteOE) {
+            /* Strengen er full, skriver ut */
+            if(strlen(temp) >= (MAX_LEN-2)) {
+               if (ledig_linje > Sys.pGrInfo->ngi) {
+                  ledig_linje = LC_AppGiL();
+               }
+               LC_PutGi(ledig_linje,temp);
+               ledig_linje ++;
+
+               if (Sys.GrId.pFil->sSosiVer >= 220) {
+                  *temp = '\0';
+                  cp = temp;
+               } else {   
+                  UT_StrCopy(temp,".. ",LC_MAX_SOSI_LINJE_LEN);
+                  cp = temp + 3;
+               }
+            }
+
+            /* Startparantesen */
+            if (cp > temp) {
+               if (! UT_IsSpace(*(cp-1))) {
+                  *cp++ = ' ';
+               }
+            }
+            *cp++ = '(';
+            *cp = '\0';
+
+            /* Legger ut elementa i �yane */
+            for (pPE = pOE->PO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+
+               /* Strengen er full, skriver ut */
+               if(strlen(temp) >= MAX_LEN) {
+                  if (ledig_linje > Sys.pGrInfo->ngi) {
+                     ledig_linje = LC_AppGiL();
+                  }
+                  LC_PutGi(ledig_linje,temp);
+                  ledig_linje ++;
+
+                  if (Sys.GrId.pFil->sSosiVer >= 220) {
+                     *temp = '\0';
+                     cp = temp;
+                  } else {   
+                     UT_StrCopy(temp,".. ",LC_MAX_SOSI_LINJE_LEN);
+                     cp = temp + 3;
+                  }
+               }
+
+               /* Skriv ut referansen */
+               if (cp > temp) {
+                  if (! UT_IsSpace(*(cp-1))  &&  *(cp-1) != '(') {
+                     *cp++ = ' ';
+                     *cp = '\0';
+                  }
+               }
+               UT_SNPRINTF(szOrd, 50, ":%ld", ((pPE->sRetning == LC_MED_DIG)?  pPE->lSnr : -pPE->lSnr));
+               UT_StrCat(temp, szOrd, LC_MAX_SOSI_LINJE_LEN);
+               cp = strchr(temp,'\0');
+            }
+
+
+            /* Sluttparantesen */
+            if (cp > temp) {
+               if (*(cp-1) == '.') {
+                  *cp++ = ' ';
+               }
+            }
+            *cp++ = ')';
+            *cp = '\0';
+         }
+
+
+         /* Skriver ut resten av strengen */
+         if ((Sys.GrId.pFil->sSosiVer >= 220  &&  strlen(temp) > 0)  ||
+             strlen(temp) > 3) {
+            if (ledig_linje > Sys.pGrInfo->ngi) {
+               ledig_linje = LC_AppGiL();
+            }
+            LC_PutGi(ledig_linje,temp);
+            ledig_linje ++;
+         }
+
+      } else {
+         Sys.pGrInfo->info &= ~((unsigned short)GI_REF);
+         Sys.pGrInfo->info &= ~((unsigned short)GI_OY_REF);
+      }
+
+      /* Sletter 1. ledige og resten */
+      LC_DelGiL(ledig_linje, (short)(Sys.pGrInfo->ngi - ledig_linje + 1));
+   }
+
+   return Sys.pGrInfo->ngi;
+}
+
+ 
+/*
+AR-931212
+CH LC_POL_GetRef                        Hent referanser for flate fra GINFO
+CD ==========================================================================
+CD Form�l:
+CD Henter referanser fra GINFO til struktur.
+CD
+CD Parametre:
+CD Type         Navn      I/U  Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POLYGON  *pPolygon   I   Peker til adm. for polygonbeskrivelse
+CD
+CD
+CD Bruk:
+CD    short ngi;
+CD    long nko;
+CD    unsigned short info;
+CD    LC_POLYGON Polygon;
+CD    LC_POL_ELEMENT * pPE;
+CD    LC_OY_ELEMENT * pOE;
+CD
+CD    LC_POL_InitPolygon(&Polygon);
+CD
+CD    LC_POL_GetRef(&Polygon);
+CD
+CD    . Omkretsen .
+CD    for(pPE = Polygon.HovedPO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+CD       gnavn = LC_RxGr(&pPE->Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+CD       .
+CD       Behandle ytre avgrensing            
+CD       .
+CD    }
+CD
+CD    . �yer .
+CD    for (pOE = Polygon.OyOA.pForsteOE; pOE != NULL; pOE = pOE->pNesteOE) {
+CD       for (pPE = pOE->PO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+CD          gnavn = LC_RxGr(&pPE->Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+CD          .
+CD          Behandle indre avgrensing (�y)           
+CD          .
+CD       }
+CD    }
+CD
+CD    . Frigi allokerte kjeder .
+CD    LC_POL_FrigiPolygon(&Polygon);
+CD
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_GetRef(LC_POLYGON *pPolygon)
+{
+   char *gp,ginfo[LC_MAX_SOSI_LINJE_LEN];
+   long lSnr;
+   LC_BGR Bgr;
+   short ngi;
+   long nko;
+   unsigned short info;
+   short sRetning;
+   LC_POL_OMKR OyPO;
+   short sGiLinNr = 2;
+   short sOy = UT_FALSE;
+   LC_BGR AktBgr = Sys.GrId;
+   short sRefLin = UT_FALSE;   /* Viser om aktuel linje inneholder referanser */
+
+
+   LC_POL_InitOmkrets(&OyPO);
+
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {            /* Aktuell gruppe OK */
+
+      Bgr.pFil = Sys.GrId.pFil;
+
+      /* Finn referanser */
+      while (sGiLinNr <= Sys.pGrInfo->ngi) {
+         gp = LX_GetGi(sGiLinNr);
+         
+         /* Handter referanselinjer */
+         if ((sRefLin = LC_ErLinjeRefLin(gp,sRefLin)) == UT_TRUE) {
+            UT_StrCopy(ginfo,gp,LC_MAX_SOSI_LINJE_LEN);
+            gp = ginfo;
+            while (*gp) {                  /* Tolk en linje */
+               if (*gp == ':') {                              /* Tall */
+                  gp++;
+                  /* Husk retning */
+                  if (*gp == '-') {
+                     sRetning = LC_MOT_DIG;
+                     gp++;
+                  } else {
+                     sRetning = LC_MED_DIG;
+                  }
+                  /* Hent serienummer og konverter til gruppenummer */
+                  if (isdigit(*gp)) {
+                     lSnr = strtol(gp,&gp,10);
+                     /* Konverter til gruppenummer */
+                     if ((Bgr.lNr = LI_GetSnr(Sys.GrId.pFil,lSnr)) != INGEN_GRUPPE) {
+                        /* Legg gruppen inn i kjeden */
+                        if (sOy == UT_TRUE) {
+                           /* Referanse til flate, pakk ut denne */
+                           if (LC_GetGrParaBgr(&Bgr,&ngi,&nko,&info) == L_FLATE) {
+                              LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+                              LC_POL_GetRefOmkrets(&OyPO);
+                              LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+
+                           } else {
+                              LC_POL_LeggTilGruppeOmkrets(&OyPO,&Bgr,sRetning,lSnr);
+                           }
+
+                        } else {
+                           LC_POL_LeggTilGruppeOmkrets(&(pPolygon->HovedPO),
+                                                       &Bgr,sRetning,lSnr);
+                        }
+
+                     } else {
+                        UT_FPRINTF(stderr,"Snr. %ld er referert i \"%s : %s\", finnes ikke!\n",lSnr,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+                        Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+                     }
+
+                  } else {
+                     //UT_FPRINTF(stderr,"Ulovlig referanse \"%s\" i \"%s : %s\"\n",ginfo,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+                     //Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+                     gp++;
+                  }
+
+
+               } else if (*gp == '(') {                     /* Start �y */
+
+                  if (sOy == UT_FALSE) {
+                     LC_POL_InitOmkrets(&OyPO);
+                     sOy = UT_TRUE;
+
+                  } else {
+                     /* �y i �y er ikke lovlig */
+                     LC_Error(56,"(LC_POL_GetRef)",Sys.GrId.pFil->pszNavn);
+                     UT_FPRINTF(stderr,"�y i �y i gruppe \"%s : %s\"\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+                     Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+                  }
+                  gp++;
+
+               } else if (*gp == ')') {                     /* Slutt �y */
+
+                  if (sOy == UT_TRUE) {
+                     LC_POL_LeggTilOy(&(pPolygon->OyOA),&OyPO);
+                     sOy = UT_FALSE;
+
+                  } else {
+                     /* �y i �y er ikke lovlig */
+                     LC_Error(56,"(LC_POL_GetRef)",Sys.GrId.pFil->pszNavn);
+                     UT_FPRINTF(stderr,"�y i �y i gruppe \"%s : %s\"\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+                     Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+                  }
+                  gp++;
+
+               } else {                                    /* Ukjent tegn */
+                  gp++;
+               }
+            }
+         }
+
+         sGiLinNr++;
+      }
+   }
+
+   return;
+}
+
+
+/*
+AR-931212
+CH LC_POL_GetRefOmkrets               Hent referanser for omkretsen av flate
+CD ==========================================================================
+CD Form�l:
+CD Henter referanser fra GINFO til struktur.
+CD Rutinen initierer strukturen pPO, men frigir ikke eventuellt gammelt innhold.
+CD
+CD
+CD Parametre:
+CD Type          Navn    I/U  Forklaring
+CD -------------------------------------------------------------------------
+CD LC_POL_OMKR  *pPO;     IU  Peker til kjede som beskriver omkretsen.
+CD
+CD Bruk:
+CD    LC_POL_GetRefOmkrets(&OyPO);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_GetRefOmkrets(LC_POL_OMKR *pPO)
+{
+   char *gp,ginfo[LC_MAX_SOSI_LINJE_LEN];
+   long lSnr;
+   short sRetning;
+   short sGiLinNr = 2;
+   short sFerdig = UT_FALSE;
+   LC_BGR Bgr = Sys.GrId;
+   short sRefLin = UT_FALSE;   /* Viser om aktuel linje inneholder referanser */
+
+
+   LC_POL_InitOmkrets(pPO);
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE  &&  Sys.pGrInfo->ngi > 0) {
+      /* Finn referanser */
+      while (sFerdig == UT_FALSE  &&  sGiLinNr <= Sys.pGrInfo->ngi) {
+         gp = LX_GetGi(sGiLinNr);
+         
+         /* Handter referanselinjer */
+         if ((sRefLin = LC_ErLinjeRefLin(gp,sRefLin)) == UT_TRUE) {
+            UT_StrCopy(ginfo,gp,LC_MAX_SOSI_LINJE_LEN);
+            gp = ginfo;
+            while (sFerdig == UT_FALSE  &&  *gp) {  /* Tolk en linje */
+               if (*gp == ':') {                              /* Tall */
+                  gp++;
+                  /* Husk retning */
+                  if (*gp == '-') {
+                     sRetning = LC_MOT_DIG;
+                     gp++;
+                  } else {
+                     sRetning = LC_MED_DIG;
+                  }
+                  /* Hent serienummer og konverter til gruppenummer */
+                  if (isdigit(*gp)) {
+                     lSnr = strtol(gp,&gp,10);
+                     /* Konverter til gruppenummer */
+                     if ((Bgr.lNr = LI_GetSnr(Sys.GrId.pFil,lSnr)) != INGEN_GRUPPE) {
+                        /* Legg gruppen inn i kjeden */
+                        LC_POL_LeggTilGruppeOmkrets(pPO,&Bgr,sRetning,lSnr);
+
+                     } else {
+                        UT_FPRINTF(stderr,"Snr. %ld er referert i \"%s : %s\", finnes ikke!\n",lSnr,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+                        Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+                     }
+
+                  } else {
+                     UT_FPRINTF(stderr,"Ulovlig referanse \"%s\" i \"%s : %s\"\n",ginfo,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+                     Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+                  }
+
+               /* Start �y */
+               } else if (*gp == '(') {
+                  sFerdig = UT_TRUE;
+                  gp++;
+
+               } else {                                    /* Ukjent tegn */
+                  gp++;
+               }
+            }
+         }
+
+         sGiLinNr++;
+      }
+   }
+}
+
+
+/*
+SJM-930928
+CH LC_POL_TestBrukt              Testar om ei gruppe er brukt i polygonet
+CD =======================================================================
+CD Bruk:
+CD LC_POL_TestBrukt(pPolygon,&Bgr);
+CD
+CD parametere:
+CD Type        Navn     I/U    Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POLYGON *pPolygon  I     Peker til polygonbeskrivelse.
+CD LC_BGR     *pBgr      I     Peikar til gruppe
+CD short       status    R     Status UT_TRUE = gruppe er brukt i polygonet
+CD                              Status UT_FALSE = gruppe er IKKJE brukt i polygonet
+CD
+CD Testar om ei gruppe er brukt i gitt polygon.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA short LC_POL_TestBrukt(LC_POLYGON *pPolygon,LC_BGR *pBgr)
+{
+   LC_POL_ELEMENT *pPE;
+   LC_OY_ELEMENT *pOE;
+
+   /* Sjekk omkretsen */
+   for(pPE = pPolygon->HovedPO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+      if (memcmp(pBgr,&pPE->Bgr, sizeof(LC_BGR)) == 0) {
+         return UT_TRUE;
+      }
+   }
+
+   /* Sjekk �yene */
+   for (pOE = pPolygon->OyOA.pForsteOE; pOE != NULL; pOE = pOE->pNesteOE) {
+      for (pPE = pOE->PO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+         if (memcmp(pBgr,&pPE->Bgr, sizeof(LC_BGR)) == 0) {
+            return UT_TRUE;
+         }
+      }
+   }
+
+   return UT_FALSE;
+}
+
+
+/*
+AR:2009-03-04
+CH LC_POL_PTst                                                   Polygontest
+CD ==========================================================================
+CD Form�l:
+CD Sjekker om gitt punkt ligger innenfor polygon angitt av pPolygon.
+CD Forutsetter at pPolygon danner et lukket polygon.
+CD Skifter ikke aktuell gruppe.
+CD
+CD Parametre:
+CD Type    Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double  a        i    Punkt som skal sjekkes
+CD double  n        i
+CD short   ist      r    status: UT_FALSE = punktet er utenfor flaten
+CD                               UT_TRUE = punktet ligger inne p� flaten
+CD
+CD Bruk:
+CD .
+==========================================================================
+*/
+SK_EntPnt_FYBA short LC_POL_PTst(LC_POLYGON *pPolygon,double a,double n)
+{
+   short ngi;
+   long nko;
+   unsigned short info;
+   LC_POL_ELEMENT * pPE;
+   LC_OY_ELEMENT * pOE;
+   short sAntSkjaer;
+   LC_BGR Flate = Sys.GrId;      /* Husk gruppenummer for flaten */
+   short inni = UT_FALSE;   /* Returverdi: 1 = inne p� flaten, 0 = utenfor  */
+   
+
+   // Har ytre avgrensning? 
+   if (pPolygon == NULL  ||  pPolygon->HovedPO.pForstePE == NULL)  return inni;  // ==> Avbryter, har ikke noen ytre avgrensning
+
+
+   double dEnhet = pPolygon->HovedPO.pForstePE->Bgr.pFil->TransPar.dEnhet;
+
+   // Pluss p� et lite tillegg for � unng� treff p� node
+   a += dEnhet / 1000.0;
+   n += dEnhet / 1000.0;
+
+   // Inndata
+   if (pPolygon) {
+      // ----- Behandle ytre avgrensing  (Omkretsen)
+      sAntSkjaer = 0;
+      for(pPE = pPolygon->HovedPO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+         sAntSkjaer += LR_PTstGruppe(&pPE->Bgr,a,n);
+      }
+      // Sjekk om punktet er innenfor
+      inni = ((sAntSkjaer % 2) == 1)?  1 : 0;
+      
+      // ----- Behandler indre avgrensing (�y)
+      for (pOE = pPolygon->OyOA.pForsteOE;  inni && (pOE != NULL);  pOE = pOE->pNesteOE) {
+         // Behandler en �y
+         sAntSkjaer = 0;
+         for (pPE = pOE->PO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+            sAntSkjaer += LR_PTstGruppe(&pPE->Bgr,a,n);
+         }
+         // Sjekk om punktet er inni �ya
+         inni = ((sAntSkjaer % 2) == 1)?  UT_FALSE : UT_TRUE;
+      }
+     
+      // Les inn flaten igjen
+      LC_RxGr(&Flate,LES_OPTIMALT,&ngi,&nko,&info);
+   }
+
+   return  inni;
+}
+
+
+/*
+AR-931213
+CH LC_POL_PTstOmkrets              Sjekk om punkt ligger inni polygonomkrets
+CD ==========================================================================
+CD Form�l:
+CD Sjekker om gitt punkt ligger innenfor yttergrensen for polygon angitt
+CD av struktur.
+CD Forutsetter at tabellen danner et lukket polygon
+CD Skifter ikke aktuell gruppe.
+CD
+CD Parametre:
+CD Type          Navn  I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_POL_OMKR  *pPO    I/U  Peker til beskrivelse av omkretsen
+CD double        a      i    Punkt som skal sjekkes
+CD double        n      i
+CD short         ist    r    status: UT_FALSE = punktet er utenfor flaten
+CD                                   UT_TRUE  = punktet ligger inne p� flaten
+CD
+CD Bruk:
+CD ist = LC_POL_PTstOmkrets(pPO,a,n);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_POL_PTstOmkrets(LC_POL_OMKR *pPO,double a,double n)
+{
+   short ngi;
+   long nko;
+   unsigned short info;
+   LC_POL_ELEMENT *pPE;
+   short sAntSkjaer = 0;
+   LC_BGR AktBgr = Sys.GrId;      /* Husk gruppenummer for aktuell gruppe */
+
+
+   // Har ytre avgrensning? 
+   if (pPO == NULL  ||  pPO->pForstePE == NULL)  return UT_FALSE;  // ==> Avbryter, har ikke noen ytre avgrensning
+
+
+   double dEnhet = pPO->pForstePE->Bgr.pFil->TransPar.dEnhet;
+
+   // Pluss p� et lite tillegg for � unng� treff p� node
+   a += dEnhet / 1000.0;
+   n += dEnhet / 1000.0;
+
+   /*
+    * Sjekk omkretsen ved � beregne antall skj�ringer mellom omkretsen
+    * og en linje fra "test-punktet" til "uendelig �st".
+    */
+
+   for (pPE = pPO->pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+      /* Beregn skj�ringer med denne gruppen */
+      sAntSkjaer += LR_PTstGruppe(&pPE->Bgr,a,n);
+   }
+
+   /* Les inn opprinnelig gruppe igjen */
+   LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+
+   /*
+    * Sjekk om punktet er innenfor omkretsen.
+    * (Inni hvis antall skj�ringspunkt er oddetall.)
+    */
+   return  ((sAntSkjaer % 2) == 1)?  UT_TRUE : UT_FALSE;
+}
+ 
+
+/*
+JA�-20061130
+CH LC_POL_OmkretsSkjaering        Finner antall skj�ringer med polygonomkrets
+CD ==========================================================================
+CD Form�l:
+CD Sjekker om gitt punkt ligger innenfor yttergrensen for polygon angitt
+CD av struktur. Egentlig kopi av LC_POL_PTstOmkrets, men returnerer antall 
+CD skj�ringer istedet for inni/utenfor. 
+CD Forutsetter at tabellen danner et lukket polygon
+CD Skifter ikke aktuell gruppe.
+CD
+CD Parametre:
+CD Type          Navn  I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_POL_OMKR  *pPO    I/U  Peker til beskrivelse av omkretsen
+CD double        a      i    Punkt som skal sjekkes
+CD double        n      i
+CD short         ist    r    Antall skj�ringer med omkrets fra pkt til "uendelig" �st
+CD
+CD Bruk:
+CD ist = LC_POL_PTstOmkrets(pPO,a,n);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_POL_OmkretsSkjaering(LC_POL_OMKR *pPO,double a,double n)
+{
+   short ngi;
+   long nko;
+   unsigned short info;
+   LC_POL_ELEMENT *pPE;
+   short sAntSkjaer = 0;
+   LC_BGR AktBgr = Sys.GrId;      /* Husk gruppenummer for aktuell gruppe */
+
+
+   // Har ytre avgrensning? 
+   if (pPO == NULL  ||  pPO->pForstePE == NULL)  return 0;  // ==> Avbryter, har ikke noen ytre avgrensning
+   
+
+   double dEnhet = pPO->pForstePE->Bgr.pFil->TransPar.dEnhet;
+
+   // Pluss p� et lite tillegg for � unng� treff p� node
+   a += dEnhet / 1000.0;
+   n += dEnhet / 1000.0;
+
+   /*
+    * Sjekk omkretsen ved � beregne antall skj�ringer mellom omkretsen
+    * og en linje fra "test-punktet" til "uendelig �st".
+    */
+
+   for (pPE = pPO->pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+      /* Beregn skj�ringer med denne gruppen */
+      sAntSkjaer += LR_PTstGruppe(&pPE->Bgr,a,n);
+   }
+  
+   /* Les inn opprinnelig gruppe igjen */
+   LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+
+   return  sAntSkjaer;
+}
+
+
+/*
+AR-950421
+CH LC_POL_Box                                  Henter omskreven boks
+CD =======================================================================
+CD Bruk:
+CD LC_POL_Box(pPA,&nva,&nvn,&oha,&ohn);
+CD
+CD parametere:
+CD Type          Navn     I/U    Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POL_OMKR  *pPO       I     Peikar til polygonadministrasjonsblokka
+CD double       *nva       U
+CD double       *nvn       U
+CD double       *oha       U
+CD double       *ohn       U
+CD
+CD Henter omskriven boks for polygon.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_Box(LC_POL_OMKR *pPO,double *nva,double *nvn, double *oha,double*ohn)
+{
+   LC_POL_ELEMENT *pPE;
+   double na,nn,oa,on;
+   /* Omskreven boks */
+   double mina = (double)LONG_MAX;
+   double minn = (double)LONG_MAX;
+   double maxa = (double)LONG_MIN;
+   double maxn = (double)LONG_MIN;
+
+   for (pPE = pPO->pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+
+      if (LC_GetGrWin(&pPE->Bgr,&na,&nn,&oa,&on) ) {
+         if (na < mina)  mina = na;
+         if (nn < minn)  minn = nn;
+         if (oa > maxa)  maxa = oa;
+         if (on > maxn)  maxn = on;
+      }
+   }
+
+   *nva = mina;
+   *nvn = minn;
+   *oha = maxa;
+   *ohn = maxn;
+}
+
+
+/*
+AR-950421
+CH LC_ErLinjeRefLin                  Sjekk om linje inneholder referanser
+CD =======================================================================
+CD Bruk:
+CD sRefLin = LC_ErLinjeRefLin(gp,sRefLin);
+CD
+CD parametere:
+CD Type    Navn        I/U  Forklaring
+CD -----------------------------------------------------------------------
+CD char   *pszGinfoLin  i   Peikar til GINFO-linje
+CD short   sRefLin      i   Flagg som viser om forrige linje inneholdt referanser
+CD short   sRefLin      r   Flagg som viser om aktuell linje inneholdt referanser
+CD
+CD Sjekk om linje er linje med referanser.
+CD =======================================================================
+*/
+short LC_ErLinjeRefLin(char *pszSosiLin, short sRefLin)
+{
+   /* Sjekk om dette er referanselinje */
+   if (strncmp(pszSosiLin,".. ",3) == 0) {
+      return UT_TRUE;
+
+   } else if (strncmp(pszSosiLin,"..REF ",6) == 0) {
+      //if (sRefLin == UT_TRUE) {
+      //   UT_FPRINTF(stderr,"Ulovlig SOSI-syntaks \"%s\" i gruppe \"%s : %s\"\n",pszSosiLin,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+      //   Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+      //}
+      return UT_TRUE;
+
+   } else if (sRefLin == UT_TRUE) {
+      /* Annet SOSI-navn */
+      if (*pszSosiLin == '.') {
+         return UT_FALSE;
+      
+      } else {
+         return UT_TRUE;
+      }
+
+   } else {
+      return UT_FALSE;
+   }
+}
diff --git a/FYBA/FYLR.cpp b/FYBA/FYLR.cpp
new file mode 100644
index 0000000..a56879e
--- /dev/null
+++ b/FYBA/FYLR.cpp
@@ -0,0 +1,2240 @@
+/* === 911001 ============================================================ */
+/*  STATENS KARTVERK  -  FYSAK-PC                                          */
+/*  Fil: fylr.c                                                            */
+/*  Ansvarlig: Andreas R�stad                                              */
+/*  Innhold: Rutiner for geografisk s�king mm. i fysak-pc                  */
+/* ======================================================================= */
+
+#include "stdafx.h"
+
+#include <float.h>
+#include <math.h>
+#include <limits.h>
+#include <memory.h>
+
+
+/* Globale variabler */
+extern LC_SYSTEMADM Sys;
+
+/* --- Lokale rutiner */
+static LC_R_LEAF * LR_R_Insert(long lGrNr,LC_BOKS * pB,LC_R_NODE * pFar,LC_R_NODE * pRN,LC_R_NODE * *ppNyRN);
+static LC_R_NODE * LR_R_CreateRNode( LC_R_NODE * pFar,short sSonType);
+static LC_R_LEAF * LR_R_CreateRLeaf(long lGrNr, LC_BOKS * pB,LC_R_NODE * pFar);
+static void LR_R_BoksSum(LC_BOKS * pB1,LC_BOKS * pB2);
+static double LR_BoksDeltaArealSum(LC_BOKS * pB1,LC_BOKS * pB2);
+static void LR_LeggTilKB(LC_GEO_STATUS * pGeoStat,LC_FILADM *pFil,long lNr);
+static short LR_R_BoksTestIntersect(LC_BOKS * pB1,LC_BOKS * pB2);
+static void LR_R_SjekkNode(LC_GEO_STATUS * pGeoStat,LC_BOKS * pB,LC_FILADM *pFil,LC_R_NODE * pRN);
+static void LR_R_SjekkNodeFlate(LC_GEO_STATUS * pGeoStat,LC_BOKS * pB,LC_FILADM *pFil,LC_R_NODE * pRN);
+static void LR_VelgMetode(LC_GEO_STATUS * pGeoStat);
+
+//#ifdef TEST
+//#include <string.h>
+//static void LR_R_DumpNode(LC_R_NODE * pRN, int iNivo);
+static void LR_R_DumpLov(LC_R_LEAF * pRL, LC_FILADM *pDumpFil, int iNivo, double dA, double dN,long *plAntBarn);
+static void LR_R_DumpNode(LC_R_NODE * pRN, LC_FILADM *pDumpFil, int iNivo, double dA, double dN, double dLengde,long *plAntBarn);
+//#endif
+
+
+
+
+#define MAX_REF 25
+
+
+/*
+AR:2000-07-25
+CH LC_GetGrWin                           Hent omskrevet rektangel for gruppe
+CD ==========================================================================
+CD Form�l:
+CD Henter omskrevet rektangel for gitt gruppe.
+CD For flater er refererte grupper medregnet.
+CD
+CD Parametre:
+CD Type     Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR *  pBgr      i    Gruppenummer
+CD double  *nva       u    Omskrevet rektangel for gruppen. Avrundet utover
+CD double  *nvn       u    en enhet.
+CD double  *oha       u    
+CD double  *ohn       u    
+CD short    ist       r    Status. UT_TRUE=OK, UT_FALSE=ulovlig gruppenummer.
+CD
+CD Bruk:
+CD    ist = LC_GetGrWin(&Bgr,&nva,&nvn,&oha,&ohn);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetGrWin(LC_BGR * pBgr,double *nva,double *nvn,double *oha,double *ohn)
+{
+   LC_R_LEAF * pRL;
+
+   /* LO_TestFilpeker(pBgr->pFil,"LC_GetGrWin"); */
+   LO_TestFilpeker(pBgr->pFil,"GetGrWin");
+
+                                           /* Lovlig gruppe */
+   if (pBgr->lNr >= 0L  &&  pBgr->lNr < pBgr->pFil->lAntGr) {
+      pRL = LI_GetGeo(pBgr->pFil,pBgr->lNr);
+
+      if (pRL != NULL) {
+         *nva = pRL->Boks.dMinAust;
+         *nvn = pRL->Boks.dMinNord;
+         *oha = pRL->Boks.dMaxAust;
+         *ohn = pRL->Boks.dMaxNord;
+
+      } else {
+         *nva = *nvn = (double)LONG_MAX;
+         *oha = *ohn = (double)LONG_MIN;
+      }
+
+      return  UT_TRUE;         /* ======> */
+   }
+
+   /* Ulovlig gruppe */
+   LC_Error(36,"(LC_GetGrWin)","");
+   return  UT_FALSE;
+}
+
+
+/*
+AR-930608
+CH LR_Indx                               Beregn geografiske ruter for gruppe
+CD ==========================================================================
+CD Form�l:
+CD Beregner og lagrer omskrevet boks for koordinatene p� aktuell gruppe.
+CD
+CD Parametre: ingen
+CD
+CD Bruk:
+CD LR_Indx();
+   ==========================================================================
+*/
+void LR_Indx(void)
+{
+   short sfeil;
+   long pt;
+   double min_n,min_a,max_n,max_a;
+   double radius,aust,nord,fi,dfi;
+   LC_BOKS Boks;
+
+   // UT_FPRINTF(stderr,"Indeks for: %s\n",LX_GetGi(1));
+
+   /* Bygg ny indeks */
+   if (Sys.pGrInfo->nko > 0) {
+
+      /* Nullstill omskreven boks */
+      min_a = min_n = (double)LONG_MAX;
+      max_a = max_n = (double)LONG_MIN;
+
+                                    /* Handterer "bue" */
+      if (Sys.pGrInfo->gnavn == L_BUE  ||  Sys.pGrInfo->gnavn == L_BUEP ||
+          Sys.pGrInfo->gnavn == L_SIRKEL  ||  Sys.pGrInfo->gnavn == L_SIRKELP) {
+
+         if (LC_GetBuePar(HENT_FORRFRA,&aust,&nord,&radius,&fi,&dfi,&sfeil)) {
+            /* Beregner omskrevet rektangel for "buen" */
+            GM_buebox(aust,nord,radius,fi,dfi,&min_a,&min_n,&max_a,&max_n);
+
+         } else {
+            if (Sys.pGrInfo->gnavn == L_BUE) {
+               /* Ulovlig bue-angivelse */
+               //LC_Error(130,"(LR_Indx)",LX_GetGi(1));
+               UT_FPRINTF(stderr,"Ulovlig forhold mellom koordinater og radius i: %s : %s\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+            }
+
+            // Spesialhandtering av ulogiske sirkler og buer. H�ndteres som KURVE
+            for (pt=0; pt<Sys.pGrInfo->nko; pt++) {
+               min_a = min(min_a,*(Sys.pdAust + pt));
+               min_n = min(min_n,*(Sys.pdNord + pt));
+               max_a = max(max_a,*(Sys.pdAust + pt));
+               max_n = max(max_n,*(Sys.pdNord + pt));
+            }
+         }
+
+                                    /* Andre grupper enn "bue" */
+      } else {
+         /* Omskreven firkant */
+         for (pt=0; pt<Sys.pGrInfo->nko; pt++) {
+            min_a = min(min_a,*(Sys.pdAust + pt));
+            min_n = min(min_n,*(Sys.pdNord + pt));
+            max_a = max(max_a,*(Sys.pdAust + pt));
+            max_n = max(max_n,*(Sys.pdNord + pt));
+         }
+      }
+
+      /* Beregn omskreven boks */
+      /* Nedre venstre justeres ut en enhet */
+      Boks.dMinAust = min_a - Sys.pGrInfo->dEnhet;
+      Boks.dMinNord = min_n - Sys.pGrInfo->dEnhet;
+         /* �vre h�yre justeres ut en enhet */
+      Boks.dMaxAust = max_a + Sys.pGrInfo->dEnhet;
+      Boks.dMaxNord = max_n + Sys.pGrInfo->dEnhet;
+
+      // Finnes ikke i treet fra f�r
+      if (Sys.pGrInfo->pRL == NULL ) { 
+         /* Lagre omskrevet boks i s�ketreet */
+         Sys.pGrInfo->pRL = LR_InsertGeo(Sys.GrId.pFil,Sys.GrId.lNr,&Boks);
+
+      // Sjekk om boksen avviker fra gammel boks
+      } else if (memcmp(&(Sys.pGrInfo->pRL->Boks),&Boks,sizeof(LC_BOKS)) != 0) { 
+      
+         /* Fjern eventuell gammel forekomst i R-treet */
+         LR_R_Delete(Sys.pGrInfo->pRL);
+
+         /* Lagre omskreven firkant i s�ketreet */
+         Sys.pGrInfo->pRL = LR_InsertGeo(Sys.GrId.pFil,Sys.GrId.lNr,&Boks);
+      }
+
+   } else if (Sys.pGrInfo->pRL != NULL) {
+      /* Fjern eventuell gammel forekomst i R-treet */
+      LR_R_Delete(Sys.pGrInfo->pRL);
+      Sys.pGrInfo->pRL = NULL;
+   }
+}
+
+
+// ==========================================================================
+SK_EntPnt_FYBA void LC_DumpGeoRtre(LC_FILADM *pFil)
+{
+   short ostat;
+   LC_FILADM *pDumpFil;
+   long lAntBarn = 0;
+
+   // �pner ny SOSI-fil for dump
+   HO_New("Indeksdump.sos", 99, 0.0, 0.0, 0.001, 0.001, 0.001,
+          -151000, -151000, 151000, 1000);
+   if (LC_OpenSos("Indeksdump.sos",LC_BASE_FRAMGR,LC_NY_IDX,LC_INGEN_STATUS,&pDumpFil,&ostat))
+   {
+      short sUtvidModus = LC_GetUtvidModus();
+      long lMaxSkriv = LC_InqMaxSkriv();
+      LC_SetUtvidModus(LC_UTVID_RASK); 
+      LC_MaxSkriv(100000000L);
+
+      if (pFil->pGeoRN != NULL)
+      {
+         LR_R_DumpNode(pFil->pGeoRN,pDumpFil,0, 0.0, 0.0, 100000.0,&lAntBarn);
+      }   
+
+      LC_MaxSkriv(lMaxSkriv);
+      LC_Save();
+      LC_SetUtvidModus(sUtvidModus);  
+
+      LC_CloseSos(pDumpFil,SAVE_IDX);
+   }
+}
+
+
+// ==========================================================================
+static void LR_R_DumpNode(LC_R_NODE * pRN, LC_FILADM *pDumpFil, int iNivo, double dA, double dN, double dLengde,long *plAntBarn)
+{
+   LC_BGR Bgr;
+   char szTx[100];
+   int i;
+   long lSnr;
+   double dDeltaN;
+   long lBarn = 0;
+
+   iNivo++;
+   /* Rekursiv sjekk av de underliggende l�v eller nodene */
+   for (i=0; i<pRN->sSonAnt; i++) { 
+      LC_NyGr(pDumpFil,".LINJE",&Bgr,&lSnr);
+      LC_PutGi(LC_AppGiL(), "..LTEMA 1000");
+      LC_PutTK(LC_AppKoL(), dA, dN);
+      dDeltaN = dLengde;
+
+      if (i == 0) {
+         LC_PutTK(LC_AppKoL(), dA-dLengde, dN-dDeltaN);
+         LC_WxGr(SKRIV_OPTIMALT);
+
+         if (pRN->sSonType == LC_LEAF) {
+            LR_R_DumpLov(pRN->Son.pLeaf[i], pDumpFil, iNivo, dA-dLengde, dN-dDeltaN, &lBarn);
+         } else {
+            LR_R_DumpNode(pRN->Son.pNode[i], pDumpFil, iNivo, dA-dLengde, dN-dDeltaN, dLengde / 3.1, &lBarn);
+         }
+
+      } else if (i == 1) {
+         LC_PutTK(LC_AppKoL(), dA, dN-dDeltaN);
+         LC_WxGr(SKRIV_OPTIMALT);
+
+         if (pRN->sSonType == LC_LEAF) {
+            LR_R_DumpLov(pRN->Son.pLeaf[i], pDumpFil, iNivo, dA, dN-dDeltaN, &lBarn);
+         } else {
+            LR_R_DumpNode(pRN->Son.pNode[i], pDumpFil, iNivo, dA, dN-dDeltaN, dLengde / 3.1, &lBarn);
+         }
+
+      } else {
+         LC_PutTK(LC_AppKoL(), dA+dLengde, dN-dDeltaN);
+         LC_WxGr(SKRIV_OPTIMALT);
+
+         if (pRN->sSonType == LC_LEAF) {
+            LR_R_DumpLov(pRN->Son.pLeaf[i], pDumpFil, iNivo, dA+dLengde, dN-dDeltaN, &lBarn);
+         } else {
+            LR_R_DumpNode(pRN->Son.pNode[i], pDumpFil, iNivo, dA+dLengde, dN-dDeltaN, dLengde / 3.1, &lBarn);
+         }
+      }
+   }
+
+   // Skriv ut noden 
+   LC_NyGr(pDumpFil,".PUNKT",&Bgr,&lSnr);
+   LC_PutGi(LC_AppGiL(), "..PTEMA 3000");
+   LC_PutGi(LC_AppGiL(), "..NODE 1");
+   
+   UT_SNPRINTF(szTx,100,"..NIV� %d", iNivo-1);
+   LC_PutGi(LC_AppGiL(), szTx);
+   
+   UT_SNPRINTF(szTx,100,"..MIN-N� %f %f", pRN->Boks.dMinNord, pRN->Boks.dMinAust);
+   LC_PutGi(LC_AppGiL(), szTx);
+
+   UT_SNPRINTF(szTx,100,"..MAX-N� %f %lf", pRN->Boks.dMaxNord, pRN->Boks.dMaxAust);
+   LC_PutGi(LC_AppGiL(), szTx);
+
+   UT_SNPRINTF(szTx,100,"..DELTA-N� %f %f",
+            pRN->Boks.dMaxNord - pRN->Boks.dMinNord,
+            pRN->Boks.dMaxAust - pRN->Boks.dMinAust);
+   LC_PutGi(LC_AppGiL(), szTx);
+
+   UT_SNPRINTF(szTx,100,"..BARN %ld",lBarn);
+   LC_PutGi(LC_AppGiL(), szTx);
+
+   LC_PutTK(LC_AppKoL(), dA, dN);
+   LC_WxGr(SKRIV_OPTIMALT);
+
+   (*plAntBarn) += lBarn;
+
+}
+
+
+// ==========================================================================
+static void LR_R_DumpLov(LC_R_LEAF * pRL, LC_FILADM *pDumpFil, int iNivo, double dA, double dN, long *plAntBarn)
+{
+   LC_BGR Bgr;
+   char szTx[100];
+   long lSnr;
+
+
+   (*plAntBarn)++;
+   // Skriv ut l�vet
+   LC_NyGr(pDumpFil,".PUNKT",&Bgr,&lSnr);
+   LC_PutGi(LC_AppGiL(), "..PTEMA 5000");
+   LC_PutGi(LC_AppGiL(), "..L�V 1");
+
+   UT_SNPRINTF(szTx,100,"..NR %ld", pRL->lNr);
+   LC_PutGi(LC_AppGiL(), szTx);
+   
+   UT_SNPRINTF(szTx,100,"..NIV� %d", iNivo);
+   LC_PutGi(LC_AppGiL(), szTx);
+   
+   UT_SNPRINTF(szTx,100,"..MIN-N� %f %f", pRL->Boks.dMinNord, pRL->Boks.dMinAust);
+   LC_PutGi(LC_AppGiL(), szTx);
+
+   UT_SNPRINTF(szTx,100,"..MAX-N� %f %f", pRL->Boks.dMaxNord, pRL->Boks.dMaxAust);
+   LC_PutGi(LC_AppGiL(), szTx);
+
+   UT_SNPRINTF(szTx,100,"..DELTA-N� %f %f",
+            pRL->Boks.dMaxNord - pRL->Boks.dMinNord,
+            pRL->Boks.dMaxAust - pRL->Boks.dMinAust);
+   LC_PutGi(LC_AppGiL(), szTx);
+
+   LC_PutTK(LC_AppKoL(), dA, dN);
+   LC_WxGr(SKRIV_OPTIMALT);
+}
+
+
+/*
+AR-900214
+CH LR_IndxFlate                            Beregn geografisk indeks for flate
+CD =============================================================================
+CD Form�l:
+CD Utvider omskrevet boks for aktuell gruppe, slik at den tar hensyn til
+CD referanser.
+CD
+CD Parametre: ingen
+CD
+CD Bruk:
+CD LR_IndxFlate();
+   =============================================================================
+*/
+void LR_IndxFlate(void)
+{
+   long ref_arr[MAX_REF];
+   unsigned char ref_status[MAX_REF];
+   long ant_ref;
+   short s,ngi;
+   long nko;
+   unsigned short info;
+   double min_n,min_a,max_n,max_a;
+   LC_R_LEAF * pRL;
+   LC_FILADM *pFi = Sys.GrId.pFil;
+   LC_GRF_STATUS GrfStat;
+   LC_BOKS Boks;
+   short sRefBrukt = UT_FALSE;
+
+
+   LC_GetGrPara(&ngi,&nko,&info);
+
+   /* Sjekk om gruppen har referanser */
+   if ((info & GI_REF) != 0  ||  nko >0) {
+
+      /* Nullstill omskreven boks */
+      min_a = min_n = (double)LONG_MAX;
+      max_a = max_n = (double)LONG_MIN;
+
+      /* Koordinater direkte p� denne gruppen */
+      if (nko > 0) {
+         pRL = LI_GetGeo(pFi,Sys.GrId.lNr);
+         if (pRL != NULL) {
+            min_a = pRL->Boks.dMinAust;
+            min_n = pRL->Boks.dMinNord;
+            max_a = pRL->Boks.dMaxAust;
+            max_n = pRL->Boks.dMaxNord;
+
+         } else {
+            /* Initier med inverse omr�de fra filhodet */
+            min_a = Sys.GrId.pFil->Omraade.dMaxAust;
+            min_n = Sys.GrId.pFil->Omraade.dMaxNord;
+            max_a = Sys.GrId.pFil->Omraade.dMinAust;
+            max_n = Sys.GrId.pFil->Omraade.dMinNord;
+         }
+
+      } else {
+         /* Initier med inverse omr�de fra filhodet */
+         min_a = Sys.GrId.pFil->Omraade.dMaxAust;
+         min_n = Sys.GrId.pFil->Omraade.dMaxNord;
+         max_a = Sys.GrId.pFil->Omraade.dMinAust;
+         max_n = Sys.GrId.pFil->Omraade.dMinNord;
+      }
+
+      LC_InitGetRefFlate(&GrfStat);
+      /*
+       * Bygger opp omskreven firkant for gruppen ut fra omskreven
+       * firkant for gruppene som inng�r.
+       * (Behandle bare ytre avgrensing.)
+       */
+      ant_ref = LC_GetRefFlate(&GrfStat,GRF_YTRE,ref_arr,ref_status,MAX_REF);
+      do {
+         for (s=0; s<ant_ref; s++) {
+            pRL = LI_GetGeo(pFi,ref_arr[s]);
+            if (pRL != NULL) {
+               min_a = min(min_a, pRL->Boks.dMinAust);
+               min_n = min(min_n, pRL->Boks.dMinNord);
+               max_a = max(max_a, pRL->Boks.dMaxAust);
+               max_n = max(max_n, pRL->Boks.dMaxNord);
+            }
+         }
+
+         if (ant_ref > 0)  sRefBrukt = UT_TRUE;
+
+         if (ant_ref < MAX_REF)  break;
+
+         ant_ref = LC_GetRefFlate(&GrfStat,GRF_YTRE,ref_arr,ref_status,MAX_REF);
+      } while (ant_ref > 0);
+
+      /* Lagre omskreven firkant i s�ketreet */
+      Boks.dMinAust = min_a;
+      Boks.dMinNord = min_n;
+      Boks.dMaxAust = max_a;
+      Boks.dMaxNord = max_n;
+
+      /* Fjern eventuell representasjonspunktet fra R-treet */
+      if (Sys.pGrInfo->pRL != NULL) LR_R_Delete(Sys.pGrInfo->pRL);
+
+      /* Legger inn hele flaten */
+      Sys.pGrInfo->pRL = LR_InsertGeo(Sys.GrId.pFil,Sys.GrId.lNr,&Boks);
+   }
+
+   /* Husk om referanser er brukt */
+   if (sRefBrukt == UT_TRUE) {
+      LI_SetBt(pFi,Sys.GrId.lNr,BT_REFBOX);
+   } else {
+      LI_ClrBt(pFi,Sys.GrId.lNr,BT_REFBOX);
+   }
+}
+   
+/*
+AR-911003
+CH LC_SBGeo                             Sett s�kegrense for grov geografisk s�k
+CD =============================================================================
+CD Form�l:
+CD Definerer geografisk omr�de for geografisk s�k.
+CD
+CD Parametre:
+CD Type           Navn      I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat  iu   Peker til struktur for s�kestatus.
+CD unsigned short usLag      i   Velg hvilke "lag" det skal s�kes i.
+CD                               LC_FRAMGR og /eller LC_BAKGR
+CD double         nv_a       i   Koordinat nedre venstre hj�rne.
+CD double         nv_n       i
+CD double         oh_a       i   Koordinat �vre h�yre hj�rne.
+CD double         oh_n       i
+CD
+CD Bruk:
+CD LC_GEO_STATUS GeoStat;
+CD .
+CD LC_SBGeo(&GeoStat,LC_FRAMGR | LC_BAKGR,nv_a,nv_n,oh_a,oh_n);
+CD if (LC_FFGeo(&GeoStat,&Bgr)) {
+CD     do{
+CD         . Behandle funnet gruppe
+CD         .
+CD     } while (LC_FNGeo(&GeoStat,&bgr));
+CD }
+CD LC_AvsluttSok(&GeoStat);
+CD .
+   =============================================================================
+*/
+SK_EntPnt_FYBA void LC_SBGeo(LC_GEO_STATUS * pGeoStat,unsigned short usLag,
+              double nv_a,double nv_n,double oh_a,double oh_n)
+{
+   /* Normaliserer vinduet */
+   GM_NormVindu(&nv_a,&nv_n,&oh_a,&oh_n);
+
+   /* Avrunder ut til n�rmeste meter utover */
+   /* Nedre venstre ut til n�rneste heltall under */
+   //pGeoStat->nvn = (long)floor(nv_n);
+   //pGeoStat->nva = (long)floor(nv_a);
+   /* �vre h�yre ut til n�rneste heltall over */
+   //pGeoStat->ohn = (long)ceil(oh_n);
+   //pGeoStat->oha = (long)ceil(oh_a);
+
+   pGeoStat->nvn = nv_n;
+   pGeoStat->nva = nv_a;
+   pGeoStat->ohn = oh_n;
+   pGeoStat->oha = oh_a;
+
+   /* Husk lag */
+   pGeoStat->usLag = usLag;
+
+   /* Nullstiller resultatpekerne */
+   pGeoStat->pForsteKB = NULL;
+   pGeoStat->pSisteKB = NULL;
+   pGeoStat->pAktuellKB = NULL;
+
+   /* Velg s�kemetode */
+   LR_VelgMetode(pGeoStat);
+}
+
+
+/*
+AR-911003
+CH LC_FFGeo                                   Finn f�rste ved geografisk s�k
+CD ==========================================================================
+CD Form�l:
+CD Finner f�rste gruppe i det definerte omr�det for kombinert geografisk s�k.
+CD
+CD Parametre:
+CD Type     Navn      I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat  iu   Peker til struktur for s�kestatus
+CD LC_BGR *        pBgr       u   Funnet gruppe
+CD short          sstat      r   S�kestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD Se under LC_SBGeo.
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_FFGeo(LC_GEO_STATUS * pGeoStat,LC_BGR * pBgr)
+{
+   /* Bruker R-tre */
+   if (pGeoStat->usMetode == LC_GEO_RTRE) {
+      LC_BOKS Boks;
+      LC_FILADM *pFil;
+
+      /* Beregn s�keboksen */
+      Boks.dMinAust = pGeoStat->nva;
+      Boks.dMinNord = pGeoStat->nvn;
+      Boks.dMaxAust = pGeoStat->oha;
+      Boks.dMaxNord = pGeoStat->ohn;
+
+      /* Frigir eventuell gammel resultatkjede */
+      LC_AvsluttSok(pGeoStat);
+
+      /* Sjekker alle filer */
+      LC_InitNextFil(&pFil);
+	   while (LC_NextFil(&pFil,pGeoStat->usLag)) {
+         /* Filen inneholder data, m� sjekke alle ber�rte noder */
+         if (pFil->pGeoRN != NULL) {
+            LR_R_SjekkNode(pGeoStat,&Boks,pFil,pFil->pGeoRN);
+         }   
+      }
+
+      pGeoStat->pAktuellKB = pGeoStat->pForsteKB;
+      if (pGeoStat->pAktuellKB != NULL) {
+         /* Tilslag */
+         *pBgr = pGeoStat->pAktuellKB->Bgr;
+         return UT_TRUE;
+      }
+
+   /* Sekvensiell gjennomgang av alle grupper */
+   } else {
+      LC_BGR Bgr;
+      LC_R_LEAF * pRL;
+
+      LC_InitNextBgr(&Bgr);
+      while (LC_NextBgr(&Bgr,pGeoStat->usLag)) {
+         pRL = LI_GetGeo(Bgr.pFil,Bgr.lNr);
+         if (pRL != NULL) {
+            /* Sjekk omr�de-tabellen */
+            if (pGeoStat->ohn >= pRL->Boks.dMinNord && pGeoStat->oha >= pRL->Boks.dMinAust &&
+                pGeoStat->nvn <= pRL->Boks.dMaxNord && pGeoStat->nva <= pRL->Boks.dMaxAust) {
+               *pBgr = pGeoStat->Bgr = Bgr;            /* Tilslag */
+               return UT_TRUE;
+            }
+         }
+      }
+
+      /* Ikke tilslag */
+      pGeoStat->Bgr = Bgr;
+   }
+   
+   /* Ikke tilslag */
+   return UT_FALSE;
+}
+
+
+/*
+AR-911003
+CH LR_R_SjekkNode                          Sjekker node om overlappende boks
+CD ==========================================================================
+CD Form�l:
+CD Sjekker en node og underliggende noder om de har lagret bokser
+CD som overlapper s�kerektanglet. De gruppene som blir funnet blir hengt p�
+CD kjeden med s�keresultat i pGeoStat.
+CD
+CD Parametre:
+CD Type     Navn      I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat   i   Peker til struktur for s�kestatus
+CD LC_BOKS *       pB         i   S�keboks
+CD LC_FILADM *    pFil       i   Filpeker
+CD LC_R_NODE *     pRN        i   Peker til node som skal sjekkes
+CD
+CD Bruk:
+CD LR_R_SjekkNode(pGeoStat,pB,pFil,pRN->pSon[i]);
+   ==========================================================================
+*/
+static void LR_R_SjekkNode(LC_GEO_STATUS * pGeoStat,LC_BOKS * pB,LC_FILADM *pFil,LC_R_NODE * pRN)
+{
+   int i;
+
+
+   /* Sjekk om denne noden ber�rer s�keboksen */
+   if (LR_R_BoksTestIntersect(&(pRN->Boks),pB)) {
+
+      /* Har kommet til ytterste niv� */
+      if (pRN->sSonType == LC_LEAF) {
+
+         /* Sjekk de gruppene som er lagret under denne noden */
+         for (i=0; i<pRN->sSonAnt; i++) { 
+            if (LR_R_BoksTestIntersect(&(pRN->Son.pLeaf[i]->Boks),pB)) {
+               LR_LeggTilKB(pGeoStat,pFil,pRN->Son.pLeaf[i]->lNr);
+            }
+         }
+
+      /* Node */
+      } else {
+
+         /* Rekursiv sjekk av de underliggende nodene */
+         for (i=0; i<pRN->sSonAnt; i++) { 
+            LR_R_SjekkNode(pGeoStat,pB,pFil,pRN->Son.pNode[i]);
+         }
+      }
+   }
+}
+
+
+/*
+AR-911003
+CH LR_R_BoksTestIntersect             Sjekker om to bokser "ber�rer" hverandre
+CD ==========================================================================
+CD Form�l:
+CD Sjekker om to bokser "ber�rer" hverandre.
+CD
+CD Parametre:
+CD Type     Navn     I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BOKS *  pB1      i   Rektangel 1
+CD LC_BOKS *  pB2      i   Rektangel 2
+CD short     sStatus  r   UT_TRUE=Ber�rer,  UT_FALSE=Ikke ber�ring 
+CD
+CD Bruk:
+CD LR_R_BoksTestIntersect(...);
+   ==========================================================================
+*/
+static short LR_R_BoksTestIntersect(LC_BOKS * pB1,LC_BOKS * pB2)
+{
+   if (pB1->dMaxNord  >=  pB2->dMinNord  &&
+       pB1->dMaxAust  >=  pB2->dMinAust  &&
+       pB1->dMinNord  <=  pB2->dMaxNord  &&
+       pB1->dMinAust  <=  pB2->dMaxAust ) {
+
+      /* Tilslag */
+      return UT_TRUE;
+   }
+
+   return UT_FALSE;
+}
+
+
+/*
+AR-911003
+CH LC_FNGeo                                    Finn neste ved geografisk s�k
+CD ==========================================================================
+CD Form�l:
+CD Finner neste gruppe i det definerte omr�det for geografisk s�k.
+CD
+CD Parametre:
+CD Type           Navn      I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat  iu   Peker til struktur for s�kestatus
+CD LC_BGR *        pBgr       u   Funnet gruppe
+CD short          sstat      r   S�kestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD Se under LC_SBGeo.
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_FNGeo(LC_GEO_STATUS * pGeoStat,LC_BGR * pBgr)
+{
+   /* Bruker R-tre */
+   if (pGeoStat->usMetode == LC_GEO_RTRE) {
+      /* S�ket er utf�rt og ligger som en kjede */
+      if (pGeoStat->pAktuellKB != NULL) {
+         pGeoStat->pAktuellKB = pGeoStat->pAktuellKB->pNesteKB;
+         if (pGeoStat->pAktuellKB != NULL) {
+            /* Tilslag */
+            *pBgr = pGeoStat->pAktuellKB->Bgr;
+            return UT_TRUE;
+         }
+      }
+
+   /* Sekvensiell gjennomgang av alle grupper */
+   } else {
+      LC_R_LEAF * pRL;
+      LC_BGR Bgr = pGeoStat->Bgr;
+   
+      while (LC_NextBgr(&Bgr,pGeoStat->usLag)) {
+         pRL = LI_GetGeo(Bgr.pFil,Bgr.lNr);
+         if (pRL != NULL) {
+            /* Sjekk omr�de-tabellen */
+            if (pGeoStat->ohn >= pRL->Boks.dMinNord && pGeoStat->oha >= pRL->Boks.dMinAust &&
+                pGeoStat->nvn <= pRL->Boks.dMaxNord && pGeoStat->nva <= pRL->Boks.dMaxAust) {
+               *pBgr = pGeoStat->Bgr = Bgr;            /* Tilslag */
+               return UT_TRUE;
+            }
+         }
+      }
+
+      /* Ikke tilslag */
+      pGeoStat->Bgr = Bgr;
+   }
+   
+   /* Ikke tilslag */
+   return UT_FALSE;
+}
+
+
+/*
+AR-911003
+CH LC_FFGeoFil                       Finn f�rste ved geografisk s�k i en fil
+CD ==========================================================================
+CD Form�l:
+CD Finner f�rste gruppe i det definerte omr�det for kombinert geografisk s�k.
+CD S�ker bare i en gitt fil.
+CD
+CD Parametre:
+CD Type           Navn       I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat   iu   Peker til struktur for s�kestatus
+CD LC_FILADM *    pOnsketFil  i   Filpeker til den filen det skal s�kes i.
+CD LC_BGR *        pBgr        u   Funnet gruppe
+CD short          sstat       r   S�kestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD Se under LC_SBGeo.
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_FFGeoFil(LC_GEO_STATUS * pGeoStat,LC_FILADM *pOnsketFil,LC_BGR * pBgr)
+{
+   /* Bruker R-tre */
+   if (pGeoStat->usMetode == LC_GEO_RTRE) {
+      LC_BOKS Boks;
+
+      /* Beregn s�keboksen */
+      Boks.dMinAust = pGeoStat->nva;
+      Boks.dMinNord = pGeoStat->nvn;
+      Boks.dMaxAust = pGeoStat->oha;
+      Boks.dMaxNord = pGeoStat->ohn;
+   
+      /* Frigir eventuell gammel resultatkjede */
+      LC_AvsluttSok(pGeoStat);
+
+      /* Sjekker den aktuelle filen */
+	   if (pOnsketFil->usLag & pGeoStat->usLag) {
+         /* File inneholder data, m� sjekke alle ber�rte noder */
+         if (pOnsketFil->pGeoRN != NULL) {
+            LR_R_SjekkNode(pGeoStat,&Boks,pOnsketFil,pOnsketFil->pGeoRN);
+         }   
+      }
+
+      pGeoStat->pAktuellKB = pGeoStat->pForsteKB;
+      if (pGeoStat->pAktuellKB != NULL) {
+         /* Tilslag */
+         *pBgr = pGeoStat->pAktuellKB->Bgr;
+         return UT_TRUE;
+      }
+
+   /* Sekvensiell gjennomgang av alle grupper */
+   } else {
+      LC_BGR Bgr;
+      LC_R_LEAF * pRL;
+   
+      LC_InitNextBgr(&Bgr);
+      while (LC_NextBgr(&Bgr,pGeoStat->usLag)) {
+         /* Rett fil? */ 
+         if (Bgr.pFil == pOnsketFil) {
+            pRL = LI_GetGeo(Bgr.pFil,Bgr.lNr);
+            if (pRL != NULL) {
+               /* Sjekk omr�de-tabellen */
+               if (pGeoStat->ohn >= pRL->Boks.dMinNord && pGeoStat->oha >= pRL->Boks.dMinAust &&
+                   pGeoStat->nvn <= pRL->Boks.dMaxNord && pGeoStat->nva <= pRL->Boks.dMaxAust) {
+                  *pBgr = pGeoStat->Bgr = Bgr;            /* Tilslag */
+                  return UT_TRUE;
+               }
+            }
+         }
+      }
+
+      /* Ikke tilslag */
+      pGeoStat->Bgr = Bgr;
+   }
+
+   /* Ikke tilslag */
+   return UT_FALSE;
+}
+
+
+/*
+AR-911003
+CH LC_FNGeoFil                        Finn neste ved geografisk s�k i en fil
+CD ==========================================================================
+CD Form�l:
+CD Finner neste gruppe i det definerte omr�det for geografisk s�k.
+CD S�ker bare i en gitt fil.
+CD
+CD Parametre:
+CD Type           Navn      I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat  iu   Peker til struktur for s�kestatus
+CD LC_FILADM *    pFil      i    Filpeker til den filen det skal s�kes i.
+CD LC_BGR *        pBgr       u   Funnet gruppe
+CD short          sstat      r   S�kestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD Se under LC_SBGeo.
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_FNGeoFil(LC_GEO_STATUS * pGeoStat,LC_FILADM *pFil,LC_BGR * pBgr)
+{
+   /* Bruker R-tre */
+   if (pGeoStat->usMetode == LC_GEO_RTRE) {
+      if (pGeoStat->pAktuellKB != NULL) {
+         pGeoStat->pAktuellKB = pGeoStat->pAktuellKB->pNesteKB;
+         if (pGeoStat->pAktuellKB != NULL) {
+            /* Tilslag */
+            *pBgr = pGeoStat->pAktuellKB->Bgr;
+            return UT_TRUE;
+         }
+      }
+
+   /* Sekvensiell gjennomgang av alle grupper */
+   } else {
+      LC_R_LEAF * pRL;
+      LC_BGR Bgr = pGeoStat->Bgr;
+   
+      while (LC_NextBgr(&Bgr,pGeoStat->usLag)) {
+
+         if (Bgr.pFil == pFil) {
+            pRL = LI_GetGeo(Bgr.pFil,Bgr.lNr);
+            if (pRL != NULL) {
+               /* Sjekk omr�de-tabellen */
+               if (pGeoStat->ohn >= pRL->Boks.dMinNord && pGeoStat->oha >= pRL->Boks.dMinAust &&
+                   pGeoStat->nvn <= pRL->Boks.dMaxNord && pGeoStat->nva <= pRL->Boks.dMaxAust) {
+                  *pBgr = pGeoStat->Bgr = Bgr;            /* Tilslag */
+                  return UT_TRUE;
+               }
+            }
+         }
+      }
+
+      /* Ikke tilslag */
+      pGeoStat->Bgr = Bgr;
+   }
+   
+   /* Ikke tilslag */
+   return UT_FALSE;
+}
+
+
+/*
+AR-911002
+CH LC_FAGeo                                     Finn alle ved geografisk s�k
+CD ==========================================================================
+CD Form�l:
+CD Finn alle i geografisk s�keomr�de.
+CD Tilslag merkes i brukttabellen kolonne BT_GEOSOK (15).
+CD
+CD Parametre:
+CD Type           Navn      I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat  iu   Peker til struktur for s�kestatus
+CD long           lAntall    r   Antall funnet.
+CD
+CD Bruk:
+CD .
+CD LC_SBGeo(&GeoStat,LC_FRAMGR | LC_BAKGR,nv_a,nv_n,oh_a,oh_n);
+CD antall = LC_FAGeo(&Bgr);
+CD .
+   =============================================================================
+*/
+SK_EntPnt_FYBA long LC_FAGeo(LC_GEO_STATUS * pGeoStat)
+{
+   short ngi;
+   long nko;
+   unsigned short info;
+   LC_BGR AktBgr,Bgr;
+   long lAntall = 0;
+
+
+   /* Husk aktuell gruppe */
+   AktBgr = Sys.GrId;
+
+   /* Blanker brukttabellen */
+   LI_EraseBt(BT_GEOSOK,BT_GEOSOK);
+   
+   /* Utf�rer s�ket */
+   if (LC_FFGeo(pGeoStat,&Bgr)) {
+      do {
+         LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+         lAntall += LC_MerkGr(BT_GEOSOK,1);     /* Tilslag */
+      } while (LC_FNGeo(pGeoStat,&Bgr));
+   }
+   LC_AvsluttSok(pGeoStat);
+
+   /* Les tilbake aktuell gruppe */
+   if (AktBgr.lNr != INGEN_GRUPPE) {
+      LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+   }
+
+   return lAntall;
+}
+
+
+/*
+AR-911003
+CH LC_SBFlate                     Sett s�kegrense for geografisk s�k p� flate
+CD =============================================================================
+CD Form�l:
+CD Definerer punkt for geografisk s�k p� flate.
+CD
+CD Parametre:
+CD Type     Navn      I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat  iu   Peker til struktur for s�kestatus
+CD unsigned short usLag      i   Velg hvilke "lag" det skal s�kes i.
+CD                               LC_FRAMGR og /eller LC_BAKGR
+CD double         nv_a       i   Koordinat nedre venstre hj�rne
+CD double         nv_n       i
+CD double         oh_a       i   Koordinat �vre h�yre hj�rne
+CD double         oh_n       i
+CD
+CD Bruk:
+CD LC_GEO_STATUS GeoStat;
+CD .
+CD LC_SBFlate(&GeoStat,LC_FRAMGR | LC_BAKGR,nv_a,nv_n,oh_a,oh_n);
+CD if (LC_FFFlate(&GeoStat,&Bgr)) {
+CD     do{
+CD         . Behandle funnet gruppe
+CD         .
+CD     } while (LC_FNFlate(&GeoStat,&Bgr));
+CD }
+CD LC_AvsluttSok(&GeoStat);
+CD .
+   =============================================================================
+*/
+SK_EntPnt_FYBA void LC_SBFlate(LC_GEO_STATUS * pGeoStat,unsigned short usLag,
+              double nv_a,double nv_n,double oh_a,double oh_n)
+{
+                     /* Normaliserer vinduet */
+   GM_NormVindu(&nv_a,&nv_n,&oh_a,&oh_n);
+
+                          /* Avrunder ut til n�rmeste meter utover */
+                          /* Nedre venstre ut til n�rneste heltall under */
+   pGeoStat->nvn = (long)floor(nv_n);
+   pGeoStat->nva = (long)floor(nv_a);
+                           /* �vre h�yre ut til n�rneste heltall over */
+   pGeoStat->ohn = (long)ceil(oh_n);
+   pGeoStat->oha = (long)ceil(oh_a);
+
+                           /* Husk lag */
+   pGeoStat->usLag = usLag;
+
+   /* Nullstiller resultatpekerne */
+   pGeoStat->pForsteKB = NULL;
+   pGeoStat->pSisteKB = NULL;
+   pGeoStat->pAktuellKB = NULL;
+
+   /* Velg s�kemetode */
+   LR_VelgMetode(pGeoStat);
+}
+
+
+/*
+AR-911003
+CH LC_FFFlate                                        Finn f�rste ved flates�k
+CD =============================================================================
+CD Form�l:
+CD Finner f�rste gruppe i det definerte omr�det for flates�k.
+CD
+CD Parametre:
+CD Type     Navn      I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat  iu   Peker til struktur for s�kestatus
+CD LC_BGR *        pBgr       u   Funnet gruppe
+CD short          sstat      r   S�kestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD Se under LC_SBFlate.
+   =============================================================================
+*/
+SK_EntPnt_FYBA short LC_FFFlate(LC_GEO_STATUS * pGeoStat,LC_BGR * pBgr)
+{
+   /* Bruker R-tre */
+   if (pGeoStat->usMetode == LC_GEO_RTRE) {
+      LC_BOKS Boks;
+      LC_FILADM *pFil;
+
+      /* Beregn s�keboksen */
+      Boks.dMinAust = pGeoStat->nva;
+      Boks.dMinNord = pGeoStat->nvn;
+      Boks.dMaxAust = pGeoStat->oha;
+      Boks.dMaxNord = pGeoStat->ohn;
+  
+      /* Frigir eventuell gammel resultatkjede */
+      LC_AvsluttSok(pGeoStat);
+
+      /* Sjekker alle filer */
+      LC_InitNextFil(&pFil);
+	   while (LC_NextFil(&pFil,pGeoStat->usLag)) {
+
+         /* File inneholder data, m� sjekke alle ber�rte kvadranter */
+         if (pFil->pGeoRN != NULL) {
+            LR_R_SjekkNodeFlate(pGeoStat,&Boks,pFil,pFil->pGeoRN);
+         }   
+      }
+
+      pGeoStat->pAktuellKB = pGeoStat->pForsteKB;
+
+      if (pGeoStat->pAktuellKB != NULL) {
+         /* Tilslag */
+         *pBgr = pGeoStat->pAktuellKB->Bgr;
+         return UT_TRUE;
+      }
+
+   /* Sekvensiell gjennomgang av alle grupper */
+   } else {
+      LC_BGR Bgr;
+      LC_R_LEAF * pRL;
+
+      LC_InitNextBgr(&Bgr);
+
+      while (LC_NextBgr(&Bgr,pGeoStat->usLag)) {
+         if (LI_InqBt(Bgr.pFil,Bgr.lNr,BT_REFBOX)) {
+            pRL = LI_GetGeo(Bgr.pFil,Bgr.lNr);
+            if (pRL != NULL) {
+               /* Sjekk omr�de-tabellen */
+               if (pGeoStat->ohn >= pRL->Boks.dMinNord && pGeoStat->oha >= pRL->Boks.dMinAust &&
+                   pGeoStat->nvn <= pRL->Boks.dMaxNord && pGeoStat->nva <= pRL->Boks.dMaxAust) {
+                  *pBgr = pGeoStat->Bgr = Bgr;            /* Tilslag */
+                  return UT_TRUE;
+               }
+            }
+         }
+      }
+
+      /* Ikke tilslag */
+      pGeoStat->Bgr = Bgr;
+   }
+   
+   /* Ikke tilslag */
+   return UT_FALSE;
+}
+
+
+/*
+AR-980205
+CH LR_R_SjekkNodeFlate            Sjekker node om overlappende boks (flate)
+CD ==========================================================================
+CD Form�l:
+CD Sjekker en node og underliggende noder om de har lagret bokser
+CD som overlapper s�kerektanglet. De gruppene som blir funnet blir hengt p�
+CD kjeden med s�keresultat i pGeoStat. Finner bare grupper der det er brukt
+CD referanser for oppbygging av geografisk boks.
+CD
+CD Parametre:
+CD Type     Navn      I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat   i   Peker til struktur for s�kestatus
+CD LC_BOKS *       pB         i   S�keboks
+CD LC_FILADM *    pFil       i   Filpeker
+CD LC_R_NODE *     pRN        i   Peker til node som skal sjekkes
+CD
+CD Bruk:
+CD LR_R_SjekkNodeFlate(pGeoStat,pB,pFil,pRN->pSon[i]);
+   ==========================================================================
+*/
+static void LR_R_SjekkNodeFlate(LC_GEO_STATUS * pGeoStat,LC_BOKS * pB,LC_FILADM *pFil,LC_R_NODE * pRN)
+{
+   int i;
+
+
+   /* Sjekk om denne noden ber�rer s�keboksen */
+   if (LR_R_BoksTestIntersect(&(pRN->Boks),pB)) {
+
+      /* Har kommet til ytterste niv� */
+      if (pRN->sSonType == LC_LEAF) {
+
+         /* Sjekk de gruppene som er lagret under denne noden */
+         for (i=0; i<pRN->sSonAnt; i++) { 
+            if (LR_R_BoksTestIntersect(&(pRN->Son.pLeaf[i]->Boks),pB)) {
+               /* Huskes bare hvis det er brukt referanser */
+               if (LI_InqBt(pFil,pRN->Son.pLeaf[i]->lNr,BT_REFBOX)) {
+                  LR_LeggTilKB(pGeoStat,pFil,pRN->Son.pLeaf[i]->lNr);
+               }
+            }
+         }
+
+      /* Node */
+      } else {
+
+         /* Rekursiv sjekk av de underliggende nodene */
+         for (i=0; i<pRN->sSonAnt; i++) { 
+            LR_R_SjekkNodeFlate(pGeoStat,pB,pFil,pRN->Son.pNode[i]);
+         }
+      }
+   }
+}
+
+
+/*
+AR-911002
+CH LC_FNFlate                                        Finn neste ved flates�k
+CD ==========================================================================
+CD Form�l:
+CD Finner neste gruppe i det definerte omr�det for flates�k.
+CD
+CD Parametre:
+CD Type     Navn      I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat  iu   Peker til struktur for s�kestatus
+CD LC_BGR *        pBgr       u   Funnet gruppe
+CD short          sstat      r   S�kestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD Se under LC_SBFlate.
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_FNFlate(LC_GEO_STATUS * pGeoStat,LC_BGR * pBgr)
+{
+   /* Bruker R-tre */
+   if (pGeoStat->usMetode == LC_GEO_RTRE) {
+      if (pGeoStat->pAktuellKB != NULL) {
+         pGeoStat->pAktuellKB = pGeoStat->pAktuellKB->pNesteKB;
+         if (pGeoStat->pAktuellKB != NULL) {
+            /* Tilslag */
+            *pBgr = pGeoStat->pAktuellKB->Bgr;
+            return UT_TRUE;
+         }
+      }
+
+   /* Sekvensiell gjennomgang av alle grupper */
+   } else {
+      LC_R_LEAF * pRL;
+      LC_BGR Bgr = pGeoStat->Bgr;
+
+      while (LC_NextBgr(&Bgr,pGeoStat->usLag)) {
+         if (LI_InqBt(Bgr.pFil,Bgr.lNr,BT_REFBOX)) {
+            pRL = LI_GetGeo(Bgr.pFil,Bgr.lNr);
+            if (pRL != NULL) {
+               /* Sjekk omr�de-tabellen */
+               if (pGeoStat->ohn >= pRL->Boks.dMinNord && pGeoStat->oha >= pRL->Boks.dMinAust &&
+                   pGeoStat->nvn <= pRL->Boks.dMaxNord && pGeoStat->nva <= pRL->Boks.dMaxAust) {
+                  *pBgr = pGeoStat->Bgr = Bgr;            /* Tilslag */
+                  return UT_TRUE;
+               }
+            }
+         }
+      }
+
+      /* Ikke tilslag */
+      pGeoStat->Bgr = Bgr;
+   }
+   
+   /* Ikke tilslag */
+   return UT_FALSE;
+}
+
+
+/*
+AR-890824
+CH LC_WTst                                                        Vindustest
+CD ==========================================================================
+CD Form�l:
+CD Sjekk om aktuell gruppe ber�rer gitt vindu.
+CD Tar hensyn til gruppenavnet. Handterer (PUNKT, LINJE, KURVE, BUE,
+CD BUEP, SIRKEL, SIRKELP, SVERM, TRASE ).
+CD
+CD Parametre:
+CD Type    Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double  nva        i    Avgrensing av vinduet
+CD double  nvn        i
+CD double  oha        i
+CD double  ohn        i
+CD short   ist        r    status: 0 = ikke ber�ring
+CD                                 1 = skj�ring
+CD
+CD Bruk:
+CD .
+CD LC_SBGeo(&GeoStat,nv_a,nv_n,oh_a,oh_n);
+CD if (LC_FFGeo(&GeoStat,&Bgr)){
+CD     do{
+CD         LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+CD         if (LC_WTst(nv_a,nv_n,oh_a,oh_n)) {       (N�yaktig vindustest)
+CD             . Behandle funnet gruppe
+CD             .
+CD         }
+CD     } while (LC_FNGeo(&GeoStat,&Bgr));
+CD }
+CD LC_AvsluttSok(&GeoStat);
+CD .
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_WTst(double nva,double nvn,double oha,double ohn)
+{
+   short ngi,gruppenavn,sfeil;
+   long nko,pt;
+   unsigned short info;
+   double radius,aust,nord,fi,dfi;
+   double *pdAust = Sys.pdAust;
+   double *pdNord = Sys.pdNord;
+
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {            /* Har aktuell gruppe */
+      gruppenavn = LC_GetGrPara(&ngi,&nko,&info);
+      if (nko > 0){                           /* Har koordinater */
+
+            /* .BUE, .BUEP, .SIRKEL eller .SIRKELP */
+         if (gruppenavn == L_BUE  ||  gruppenavn == L_BUEP ||
+             gruppenavn == L_SIRKEL  ||  gruppenavn == L_SIRKELP) {
+
+            if (LC_GetBuePar(HENT_FORRFRA,&aust,&nord,&radius,&fi,&dfi,&sfeil)) {
+               /* Vindustest p� buen */
+               if (GM_wtstBue(aust,nord,radius,fi,dfi,nva,nvn,oha,ohn)) {
+                  return(1);
+               }
+
+            } else {
+               // Spesialhandtering av ulogiske sirkler og buer
+               // Handteres som punkt/linje
+                                           // Sjekk f�rste koordinat
+               if (GM_wtst(*pdAust,*pdNord,*pdAust,*pdNord,nva,nvn,oha,ohn)) {
+                  return(1);
+               }
+
+               // Sjekk resten av gruppen
+               ++pdAust;
+               ++pdNord;
+               for (pt=1; pt<Sys.pGrInfo->nko; ++pt,++pdAust,++pdNord) {
+                  if (GM_wtst(*(pdAust-1),*(pdNord-1),*pdAust,*pdNord,
+                              nva,nvn,oha,ohn)) {
+                     return(1);
+                  }
+               }
+            }
+
+         /* .PUNKT eller .SVERM */
+         } else if (gruppenavn == L_PUNKT  ||  gruppenavn == L_SVERM) {
+            /* Sjekk om noe punkt er innenfor */
+            for (pt=1; pt<=Sys.pGrInfo->nko; ++pt) {
+               LC_GetTK(pt,&aust,&nord);
+               if (aust >= nva  &&  aust <= oha  &&
+                   nord >= nvn  &&  nord <= ohn    ) {
+                  return(1);
+               }
+            }
+
+         /* .TRASE */
+         } else if (gruppenavn == L_TRASE) {
+
+            short ngi;
+            long nko;
+            unsigned short info;
+            LC_POLYGON Polygon;
+            LC_POL_ELEMENT * pPE;
+            LC_BGR BgrTrase = Sys.GrId;      /* Husk gruppenummer for traseen */
+
+
+            /* Initier referansehandtering, og les beskrivelsen */
+            LC_POL_InitPolygon(&Polygon);
+            LC_POL_GetRef(&Polygon);
+
+            /* Behandle referansene */
+            for (pPE = Polygon.HovedPO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+               LC_RxGr(&pPE->Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+               if (LC_WTst(nva,nvn,oha,ohn)) {      /* (N�yaktig vindustest) */
+                  /* Frigi allokerte kjeder */
+                  LC_POL_FrigiPolygon(&Polygon);
+
+                  /* Les inn traseen igjen */
+                  LC_RxGr(&BgrTrase,LES_OPTIMALT,&ngi,&nko,&info);
+                  
+                  return (1);
+               }
+            }
+
+            /* Frigi allokerte kjeder */
+            LC_POL_FrigiPolygon(&Polygon);
+
+            /* Les inn traseen igjen */
+            LC_RxGr(&BgrTrase,LES_OPTIMALT,&ngi,&nko,&info);
+
+
+         /* Andre gruppenavn */
+         } else {
+                                           /* Sjekk f�rste koordinat */
+            if (GM_wtst(*pdAust,*pdNord,*pdAust,*pdNord,nva,nvn,oha,ohn)) {
+               return(1);
+            }
+
+            /* Sjekk resten av gruppen */
+            ++pdAust;
+            ++pdNord;
+            for (pt=1; pt<Sys.pGrInfo->nko; ++pt,++pdAust,++pdNord) {
+               if (GM_wtst(*(pdAust-1),*(pdNord-1),*pdAust,*pdNord,
+                           nva,nvn,oha,ohn)) {
+                  return(1);
+               }
+            }
+         }
+      }
+   }
+   return (0);
+}
+
+
+/*
+AR-890824
+CH LC_PTst                                                        Polygontest
+CD ==========================================================================
+CD Form�l:
+CD Sjekker om gitt punkt ligger innenfor polygon angitt av aktuell gruppe.
+CD Forutsetter at tabellen danner et lukket polygon
+CD
+CD Parametre:
+CD Type    Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double  a        i    Punkt som skal sjekkes
+CD double  n        i
+CD short   ist      r    status: 0 = punktet er utenfor flaten
+CD                               1 = punktet ligger inne p� flaten
+CD
+CD Bruk:
+CD .
+CD LC_SBFlate(&GeoStat,a-d,n-d,a+d,n+d);
+CD if (LC_FFFlate(&GeoStat,&Bgr)) {
+CD     do{
+CD         LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+CD         if (LC_PTst(a,n)){          (N�yaktig polygontest)
+CD             . Behandle funnet gruppe
+CD             .
+CD         }
+CD     } while (LC_FNFlate(&GeoStat,&Bgr));
+CD }
+CD LC_AvsluttSok(&GeoStat);
+CD .
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_PTst(double a,double n)
+{
+   LC_POLYGON Polygon;
+   short inni = 0;   /* Returverdi: 1 = inne p� flaten, 0 = utenfor  */
+      
+   // Sjekk om gruppen er flate
+   if (Sys.pGrInfo->gnavn == L_FLATE)
+   {
+      // Initier flatehandtering, og les flatebeskrivelsen
+      LC_POL_InitPolygon(&Polygon);
+      LC_POL_GetRef(&Polygon);
+
+      // Utf�r selve polygontesten
+      inni = LC_POL_PTst(&Polygon,a,n);
+
+      // Frigi allokerte kjeder
+      LC_POL_FrigiPolygon(&Polygon);
+   }
+   
+   return  inni;
+}
+
+
+/*
+AR-911002
+CH LC_PTstOmkrets                         Sjekk om punkt ligger inni polygon
+CD ==========================================================================
+CD Form�l:
+CD Sjekker om gitt punkt ligger innenfor yttergrensen for polygon angitt
+CD av aktuell gruppe.
+CD Forutsetter at tabellen danner et lukket polygon
+CD
+CD Parametre:
+CD Type    Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double  a        i    Punkt som skal sjekkes
+CD double  n        i
+CD short   ist      r    status: 0 = punktet er utenfor flaten
+CD                               1 = punktet ligger inne p� flaten
+CD
+CD Bruk:
+CD ist = LC_PTstOmkrets(a,n);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_PTstOmkrets(double a,double n)
+{
+   long ref_arr[MAX_REF];
+   unsigned char ref_status[MAX_REF];
+   long ant_ref;
+   short ngi,s;
+   long nko;
+   unsigned short info;
+   LC_GRF_STATUS GrfStat;
+   LC_BGR Bgr;
+   short sAntSkjaer = 0;
+   LC_BGR Flate = Sys.GrId;      /* Husk gruppenummer for flaten */
+
+   Bgr.pFil = Flate.pFil;
+
+   double dEnhet = Sys.pGrInfo->dEnhet;
+
+   // Pluss p� et lite tillegg for � unng� treff p� node
+   a += dEnhet / 1000.0;
+   n += dEnhet / 1000.0;
+
+   /* Sjekk om gruppen er flate */
+   if (LC_GetGrPara(&ngi,&nko,&info) == L_FLATE){
+
+      LC_InitGetRefFlate(&GrfStat);
+
+      /* Behandle ytre avgrensing */
+      ant_ref = LC_GetRefFlate(&GrfStat,GRF_YTRE,ref_arr,ref_status,MAX_REF);
+      do {
+         for (s=0; s<ant_ref; s++) {
+            Bgr.lNr = ref_arr[s];
+            sAntSkjaer += LR_PTstGruppe(&Bgr,a,n);
+         }
+         /* Les inn flaten igjen */    
+         LC_RxGr(&Flate,LES_OPTIMALT,&ngi,&nko,&info);
+
+         if (ant_ref < MAX_REF)  break;
+
+         ant_ref = LC_GetRefFlate(&GrfStat,GRF_YTRE,ref_arr,ref_status,MAX_REF);
+      } while (ant_ref > 0);
+   }
+
+   /* Sjekk om punktet er innenfor */
+   return  ((sAntSkjaer % 2) == 1)?  1 : 0;
+}
+
+
+/*
+AR-921028
+CH LR_PTstGruppe                  Sjekk om punkt ligger inni polygon
+CD ==========================================================================
+CD Form�l:
+CD Sjekker antall skj�ringer mellom gitt gruppe og linje fra gitt punkt
+CD til "uendelig" �st.
+CD
+CD Parametre:
+CD Type    Navn       I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR * pBgr        i    Peker til datagruppe
+CD double  a           i    Punkt som skal sjekkes
+CD double  n           i
+CD short   sAntSkjaer  r    Antall skj�ringer
+CD
+CD Bruk:
+CD ist = LR_PTstOmkrets(&Bgr,a,n);
+   ==========================================================================
+*/
+short LR_PTstGruppe(LC_BGR * pBgr,double a,double n)
+{
+   double maxa = 99999999999.0;           /* "Uendelig" �st */
+   short ngi,gruppenavn,sfeil;
+   long pt,nko;
+   unsigned short info;
+   #define ARR_LEN 50
+   long punkt, antall;
+   double a1,n1,a2,n2,radius,as,ns,fi,dfi;
+   double n_arr[ARR_LEN],a_arr[ARR_LEN];
+   LC_POLYGON Polygon;
+   LC_POL_ELEMENT * pPE;
+   LC_BGR BgrTrase;
+   short sAntSkjaer = 0;
+
+       
+   /* Sjekk gruppen */
+   gruppenavn = LC_RxGr(pBgr,LES_OPTIMALT,&ngi,&nko,&info);
+   if (nko > 0) {
+       
+      /* .TRASE */
+      if (gruppenavn == L_TRASE) {
+         BgrTrase = Sys.GrId;      /* Husk gruppenummer for traseen */
+
+         /* Initier referansehandtering, og les beskrivelsen */
+         LC_POL_InitPolygon(&Polygon);
+         LC_POL_GetRef(&Polygon);
+
+         /* Behandle referansene */
+         for (pPE = Polygon.HovedPO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+            sAntSkjaer += LR_PTstGruppe(&pPE->Bgr,a,n);
+         }
+
+         /* Frigi allokerte kjeder, og les inn traseen igjen */
+         LC_POL_FrigiPolygon(&Polygon);
+         LC_RxGr(&BgrTrase,LES_OPTIMALT,&ngi,&nko,&info);
+
+      /* "bue" */
+      } else if (gruppenavn == L_BUE     ||  gruppenavn == L_BUEP ||
+                 gruppenavn == L_SIRKEL  ||  gruppenavn == L_SIRKELP) {
+
+         if (LC_GetBuePar(HENT_FORRFRA,&as,&ns,&radius,&fi,&dfi,&sfeil)) {
+            sAntSkjaer += GM_sLinBue(as,ns,radius,fi,dfi,
+                               a,n,maxa,n,&a1,&n1,&a2,&n2);
+         }
+
+      /* Annen gruppe */
+      } else {                    
+         punkt = 1;
+         do {                       /* Finn skj�ringspunkter */
+            LC_GetArrayTK(HENT_FORRFRA,ARR_LEN,punkt,a_arr,n_arr,&antall);/* Henter */
+            if (antall > 0) {
+               for (pt=1; pt<antall; pt++) {
+                  sAntSkjaer += GM_shor(a_arr[pt-1],n_arr[pt-1],
+                                    a_arr[pt],n_arr[pt],a,n,maxa,n,&a1,&n1);
+               }
+               punkt += (antall-1);
+            }
+         } while (punkt < nko);
+      }
+   }
+
+   return  sAntSkjaer;
+}
+
+
+/*
+AR-980108
+CH LR_InsertGeo                     Legg gruppen inn i geografisk indeks
+CD =======================================================================
+CD Bruk:
+CD
+CD Parametere:
+CD Type          Navn  I/U  Forklaring
+CD -----------------------------------------------------------------------
+CD LC_FILADM *   pFil   i   Filpeker
+CD long          lNr    i   Gruppenummer i filen
+CD LC_BOKS *      pB     i   Boks som skal legges inn i treet
+CD LC_R_LEAF *    pRL    r   Peker inn i geografisk s�ketre
+CD
+CD Form�l:
+CD Legg gruppen inn i geografisk indeks.
+CD Forutsetter at grupen ikke ligger i s�ketreet fra f�r.
+CD =======================================================================
+*/
+LC_R_LEAF * LR_InsertGeo(LC_FILADM *pFil,long lNr,LC_BOKS * pB)
+{
+   LC_R_NODE * pNyRN,*pRotRN;
+   LC_R_LEAF * pRL;
+
+
+   /* Lagre omskrevet boks i s�ketreet */
+   pRL = LR_R_Insert(lNr,pB,NULL,pFil->pGeoRN,&pNyRN);
+
+   /* Hvis rot-noden er splittet m� det lages ny rot-node */
+   if (pNyRN != NULL) {
+      if (pFil->pGeoRN != NULL) {
+         /* Lag ny rot-node */
+         pRotRN = LR_R_CreateRNode(NULL,LC_NODE);
+         pRotRN->Son.pNode[0] = pFil->pGeoRN;
+         pRotRN->Son.pNode[1] = pNyRN;
+         pRotRN->sSonAnt = 2;
+
+         /* Oppdater boks */
+         pRotRN->Boks = pFil->pGeoRN->Boks;
+         LR_R_BoksSum(&(pRotRN->Boks),&(pNyRN->Boks));
+
+         /* Oppdater far i s�nnene */
+         pFil->pGeoRN->pFar = pRotRN;
+         pNyRN->pFar = pRotRN;
+
+         pFil->pGeoRN = pRotRN;
+
+      } else {
+         pFil->pGeoRN = pNyRN;
+      }
+   }
+
+   return pRL;
+}
+
+
+/*
+AR-980108
+CH LR_R_Insert                                             Insert i R-tre
+CD =======================================================================
+CD Bruk:
+CD
+CD Parametere:
+CD Type         Navn  I/U  Forklaring
+CD -----------------------------------------------------------------------
+CD long         lGrNr  i   Gruppenummer i filen
+CD LC_BOKS     *pB     i   Boks som skal legges inn i treet
+CD LC_R_NODE   *pFar   i   Peker til far i quad-treet
+CD LC_R_NODE   *pRN    i   Peker til node i R-treet
+CD LC_R_NODE  **ppNyRN u   Peker til peker til nyopprettet node i R-treet
+CD LC_R_LEAF   *pRL    r   Peker til forekomst i R-treet
+CD
+CD Form�l:
+CD Leger inn et rektangl i R-treet med rot i node pRN.
+CD Hvis pRN == NULL (Tomt tre) settes *ppNyRN til � peke til et nyt tre.
+CD =======================================================================
+*/
+static LC_R_LEAF * LR_R_Insert(long lGrNr,LC_BOKS *pB,LC_R_NODE *pFar,LC_R_NODE *pRN,LC_R_NODE **ppNyRN)
+{
+   LC_R_NODE *pNyRN,*pKandidatRN[LC_R_MAX_SON+1];
+   LC_R_LEAF *pRL,*pKandidatRL[LC_R_MAX_SON+1];
+   int i,iIdxMin=0,iIdxMax=0;
+   double dDeltaAreal,dMinDeltaAreal;
+   double dMinAust,dMaxAust;
+
+   // Test
+   //static int iNivo;
+   //iNivo++;
+   //UT_FPRINTF(stderr,"LR_R_Insert niv� :%d\n",iNivo);
+
+   
+   *ppNyRN = NULL;
+
+
+   /* Treet er tomt, m� allokere ny node */
+   if (pRN == NULL) {
+      *ppNyRN = pRN = LR_R_CreateRNode(NULL,LC_LEAF);
+   }
+
+   /* Har kommet til ytterste niv� */
+   if (pRN->sSonType == LC_LEAF) {
+
+      pRL = LR_R_CreateRLeaf(lGrNr,pB,pRN);
+
+      /* Hvis ledig plass */
+      if (pRN->sSonAnt < LC_R_MAX_SON) {
+         /* Legg inn rektanglet */
+         pRN->Son.pLeaf[pRN->sSonAnt] = pRL;
+         (pRN->sSonAnt)++;
+         
+         /* Oppdaterer omskrevet boks */
+         LR_R_BoksSum(&(pRN->Boks),pB);
+
+      /* Fullt, m� opprett ny node */
+      } else {
+         *ppNyRN = pNyRN = LR_R_CreateRNode(pRN->pFar,LC_LEAF);
+
+         /* Fordel boksene p� de to nodene etter line�r kost algoritmen */
+
+         /* Beregn "ekstrem-bokser" */
+         dMinAust = LONG_MAX;
+         dMaxAust = LONG_MIN;
+
+         iIdxMax = 0;
+         for (i=0; i<pRN->sSonAnt; i++) {
+            pKandidatRL[i] = pRN->Son.pLeaf[i];
+            if (pKandidatRL[i]->Boks.dMinAust > dMaxAust) {
+               dMaxAust = pKandidatRL[i]->Boks.dMinAust;
+               iIdxMax = i;
+            }
+         }
+         pKandidatRL[LC_R_MAX_SON] = pRL;
+         if (pB->dMinAust > dMaxAust) {
+            dMaxAust = pB->dMinAust;
+            iIdxMax = LC_R_MAX_SON;
+         }
+
+         for (i=0; i<pRN->sSonAnt; i++) {
+            if (iIdxMax != i) {
+               if (pKandidatRL[i]->Boks.dMaxAust < dMinAust) {
+                  dMinAust = pKandidatRL[i]->Boks.dMaxAust;
+                  iIdxMin = i;
+               }
+            }
+         }
+         if (iIdxMax != LC_R_MAX_SON  &&  pB->dMaxAust < dMinAust) {
+            dMinAust = pB->dMaxAust;
+            iIdxMin = LC_R_MAX_SON;
+         }
+
+         /* Plasser ut ekstremboksene */
+         pRN->Son.pLeaf[0] = pKandidatRL[iIdxMax];
+         pRN->sSonAnt = 1;
+         pRN->Boks = pKandidatRL[iIdxMax]->Boks;
+         pKandidatRL[iIdxMax]->pFar = pRN;
+         pKandidatRL[iIdxMax] = NULL;
+
+         pNyRN->Son.pLeaf[0] = pKandidatRL[iIdxMin];
+         pNyRN->sSonAnt = 1;
+         pNyRN->Boks = pKandidatRL[iIdxMin]->Boks;
+         pKandidatRL[iIdxMin]->pFar = pNyRN;
+         pKandidatRL[iIdxMin] = NULL;
+
+         /* Resten av boksene plasseres der de f�rer til minst utvielse av boksen */
+         for (i=0; i<=LC_R_MAX_SON; i++) {
+            if (pKandidatRL[i] != NULL) {
+
+               if (LR_BoksDeltaArealSum(&(pRN->Boks),&(pKandidatRL[i]->Boks)) <
+                   LR_BoksDeltaArealSum(&(pNyRN->Boks),&(pKandidatRL[i]->Boks)) ) {
+
+                  pRN->Son.pLeaf[pRN->sSonAnt] = pKandidatRL[i];
+                  pRN->sSonAnt++;
+                  LR_R_BoksSum(&(pRN->Boks),&(pKandidatRL[i]->Boks));
+                  pKandidatRL[i]->pFar = pRN;
+
+               } else {
+                  pNyRN->Son.pLeaf[pNyRN->sSonAnt] = pKandidatRL[i];
+                  pNyRN->sSonAnt++;
+                  LR_R_BoksSum(&(pNyRN->Boks),&(pKandidatRL[i]->Boks));
+                  pKandidatRL[i]->pFar = pNyRN;
+               }
+            }
+         }
+      }
+
+   /* Node */
+   } else {
+      /* velg den noden som utvides minst ved tillegg av den nye boksen */
+      dMinDeltaAreal = LONG_MAX;
+      iIdxMin = 0;
+      for (i=0; i<pRN->sSonAnt; i++) {
+         /* Beregn hvor mye boksen ville ha blitt utvidet hvis denne ble valget */
+         dDeltaAreal = LR_BoksDeltaArealSum(&(pRN->Son.pNode[i]->Boks),pB);
+         if (dDeltaAreal < dMinDeltaAreal) {
+
+            dMinDeltaAreal = dDeltaAreal;
+            iIdxMin = i;
+         }
+      }
+
+      /* Legger inn rektanglet i den noden med minst utvdelse */
+      pRL = LR_R_Insert(lGrNr,pB,pRN,pRN->Son.pNode[iIdxMin],ppNyRN);
+
+      /* Denne noden har blitt splittet, dette m� tas vare p� her */
+      if (*ppNyRN != NULL) {
+
+         /* Hvis ledig plass */
+         if (pRN->sSonAnt < LC_R_MAX_SON) {
+            /* Legg inn rektanglet */
+            pRN->Son.pNode[pRN->sSonAnt] = *ppNyRN;
+            (pRN->sSonAnt)++;
+         
+            /* Oppdaterer omskrevet boks */
+            LR_R_BoksSum(&(pRN->Boks),pB);
+
+            /* Ingen splitting p� niv�et over */
+            *ppNyRN = NULL;
+
+         /* Fullt, m� opprett ny node */
+         } else {
+            pNyRN = LR_R_CreateRNode(pFar,LC_NODE);
+
+            /* Fordel boksene p� de to nodene etter line�r kost algoritmen */
+
+            /* Beregn "ekstrem-bokser" */
+            dMinAust = LONG_MAX;
+            dMaxAust = LONG_MIN;
+
+            for (i=0; i<pRN->sSonAnt; i++) {
+               pKandidatRN[i] = pRN->Son.pNode[i];
+               if (pKandidatRN[i]->Boks.dMinAust > dMaxAust) {
+                  dMaxAust = pKandidatRN[i]->Boks.dMinAust;
+                  iIdxMax = i;
+               }
+            }
+            pKandidatRN[LC_R_MAX_SON] = *ppNyRN;
+            if (pKandidatRN[i]->Boks.dMinAust > dMaxAust) {
+               dMaxAust = pKandidatRN[i]->Boks.dMinAust;
+               iIdxMax = LC_R_MAX_SON;
+            }
+
+            for (i=0; i<pRN->sSonAnt; i++) {
+               if (iIdxMax != i) {
+                  if (pKandidatRN[i]->Boks.dMaxAust < dMinAust) {
+                     dMinAust = pKandidatRN[i]->Boks.dMaxAust;
+                     iIdxMin = i;
+                  }
+               }
+            }
+
+            /* Plasser ut ekstremboksene */
+            pRN->Son.pNode[0] = pKandidatRN[iIdxMax];
+            pRN->sSonAnt = 1;
+            pRN->Boks = pKandidatRN[iIdxMax]->Boks;
+            pKandidatRN[iIdxMax]->pFar = pRN;
+            pKandidatRN[iIdxMax] = NULL;
+
+            pNyRN->Son.pNode[0] = pKandidatRN[iIdxMin];
+            pNyRN->sSonAnt = 1;
+            pNyRN->Boks = pKandidatRN[iIdxMin]->Boks;
+            pKandidatRN[iIdxMin]->pFar = pNyRN;
+            pKandidatRN[iIdxMin] = NULL;
+
+            /* Resten av boksene plasseres der de f�rer til minst utvielse av boksen */
+            for (i=0; i<=LC_R_MAX_SON; i++) {
+               if (pKandidatRN[i] != NULL) {
+
+                  if (LR_BoksDeltaArealSum(&(pRN->Boks),&(pKandidatRN[i]->Boks)) <
+                      LR_BoksDeltaArealSum(&(pNyRN->Boks),&(pKandidatRN[i]->Boks)) ) {
+
+                     pRN->Son.pNode[pRN->sSonAnt] = pKandidatRN[i];
+                     pRN->sSonAnt++;
+                     LR_R_BoksSum(&(pRN->Boks),&(pKandidatRN[i]->Boks));
+                     pKandidatRN[i]->pFar = pRN;
+
+                  } else {
+                     pNyRN->Son.pNode[pNyRN->sSonAnt] = pKandidatRN[i];
+                     pNyRN->sSonAnt++;
+                     LR_R_BoksSum(&(pNyRN->Boks),&(pKandidatRN[i]->Boks));
+                     pKandidatRN[i]->pFar = pNyRN;
+                  }
+               }
+            }
+
+            /* Husk den nye noden til niv�et over */
+            *ppNyRN = pNyRN;
+         }
+
+      } else {
+         /* Oppdater omskrevet boks for noden */
+         LR_R_BoksSum(&(pRN->Boks),pB);
+      }
+   }
+
+
+   // Test
+   //iNivo--;
+
+   return pRL;
+}
+  
+
+/*
+AR-980108
+CH LR_R_BoksSum                                        Summerer to bokser
+CD =======================================================================
+CD Form�l:
+CD Summerer to bokser ved at boks1 blir utvidet slik at den ogs� dekker 
+CD boks2.
+CD
+CD Parametere:
+CD Type       Navn  I/U  Forklaring
+CD -----------------------------------------------------------------------
+CD LC_BOKS *   pB1   iu   Boks1 som skal utvides
+CD LC_BOKS *   pB2   i    Boks2 som skal legges til boks1
+CD =======================================================================
+*/
+static void LR_R_BoksSum(LC_BOKS * pB1,LC_BOKS * pB2)
+{
+   pB1->dMinAust = min(pB1->dMinAust,pB2->dMinAust);
+	pB1->dMinNord = min(pB1->dMinNord,pB2->dMinNord);
+   pB1->dMaxAust = max(pB1->dMaxAust,pB2->dMaxAust);      
+   pB1->dMaxNord = max(pB1->dMaxNord,pB2->dMaxNord);  
+}
+
+
+/*
+AR-980108
+CH LR_BoksDeltaArealSum                   Bereg arealendring ved sumering
+CD =======================================================================
+CD Form�l:
+CD Beregner hvor mye arealet av boks1 blir utvidet hvis den blir
+CD summert med boks2.
+CD
+CD Parametere:
+CD Type       Navn       I/U  Forklaring
+CD -----------------------------------------------------------------------
+CD LC_BOKS *   pB1         i   Boks1
+CD LC_BOKS *   pB2         i   Boks2
+CD double     dDeltaAreal r   Arealendring
+CD =======================================================================
+*/
+static double LR_BoksDeltaArealSum(LC_BOKS * pB1,LC_BOKS * pB2)
+{
+    //long lNy, lGml;
+    //lGml = (pB1->dMaxAust - pB1->dMinAust) * (pB1->dMaxNord - pB1->dMinNord);
+    //return (lNy - lGml); 
+
+    double dDeltaAreal = (max(pB1->dMaxAust,pB2->dMaxAust) - min(pB1->dMinAust,pB2->dMinAust)) *
+                         (max(pB1->dMaxNord,pB2->dMaxNord) - min(pB1->dMinNord,pB2->dMinNord));
+
+    return dDeltaAreal; 
+}
+
+
+/*
+AR-980108
+CH LR_R_Delete                                       Fjern fra "s�ketreet"
+CD =======================================================================
+CD Bruk:
+CD
+CD Parametere:
+CD Type        Navn  I/U  Forklaring
+CD -----------------------------------------------------------------------
+CD LC_R_LEAF *  pRL    i   Peker til forekomst i R-treet
+CD
+CD Form�l:
+CD Fjern et gitt element fra R-treet for geografisk s�k.
+CD =======================================================================
+*/
+void LR_R_Delete(LC_R_LEAF * pRL)
+{
+   LC_R_NODE *pFar,*pRN,*pSonRN;
+   int i,iFunnet,iIdx=0,iFerdig;
+
+
+   if (pRL != NULL) {
+      // Husk "far"
+      pFar = pRL->pFar;
+
+      /* Fjerner pekeren fra gruppetabellen */
+      Sys.pGrInfo->pRL = NULL;
+
+      /* Fjern pekeren til l�vet */
+      pRN = pFar;
+      iFunnet = UT_FALSE;
+
+      for (i=0; i<pRN->sSonAnt; i++) {
+      
+         /* Sjekk om dette er den rette pekeren */
+         if (iFunnet == UT_FALSE) {
+            if (pRN->Son.pLeaf[i] == pRL) {
+               iFunnet = UT_TRUE;
+               iIdx = i;
+            }
+
+         /* Pakk de andre pekerne i denne noden */
+         } else {
+            pRN->Son.pLeaf[iIdx] = pRN->Son.pLeaf[i];
+         }
+      }
+
+      if (iFunnet == UT_TRUE) {
+         (pRN->sSonAnt)--;
+      }
+
+      // Frigir det aktuelle "l�vet"
+      UT_FREE((char *)pRL);
+
+      /* Sjekk om det er mere som skal fjernes oppover i treet */
+      iFerdig = UT_FALSE;
+      while ( iFerdig == UT_FALSE) {
+
+         /* Antall s�nner er 0, denne noden skal fjernes p� niv�et over */
+         if (pRN->sSonAnt == 0) {
+
+            // Er ikke p� �verste niv�
+            if (pRN->pFar != NULL)  {
+
+               /* Husk noden */
+               pSonRN = pRN;
+         
+               /* Fjern pekeren til noden */
+               pRN = pSonRN->pFar;
+               iFunnet = UT_FALSE;
+   
+               for (i=0; i<pRN->sSonAnt; i++) {
+      
+                  /* Sjekk om dette er den rette pekeren */
+                  if (iFunnet == UT_FALSE) {
+                     if (pRN->Son.pNode[i] == pSonRN) {
+                        iFunnet = UT_TRUE;
+                        iIdx = i;
+                     }
+
+                  /* Pakk de andre pekerne i denne noden */
+                  } else {
+                     pRN->Son.pNode[iIdx] = pRN->Son.pNode[i];
+                  }
+               }
+
+               if (iFunnet == UT_TRUE) {
+                  (pRN->sSonAnt)--;
+               }
+
+               /* Frigir noden */
+               UT_FREE((char *)pSonRN);
+         
+
+            /* Har kommet til toppen */
+            } else {
+               iFerdig = UT_TRUE;
+
+               /* Treet er tomt initierer verdier p� nytt */
+               pRN->sSonType = LC_LEAF;
+               /* Omskrevet boks initieres til stor invers verdi */
+               pRN->Boks.dMinAust =	pRN->Boks.dMinNord = LONG_MAX;
+               pRN->Boks.dMaxAust = pRN->Boks.dMaxNord = LONG_MIN;
+            }
+
+
+         /* Har flere s�nner, m� beregne omskrevet boks p� nytt */
+         } else {
+
+            pRN->Boks.dMinAust =	pRN->Boks.dMinNord = LONG_MAX;
+            pRN->Boks.dMaxAust = pRN->Boks.dMaxNord = LONG_MIN;
+
+            if (pRN->sSonType == LC_LEAF) {
+               for (i=0; i<pRN->sSonAnt; i++) {
+                  LR_R_BoksSum(&(pRN->Boks),&(pRN->Son.pLeaf[i]->Boks));
+               }
+
+            } else {
+               for (i=0; i<pRN->sSonAnt; i++) {
+                  LR_R_BoksSum(&(pRN->Boks),&(pRN->Son.pNode[i]->Boks));
+               }
+            }
+
+            iFerdig = UT_TRUE;
+         }
+      }
+   }
+}
+
+
+/*
+AR-980204
+CH LR_R_CreateRNode                         Alloker og initier R-tre-node
+CD =======================================================================
+CD Bruk:
+CD
+CD Parametere:
+CD Type          Navn  I/U  Forklaring
+CD -----------------------------------------------------------------------
+CD LC_R_NODE *  pFar     i  Peker til far i R-treet
+CD short       sSonType i  Hvilken type s�nner har denne noden LC_NODE / LC_LEAF
+CD LC_R_NODE *  pRN      r  Peker til ny node i R-tre
+CD
+CD Form�l:
+CD Alloker og initier node i R-tre.
+CD =======================================================================
+*/
+static LC_R_NODE * LR_R_CreateRNode( LC_R_NODE * pFar,short sSonType)
+{
+   LC_R_NODE * pRN;
+
+   pRN = (LC_R_NODE *)UT_MALLOC(sizeof(LC_R_NODE));
+
+   pRN->pFar = pFar;
+   pRN->sSonType = sSonType;
+   pRN->sSonAnt = 0;
+
+
+   //for (i=0; i>LC_R_MAX_SON; i++) {
+   //   if (sSonType == LC_NODE) {
+   //      pRN->Son.pNode[i] = NULL;
+   //   } else {
+   //      pRN->Son.pLeaf[i] = NULL;
+   //   }
+   //}
+
+   /* Omskrevet boks initieres til stor invers boks */
+   pRN->Boks.dMinAust =	pRN->Boks.dMinNord = LONG_MAX;
+   pRN->Boks.dMaxAust = pRN->Boks.dMaxNord = LONG_MIN;
+
+   return pRN;
+}
+
+
+/*
+AR-980204
+CH LR_R_CreateRLeaf                         Alloker og initier R-tre-l�v
+CD =======================================================================
+CD Bruk:
+CD
+CD Parametere:
+CD Type        Navn   I/U  Forklaring
+CD -----------------------------------------------------------------------
+CD long        lGrNr   i  Gruppenummer i filen
+CD LC_BOKS *    pB      i  Boks som skal legges inn i treet
+CD LC_R_NODE *  pFar    i  Peker til far i R-treet
+CD LC_R_LEAF *  pCL     r  Peker til ny forekomst
+CD
+CD Form�l:
+CD Alloker og initier l�v R-tre.
+CD =======================================================================
+*/
+static LC_R_LEAF * LR_R_CreateRLeaf(long lGrNr, LC_BOKS * pB,LC_R_NODE * pFar)
+{
+   LC_R_LEAF * pCL = (LC_R_LEAF *)UT_MALLOC(sizeof(LC_R_LEAF));
+
+   pCL->pFar = pFar;
+   pCL->Boks = *pB;
+   pCL->lNr = lGrNr;
+
+   return pCL;
+}
+
+
+/*
+AR-980113
+CH LR_LeggTilKB                         Legg til Bgr i s�keresultat-kjede
+CD =======================================================================
+CD Bruk:
+CD
+CD parametere:
+CD Type            Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------
+CD LC_GEO_STATUS *  pGeoStat  i    Peker til struktur for s�kestatus
+CD LC_FILADM *     pFil      i    Filpeker
+CD long            lNr       i    Gruppenummer i filen
+CD
+CD Form�l:
+CD Legg til Bgr i kjede med s�keresultat.
+CD =======================================================================
+*/
+static void LR_LeggTilKB(LC_GEO_STATUS * pGeoStat,LC_FILADM *pFil,long lNr)
+{
+   LC_KJEDE_BGR * pKB;
+
+   pKB = (LC_KJEDE_BGR *) UT_MALLOC(sizeof(LC_KJEDE_BGR));
+
+   /* Sosi-gruppe */
+   pKB->Bgr.pFil = pFil;
+   pKB->Bgr.lNr = lNr;   
+  
+  /* Oppdater pekerne i kjeden */
+  pKB->pNesteKB = NULL;
+  
+  if (pGeoStat->pForsteKB == NULL) {
+    pGeoStat->pForsteKB = pKB;
+
+  } else {
+    pGeoStat->pSisteKB->pNesteKB = pKB;
+  }
+
+  pGeoStat->pSisteKB = pKB;
+}
+
+
+/*
+AR-980113
+CH LC_AvsluttSok                                 Avslutter geografisk s�k
+CD =======================================================================
+CD Bruk:
+CD
+CD parametere:
+CD Type            Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------
+CD LC_GEO_STATUS *  pGeoStat  i    Peker til struktur for s�kestatus
+CD
+CD Form�l:
+CD Avslutter geografisk s�k, og frigir kjede med s�keresultat.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_AvsluttSok(LC_GEO_STATUS * pGeoStat)
+{
+   LC_KJEDE_BGR *pKB, *pNesteKB; 
+      
+      
+   pNesteKB = pGeoStat->pForsteKB;
+
+   while (pNesteKB != NULL) {
+      pKB = pNesteKB;
+      pNesteKB = pKB->pNesteKB;
+      UT_FREE(pKB);
+   }
+
+   pGeoStat->pForsteKB = NULL;
+   pGeoStat->pSisteKB = NULL;
+   pGeoStat->pAktuellKB = NULL;
+}
+
+
+/*
+AR-980209
+CH LR_VelgMetode                         Velg s�kemetode for geografisk s�k
+CD ==========================================================================
+CD Form�l:
+CD Velg s�kemetode for geografisk s�k. Bruker R-tre hvis utstrekningen av
+CD s�keomr�det er mindre enn 10% av baseomr�det i nord eller �st retning.
+CD
+CD Parametre:
+CD Type     Navn      I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat  iu   Peker til struktur for s�kestatus
+CD
+   ==========================================================================
+*/
+static void LR_VelgMetode(LC_GEO_STATUS * pGeoStat)
+{
+   LC_BOKS * pB = &Sys.pAktBase->Omraade;
+ 
+   if ( pGeoStat->oha - pGeoStat->nva < (pB->dMaxAust - pB->dMinAust) / 10  ||
+        pGeoStat->ohn - pGeoStat->nvn < (pB->dMaxNord - pB->dMinNord) / 10 ) {
+     pGeoStat->usMetode = LC_GEO_RTRE;
+
+   } else {
+     pGeoStat->usMetode = LC_GEO_SEKV;
+   }
+}
+
+
+/*
+AR-980108
+CH LR_R_FrigiGren                           Frigir en gren fra "s�ketreet"
+CD =======================================================================
+CD Bruk:
+CD
+CD Parametere:
+CD Type        Navn  I/U  Forklaring
+CD -----------------------------------------------------------------------
+CD LC_R_NODE *  pRN    i   Peker til node i R-treet
+CD
+CD Form�l:
+CD Frigir en gren fra R-treet for geografisk s�k.
+CD =======================================================================
+*/
+void LR_R_FrigiGren(LC_R_NODE * pRN)
+{
+   int i;
+
+   /* Har kommet til ytterste niv� */
+   if (pRN->sSonType == LC_LEAF) {
+      /* Sjekk l�vene som er lagret under denne noden */
+      for (i=0; i<pRN->sSonAnt; i++) { 
+         UT_FREE((char *)pRN->Son.pLeaf[i]);
+      }
+
+   /* Node */
+   } else {
+      /* Rekursiv sjekk av de underliggende nodene */
+      for (i=0; i<pRN->sSonAnt; i++) { 
+         // Vis alle underliggende niv�er
+         LR_R_FrigiGren(pRN->Son.pNode[i]);
+      }
+   }
+
+   UT_FREE((char *)pRN);
+}
diff --git a/FYBA/FYLS.cpp b/FYBA/FYLS.cpp
new file mode 100644
index 0000000..e4261fc
--- /dev/null
+++ b/FYBA/FYLS.cpp
@@ -0,0 +1,678 @@
+/* == AR 891104 ========================================== */
+/*  STATENS KARTVERK  -  FYSAK-PC                          */
+/*  Fil: fyls.c                                            */
+/*  Innhold: Serienummer system for fysak-pc               */
+/* ======================================================= */
+
+#include "stdafx.h"
+
+#include <ctype.h>
+
+
+/* Globale variabler */
+extern LC_SYSTEMADM    Sys;
+
+
+/*
+AR-910930
+CH LS_Indx                                              Oppdater indekstabellen
+CD =============================================================================
+CD Form�l:
+CD Oppdater s�ketabellen for serienummer.
+CD
+CD Parametre: ingen
+CD
+CD Bruk:
+CD LS_Indx();
+================================================================================
+*/
+void LS_Indx(void)
+{
+   long lSnr = LC_GetSn();
+
+   /* Legg inn snr i tabellen  og oppdaterer max snr for filen */
+   LS_PutSn(Sys.GrId.pFil,Sys.GrId.lNr,lSnr);
+}
+
+
+/*
+AR-910930
+CH LC_SBSn                                   Sett s�kegrense for serienummer
+CD ==========================================================================
+CD Form�l:
+CD Setter s�kegrenser for serienummers�k.
+CD
+CD Parametre:
+CD Type        Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm  iu    Peker til statusblokk for serienummers�k
+CD LC_FILADM * pFil     i     Peker til FilAdm
+CD long        lMinSnr  i     Fra og med serienummer
+CD long        lMaxSnr  i     Til og med serienummer
+CD
+CD Bruk:
+CD LC_SNR_ADM SnrAdm;
+CD LC_SBSn(&SnrAdm,pFil,lMinSnr,lMaxSnr);
+=============================================================================
+*/
+SK_EntPnt_FYBA void LC_SBSn(LC_SNR_ADM * pSnrAdm,LC_FILADM *pFil,long lMinSnr,long lMaxSnr)
+{
+   /* LO_TestFilpeker(pFil,"LC_SBSn"); */
+   LO_TestFilpeker(pFil,"SBSn");
+
+   pSnrAdm->pFil = pFil;
+   pSnrAdm->lMinSnr = lMinSnr;
+   pSnrAdm->lMaxSnr = lMaxSnr;
+}
+
+
+/*
+AR-911118
+CH LC_FiSn                              Finn gruppenummer for et serienummer
+CD ==========================================================================
+CD Form�l:
+CD Finn gruppenummer for et gitt serienummer i s�keomr�det for serienummer.
+CD Endrer IKKE "current gruppe".
+CD
+CD Parametre:
+CD Type        Navn    I/U    Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_FILADM * pFil     i     Peker til FilAdm
+CD long        lSnr     i     Serienummer som skal finnes
+CD LC_BGR *     pBgr     u     Gruppenummer i basen
+CD short       sstat    r     S�kestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD sstat = LC_FiSn(pFil,lSnr,&Bgr);
+================================================================================
+*/
+SK_EntPnt_FYBA short LC_FiSn(LC_FILADM *pFil,long lSnr,LC_BGR * pBgr)
+{
+   /* LO_TestFilpeker(pFil,"LC_FiSn"); */
+   LO_TestFilpeker(pFil,"FiSn");
+
+   pBgr->pFil = pFil;
+   pBgr->lNr = LI_GetSnr(pFil,lSnr);
+
+   /* Ukjent serienummer  ==> */
+   if (pBgr->lNr == INGEN_GRUPPE)  return UT_FALSE;
+
+   return UT_TRUE;
+}
+
+
+/*
+AR-91118
+CH LC_MoveSn                       Flytt til gruppenummer for et serienummer
+CD ==========================================================================
+CD Form�l:
+CD Finn gruppenummer for et gitt serienummer i s�keomr�det for serienummer.
+CD Intern "aktuellt serienummer" blir endret, slik at videre s�k med
+CD neste/forrige n� tar utgangspunkt i dette serienummer.
+CD (Bare hvis snr er funnet).
+CD
+CD Parametre:
+CD Type     Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm  iu    Peker til statusblokk for serienummers�k
+CD long        lSnr     i     Serienummer som skal finnes
+CD LC_BGR *     pBgr     u     Gruppenummer i basen
+CD short       sstat    r     S�kestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD sstat = LC_MoveSn(pSnrAdm,snr,&Bgr);
+================================================================================
+*/
+SK_EntPnt_FYBA short LC_MoveSn(LC_SNR_ADM * pSnrAdm,long lSnr,LC_BGR * pBgr)
+{
+   /* LO_TestFilpeker(pSnrAdm->pFil,"LC_MoveSn"); */
+   LO_TestFilpeker(pSnrAdm->pFil,"MoveSn");
+
+   pBgr->pFil = pSnrAdm->pFil;
+   pBgr->lNr = LI_GetSnr(pSnrAdm->pFil,lSnr);
+
+   /* Ukjent serienummer  ==> */
+   if (pBgr->lNr == INGEN_GRUPPE)  return UT_FALSE;
+
+   pSnrAdm->lAktSnr = lSnr;
+
+   return UT_TRUE;
+}
+
+
+/*
+AR-910930
+CH LC_FiArraySn                      Finn gruppenummer for flere serienummer
+CD ==========================================================================
+CD Form�l:
+CD Finner gruppenummer for tabell med serienummer.
+CD Endrer IKKE "current gruppe".
+CD Serienummertabellen kan v�re "r�" slik den kommer fra GetRef. Linjer med
+CD start �y og slutt �y overses.
+CD
+CD Parametre:
+CD Type       Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_FILADM *pFil     i     Peker til FilAdm
+CD short      antall   i     Antall linjer brukt i serienummertabellen
+CD long      *snr      i     Tabell med serienummer som skal finnes
+CD long      *bgr      u     Tabell med gruppenummer funnet
+CD                             (INGEN_GRUPPE = ikke funnet)
+CD
+CD Bruk:
+CD LC_FiArraySn(pFil,antall,snr,bgr);
+================================================================================
+*/
+SK_EntPnt_FYBA void LC_FiArraySn(LC_FILADM *pFil,short antall,long *snr,long *bgr)
+{
+   short s;
+
+   LO_TestFilpeker(pFil,"LC_FiArraySn");
+
+   /* S�k gjennom hele serienummertabellen */
+   for (s=0; s<antall; s++) {
+      if (snr[s] == START_OY  ||  snr[s] == SLUTT_OY) {
+         bgr[s] = INGEN_GRUPPE;
+
+      } else {
+         bgr[s] = LI_GetSnr(pFil,labs(snr[s]));
+      } /* endif */
+   }
+}
+
+
+/*
+AR-911022
+CH LC_FASn                                             Finn alle serienummer
+CD ==========================================================================
+CD Form�l:
+CD Finner alle grupper i fil/serienummer s�keomr�det og merker i kolonne
+CD BT_SNRSOK i brukttabellen.
+CD
+CD Parametre:
+CD Type        Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm  i    Peker til statusblokk for serienummers�k
+CD long        antall   r    Antall grupper funnet.
+CD
+CD Bruk:
+CD antall_funnet = LC_FASn(&SnrAdm);
+=============================================================================
+*/
+SK_EntPnt_FYBA long LC_FASn(LC_SNR_ADM * pSnrAdm)
+{
+   short ngi;
+   long nko;
+   unsigned short info;
+   LC_BGR AktBgr,Bgr;
+   long lSnr,lGrNr;
+   long lAntall = 0;
+   long lMaxSnr = min(pSnrAdm->pFil->lMaxSnr, pSnrAdm->lMaxSnr);
+
+
+   /* LO_TestFilpeker(pSnrAdm->pFil,"LC_FASn"); */
+   LO_TestFilpeker(pSnrAdm->pFil,"FASn");
+
+   /* Husk aktuell gruppe */
+   AktBgr = Sys.GrId;
+
+   /* Blanker brukttabellen */
+   LI_EraseBt(BT_SNRSOK,BT_SNRSOK);
+
+   /* Sjekker alle serienummer i s�keomr�det */
+   Bgr.pFil = pSnrAdm->pFil;
+   for (lSnr=pSnrAdm->lMinSnr; lSnr<=lMaxSnr; lSnr++) {
+      if ((lGrNr = LI_GetSnr(pSnrAdm->pFil,lSnr)) != INGEN_GRUPPE) {
+         Bgr.lNr = lGrNr;
+         LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+         lAntall += LC_MerkGr(BT_SNRSOK,1);     /* Tilslag */
+      }
+   }
+
+   /* Les tilbake aktuell gruppe */
+   if (AktBgr.lNr != INGEN_GRUPPE) {
+      LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+   }
+
+   return lAntall;
+}
+
+
+/*
+AR-911022
+CH LC_FFSn                                              Finn f�rste serienummer
+CD =============================================================================
+CD Form�l:
+CD Finner f�rste gruppe i fil/serienummer s�keomr�det.
+CD
+CD Parametre:
+CD Type        Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm  iu    Peker til statusblokk for serienummers�k
+CD LC_BGR *     pBgr     u     Gruppenummer
+CD short       sstat    r     S�kestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD sstat = LC_FFSn(&SnrAdm,&Bgr);
+================================================================================
+*/
+SK_EntPnt_FYBA short LC_FFSn(LC_SNR_ADM * pSnrAdm,LC_BGR * pBgr)
+{
+   long lSnr,lGrNr;
+   long lMaxSnr;
+
+   if (pSnrAdm->pFil == NULL) {
+		LC_Error(5,"(LC_FFSn)","Ingen aktuelt fil.");
+		return UT_FALSE;
+   }
+
+   /* LO_TestFilpeker(pSnrAdm->pFil,"LC_FFSn"); */
+   LO_TestFilpeker(pSnrAdm->pFil,"FFSn");
+
+   lMaxSnr = min(pSnrAdm->pFil->lMaxSnr, pSnrAdm->lMaxSnr);
+
+   /* Sjekker fra starten av s�keomr�det */
+   for (lSnr=pSnrAdm->lMinSnr; lSnr<=lMaxSnr; lSnr++) {
+      if ((lGrNr = LI_GetSnr(pSnrAdm->pFil,lSnr)) != INGEN_GRUPPE) {
+         /* Tilslag ==> */
+         pBgr->pFil = pSnrAdm->pFil;
+         pBgr->lNr = lGrNr;
+         pSnrAdm->lAktSnr = lSnr;
+         return UT_TRUE;
+      }
+   }
+
+   return UT_FALSE;
+}
+
+
+/*
+AR-911022
+CH LC_FFSnBt                        Finn f�rste serienummer med tilleggskrav
+CD ==========================================================================
+CD Form�l:
+CD Finner f�rste gruppe som er merka i gitt kolonne i brukttabellen.
+CD
+CD Parametre:
+CD Type        Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm   i    Peker til statusblokk for serienummers�k
+CD short       kolonne   i    Kolonne i brukt-tabellen som skal sjekkes
+CD LC_BGR *     pBgr      u    Gruppenummer
+CD short       sstat     r    S�kestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD sstat = LC_FFSnBt(&SnrAdm,BT_GEOSOK,&Bgr);
+=============================================================================
+*/
+SK_EntPnt_FYBA short LC_FFSnBt(LC_SNR_ADM * pSnrAdm,short kolonne,LC_BGR * pBgr)
+{
+   long lSnr,lGrNr;
+   LC_BGR Bgr;
+   long lMaxSnr;
+
+   /* LO_TestFilpeker(pSnrAdm->pFil,"LC_FFSnBt"); */
+   LO_TestFilpeker(pSnrAdm->pFil,"FFSnBt");
+
+   lMaxSnr = min(pSnrAdm->pFil->lMaxSnr, pSnrAdm->lMaxSnr);
+
+   /* Sjekker fra starten av s�keomr�det */
+   for (lSnr=pSnrAdm->lMinSnr; lSnr<=lMaxSnr; lSnr++) {
+      if ((lGrNr = LI_GetSnr(pSnrAdm->pFil,lSnr)) != INGEN_GRUPPE) {
+         Bgr.pFil = pSnrAdm->pFil;
+         Bgr.lNr = lGrNr;
+         if (LC_GetBt(&Bgr,kolonne)) {          /* Merka? */
+            /* Tilslag ==> */
+            pBgr->pFil = pSnrAdm->pFil;
+            pBgr->lNr = lGrNr;
+            pSnrAdm->lAktSnr = lSnr;
+            return UT_TRUE;
+         }
+      }
+   }
+
+   return UT_FALSE;
+}
+
+
+/*
+AR-911022
+CH LC_FNSn                                            Finn neste serienummer
+CD ==========================================================================
+CD Form�l:
+CD Finner neste gruppe i fil/serienummer s�keomr�det.
+CD
+CD Parametre:
+CD Type     Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm  iu    Peker til statusblokk for serienummers�k
+CD LC_BGR *     pBgr     u     Gruppenummer
+CD short       sstat    r     S�kestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD sstat = LC_FNSn(&SnrAdm,&Bgr);
+================================================================================
+*/
+SK_EntPnt_FYBA short LC_FNSn(LC_SNR_ADM * pSnrAdm,LC_BGR * pBgr)
+{
+   long lSnr,lGrNr;
+   long lMaxSnr;
+
+   /* LO_TestFilpeker(pSnrAdm->pFil,"LC_FNSn"); */
+   LO_TestFilpeker(pSnrAdm->pFil,"FNSn");
+
+   lMaxSnr = min(pSnrAdm->pFil->lMaxSnr, pSnrAdm->lMaxSnr);
+
+   /* Sjekker fra aktuellt serienummer */
+   for (lSnr=pSnrAdm->lAktSnr+1L; lSnr<=lMaxSnr; lSnr++) {
+      if ((lGrNr = LI_GetSnr(pSnrAdm->pFil,lSnr)) != INGEN_GRUPPE) {
+         /* Tilslag ==> */
+         pBgr->pFil = pSnrAdm->pFil;
+         pBgr->lNr = lGrNr;
+         pSnrAdm->lAktSnr = lSnr;
+         return UT_TRUE;
+      }
+   }
+
+   return UT_FALSE;
+}
+
+
+/*
+AR-911022
+CH LC_FNSnBt                         Finn neste serienummer med tilleggskrav
+CD ==========================================================================
+CD Form�l:
+CD Finner neste gruppe ogs� er merka i gitt kolonne i brukttabellen.
+CD
+CD Parametre:
+CD Type        Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm   i    Peker til statusblokk for serienummers�k
+CD short       kolonne   i    Kolonne i brukt-tabellen som skal sjekkes
+CD LC_BGR *     pBgr      u    Gruppenummer
+CD short       sstat     r    S�kestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD sstat = LC_FNSnBt(&SnrAdm,BT_GEOSOK,&Bgr);
+================================================================================
+*/
+SK_EntPnt_FYBA short LC_FNSnBt(LC_SNR_ADM * pSnrAdm,short kolonne,LC_BGR * pBgr)
+{
+   long lSnr,lGrNr;
+   LC_BGR Bgr;
+   long lMaxSnr;
+
+   /* LO_TestFilpeker(pSnrAdm->pFil,"LC_FNSnBt"); */
+   LO_TestFilpeker(pSnrAdm->pFil,"FNSnBt");
+
+   lMaxSnr = min(pSnrAdm->pFil->lMaxSnr, pSnrAdm->lMaxSnr);
+
+   /* Sjekker fra aktuellt serienummer */
+   for (lSnr=pSnrAdm->lAktSnr+1L; lSnr<=lMaxSnr; lSnr++) {
+      if ((lGrNr = LI_GetSnr(pSnrAdm->pFil,lSnr)) != INGEN_GRUPPE) {
+         Bgr.pFil = pSnrAdm->pFil;
+         Bgr.lNr = lGrNr;
+         if (LC_GetBt(&Bgr,kolonne)) {          /* Merka? */
+            /* Tilslag ==> */
+            pBgr->pFil = pSnrAdm->pFil;
+            pBgr->lNr = lGrNr;
+            pSnrAdm->lAktSnr = lSnr;
+            return UT_TRUE;
+         }
+      }
+   }
+
+   return UT_FALSE;
+}
+
+
+/*
+AR-911022
+CH LC_FPSn                                              Finn forige serienummer
+CD =============================================================================
+CD Form�l:
+CD Finner forrige gruppe i fil/serienummer s�keomr�det.
+CD
+CD Parametre:
+CD Type        Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm  iu    Peker til statusblokk for serienummers�k
+CD LC_BGR *     pBgr     u     Gruppenummer
+CD short       sstat    r     S�kestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD sstat = LC_FPSn(&SnrAdm,&Bgr);
+================================================================================
+*/
+SK_EntPnt_FYBA short LC_FPSn(LC_SNR_ADM * pSnrAdm,LC_BGR * pBgr)
+{
+   long lSnr,lGrNr;
+
+   /* LO_TestFilpeker(pSnrAdm->pFil,"LC_FPSn"); */
+   LO_TestFilpeker(pSnrAdm->pFil,"FPSn");
+
+   /* Sjekker fra aktuellt serienummer */
+   for (lSnr=pSnrAdm->lAktSnr-1L; lSnr>=pSnrAdm->lMinSnr; lSnr--) {
+      if ((lGrNr = LI_GetSnr(pSnrAdm->pFil,lSnr)) != INGEN_GRUPPE) {
+         /* Tilslag ==> */
+         pBgr->pFil = pSnrAdm->pFil;
+         pBgr->lNr = lGrNr;
+         pSnrAdm->lAktSnr = lSnr;
+         return UT_TRUE;
+      }
+   }
+
+   return UT_FALSE;
+}
+
+
+/*
+AR-910930
+CH LC_FPSnBt                         Finn forige serienummer med tilleggskrav
+CD ==========================================================================
+CD Form�l:
+CD Finner forrige gruppe i fil/serienummer s�keomr�det, som ogs� er merka i
+CD gitt kolonne i brukttabellen.
+CD
+CD Parametre:
+CD Type        Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm   i    Peker til statusblokk for serienummers�k
+CD short       kolonne   i    Kolonne i brukt-tabellen som skal sjekkes
+CD LC_BGR *     pBgr      u    Gruppenummer
+CD short       sstat     r    S�kestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD sstat = LC_FPSnBt(&SnrAdm,BT_GEOSOK,&Bgr);
+================================================================================
+*/
+SK_EntPnt_FYBA short LC_FPSnBt(LC_SNR_ADM * pSnrAdm,short kolonne,LC_BGR * pBgr)
+{
+   long lSnr,lGrNr;
+   LC_BGR Bgr;
+
+   /* LO_TestFilpeker(pSnrAdm->pFil,"LC_FPSnBt"); */
+   LO_TestFilpeker(pSnrAdm->pFil,"FPSnBt");
+
+   /* Sjekker fra aktuellt serienummer */
+   for (lSnr=pSnrAdm->lAktSnr-1L; lSnr>=pSnrAdm->lMinSnr; lSnr--) {
+      if ((lGrNr = LI_GetSnr(pSnrAdm->pFil,lSnr)) != INGEN_GRUPPE) {
+         Bgr.pFil = pSnrAdm->pFil;
+         Bgr.lNr = lGrNr;
+         if (LC_GetBt(&Bgr,kolonne)) {          /* Merka? */
+            /* Tilslag ==> */
+            pBgr->pFil = pSnrAdm->pFil;
+            pBgr->lNr = lGrNr;
+            pSnrAdm->lAktSnr = lSnr;
+            return UT_TRUE;
+         }
+      }
+   }
+
+   return UT_FALSE;
+}
+
+
+/*
+AR-910930
+CH LC_FLSn                                              Finn siste serienummer
+CD =============================================================================
+CD Form�l:
+CD Finner siste gruppe i fil/serienummer s�keomr�det.
+CD
+CD Parametre:
+CD Type        Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm  iu    Peker til statusblokk for serienummers�k
+CD LC_BGR *     pBgr     u     Gruppenummer
+CD short       sstat    r     S�kestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD sstat = LC_FLSn(&SnrAdm,&Bgr);
+================================================================================
+*/
+SK_EntPnt_FYBA short LC_FLSn(LC_SNR_ADM * pSnrAdm,LC_BGR * pBgr)
+{
+   long lGrNr;
+   long lSnr;
+
+   /* LO_TestFilpeker(pSnrAdm->pFil,"LC_FLSn"); */
+   LO_TestFilpeker(pSnrAdm->pFil,"FLSn");
+
+   lSnr = min(pSnrAdm->pFil->lMaxSnr, pSnrAdm->lMaxSnr);
+
+   /* Sjekker fra slutten av tabellen */
+   for (; lSnr>=pSnrAdm->lMinSnr; lSnr--) {
+      if ((lGrNr = LI_GetSnr(pSnrAdm->pFil,lSnr)) != INGEN_GRUPPE) {
+         /* Tilslag ==> */
+         pBgr->pFil = pSnrAdm->pFil;
+         pBgr->lNr = lGrNr;
+         pSnrAdm->lAktSnr = lSnr;
+         return UT_TRUE;
+      }
+   }
+
+   return UT_FALSE;
+}
+
+
+/*
+AR-910930
+CH LC_FLSnBt                         Finn siste serienummer med tilleggskrav
+CD ==========================================================================
+CD Form�l:
+CD Finner siste gruppe i fil/serienummer s�keomr�det som ogs� er merka i
+CD gitt kolonne i brukttabellen.
+CD
+CD Parametre:
+CD Type        Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm   i    Peker til statusblokk for serienummers�k
+CD short       kolonne   i    Kolonne i brukt-tabellen som skal sjekkes
+CD LC_BGR *     pBgr      u    Gruppenummer
+CD short       sstat     r    S�kestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD sstat = LC_FLSnBt(&SnrAdm,BT_GEOSOK,&Bgr);
+================================================================================
+*/
+SK_EntPnt_FYBA short LC_FLSnBt(LC_SNR_ADM * pSnrAdm,short kolonne,LC_BGR * pBgr)
+{
+   long lGrNr;
+   LC_BGR Bgr;
+   long lSnr;
+
+   /* LO_TestFilpeker(pSnrAdm->pFil,"LC_FLSnBt"); */
+   LO_TestFilpeker(pSnrAdm->pFil,"FLSnBt");
+
+   lSnr = min(pSnrAdm->pFil->lMaxSnr, pSnrAdm->lMaxSnr);
+
+   /* Sjekker fra slutten av tabellen */
+   for (; lSnr>=pSnrAdm->lMinSnr; lSnr--) {
+      if ((lGrNr = LI_GetSnr(pSnrAdm->pFil,lSnr)) != INGEN_GRUPPE) {
+         Bgr.pFil = pSnrAdm->pFil;
+         Bgr.lNr = lGrNr;
+         if (LC_GetBt(&Bgr,kolonne)) {          /* Merka? */
+            /* Tilslag ==> */
+            pBgr->pFil = pSnrAdm->pFil;
+            pBgr->lNr = lGrNr;
+            pSnrAdm->lAktSnr = lSnr;
+            return UT_TRUE;
+         }
+      }
+   }
+
+   return UT_FALSE;
+}
+
+
+/*
+AR-910930
+CH LS_PutSn                                             Legg inn serienummer
+CD ==========================================================================
+CD Form�l:
+CD Legg inn snr i tabellen  og oppdaterer max snr for filen
+CD
+CD Parametre:
+CD Type     Navn   I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil  i   Peker til FilAdm
+CD long       lGrNr i   Gruppenummer
+CD long       lSnr  i   Serienummer
+CD
+CD Bruk:
+CD LS_PutSn(pFil,lGrNr,lSnr);
+=============================================================================
+*/
+void LS_PutSn(LC_FILADM *pFil,long lGrNr,long lSnr)
+{
+   if (lSnr >= 0L) {
+      /* LO_TestFilpeker(pFil,"LC_PutSn"); */
+      LO_TestFilpeker(pFil,"PutSn");
+
+      /* Max snr p� filen */
+      if (lSnr > pFil->lMaxSnr) {
+         pFil->lMaxSnr = lSnr;
+      }
+
+      /* Legg inn verdi */
+      LI_PutSnr(pFil,lSnr,lGrNr);
+
+   } else {
+      UT_SNPRINTF(err().tx,LC_ERR_LEN," %ld ",lSnr);
+      LC_Error(61,"(LS_PutSn)",err().tx);
+   }
+}
+
+
+/*
+AR-891104
+CH LS_VisSn                                            Vis serienummer-tabellen
+CD =============================================================================
+CD Form�l:
+CD Henter en linje fra serienummer-tabellen som formatert streng.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_FILADM *pFil   i    Peker til FilAdm
+CD long       lin    i    Linjenummer i SN-tab som skal hentes
+CD char      *tx     r    Peker til streng med formatert SN-linje
+CD
+CD Bruk:
+CD UT_FPRINTF(stderr,"\nSerienummertabell:\n");
+CD for (lin=0L; lin<100L; lin++) {
+CD     UT_FPRINTF(stderr,"%s\n",LS_VisSn(BlaFile,lin));
+CD }
+   =============================================================================
+*/
+char *LS_VisSn(LC_FILADM *pFil,long lin)
+{
+   if (lin >= 0L  &&  lin < pFil->lMaxSnr){
+       UT_SNPRINTF(err().tx,LC_ERR_LEN,"%8ld: %8ld",lin,LI_GetSnr(pFil,lin));
+   } else{
+       *err().tx = '\0';
+   }
+   return err().tx;
+}
diff --git a/FYBA/FYLU.cpp b/FYBA/FYLU.cpp
new file mode 100644
index 0000000..d14fa7a
--- /dev/null
+++ b/FYBA/FYLU.cpp
@@ -0,0 +1,2904 @@
+/* === AR-920613 ========================================================== */
+/*  STATENS KARTVERK  -  FYSAK-PC                                           */
+/*  Fil: fylu.c                                                             */
+/*  Innhold: Rutiner for utvalg                                             */
+/* ======================================================================== */
+
+#include "stdafx.h"
+
+#include <ctype.h>
+#include <math.h>
+#include <locale>
+
+using namespace std;
+
+#define U_PARA_LEN    128     /* Max lengde av parameterstreng */
+
+
+/* Felles variabler for hele FYBA */
+extern LC_SYSTEMADM Sys;
+
+/*  Funksjonsdefinisjoner for interne funksjoner */
+static void  LU_FrigiUtvalg(LC_UTVALG *pU);
+static void  LU_DelLastQuery(LC_UTVALG_BLOKK *pUB);
+static short LU_TolkUtvalgslinje(LC_UTVALG_ELEMENT * pUE,const char *pszTx);
+static short LU_PiTestDelutvalg(LC_UT_ADM * pUtAdm,LC_UTVALG_ELEMENT * pUE,long lPnr);
+static short LU_PiTestLinje(LC_UTVALG_ELEMENT * pUE,long lPnr);
+//static short LU_GiTestUtvalg(LC_UT_ADM * pUtAdm,LC_UTVALG *pU);
+static short LU_GiTestDelutvalg(LC_UT_ADM * pUtAdm,LC_UTVALG_ELEMENT * pUE);
+static short LU_GiTestLinje(LC_UT_ADM * pUtAdm,LC_UTVALG_ELEMENT * pUE,
+                            short *gilin,char **apara);
+static short LU_ParaTest(LC_UTVALG_ELEMENT * pUE,char *para,char *pszAktPara,short sMaxLen);
+static void  LU_JustPara(char *para,short ledd,short start,short slutt,
+                         char *akt_para,short max_len);
+static short LU_LesULinje(FILE *pKomFil,short sMaxTxLen,char *pszTx,
+                          short *psNiv);
+static void LU_AppUtvalg (LC_UTVALG_BLOKK *pUtBlokk,char *pszNavn);
+static void LU_PakkPrioritet(LC_UT_ADM * pUtAdm);
+static void LU_HuskPrior(short *NyPrior,short *sAntPrior,short sPrior);
+static void LU_SjekkDatatype(char *pszVerdi,char szMetode,short *sType);
+
+
+int LU_compare (const void *arg1, const void *arg2);
+
+
+/*
+AR-911003
+CH LC_OpenQuery                                                Initier query
+CD ==========================================================================
+CD Form�l:
+CD Initierer query mot GINFO/PINFO.
+CD Tildeler administrasjonsblokk for utvalg.
+CD
+CD Parametre:
+CD Type         Navn   I/U  Forklaring
+CD -----------------------------------------------------------------------
+CD LC_UT_ADM   *UtAdm   r   Peker til administrasjonsblokk for utvalg.
+CD
+CD Bruk:
+CD pUtAdm = LC_OpenQuery();
+   ==========================================================================
+*/
+SK_EntPnt_FYBA LC_UT_ADM *LC_OpenQuery(void)
+{
+   LC_UT_ADM *pUtAdm;
+
+	/* Tildeler administrasjonsblokk */
+	pUtAdm = (LC_UT_ADM *) UT_MALLOC(sizeof(LC_UT_ADM));
+   memset(pUtAdm,'\0',sizeof(LC_UT_ADM));
+
+   /* Nullstiller */
+   memset(&(pUtAdm->Gruppe), 0, sizeof(LC_UTVALG_BLOKK));
+   memset(&(pUtAdm->Punkt),  0, sizeof(LC_UTVALG_BLOKK));
+   memset(&(pUtAdm->Pinfo),  0, sizeof(LC_UTVALG_BLOKK));
+
+   return pUtAdm;
+}
+
+
+/*
+AR-910718
+CH LC_CloseQuery                                             Avslutter query
+CD ==========================================================================
+CD Form�l:
+CD Avslutter query mot GINFO/PINFO.
+CD Frigir minne brukt til administrasjon og utvalgstabeller.
+CD
+CD Parametre:
+CD Type       Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UT_ADM *UtAdm    i    Peker til administrasjonsblokk for utvalg.
+CD 
+CD
+CD Bruk:
+CD LC_CloseQuery(pUtAdm);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_CloseQuery(LC_UT_ADM * pUtAdm)
+{
+   LC_UTVALG *pU,*pNesteU;
+   LC_LAG *pLag,*pNesteLag; //JA�-19980922
+
+
+   if (pUtAdm != NULL)
+   {
+      /*
+       * Frigir GRUPPE-UTVALG.
+       */
+      pU = pUtAdm->Gruppe.pForsteU;
+      while (pU != NULL) {
+         pNesteU = pU->pNesteU;
+         LU_FrigiUtvalg(pU);
+
+         pU = pNesteU;
+      }
+
+      /*
+       * Frigir PUNKT-UTVALG.
+       */
+      pU = pUtAdm->Punkt.pForsteU;
+      while (pU != NULL) {
+         pNesteU = pU->pNesteU;
+         LU_FrigiUtvalg(pU);
+         pU = pNesteU;
+      }
+
+      /*
+       * Frigir PINFO-UTVALG.
+       */
+      pU = pUtAdm->Pinfo.pForsteU;
+      while (pU != NULL) {
+         pNesteU = pU->pNesteU;
+         LU_FrigiUtvalg(pU);
+         pU = pNesteU;
+      }
+
+      /*
+       * Frigir lag. JA�-19980922
+       */
+      pLag = pUtAdm->pForsteLag;
+      while (pLag != NULL) {
+         pNesteLag = pLag->pNesteLag;
+			if (pLag->pszLagNavn != NULL)  UT_FREE(pLag->pszLagNavn);
+			UT_FREE(pLag);
+         pLag = pNesteLag;
+      }
+
+      /*
+       * Frigir Adm.blokken.
+		 */
+		UT_FREE(pUtAdm);
+   }
+}
+
+
+/*
+AR-920521
+CH LU_FrigiUtvalg                                            Frigi et utvalg
+CD ==========================================================================
+CD Form�l:
+CD Frigir et utvalg med alle underliggende utvalgselementer.
+CD
+CD Parameters:
+CD Type        Navn  I/O  Forklaring
+CD -------------------------------------------------------------------------
+CD LC_UTVALG *  pU     i   Peker til utvalget.
+CD
+CD Bruk:
+CD LU_FrigiUE(pU);
+CD ==========================================================================
+*/
+static void LU_FrigiUtvalg (LC_UTVALG * pU)
+{
+   /* Frigi utvalgs-elementer */
+   if (pU->pForsteUE != NULL)  LU_FrigiUE(pU->pForsteUE);
+
+	/* Frigi navn og regel */
+	if (pU->pszNavn != NULL)  UT_FREE(pU->pszNavn);
+	if (pU->pszRegel != NULL)  UT_FREE(pU->pszRegel);
+
+   /* Frigi toppblokken for utvalget */
+	UT_FREE(pU);
+}
+
+
+/*
+AR-920521
+CH LU_FrigiUE                                        Frigi utvalgselementer
+CD ==========================================================================
+CD Form�l:
+CD Frigir alle elementene (utvalgslinjene) p� et niv� i kjeden av
+CD utvalgselementer for et utvalg.
+CD
+CD Parameters:
+CD Type                  Navn      I/O  Forklaring
+CD -------------------------------------------------------------------------
+CD LC_UTVALG_ELEMENT *  pForsteUE  i   Start utvalgs-kjede p� dette niv�.
+CD
+CD Bruk:
+CD LU_FrigiUE(pForsteUE);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA void LU_FrigiUE (LC_UTVALG_ELEMENT * pUE)
+{
+   LC_UTVALG_ELEMENT *  pNesteUE;
+
+   /* G�r gjennom alle elementene p� dette niv� */
+   while (pUE != NULL) {
+      /* Frigi elementer p� underliggende niv� under dette objektet */
+      if (pUE->pForsteUE != NULL)  LU_FrigiUE(pUE->pForsteUE);
+
+      /* Husk hva som er neste element p� dette niv� */ 
+      pNesteUE = pUE->pNesteUE;
+
+		/* Frigi dette elementet */
+		if (pUE->min != NULL)  UT_FREE(pUE->min);
+		if (pUE->max != NULL)  UT_FREE(pUE->max);
+
+		UT_FREE((char *)pUE);
+
+      pUE = pNesteUE;
+   }
+}
+
+
+/*
+AR-920527
+CH LC_PutQueryLine                                   Legg inn en query-linje
+CD ==========================================================================
+CD Form�l:
+CD Legger inn og tolker en linje med query-tekst.
+CD
+CD Parametre:
+CD Type       Navn  I/U   Forklaring
+CD ------------------------------------------------------------------------
+CD LC_UT_ADM *UtAdm  i    Peker til administrasjonsblokk for utvalg.
+CD char      *qulin  i    Linje med query-tekst. (Uten prikker p� f�rste niv�).
+CD short     sType   i    Gruppe eller Punkt (U_GRUPPE eller U_PUNKT).
+CD short      ist    r    Status (UT_TRUE=OK, UT_FALSE=linjen er ikke OK)
+CD
+CD Bruk:
+CD ist = LC_PutQueryLine(pUtAdm,qulin,sType);
+   =============================================================================
+*/
+SK_EntPnt_FYBA short LC_PutQueryLine(LC_UT_ADM *pUtAdm,const char *qulin,short sType)
+{
+   const char *cp;
+   LC_UTVALG_BLOKK *pUB;
+   short sNiv = 0;
+   short sStatus = UT_FALSE;
+
+   if (pUtAdm != NULL)
+   {
+      /* Preparer strengen */
+      cp = qulin;
+      while (UT_IsSpace(*cp)) {
+         cp++;
+      }
+      /* Tell opp antall prikker */
+      while (*cp == '.') {
+         sNiv++;
+         cp++;
+      }
+
+      /* F�rste utvalg i blokken, alloker topp-blokk */
+      if (sType == U_GRUPPE) {
+         pUB = &pUtAdm->Gruppe;
+
+      } else { // U_PUNKT
+         pUB = &pUtAdm->Punkt;
+      }
+
+      if (pUB->pForsteU == NULL) {
+         /* Legg til et nytt utvalg */
+         LU_AppUtvalg(pUB,"Query");
+      }
+      
+      /* Alloker minne og tolk linjen */
+      sStatus = LU_AppUE(pUB->pSisteU,sNiv,cp);
+
+      // Ta vare p� opplysning om H�YDE er brukt
+      if (sStatus != UT_FALSE) {
+         if (strcmp(pUB->pSisteU->pSisteUE->sosi,"H�YDE") == 0) {
+            pUB->sHoydeBrukt = UT_TRUE;
+         }
+      }
+   }
+
+   return sStatus;
+}
+
+
+/*
+AR-920522
+CH LC_PutQueryRegel                                    Legg inn et regelnavn
+CD ==========================================================================
+CD Form�l:
+CD Legger inn et regelnavn p� siste linje i utvalgstabellen.
+CD (Navnet blir intern konvertert til "store" bokstaver.)
+CD
+CD Parametre:
+CD Type         Navn I/U   Forklaring
+CD ------------------------------------------------------------------------
+CD LC_UTVALG   *pU    i    Peker til utvalg
+CD char        *navn  i    Regelnavn. 
+CD
+CD Bruk:
+CD LC_PutQueryRegel(pU,navn);
+   =============================================================================
+*/
+SK_EntPnt_FYBA void LC_PutQueryRegel(LC_UTVALG * pU,const char *navn)
+{
+	/* Frigi eventuell gammel regel */
+	if (pU->pszRegel != NULL)  UT_FREE(pU->pszRegel);
+
+   /* Legg inn ny regel */
+	pU->pszRegel = (char*)UT_MALLOC(strlen(navn)+1);
+	UT_StrCopy(pU->pszRegel, navn, strlen(navn)+1);
+	UT_StrUpper(pU->pszRegel);
+}
+
+/*
+JA�-19980921
+CH LC_PutLag                                          Legg inn peker til lag
+CD ==========================================================================
+CD Form�l:
+CD Legger inn peker til det laget utvalget tilh�rer.
+CD
+CD Parametre:
+CD Type         Navn  I/U   Forklaring
+CD ------------------------------------------------------------------------
+CD LC_UT_ADM   *UtAdm  i    Peker til administrasjonsblokk for utvalg.
+CD LC_UTVALG   *pU     i    Peker til utvalg
+CD char        *navn   i    Lag-navn. 
+CD
+CD Bruk:
+CD LC_PutLag(pUB,pU,navn);
+   =============================================================================
+*/
+SK_EntPnt_FYBA void LC_PutLag(LC_UT_ADM *pUtAdm,LC_UTVALG *pU,const char *navn)
+{
+   LC_LAG * pLag,*pNyttLag;
+	short sFunnet = 0;
+
+
+   if (pUtAdm != NULL)
+   {
+	   /* Det er allerede lagt inn lag p� dette utvalget ? */
+      if (pU->pLag != NULL) { 
+         /* Annet lag enn forrige gang ? */
+         if (strcmp(navn,pU->pLag->pszLagNavn) != 0) {
+            LC_Error(128,"(LU_HuskPrior)",pU->pszNavn);
+         }
+
+      } else {
+	      /* Tester om lag-navnet allerede er registrert. */
+	      pLag = pUtAdm->pForsteLag;
+	      while ((pLag != NULL) && (!sFunnet)) {
+		      sFunnet = (strcmp(navn,pLag->pszLagNavn) == 0);
+		      if (!sFunnet) pLag = pLag->pNesteLag;
+	      }
+   	 
+         if (pLag == NULL) { /* Nytt lag, m� opprettes og settes inn i kjeden. */
+		      pNyttLag = (LC_LAG *)UT_MALLOC(sizeof(LC_LAG));
+		      memset(pNyttLag,0,sizeof(LC_LAG));
+		      pNyttLag->sLagAktiv = 1;
+		      pNyttLag->pszLagNavn = (char*)UT_MALLOC(strlen(navn)+1);
+            UT_StrCopy(pNyttLag->pszLagNavn,navn,strlen(navn)+1);
+		      pNyttLag->pNesteLag = NULL;
+		      pU->pLag = pNyttLag;
+   		   
+		      if (pUtAdm->pForsteLag == NULL) {
+			      pUtAdm->pForsteLag = pNyttLag;
+		      } else {
+			      pUtAdm->pSisteLag->pNesteLag = pNyttLag;
+		      }
+		      pUtAdm->pSisteLag = pNyttLag;
+		      pUtAdm->pSisteLag->pNesteLag = NULL;
+	      } else {
+		      pU->pLag = pLag;
+	      }
+      }
+   }
+} /* END LC_PutLag */
+
+
+/*
+AR-890308
+CH LC_LesUtvalg                                        Les utvalg i kom.filen
+CD =============================================================================
+CD Form�l:
+CD Leser og tolker gruppe og punktutvalg p� kommandofilen og legger i tabell.
+CD Forutsetter at filen er �pnet p� forh�nd.
+CD
+CD Parametre:
+CD Type       Navn    I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_UT_ADM *pUtAdm   i    Peker til administrasjonsblokk for utvalg.
+CD FILE      *pKomFil  i    Peker til "handle" for �pnet kommandofil.
+CD short      sStatus  r    UT_TRUE=OK, UT_FALSE=feil i linjen
+CD
+CD Bruk:
+CD sStatus = LC_LesUtvalg(pUtAdm,pKomFil);
+   =============================================================================
+*/
+SK_EntPnt_FYBA short LC_LesUtvalg(LC_UT_ADM *pUtAdm,const char *pszKomFil)
+{
+   FILE * pKomFil;
+   short sFunnet;
+   char szTx[100],ord[60],szNavn[50];
+   short itxi,lesefeil,sNiv;
+   short sForrigeMaxPrioritet,sPrioritet;
+   LC_UTVALG_BLOKK  *pUB=NULL;
+   short sStatus;
+   
+
+   if (pUtAdm != NULL)
+   {
+      /* �pner filen */
+      pKomFil = UT_OpenFile(pszKomFil,"",UT_READ,UT_OLD,&sStatus);
+
+	   /* �pningsfeil */
+      if (sStatus != UT_OK) {
+         char szError[256];
+         UT_strerror(szError,256,sStatus);
+         UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pszKomFil,szError);
+         LC_Error(101,"(LC_LesUtvalg)",err().tx);
+         return UT_FALSE;
+      }
+       
+      /* Starter f�rst p� filen og leser  */
+      UT_SetPos(pKomFil,0L);
+
+      lesefeil = LU_LesULinje(pKomFil,100,szTx,&sNiv);
+      while (! lesefeil) {
+         sFunnet = UT_FALSE;
+                                          /* Hent kommandonavn */
+         UT_StrToken(szTx,0,&itxi,60,ord);
+         UT_StrUpper(ord);
+         UT_StrToken(szTx,itxi,&itxi,60,szNavn);
+
+         if (sNiv == 1  &&  strcmp(ord,"GRUPPE-UTVALG") == 0) {
+            pUB = &pUtAdm->Gruppe;
+            sFunnet = UT_TRUE;
+
+         } else if(sNiv == 1  &&  strcmp(ord,"PUNKT-UTVALG") == 0) {
+            pUB = &pUtAdm->Punkt;
+            sFunnet = UT_TRUE;
+
+         } else if(sNiv == 1  &&  strcmp(ord,"PINFO-UTVALG") == 0) {
+            pUB = &pUtAdm->Pinfo;
+            sFunnet = UT_TRUE;
+         }
+
+         if (sFunnet) {
+            sForrigeMaxPrioritet = pUtAdm->sMaxPrior;
+
+            /* Legg til et utvalg */
+            LU_AppUtvalg(pUB,szNavn);
+
+            lesefeil = LU_LesULinje(pKomFil,100,szTx,&sNiv);
+            while (! lesefeil  && sNiv > 1) {
+               UT_StrToken(szTx,0,&itxi,60,ord);
+               UT_StrUpper(ord);
+
+               /* PRIORITET */
+               if (sNiv == 2  &&  strcmp(ord,"PRIORITET") == 0) {
+                  UT_StrShort(szTx,itxi,&itxi,&sPrioritet);
+                  pUB->pSisteU->sPrioritet = sPrioritet;
+                  pUB->pSisteU->sOriginalPrioritet = sPrioritet;
+                  if (sPrioritet > pUtAdm->sMaxPrior)  pUtAdm->sMaxPrior = sPrioritet;
+
+               /* BRUK-REGEL */
+               } else if (sNiv == 2  &&  strcmp(ord,"BRUK-REGEL") == 0) {
+                  UT_StrToken(szTx,itxi,&itxi,61,ord);
+                  LC_PutQueryRegel(pUB->pSisteU,ord);
+
+               /* GRUPPE */  //JA�-19980921
+               } else if (sNiv == 2  &&  strcmp(ord,"LAG") == 0) {
+                  UT_StrToken(szTx,itxi,&itxi,61,ord);
+                  LC_PutLag(pUtAdm,pUB->pSisteU,ord);
+
+               /* Vanlige utvalgslinjer */
+               } else {
+                  /* Legg inn linjen */
+                  if (LU_AppUE(pUB->pSisteU,(short)(sNiv-2),szTx) == UT_FALSE) {
+
+                     // Logisk feil i linjen.
+                     LU_DelLastQuery(pUB);
+                     pUtAdm->sMaxPrior = sForrigeMaxPrioritet;
+                     fclose (pKomFil);
+                     return UT_FALSE;               // Avbryter tolkingen ==>
+                  }
+
+                  /* Sjekk om H�YDE er brukt i utvalg */
+                  if (strcmp(pUB->pSisteU->pSisteUE->sosi,"H�YDE") == 0) {
+                     pUB->sHoydeBrukt = UT_TRUE;
+                  }
+
+                  /* PUNKT-UTVALG */
+                  if (pUB == &pUtAdm->Punkt) {
+                     /* "!" er brukt, m� sjekke alle punkt */
+                     if (pUB->pSisteU->pSisteUE->metode == LC_U_IKKE) {
+                        pUB->sTestAllePi = UT_TRUE;
+                     }
+                  }
+               }
+
+               /* Les neste linje */
+               lesefeil = LU_LesULinje(pKomFil,100,szTx,&sNiv);
+            }
+
+                            /* Fjern utvalg som ikker er avsluttet med regel */
+            if (pUB->pSisteU->pszRegel == NULL) {
+               LU_DelLastQuery(pUB);
+               pUtAdm->sMaxPrior = sForrigeMaxPrioritet;
+            }
+
+         } else {                                    /* Hopp over ukjent linje */
+            lesefeil = LU_LesULinje(pKomFil,100,szTx,&sNiv);
+         }
+      }
+
+      fclose (pKomFil);
+
+      /* Pakk prioritetene */
+      LU_PakkPrioritet(pUtAdm);
+
+      return UT_TRUE;
+   }
+
+   return UT_FALSE;
+}
+
+
+/*
+AR-920610
+CH LU_AppUE                                      Legg til en ny utvalgslinje
+CD ==========================================================================
+CD Form�l:
+CD Legg til et nytt element i kjeden utvalgslinjer.
+CD
+CD Parameters:
+CD Type         Navn     I/O  Forklaring
+CD -----------------------------------------------------------------------
+CD LC_UTVALG   *pU        i   Aktuellt utvalg
+CD short        sNiv      i   Niv� (antall prikker forran navnet)
+CD char        *pszTx     i   Lest linje
+CD short        sStatus   r   UT_TRUE=OK, UT_FALSE=feil i linjen
+CD
+CD Bruk:
+CD    sStatus = LU_AppUE(pUB->pSisteU,sNiv,szTx);
+CD =============================================================================
+*/
+SK_EntPnt_FYBA short LU_AppUE (LC_UTVALG *pU,short sNiv,const char *pszTx)
+{
+   LC_UTVALG_ELEMENT *pUE,*pNyUE,*pForrigeUE=NULL;
+   short sAktNiv = 0;
+
+   /* Finn rett posisjon i kjedene */
+   pUE=pU->pSisteUE;
+   while (sAktNiv < sNiv  &&  pUE != NULL) {
+      pForrigeUE = pUE;
+      pUE = pUE->pSisteUE;
+      sAktNiv++;
+   }
+
+   //if (sAktNiv < sNiv-1) {
+   if (sAktNiv < sNiv  ||  sNiv > sAktNiv) {
+      LC_Error(126,"(LU_AppUE)",pszTx);
+      return  UT_FALSE;       /* ==> Retur n�r ulovlig sprang i niv� */
+   }
+
+	/* Alloker minne og initier */
+	pNyUE = (LC_UTVALG_ELEMENT *)UT_MALLOC(sizeof(LC_UTVALG_ELEMENT));
+	memset(pNyUE,0,sizeof(LC_UTVALG_ELEMENT));
+	pNyUE->min = NULL;
+	pNyUE->max = NULL;
+
+   pNyUE->pNesteUE = NULL;
+   pNyUE->pForsteUE = NULL;
+   pNyUE->pSisteUE = NULL;
+
+
+   /* Heng inn i kjedene */
+   if (sNiv == 0) {
+      if (pU->pSisteUE == NULL) {
+         pU->pForsteUE = pNyUE;
+         pU->pSisteUE = pNyUE;
+
+      } else {
+         pU->pSisteUE->pNesteUE = pNyUE;
+         pU->pSisteUE = pNyUE;
+      }
+
+   } else {
+      if (pForrigeUE->pSisteUE == NULL) {
+         pForrigeUE->pForsteUE = pNyUE;
+         pForrigeUE->pSisteUE = pNyUE;
+
+      } else {
+         pForrigeUE->pSisteUE->pNesteUE = pNyUE;
+         pForrigeUE->pSisteUE = pNyUE;
+      }
+   }
+
+   /* Tolk linjen */
+   if ( ! LU_TolkUtvalgslinje(pNyUE,pszTx)) {
+      LC_Error(124,"(LU_AppUE)",pszTx);
+      return  UT_FALSE;       /* ==> Retur n�r ulovlig utvalgslinje */
+   }
+         
+   return  UT_TRUE;
+}
+
+
+/*
+AR-910718
+CH LU_DelLastQery                           Fjern siste utvalg fra tabellen
+CD ==========================================================================
+CD Form�l:
+CD Fjerner siste utvalg fra tabellen. (Fram til forrige regelnavn.)
+CD
+CD Parametre:
+CD Type              Navn  I/U   Forklaring
+CD ------------------------------------------------------------------------
+CD LC_UTVALG_BLOKK  *pUB    i    Peker til administrasjonsblokk for utvalg.
+CD
+CD Bruk:
+CD LU_DelLastQuery(pUB);
+   =============================================================================
+*/
+static void LU_DelLastQuery(LC_UTVALG_BLOKK *pUB)
+{
+   /* Husk aktuellt utvalg */
+   LC_UTVALG * pU = pUB->pSisteU;
+   
+   /*
+    * Ordne pekere
+    */
+   
+   /* I toppblokken */
+   pUB->pSisteU = pU->pForrigeU;
+   if (pUB->pSisteU == NULL)  pUB->pForsteU = NULL;
+
+   /* I kjeden av utvalg */
+   if (pU->pForrigeU != NULL) {
+      pU->pForrigeU->pNesteU = NULL;
+   }
+
+   /*
+    * Frigi minne
+    */
+   LU_FrigiUtvalg(pU);
+}
+
+
+/*
+�E-20040709 Forandret litt for at type skulle ta negative tall.
+AR-920526
+CH LU_TolkUtvalgslinje                         Tolk utvalgslinje i kom.filen
+CD ==========================================================================
+CD Form�l:
+CD Tolker en utvalgslinje fra kommandofilen og legger i tabell.
+CD Forutsetter at linjen er lest.
+CD
+CD Parametre:
+CD Type                Navn  I/U  Forklaring
+CD -----------------------------------------------------------------------
+CD LC_UTVALG_ELEMENT * pUE    i   Peker til utvalgselement
+CD char               *pszTx  i   Linje med query-tekst. (Uten prikker i starten)
+CD short               ist    r   Status (UT_TRUE=OK, UT_FALSE=linjen er ikke OK)
+CD
+CD Bruk:
+CD ist = LU_TolkUtvalgslinje(pUE,pszTx);
+   =============================================================================
+*/
+static short LU_TolkUtvalgslinje(LC_UTVALG_ELEMENT * pUE,const char *pszTx)
+{
+   char tx[100],ord[60];
+   const char *cp;
+   short itxi;
+   short i;
+
+   // ----- Preparer strengen
+   cp = pszTx;
+   while (UT_IsSpace(*cp)){
+      ++cp;
+   }
+   UT_StrCopy(tx,cp,100);
+   UT_StrUpper(tx);
+
+                                       
+   // ----- Hent kommandonavn
+   UT_StrToken(tx,0,&itxi,60,ord);
+
+   if (strcmp(ord,"VELG") == 0) {
+      pUE->kommando = LC_U_ELLER;
+
+   } else if (strcmp(ord,"ELLER") == 0) {
+      pUE->kommando = LC_U_ELLER;
+
+   } else if (strcmp(ord,"OG") == 0) {
+      pUE->kommando = LC_U_OG;
+
+   } else {
+      return  UT_FALSE;                /* ===> Feil i utvalgslinjen */
+   }
+
+   // ----- Tolk resten av strengen
+   pUE->metode = LC_U_ALLE;
+   pUE->type = LC_U_TALL;
+   pUE->ledd = 0;
+   pUE->start = 0;
+   pUE->slutt = 0;
+   
+   // ----- SOSI-navn
+   UT_StrToken(tx,itxi,&itxi,60,ord);
+   if (*ord) {
+       UT_StrCopy(pUE->sosi,ord,LC_MAX_SOSINAVN_LEN);
+   } else {
+      return  UT_FALSE;                /* ===> Feil i utvalgslinjen */
+   }
+
+                       /* Metode */
+   UT_StrToken(tx,itxi,&itxi,60,ord);
+   UT_StrUpper(ord);
+
+   if (*ord) {
+      if (!strcmp(ord,"="))
+         pUE->metode = LC_U_LIK;
+      else if (!strcmp(ord,"<>"))
+         pUE->metode = LC_U_FRATIL;
+      else if (!strcmp(ord,"/"))
+         pUE->metode = LC_U_DELELIG;
+      else if (!strcmp(ord,"!/"))
+         pUE->metode = LC_U_UDELELIG;
+      else if (!strcmp(ord,"()"))
+         pUE->metode = LC_U_CONTEIN;
+      else if (!strcmp(ord,"!()"))
+         pUE->metode = LC_U_IKKECONTEIN;
+      else if (!strcmp(ord,"AL"))
+         pUE->metode = LC_U_ALLE;
+      else if (!strcmp(ord,"!="))
+         pUE->metode = LC_U_IKKELIK;
+      else if (!strcmp(ord,"!"))
+         pUE->metode = LC_U_IKKE;
+      else if (!strcmp(ord,"><"))
+         pUE->metode = LC_U_UTENFOR;
+      else if (!strcmp(ord,"<"))
+         pUE->metode = LC_U_MINDRE;
+      else if (!strcmp(ord,">"))
+         pUE->metode = LC_U_STORRE;
+      else if (! strcmp(ord,"IV"))
+         pUE->metode = LC_U_IKKEVALGT;
+      else if (!strcmp(ord,"FL"))
+         pUE->metode = LC_U_FLERE;
+      else if (!strcmp(ord,"!FL"))
+         pUE->metode = LC_U_IKKEFLERE;
+      else {
+         return  UT_FALSE;                /* ===> Feil i utvalgslinjen */
+      }
+   }
+
+   // ----- Min
+   UT_StrToken(tx,itxi,&itxi,60,ord);
+	if (*ord) {
+		pUE->min = (char*)UT_MALLOC(strlen(ord)+1);
+      UT_StrCopy(pUE->min,ord,strlen(ord)+1);
+
+		// Sjekk type
+      LU_SjekkDatatype(pUE->min,0,&pUE->type);
+
+  	} else {
+		pUE->min = (char*)UT_MALLOC(1);
+		UT_StrCopy(pUE->min,"",1);
+      pUE->type = LC_U_ALFA;
+	}
+
+                       
+   // ----- Max
+   UT_StrToken(tx,itxi,&itxi,60,ord);
+	if (*ord) {
+		pUE->max = (char*)UT_MALLOC(strlen(ord)+1);
+      UT_StrCopy(pUE->max, ord, strlen(ord)+1);
+
+      // Sjekk type
+      if (pUE->type != LC_U_ALFA) {
+         LU_SjekkDatatype(pUE->max,pUE->metode,&pUE->type);
+      }
+
+	} else {
+      pUE->max = (char*)UT_MALLOC(1);
+		UT_StrCopy(pUE->max,"",1);
+   }
+							  
+   // ----- Type
+	UT_StrToken(tx,itxi,&itxi,60,ord);
+	if(*ord){
+      if(*ord == 'T'){
+          pUE->type = LC_U_TALL | LC_U_DEFINERT;
+      } else if(*ord == 'A'){
+          pUE->type = LC_U_ALFA | LC_U_DEFINERT;
+      } else if(*ord == 'F'){
+          pUE->type = LC_U_FLYT | LC_U_DEFINERT;
+      } else{
+         return  UT_FALSE;                /* ===> Feil i utvalgslinjen */
+      }
+
+      char *cp2 = ord + 1;
+      for (i=0; i<2; ++i) {
+         if (*cp2 == '#') {
+            ++cp2;
+            pUE->ledd = (char) strtol(cp2,&cp2,10);          /* Ledd-nummer */
+         }else if (*cp2 == '[') {
+            ++cp2;
+            pUE->start = (char) strtol(cp2,&cp2,10);         /* Startposisjon */
+            ++cp2;
+            pUE->slutt = (char) strtol(cp2,&cp2,10);         /* Sluttposisjon */
+         }
+      }
+   }
+
+
+	// Sikkrer at det er lagt inn strenger for min og max
+	//if (pUE->min == NULL)  pUE->min = strcpy(UT_MALLOC(2),"");
+	//if (pUE->max == NULL)  pUE->max = strcpy(UT_MALLOC(2),"");
+
+	return UT_TRUE;
+}
+
+
+/*
+AR-881115
+CH LU_SjekkDatatype                                              Sjekk datatype
+CD =============================================================================
+CD Form�l:
+CD Finner datatype ut fra utvalgsparameter.
+CD
+CD Parametre:
+CD Type      Navn       I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD char     *pszVerdi    i    Verdi
+CD char     szMetode     i    Utvalgsmetode
+CD short    *psType      iu   Type, Inn=forel�pig type, Ut=beregnet type
+CD
+CD Bruk:
+CD LU_SjekkDatatype(pszVerdi,szMetode,sType);
+   =============================================================================
+*/
+static void LU_SjekkDatatype(char *pszVerdi,char szMetode,short *psType)
+{
+   char *cp;
+   short i=0;
+
+
+   locale loc ( "Norwegian" );
+
+	/* Sjekk typen */
+	for (cp=pszVerdi; *cp!='\0'; ++cp)
+   {
+      // F�rste tegn:
+      if (i==0)
+      {
+         if (*cp=='.')
+         {
+            *psType = LC_U_FLYT;
+         } 
+         else if (*cp!='+' && *cp!='-' && !isdigit( *cp, loc ))
+         {
+            *psType = LC_U_ALFA;
+            break;
+         }
+      } 
+      else if ( ! isdigit( *cp, loc ) ) 
+      {
+         // Resten av tegnene:
+         if (*cp == '.')  // funnet '.' tidligere
+         { 
+            if ((*psType == LC_U_FLYT)&&(szMetode != LC_U_FRATIL)&&(szMetode != LC_U_UTENFOR)&&(szMetode != LC_U_DELELIG))
+            {
+               *psType = LC_U_ALFA;
+               break;
+            } 
+            else 
+            {
+               *psType = LC_U_FLYT;
+            }
+         
+         }
+         else
+         {
+            *psType = LC_U_ALFA;
+            break;
+         }
+      }
+      ++i;
+   }
+
+   if (*psType == LC_U_TALL)
+   {
+      // Hvis tallet har for mange siffer til long m� det h�ndteres som tekst
+      long lTall = atol(pszVerdi);
+      if (lTall == LONG_MAX  ||  lTall == LONG_MIN)
+      {
+         *psType = LC_U_ALFA;
+      }
+   }
+}
+
+
+/*
+AR-881115
+CH LC_GetUtRegelNavn                                      Henter regelnavn
+CD =============================================================================
+CD Form�l:
+CD Henter regelnavn for at programmet utenfor skal kunne sjekke
+CD at det er tilgjengelig videre behandling av alle definerte navn.
+CD
+CD Parametre:
+CD Type                         Navn I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_UT_ADM *pUtAdm     i     Peker til administrasjonsblokk for utvalg.
+CD short   *ist          iu    Status (Inn: 1=start,  0=neste)
+CD                                    (Ut:  0=OK,    -1=ferdig);
+CD char    *regelpeker   r     Peker til utvalgsnavn.
+CD
+CD Bruk:
+CD regelpeker = LC_GetUtRegelNavn(pUtAdm,&ist);
+   =============================================================================
+*/
+SK_EntPnt_FYBA char *LC_GetUtRegelNavn(LC_UT_ADM *pUtAdm,short *ist)
+{
+   if (pUtAdm != NULL)
+   {
+      if (*ist == 1) {
+         pUtAdm->pAktUB = &pUtAdm->Gruppe;
+         pUtAdm->pAktUB->pAktU = pUtAdm->pAktUB->pForsteU;
+
+      } else {
+         if (pUtAdm->pAktUB->pAktU != NULL) {
+            pUtAdm->pAktUB->pAktU = pUtAdm->pAktUB->pAktU->pNesteU;
+         }
+      }
+
+      /* Sjekk om dette er et lovlig utvalg */
+      while (pUtAdm->pAktUB->pAktU == NULL) {
+         /* Ferdig med GRUPPE-UTVALG ,sjekk PUNKT-UTVALG */
+         if (pUtAdm->pAktUB == &(pUtAdm->Gruppe)) {
+            pUtAdm->pAktUB = &pUtAdm->Punkt;
+            pUtAdm->pAktUB->pAktU = pUtAdm->pAktUB->pForsteU;
+         
+         /* Ferdig med PUNKT-UTVALG ,sjekk PINFO-UTVALG */
+         } else if (pUtAdm->pAktUB == &pUtAdm->Punkt) {
+            pUtAdm->pAktUB = &pUtAdm->Pinfo;
+            pUtAdm->pAktUB->pAktU = pUtAdm->pAktUB->pForsteU;
+
+         } else {
+            /* RETUR n�r det ikke er tilslag */
+            *ist = -1;
+            return NULL;
+         }
+      }
+
+      /* RETUR ved tilslag */
+      *ist = 0;
+      return  pUtAdm->pAktUB->pAktU->pszRegel;
+   }
+   
+   *ist = -1;
+   return NULL;
+}
+
+
+/*
+AR-920526
+CH LC_FinnPinfoUtvalg
+CD ==========================================================================
+CD Form�l:
+CD Finner et PINFO-UTVALG i kjeden av slike utvalg.
+CD
+CD Parametre:
+CD Type          Navn     I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UT_ADM *    pUtAdm    i   Peker til administrasjonsblokk for utvalg.
+CD char         *pszNavn   i   Utvalgsnavn
+CD LC_UTVALG *    pUtvalg   r   Peker til utvalget. (NULL = ikke funnet)
+CD
+CD Bruk:
+CD pUtvalg = LC_FinnPinfoUtvalg(pszNavn);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA LC_UTVALG * LC_FinnPinfoUtvalg(LC_UT_ADM * pUtAdm,const char *pszNavn)
+{
+   LC_UTVALG * pU;
+
+   if (pUtAdm != NULL)
+   {
+      /* S�k i kjeden av pinfo-utvalg */
+      for (pU=pUtAdm->Pinfo.pForsteU; pU != NULL; pU=pU->pNesteU) {
+         if (strcmp(pszNavn,pU->pszRegel) == 0) {
+            return  pU;              /* ==> Funnet */
+         }
+      }
+   }
+
+   // Ikke funnet
+   return NULL;
+}
+
+
+/*
+AR-881130
+CH LC_PunktUtvalg                                               PUNKT-utvalg
+CD =============================================================================
+CD Form�l:
+CD Sjekker PINFO-delen av aktuell gruppe for tilslag p� PUNKT-UTVALG.
+CD
+CD Parametre:
+CD Type       Navn       I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_UT_ADM * pUtAdm      i    Peker til administrasjonsblokk for utvalg.
+CD short      sPrior      i    Prioritet.
+CD short     *psStat     iu    S�kestatus, Inn: 1=start s�k, 0=fortsett s�k
+CD                                         Ut : 0=tilslag, -1=ikke tilslag
+CD long       lPnr        i    Punktnummer som skal sjekkes.
+CD char     **ppszRegel   u    Peker til regelnavn
+CD
+CD Bruk:
+CD LC_PunktUtvalg(pUtAdm,sPrior,&psStat,lPnr,&ppszRegel);
+   =============================================================================
+*/
+SK_EntPnt_FYBA void LC_PunktUtvalg(LC_UT_ADM *pUtAdm,short sPrior,short *psStat,long lPnr,char **ppszRegel)
+{
+   LC_UTVALG * pU;
+
+
+   if (pUtAdm != NULL)
+   {
+      if (*psStat == 1) {               /* Initier s�k */
+         /* Utvalgsmetode "!" (ikke) er brukt, eller
+            punktet har PINFO mm. */
+         if (pUtAdm->Punkt.sTestAllePi == UT_TRUE  ||
+             LC_TestPi(lPnr,pUtAdm->Punkt.sHoydeBrukt)) {
+            pU = pUtAdm->Punkt.pForsteU;
+
+         } else {
+            pU = NULL;
+         }
+
+      } else {
+         if (pUtAdm->Punkt.pAktU != NULL) {
+            pU = pUtAdm->Punkt.pAktU->pNesteU;
+         } else {
+            pU = NULL;
+         }
+      }
+
+                                      /* S�k */
+      while (pU != NULL) {
+         /* Rett prioritet ? */
+         if (sPrior == LC_OVERSE_PRIORITET  ||  pU->sPrioritet == sPrior) {
+            if (LC_PiTestUtvalg(pUtAdm,pU,lPnr)) {           /* Tilslag */
+               pUtAdm->Punkt.pAktU = pU;
+               *ppszRegel = pU->pszRegel;
+               *psStat = 0;
+               return;                     /* ==> Retur ved tilslag */
+            }
+         }
+
+         /* Fortsett med neste utvalg */
+         pU = pU->pNesteU;
+      }
+
+      pUtAdm->Punkt.pAktU = pU;
+   }
+
+   *psStat = -1;                                    /* Ikke tilslag */
+   return;
+}
+
+
+/*
+AR-920929
+CH LC_PiTestUtvalg                                  Sjekk PUNKT/PINFO utvalg
+CD ==========================================================================
+CD Form�l:
+CD Sjekk om PINFO i aktuellt punkt tilfredstiller et punkt-utvalg.
+CD
+CD Parametre:
+CD Type        Navn     I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UT_ADM *  pUtAdm    i   Administrasjonsblokk
+CD LC_UTVALG *  pU        i   Peker til utvalg
+CD long        lPnr      i    Punktnummer som skal sjekkes.
+CD short       sTilslag  r   Status: UT_TRUE=tilslag, UT_FALSE=ikke tilslag
+CD
+CD Bruk:
+CD sTilslag = LC_PiTestUtvalg(pUtAdm,pU,lPnr);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_PiTestUtvalg(LC_UT_ADM * pUtAdm,LC_UTVALG * pU,long lPnr)
+{
+   short sTilslag = UT_FALSE;
+
+
+   if (pUtAdm != NULL)
+   {
+      LC_UTVALG_ELEMENT * pUE = pU->pForsteUE;
+
+      /* S�k */
+      while (pUE != NULL) {
+                                          /* Linjen m� testes i disse tilfeller */
+                                      /* Har tilslag, og metode er ..OG */
+                                      /* Har ikke tilslag, og metode er ..ELLER */
+         if (( sTilslag  &&  pUE->kommando == LC_U_OG) ||
+             (!sTilslag  &&  pUE->kommando == LC_U_ELLER)) {
+            sTilslag = LU_PiTestDelutvalg(pUtAdm,pUE,lPnr);
+         }
+
+         pUE = pUE->pNesteUE;
+      }
+   }
+
+   return  sTilslag;
+}
+
+
+/*
+AR-920617
+CH LU_PiTestDelutvalg                              Sjekk en del av et utvalg
+CD ==========================================================================
+CD Form�l:
+CD Sjekk om PINFO i aktuellt punkt tilfredstiller en del av et
+CD punkt-utvalg. Sjekker et utvalgselement samt underliggende elementer
+CD under dette.
+CD
+CD Parametre:
+CD Type                 Navn     I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UT_ADM *           pUtAdm    i   Administrasjonsblokk
+CD LC_UTVALG_ELEMENT *  pUE       i   Peker til utvalgselement
+CD long                lPnr      i   Punktnummer som skal sjekkes.
+CD short                sTilslag  r   Status: UT_TRUE=tilslag, UT_FALSE=ikke tilslag
+CD
+CD Bruk:
+CD sTilslag = LU_PiTestDelutvalg(pUtAdm,pUE,lPnr);
+   ==========================================================================
+*/
+static short LU_PiTestDelutvalg(LC_UT_ADM * pUtAdm,LC_UTVALG_ELEMENT * pUE,long lPnr)
+{
+   short sTilslag = UT_FALSE;
+   short sForste = UT_TRUE;
+                                   /* S�k */
+   while (pUE != NULL) {
+      if (sForste) {
+         /*
+          * F�rste element i delutvalget skal alltid testes.
+          */
+         sTilslag = LU_PiTestLinje(pUE,lPnr);
+
+         pUE = pUE->pForsteUE;
+
+         sForste = UT_FALSE;
+
+      } else {
+         /*
+          * Elementet m� testes i disse tilfeller:
+          *  - Har tilslag, og metode er ..OG.
+          *  - Har ikke tilslag, og metode er ..ELLER.
+          * Elementet kan v�re toppen av et nytt delutvalg, kaller derfor
+          * LU_PiTestDelutvalg for � teste dette elementet.
+          */
+         if (( sTilslag  &&  pUE->kommando == LC_U_OG) ||
+            (!sTilslag  &&  pUE->kommando == LC_U_ELLER)) {
+
+            sTilslag = LU_PiTestDelutvalg(pUtAdm,pUE,lPnr);
+         }
+
+         pUE = pUE->pNesteUE;
+      }
+   }
+
+   return  sTilslag;
+}
+
+
+/*
+AR-920617
+CH LU_PiTestLinje                                      Sjekk en utvalgslinje
+CD ==========================================================================
+CD Form�l:
+CD Sjekk om PINFO i aktuellt punkt tilfredstiller en linje punkt-utvalg.
+CD
+CD Parametre
+CD Type                Navn   I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UTVALG_ELEMENT * pUE     i   Peker til administrasjonsblokk for utvalg.
+CD long                lPnr    i   Punktnummer som skal sjekkes.
+CD short               tilslag r   Status: 1=tilslag, 0=ikke tilslag.
+CD
+CD Bruk:
+CD tilslag = LU_PiTestLinje(pUE,lPnr);
+   ==========================================================================
+*/
+static short LU_PiTestLinje(LC_UTVALG_ELEMENT * pUE,long lPnr)
+{
+   char akt_para[U_PARA_LEN];
+   short tilslag;
+   long lMaxAntall;
+   char *para;
+   short sSett = 1;
+   short metode = pUE->metode;
+
+                                   /* Metode IKKE "!" */
+   if (metode == LC_U_IKKE){
+      /* AR:2002-04-24 */
+      /* if ((para = LC_GetPiVerdi(pUE->sosi,lPnr,&sSett)) == NULL  ||
+          *para == '\0') {  */
+      if (LC_GetPiVerdi(pUE->sosi,lPnr,&sSett) == NULL) {
+         return UT_TRUE;
+      }
+
+   } else if (metode == LC_U_FLERE) {          /* Metode "FL" */
+      /* Teller opp antall av dette SOSI-navnet */
+      tilslag = 0;
+      while (LC_GetPiVerdi(pUE->sosi,lPnr,&sSett) != NULL) {
+         tilslag++;
+         /* Tilslag hvis navnet finnes mer enn 1 gang */
+         if (tilslag > 1)  return UT_TRUE;
+         sSett++;
+      }
+
+   } else if (metode == LC_U_IKKEFLERE) {          /* Metode "!FL" */
+      /* Teller opp antall av dette SOSI-navnet */
+      lMaxAntall = max(atol(pUE->min),1l);
+      tilslag = 0;
+      
+      while (LC_GetPiVerdi(pUE->sosi,lPnr,&sSett) != NULL) {
+         tilslag++;
+         /* Har flere forekomster, avbryter */
+         if (tilslag > lMaxAntall)  return UT_FALSE;
+         sSett++;
+      }
+      /* Tilslag, ikke flere forekomster */
+      return UT_TRUE;
+
+   } else if (metode == LC_U_ALLE) {          /* Metode "AL" */
+      if (LC_GetPiVerdi(pUE->sosi,lPnr,&sSett) != NULL) {
+         return UT_TRUE;
+      }
+
+                                   /* Metode IKKE LIK "!=" */
+   } else if (metode == LC_U_IKKELIK) {
+      tilslag = 0;
+      pUE->metode = LC_U_LIK;                         /* Sjekker f�rst p� likhet */
+         /* Hent parameter */
+      while ((para = LC_GetPiVerdi(pUE->sosi,lPnr,&sSett)) != NULL) {
+         if (LU_ParaTest(pUE,para,akt_para,U_PARA_LEN)) {              /* Tilslag? */
+            tilslag = 1;
+            break;          /* Vet n� at det ikke blir tilslag, hopper ut */
+         }
+         sSett++;
+      }
+      pUE->metode = LC_U_IKKELIK;
+      if (! tilslag)              /* Tilslag n�r "=-testen" ikke ga tilslag */
+         return UT_TRUE;
+
+                                   /* Metode INNEHOLDER IKKE "!()" */
+   } else if (metode == LC_U_IKKECONTEIN) {
+      tilslag = 0;
+      pUE->metode = LC_U_CONTEIN;            /* Sjekker f�rst INNEHOLDER */
+         /* Hent parameter */
+      while ((para = LC_GetPiVerdi(pUE->sosi,lPnr,&sSett)) != NULL) {
+         if (LU_ParaTest(pUE,para,akt_para,U_PARA_LEN)) {              /* Tilslag? */
+            tilslag = 1;
+            break;          /* Vet n� at det ikke blir tilslag, hopper ut */
+         }
+         sSett++;
+      }
+      pUE->metode = LC_U_IKKECONTEIN;
+      if (! tilslag)              /* Tilslag n�r "()-testen" ikke ga tilslag */
+         return UT_TRUE;
+
+                                   /* Andre utvalgsmetoder */
+   } else {
+      /* Hent parameter */
+      while ((para = LC_GetPiVerdi(pUE->sosi,lPnr,&sSett)) != NULL) {
+         if (LU_ParaTest(pUE,para,akt_para,U_PARA_LEN)) {              /* Tilslag? */
+            return UT_TRUE;
+         }
+         sSett++;
+      }
+   }
+
+   return UT_FALSE;                                         /* Ikke tilslag */
+}
+
+
+/*
+AR-881130
+CH LC_GruppeUtvalg                                              GINFO-utvalg
+CD ==========================================================================
+CD Form�l:
+CD Sjekker GINFO-delen av aktuell gruppe mot alle gruppeutvalg fra fil.
+CD
+CD Parametre:
+CD Type       Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_UT_ADM *pUtAdm    i    Peker til administrasjonsblokk for utvalg.
+CD short      sPrior    i    Prioritet.
+CD                           LC_OVERSE_PRIORITET = Tar ikke hensyn til prioritet.
+CD short     *sstat     iu   S�kestatus, Inn: 1=start s�k, 0=fortsett s�k
+CD                                       Ut : 0=tilslag, -1=ikke tilslag
+CD char     **regelnavn  u   Peker til regelnavn
+CD char      *regelnavn  u   Peker til utvalgsnavn
+CD
+CD Bruk:
+CD pszUtvalgsNavn = LC_GruppeUtvalg(pUtAdm.sPrior,&sstat,&regel);
+   =============================================================================
+*/
+SK_EntPnt_FYBA char *LC_GruppeUtvalg(LC_UT_ADM *pUtAdm,short sPrior,short *sstat,char **regelnavn)
+{
+   LC_UTVALG * pU;
+
+   if (pUtAdm != NULL)
+   {
+      if (*sstat == 1) {               /* Initier s�k */
+         pU = pUtAdm->Gruppe.pForsteU;
+         pUtAdm->sGruppeValgt = UT_FALSE;
+
+      } else {
+         if (pUtAdm->Gruppe.pAktU != NULL) {
+            pU = pUtAdm->Gruppe.pAktU->pNesteU;
+         } else {
+            pU = NULL;
+         }
+      }
+
+                                      /* S�k */
+      while (pU != NULL) {
+         /* Rett prioritet ? */
+         if (sPrior == LC_OVERSE_PRIORITET  ||  pU->sPrioritet == sPrior) {
+            if (LU_GiTestUtvalg(pUtAdm,pU)) {           /* Tilslag */
+               *regelnavn = pU->pszRegel;
+               *sstat = 0;
+               pUtAdm->sGruppeValgt = UT_TRUE;
+               pUtAdm->Gruppe.pAktU = pU;
+
+               return  pU->pszNavn;   /* ==> Retur ved tilslag */
+            }
+         }
+
+         /* Fortsett med neste utvalg */
+         pU = pU->pNesteU;
+      }
+
+      pUtAdm->Gruppe.pAktU = pU;
+   }
+
+   *sstat = -1;                                    /* Ikke tilslag */
+   return  NULL;
+}
+
+
+/*
+AR-881213
+CH LC_GiQuery                                         Query mot aktuell ginfo
+CD =============================================================================
+CD Form�l:
+CD Sjekker GINFO-delen av aktuell gruppe mot aktuellt query-oppsett.
+CD
+CD Parametre:
+CD Type       Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_UT_ADM *pUtAdm    i    Peker til administrasjonsblokk for utvalg.
+CD short      status    r    S�kestatus, UT_TRUE=tilslag, UT_FALSE=ikke tilslag
+CD
+CD Bruk:
+CD ist = LC_GiQuery(pUtAdm);
+   =============================================================================
+*/
+SK_EntPnt_FYBA short LC_GiQuery(LC_UT_ADM *pUtAdm)
+{
+   if (pUtAdm != NULL)
+   {
+      pUtAdm->sGruppeValgt = UT_FALSE;
+
+      return  LU_GiTestUtvalg(pUtAdm,pUtAdm->Gruppe.pForsteU);
+   }
+
+   return UT_FALSE;
+}
+
+/*
+JA�-20000512
+CH LC_FAGiKombinertFlateQuery   Finn alle ved query mot ginfo i flate og omkrets
+CD =============================================================================
+CD Form�l:
+CD Sjekker GINFO-delen av alle flater mot aktuell queryopsett. Finner de flatene
+CD som har tilslag p� utvalgsblokken pUtAdmFlate og har har referanser til grupper
+CD som har tilslag p� utvalgsblokken pUtAdmOmkrets.
+CD Tilslag merkes i brukttabellen kolonne BT_GISOK (30).
+CD [Esc] avbryter utvalget, antall tilslag settes da til -1.
+CD
+CD Parametre:
+CD Type            Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_UT_ADM  *pUtAdmFlate   i    Peker til administrasjonsblokk for utvalg for flata. 
+CD LC_UT_ADM  *pUtAdmOmkrets i    Peker til administrasjonsblokk for utvalg for omkrets.
+CD unsigned short  usLag     i    Velg hvilke "lag" det skal s�kes i.
+CD                                LC_FRAMGR og /eller LC_BAKGR
+CD short           sAlle     i    Flagg for hvorvidt utvalg for omkrets m� sl� til p� 
+CD                                alle gruppene i omkretsen. TRUE/FALSE
+CD short           antall    r    Antall tilslag p� utvalget.
+CD 
+CD Bruk:
+CD antall = LC_FAGiQuery(pUtAdm, LC_FRAMGR | LC_BAKGR);
+CD
+   =============================================================================
+*/
+SK_EntPnt_FYBA long LC_FAGiKombinertFlateQuery(LC_UT_ADM * pUtAdmFlate,LC_UT_ADM * pUtAdmOmkrets,
+                                               unsigned short usLag,short sMetode)
+{
+	#define RED_MAX_REF   10
+
+	short ngi,gnavn,tilslag,i,avbryt;
+   long nko;
+   long ant_ref;
+	unsigned short info;
+	LC_BGR Bgr,AktBgr,FlateBgr;
+	short avbrutt = UT_FALSE;
+	long *gs;
+
+	LC_GRF_STATUS GrfStat;
+	long gsnr[RED_MAX_REF];
+	unsigned char ref_status[RED_MAX_REF];
+	long antall = -1L;
+
+
+   if (pUtAdmFlate != NULL  &&  pUtAdmOmkrets != NULL)
+   {   
+      antall = 0L;
+
+      LC_GetGrNr(&AktBgr);
+
+      /* Blanker brukttabellen */
+	   LI_EraseBt(BT_GISOK,BT_GISOK);
+
+	   LC_InitNextBgr(&FlateBgr);
+
+	   // Sjekker alle grupper i aktuellt lag 
+	   while (LC_NextBgr(&FlateBgr,usLag)  &&  !avbrutt) {
+		   // Filhodet behandles ikke 
+		   if (FlateBgr.lNr != 0L) {
+			   gnavn = LC_RxGr(&FlateBgr,LES_OPTIMALT,&ngi,&nko,&info);
+			   if (gnavn == L_FLATE) { // Er det en flate ?
+				   if (ngi > 0){                    // Med koordinat ?
+					   if (LC_GiQuery(pUtAdmFlate)){   // Tilslag p� flata.
+
+						   LC_InitGetRefFlate(&GrfStat);
+						   ant_ref = LC_GetRefFlate(&GrfStat,GRF_YTRE|GRF_INDRE,gsnr,(unsigned char*)ref_status,RED_MAX_REF);
+						   Bgr.pFil = FlateBgr.pFil;
+
+						   tilslag = 0;
+						   avbryt = 0;
+						   do {
+							   i = 0;
+							   gs = gsnr;
+							   while ((i < ant_ref) && !avbryt) {
+								   if (!((ref_status[i] & GRF_START_OY) || (ref_status[i] & GRF_SLUTT_OY))) {
+									   Bgr.lNr = labs(*gs);
+									   LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+									   tilslag = LC_GiQuery(pUtAdmOmkrets);
+									   if (sMetode == LC_ALLE) {
+										   avbryt = !tilslag;
+									   } else if (sMetode == LC_INGEN) {
+										   avbryt = tilslag;
+									   } else { //(sMetode == LC_NOEN)
+										   avbryt = tilslag;
+									   }
+								   }
+								   i++;
+								   gs++;
+
+							   }
+
+							   LC_RxGr(&FlateBgr,LES_OPTIMALT,&ngi,&nko,&info);
+							   ant_ref   = LC_GetRefFlate(&GrfStat,GRF_YTRE|GRF_INDRE,gsnr,(unsigned char*)ref_status,RED_MAX_REF);
+						   } while (ant_ref>0  && !avbryt);
+   						
+						   if (sMetode == LC_INGEN) tilslag = !tilslag;
+						   if (tilslag) {
+							   LC_RxGr(&FlateBgr,LES_OPTIMALT,&ngi,&nko,&info);
+							   antall += LC_MerkGr(BT_GISOK,1);     // Tilslag 
+						   }
+					   }
+				   }
+			   }
+		   }
+		   avbrutt = LC_Cancel();     /* <ESC> avbryter lesing */
+	   }
+      
+	   if (avbrutt)  antall = -1L;
+
+	   if (AktBgr.lNr != INGEN_GRUPPE) {
+		   LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+	   }
+   }
+
+	return antall;
+}
+
+/*
+AR-900109
+CH LC_FAGiQuery                                 Finn alle ved query mot ginfo
+CD =============================================================================
+CD Form�l:
+CD Sjekker GINFO-delen av alle grupper mot aktuell queryopsett.
+CD Tilslag merkes i brukttabellen kolonne BT_GISOK (14).
+CD [Esc] avbryter utvalget, antall tilslag settes da til -1.
+CD
+CD Parametre:
+CD Type            Navn    I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_UT_ADM      *pUtAdm   i    Peker til administrasjonsblokk for utvalg.
+CD unsigned short  usLag    i    Velg hvilke "lag" det skal s�kes i.
+CD                                 LC_FRAMGR og /eller LC_BAKGR
+CD short           antall   r    Antall tilslag p� utvalget.
+CD
+CD Bruk:
+CD antall = LC_FAGiQuery(pUtAdm, LC_FRAMGR | LC_BAKGR);
+CD
+   =============================================================================
+*/
+SK_EntPnt_FYBA long LC_FAGiQuery(LC_UT_ADM *pUtAdm,unsigned short usLag)
+{
+   short ngi;
+   long nko;
+   unsigned short info;
+   LC_BGR Bgr,AktBgr;
+   short avbrutt = UT_FALSE;
+   long antall = -1L;
+
+
+   if (pUtAdm != NULL)
+   {
+      antall = 0L;
+
+      LC_GetGrNr(&AktBgr);
+
+      /* Blanker brukttabellen */
+      LI_EraseBt(BT_GISOK,BT_GISOK);
+
+      LC_InitNextBgr(&Bgr);
+      
+      /* Sjekker alle grupper i aktuellt lag */
+      while(LC_NextBgr(&Bgr,usLag)  &&  !avbrutt) {
+         /* Filhodet behandles ikke */
+         if (Bgr.lNr != 0L) {
+            LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+            if (ngi > 0){                    /* Finnes gruppen ? */
+               if (LC_GiQuery(pUtAdm)){
+                  antall += LC_MerkGr(BT_GISOK,1);     /* Tilslag */
+               }
+            }
+         }
+         avbrutt = LC_Cancel();     /* <ESC> avbryter lesing */
+      }
+      
+      if (avbrutt)  antall = -1L;
+
+      if (AktBgr.lNr != INGEN_GRUPPE) {
+         LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+      }
+   }
+
+   return antall;
+}
+
+/*
+AR-20040705
+�E-20040705
+CH LC_FAPiQuery                            Finn alle grupper ved query mot pinfo
+CD =============================================================================
+CD Form�l:
+CD Sjekker PINFO-delen av alle grupper mot aktuell queryopsett.
+CD Tilslag merkes i brukttabellen kolonne BT_GISOK (14).
+CD [Esc] avbryter utvalget, antall tilslag settes da til -1.
+CD
+CD Parametre:
+CD Type            Navn    I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_UT_ADM      *pUtAdm   i    Peker til administrasjonsblokk for utvalg.
+CD unsigned short  usLag    i    Velg hvilke "lag" det skal s�kes i.
+CD                                 LC_FRAMGR og /eller LC_BAKGR
+CD short           antall   r    Antall tilslag p� utvalget.
+CD
+CD Bruk:
+CD antall = LC_FAPiQuery(pUtAdm, LC_FRAMGR | LC_BAKGR);
+CD
+   =============================================================================
+*/
+SK_EntPnt_FYBA long LC_FAPiQuery(LC_UT_ADM *pUtAdm,unsigned short usLag)
+{
+   short ngi;
+   long nko;
+   unsigned short info;
+   LC_BGR Bgr,AktBgr;
+   long lPunkt;
+   short avbrutt = UT_FALSE;
+   short ustat;
+   short sFunnet = UT_FALSE;
+   char *regel;
+   long antall = -1L;
+
+
+   if (pUtAdm != NULL)
+   {    
+      antall = 0L;
+
+      LC_GetGrNr(&AktBgr);
+
+      /* Blanker brukttabellen */
+      LI_EraseBt(BT_GISOK,BT_GISOK);
+
+      LC_InitNextBgr(&Bgr);
+      
+      /* Sjekker alle grupper i aktuellt lag */
+      while(LC_NextBgr(&Bgr,usLag)  &&  !avbrutt) {
+         /* Filhodet behandles ikke */
+         if (Bgr.lNr != 0L) {
+            LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+            if (nko > 0){                    /* Finnes gruppen ? */
+               sFunnet=UT_FALSE;
+               lPunkt=1;
+               // Kontrollerer punkt i gruppa:
+               while (lPunkt<=nko && sFunnet==UT_FALSE && !avbrutt) {
+                  ustat = 1;
+                  LC_PunktUtvalg(pUtAdm,LC_OVERSE_PRIORITET,&ustat,lPunkt,&regel);
+                  if (ustat == 0 && sFunnet==UT_FALSE && !avbrutt) {
+                     sFunnet = UT_TRUE;
+                     antall += LC_MerkGr(BT_GISOK,1);     /* Tilslag */
+                     break; // avbryter s�k i denne gruppen ved f�rste aktuelle pinfo
+                  }
+                  lPunkt++;
+                  avbrutt = LC_Cancel();     /* <ESC> avbryter lesing */
+               }
+            }
+         }
+         avbrutt = LC_Cancel();     /* <ESC> avbryter lesing */
+      }
+      
+      if (avbrutt)  antall = -1L;
+
+      if (AktBgr.lNr != INGEN_GRUPPE) {
+         LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+      }
+   }
+
+   return antall;
+}
+
+
+/*
+AR-890904
+CH LU_GiTestUtvalg                                           Sjekk et utvalg
+CD ==========================================================================
+CD Form�l:
+CD Sjekk om GINFO av aktuell gruppe tilfredstiller et gruppe-utvalg.
+CD
+CD Parametre:
+CD Type        Navn     I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UT_ADM *  pUtAdm    i   Administrasjonsblokk
+CD LC_UTVALG *  pU        i   Peker til utvalg
+CD short       sTilslag  r   Status: UT_TRUE=tilslag, UT_FALSE=ikke tilslag
+CD
+CD Bruk:
+CD bTilslag = LU_GiTestUtvalg(pUtAdm,pU);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LU_GiTestUtvalg(LC_UT_ADM * pUtAdm,LC_UTVALG *  pU)
+{
+   short sTilslag = UT_FALSE;
+   LC_UTVALG_ELEMENT * pUE = pU->pForsteUE;
+
+	// Hvis utvalgsregelen er med i et lag og dette ikke 
+	// skal tegnes ut, returneres FALSE. JA�-19980922
+	if (pU->pLag != NULL) {
+		if (pU->pLag->sLagAktiv == 0) return 0;
+	}
+   // Innf�rt at ogs� utvalgsregler kan sl�s av for tegning. JA�-20020927
+   if (!pU->sTegnes) return 0;
+                                   /* S�k */
+   while (pUE != NULL) {
+                                       /* Linjen m� testes i disse tilfeller */
+                                   /* Har tilslag, og metode er ..OG */
+                                   /* Har ikke tilslag, og metode er ..ELLER */
+      if (( sTilslag  &&  pUE->kommando == LC_U_OG) ||
+          (!sTilslag  &&  pUE->kommando == LC_U_ELLER)) {
+         sTilslag = LU_GiTestDelutvalg(pUtAdm,pUE);
+      }
+
+      pUE = pUE->pNesteUE;
+   }
+
+   return  sTilslag;
+}
+
+
+
+/*
+AR-890904
+CH LU_GiTestDelutvalg                              Sjekk en del av et utvalg
+CD ==========================================================================
+CD Form�l:
+CD Sjekk om GINFO av aktuell gruppe tilfredstiller en del av et
+CD gruppe-utvalg. Sjekker et utvalgselement samt underliggende elementer
+CD under dette.
+CD
+CD Parametre:
+CD Type                 Navn     I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UT_ADM *           pUtAdm    i   Administrasjonsblokk
+CD LC_UTVALG_ELEMENT *  pUE       i   Peker til utvalgselement
+CD short                sTilslag  r   Status: UT_TRUE=tilslag, UT_FALSE=ikke tilslag
+CD
+CD Bruk:
+CD bTilslag = LU_GiTestDelutvalg(pUtAdm,pUE);
+   ==========================================================================
+*/
+static short LU_GiTestDelutvalg(LC_UT_ADM * pUtAdm,LC_UTVALG_ELEMENT * pUE)
+{
+	char *apara;
+   short gilin;
+   short sTilslag = UT_FALSE;
+   short sForste = UT_TRUE;
+                                   /* S�k */
+   while (pUE != NULL) {
+      if (sForste) {
+         /*
+          * F�rste element i delutvalget skal alltid testes.
+          */
+         sTilslag = LU_GiTestLinje(pUtAdm,pUE,&gilin,&apara);
+
+         pUE = pUE->pForsteUE;
+
+#ifdef TEST
+         if (pUE->pForsteUE != NULL) {
+            pUE = pUE->pForsteUE;
+         } else {
+            pUE = pUE->pNesteUE;
+         }
+#endif
+
+         sForste = UT_FALSE;
+
+      } else {
+         /*
+          * Elementet m� testes i disse tilfeller:
+          *  - Har tilslag, og metode er ..OG.
+          *  - Har ikke tilslag, og metode er ..ELLER.
+          * Elementet kan v�re toppen av et nytt delutvalg, kaller derfor
+          * LU_GiTestDelutvalg for � teste dette elementet.
+          */
+         if (( sTilslag  &&  pUE->kommando == LC_U_OG) ||
+            (!sTilslag  &&  pUE->kommando == LC_U_ELLER)) {
+            sTilslag = LU_GiTestDelutvalg(pUtAdm,pUE);
+         }
+
+         pUE = pUE->pNesteUE;
+      }
+   }
+
+   return  sTilslag;
+}
+
+
+/*
+AR-881215
+CH LU_GiTestLinje                                      Sjekk en utvalgslinje
+CD ==========================================================================
+CD Form�l:
+CD Sjekk om GINFO av aktuell gruppe tilfredstiller en linje ginfo-utvalg.
+CD
+CD Parametre
+CD Type                Navn   I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UT_ADM *          pUtAdm  i   Peker til administrasjonsblokk for utvalg.
+CD LC_UTVALG_ELEMENT * pUE     i   Peker til administrasjonsblokk for utvalg.
+CD char               *gilin   u   GINFO-linje for funnet tilslag.
+CD char              **apara   u   Peker til aktuell del av parameterstreng.
+CD short               tilslag r   Status: 1=tilslag, 0=ikke tilslag.
+CD
+CD Bruk:
+CD tilslag = LU_GiTestLinje(pUtAdm,pUE,&gilin,&apara);
+   ==========================================================================
+*/
+static short LU_GiTestLinje(LC_UT_ADM * pUtAdm,LC_UTVALG_ELEMENT * pUE,
+                            short *gilin,char **apara)
+{
+   static char akt_para[U_PARA_LEN];
+   short metode,tilslag;
+   long lMaxAntall;
+   char *para;
+
+   metode = pUE->metode;
+   *gilin = 1;
+   *apara = akt_para;
+
+   /* Metode IKKE "!" */
+   if (metode == LC_U_IKKE){
+      /* AR:2002-04-24 */
+      /* if ((para = LC_GetGP(pUE->sosi,gilin,9999)) == NULL  ||
+          *para == '\0') { */
+      if (LC_GetGP(pUE->sosi,gilin,9999) == NULL) {
+         return UT_TRUE;
+      }
+
+   /* Metode "FL" */
+   } else if (metode == LC_U_FLERE) { 
+      /* Teller opp antall av dette SOSI-navnet */
+      tilslag = 0;
+      while ((*apara = LC_GetGP(pUE->sosi,gilin,9999)) != NULL) {
+         tilslag++;
+         /* Tilslag hvis navnet finnes mer enn 1 gang */
+         if (tilslag > 1)  return UT_TRUE;
+         (*gilin)++;
+      }
+
+   /* Metode "!FL" */
+   } else if (metode == LC_U_IKKEFLERE) {
+      /* Teller opp antall av dette SOSI-navnet */
+      lMaxAntall = max(atol(pUE->min),1l);
+      tilslag = 0;
+      while ((*apara = LC_GetGP(pUE->sosi,gilin,9999)) != NULL) {
+         tilslag++;
+         /* Har flere forekomster, avbryter */
+         if (tilslag > lMaxAntall)  return UT_FALSE;
+         (*gilin)++;
+      }
+      /* Tilslag, ikke flere forekomster */
+      return UT_TRUE;
+
+   /* Metode "AL" */
+   } else if (metode == LC_U_ALLE) { 
+      if ((*apara = LC_GetGP(pUE->sosi,gilin,9999)) != NULL) {
+         return UT_TRUE;
+      }
+
+   /* Metode IKKE VALGT "IV" */
+   } else if (metode == LC_U_IKKEVALGT) {
+      if (! pUtAdm->sGruppeValgt)
+         return  UT_TRUE;
+
+   /* Metode IKKE LIK "!=" */
+   } else if (metode == LC_U_IKKELIK) {
+      tilslag = 0;
+      pUE->metode = LC_U_LIK;                         /* Sjekker f�rst p� likhet */
+      while ((para = LC_GetGP(pUE->sosi,gilin,9999)) != NULL) { /* Hent parameter */
+         if (LU_ParaTest(pUE,para,akt_para,U_PARA_LEN)) {              /* Tilslag? */
+            tilslag = 1;
+            break;          /* Vet n� at det ikke blir tilslag, hopper ut */
+         }
+         (*gilin)++;
+      }
+      pUE->metode = LC_U_IKKELIK;
+      if (! tilslag)              /* Tilslag n�r "=-testen" ikke ga tilslag */
+         return UT_TRUE;
+
+   /* Metode INNEHOLDER IKKE "!()" */
+   } else if (metode == LC_U_IKKECONTEIN) {
+      tilslag = 0;
+      pUE->metode = LC_U_CONTEIN;            /* Sjekker f�rst INNEHOLDER */
+      while ((para = LC_GetGP(pUE->sosi,gilin,9999)) != NULL) { /* Hent parameter */
+         if (LU_ParaTest(pUE,para,akt_para,U_PARA_LEN)) {              /* Tilslag? */
+            tilslag = 1;
+            break;          /* Vet n� at det ikke blir tilslag, hopper ut */
+         }
+         (*gilin)++;
+      }
+      pUE->metode = LC_U_IKKECONTEIN;
+      if (! tilslag)              /* Tilslag n�r "=-testen" ikke ga tilslag */
+         return UT_TRUE;
+
+
+   /* Andre utvalgsmetoder */
+   } else {
+      while ((para = LC_GetGP(pUE->sosi,gilin,9999)) != NULL) { /* Hent parameter */
+         if (LU_ParaTest(pUE,para,akt_para,U_PARA_LEN)) {              /* Tilslag? */
+            return UT_TRUE;
+         }
+         (*gilin)++;
+      }
+   }
+
+   return 0;                                         /* Ikke tilslag */
+}
+
+
+/*
+AR:2006-08-08
+CH LU_ParaTest                                     Sjekk parameter for tilslag
+CD =============================================================================
+CD Form�l:
+CD Sjekk om parameteren tilfredsstiller denne utvalgslinjen.
+CD
+CD Parametre:
+CD Type                Navn    I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_UTVALG_ELEMENT * pUE      i   Peker til utvalgslinje
+CD char               *para     i   Peker til parameterstreng
+CD char               *akt_para i   Aktuell del av parameterstrengen.
+CD short               sMaxLen  i   Maks lengde for akt_para
+CD short               tilslag  r   Status: 1=tilslag, 0=ikke tilslag
+CD
+CD Bruk:
+CD tilslag = LU_ParaTest(pUE,para,&akt_para,sMaxLen);
+   =============================================================================
+*/
+static short LU_ParaTest(LC_UTVALG_ELEMENT * pUE,char *para,char *pszAktPara,short sMaxLen)
+{
+   long heltall;
+   double flyttall,desimal;
+   short metode = pUE->metode;
+
+   
+   /* Juster for ledd, og del av streng
+    * n�r dette er gitt som del av utvalgslinjen
+    * (og ikke som del av SOSI-navnet)
+    */
+   if((pUE->ledd > 0) || (pUE->start > 0) || (pUE->slutt > 0)) { // Ledd eller del av streng er angitt utenfor SOSI-navnet
+      LU_JustPara(para,(short)pUE->ledd,(short)pUE->start,(short)pUE->slutt,
+                   pszAktPara,U_PARA_LEN);
+   }
+   else {
+      UT_StrCopy(pszAktPara,para,sMaxLen);
+   }
+
+   // Sjekk f�rst at sammenligningen kan gj�res med aktuell talltype
+   short type = pUE->type;
+   if ((type & LC_U_TALL) == LC_U_TALL)
+   { 
+      heltall = atol(pszAktPara);   // OBS! Denne brukes i selve sammenligningen lenger nede i koden
+      if (heltall == LONG_MIN  ||  heltall == LONG_MAX)
+      {
+         // Tallet har for mange siffer, m� h�ndtere sammenligningen som tekst
+         type = LC_U_ALFA;
+      }
+   }
+
+   // ----- Utf�r testen
+   switch (metode) {
+      case LC_U_LIK:                                             /* Lik  "=" */
+         if ((type & LC_U_TALL) == LC_U_TALL){              /* Heltall */
+            if (heltall == atol(pUE->min) )
+               return (1);
+         } else if ((type & LC_U_FLYT) == LC_U_FLYT){        /* Flyttall */
+            if (atof(pszAktPara) == atof(pUE->min) )
+               return (1);
+         } else{                               /* Streng */
+            UT_StrUpper(pszAktPara);
+            if (strcmp(pszAktPara,pUE->min) == 0)
+               return (1);
+         }
+         break;
+
+      case LC_U_FRATIL:                                   /* Fra - til  "<>" */
+         if ((type & LC_U_TALL) == LC_U_TALL){             /* Heltall */
+            if (heltall >= atol(pUE->min)  &&  heltall <= atol(pUE->max))
+               return (1);
+         } else if ((type & LC_U_FLYT) == LC_U_FLYT){       /* Flyttall */
+            flyttall = atof(pszAktPara);
+            if (flyttall >= atof(pUE->min)  &&  flyttall <= atof(pUE->max))
+               return (1);
+         } else{                              /* Streng */
+            UT_StrUpper(pszAktPara);
+            if (strcmp(pszAktPara,pUE->min) >= 0  &&  strcmp(pszAktPara,pUE->max) <= 0)
+               return (1);
+         }
+         break;
+
+      case LC_U_DELELIG:                 /* Delelig "/" */
+         // 2001-03-19: Endret slik at algoritmen for desimaltall alltid brukes.
+         //if (type == U_FLYT){             /* Flyttall */
+            desimal = modf(atof(pszAktPara) / atof(pUE->min), &flyttall);
+            if (fabs(fabs(desimal*atof(pUE->min)) - fabs(atof(pUE->max))) < 1.0E-6) {
+               return (1);
+            }
+
+         //} else{                              /* Heltall eller streng */
+         //   if ((atol(pszAktPara) % atol(pUE->min)) == atol(pUE->max)) {
+         //      return (1);
+         //   }
+         //}
+         break;
+      
+      case LC_U_UDELELIG:                /* Ikke delellig "!/" */
+         // 2001-03-19: Endret slik at algoritmen for desimaltall alltid brukes.
+         //if (type == U_FLYT){             /* Flyttall */
+            desimal = modf(atof(pszAktPara) / atof(pUE->min), &flyttall);
+            if (fabs(desimal) >= 1.0E-6)
+               return (1);
+
+         //} else{                              /* Heltall eller streng */
+         //   if ((atol(pszAktPara) % atol(pUE->min)) != 0L)
+         //      return (1);
+         //}
+         break;
+
+      case LC_U_CONTEIN:                 /* Inneholder "()" */
+         UT_StrUpper(pszAktPara);
+         if (strstr(pszAktPara,pUE->min) != NULL)
+            return (1);
+         break;
+
+      case LC_U_UTENFOR:                 /* Utenfor "><" */
+         if ((type & LC_U_TALL) == LC_U_TALL){             /* Heltall */
+            if (heltall < atol(pUE->min)  ||  heltall > atol(pUE->max))
+               return (1);
+         } else if ((type & LC_U_FLYT) == LC_U_FLYT){             /* Flyttall */
+            flyttall = atof(pszAktPara);
+            if (flyttall < atof(pUE->min)  ||  flyttall > atof(pUE->max))
+               return (1);
+         } else{                              /* Streng */
+            UT_StrUpper(pszAktPara);
+            if (strcmp(pszAktPara,pUE->min) < 0  ||  strcmp(pszAktPara,pUE->max) > 0)
+               return (1);
+         }
+         break;
+
+      case LC_U_MINDRE:                  /* Mindre enn "<" */
+         if ((type & LC_U_TALL) == LC_U_TALL){             /* Heltall */
+            if (heltall < atol(pUE->min))
+               return (1);
+         } else if ((type & LC_U_FLYT) == LC_U_FLYT){       /* Flyttall */
+            if (atof(pszAktPara) < atof(pUE->min))
+               return (1);
+         } else{                              /* Streng */
+            UT_StrUpper(pszAktPara);
+            if (strcmp(pszAktPara,pUE->min) < 0)
+               return (1);
+         }
+         break;
+
+      case LC_U_STORRE:                  /* St�rre enn ">" */
+         if ((type & LC_U_TALL) == LC_U_TALL){             /* Heltall */
+            if (heltall > atol(pUE->min))
+               return (1);
+         } else if ((type & LC_U_FLYT) == LC_U_FLYT){      /* Flyttall */
+            if (atof(pszAktPara) > atof(pUE->min))
+               return (1);
+         } else{                              /* Streng */
+            UT_StrUpper(pszAktPara);
+            if (strcmp(pszAktPara,pUE->min) > 0)
+               return (1);
+         }
+         break;
+   }
+
+   return (0);                             /* Ikke tilslag */
+}
+
+
+/*
+AR-891206
+CH LU_JustPara                          Juster parameter for ledd og posisjon
+CD =============================================================================
+CD Form�l:
+CD Juster parameteren for leddnummer og del av streng.
+CD
+CD Parametre:
+CD Type       Navn    I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD char      *para     i    Parameterstreng som skal behandles
+CD short      ledd     i    Leddnummer
+CD short      start    i    Startposisjon i strengen (0=hele strengen)
+CD short      slutt    i    Sluttposisjon i strengen (0=resten)
+CD char      *akt_para iu   Ny behandla parameterstreng
+CD short      max_len  i    Max lengde p� akt_para
+CD
+CD Bruk:
+CD LU_JustPara(para,ledd,start,slutt,akt_para,max_len);
+   =============================================================================
+*/
+static void LU_JustPara(char *para,short ledd,short start,short slutt,
+                         char *akt_para,short max_len)
+{
+   char *cp,*nt;
+                                    /* Juster for ledd */
+   cp = UT_strtok(para," ",&nt);
+   while(cp != NULL  &&  --ledd > 0){
+      cp = UT_strtok(NULL," ",&nt);
+   }
+
+                                    /* Juster for delstreng */
+   if (cp != NULL){
+      if (start != 0){
+         if (slutt != 0){
+            slutt = min(slutt,((short)strlen(cp)));
+            *(cp+slutt) = '\0';
+         }
+         start = min(start,((short)strlen(cp)));
+         cp += (start-1);
+      }
+      UT_StrCopy(akt_para,cp,max_len);
+
+   } else{
+      *akt_para = '\0';
+   }
+}
+
+
+/*
+AR-891207
+CH LC_QueryGP                                       S�k i ginfo og finn verdi
+CD =============================================================================
+CD Form�l:
+CD Bruker query-tekst for � finne linje der parameter skal hentes.
+CD
+CD Parametre:
+CD Type     Navn   I/U   Forklaring
+CD ---------------------------------------------------------------------------
+CD char    *qulin   i    Linje med query-tekst.
+CD unsigned short    iniv    i    Niv�: Det er definert konstanter som henges
+CD                             sammen med "|".
+CD                             LC_GINFO = s�k i GINFO p� aktuell gruppe
+CD                             LC_HODE = s�k i filhodet
+CD                             Hvis begge er brukt s�kes det f�rst i GINFO.
+CD unsigned short   *univ    u    Niv�: LC_GINFO = parameter er fra GINFO
+CD                             LC_HODE = parameter er fra filhodet
+CD short   *ulin    u    GINFO-linjenummer for tilslaget.
+CD char   **para    u    Funnet parameter.
+CD short     funnet  r    Status: UT_TRUE=funnet, UT_FALSE=ikke funnet
+CD
+CD Bruk:
+CD funnet = LC_QueryGP(qulin,LC_GINFO | LC_HODE,&univ,&ulin,&para);
+   =============================================================================
+*/
+SK_EntPnt_FYBA short LC_QueryGP(char *qulin,unsigned short iniv,unsigned short *univ,short *ulin,char **para)
+{
+   LC_BGR Bgr,Hode;
+   short ngi;
+   long nko;
+   unsigned short info;
+   short sFunnet = UT_FALSE;
+   LC_UT_ADM *pUtAdm;
+
+   /* �pne query */
+   pUtAdm = LC_OpenQuery();
+   /* Tolk linjen */
+   if (LC_PutQueryLine(pUtAdm,qulin,U_GRUPPE)) {
+      LC_PutQueryRegel(pUtAdm->Gruppe.pSisteU,"S");
+
+      /* Sjekk GINFO */
+      /* Initier s�k */
+      pUtAdm->Gruppe.pAktU = pUtAdm->Gruppe.pForsteU;
+      pUtAdm->sGruppeValgt = UT_FALSE;
+
+      /* S�k */
+      sFunnet = LU_GiTestLinje(pUtAdm,pUtAdm->Gruppe.pForsteU->pForsteUE,ulin,para);
+      *univ = LC_GINFO;
+
+      /*
+       * Ikke funnet, og konstant er satt for at hodet skal sjekkes.
+       * Sjekk hodet.
+       */
+      if ( (! sFunnet)  &&  (iniv & LC_HODE)) {
+         LC_GetGrNr(&Bgr);    /* Husk aktuell gruppe */
+         Hode.pFil = Bgr.pFil;
+         Hode.lNr = 0L;
+         /* Les filhode */
+         LC_RxGr(&Hode,LES_OPTIMALT,&ngi,&nko,&info);
+
+         /* Initier s�k */
+         pUtAdm->Gruppe.pAktU = pUtAdm->Gruppe.pForsteU;
+         pUtAdm->sGruppeValgt = UT_FALSE;
+
+         /* S�k */
+         sFunnet = LU_GiTestLinje(pUtAdm,pUtAdm->Gruppe.pForsteU->pForsteUE,ulin,para);   
+         *univ = LC_HODE;
+
+         /* Les tilbake opprinnelig gruppe */
+         LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+      }
+   }
+
+   LC_CloseQuery(pUtAdm);
+   return sFunnet;
+}
+
+
+/*
+AR-920524
+CH LU_LesULinje                       Les en utvalgs-linje fra kommandofilen
+CD ==========================================================================
+CD Form�l:
+CD Les en utvalgs-linje fra kommandofilen.
+CD
+CD Parameters:
+CD Type     Name     I/O  Forklaring
+CD ----------------------------------------------------------------
+CD FILE    *pKomFil   i   Filpeker for beskrivelsesfil
+CD short    sMaxTxLen i   Max lengde av pszTx
+CD char    *pszTx     i   Lest linje
+CD short   *psNiv     u   Niv� (antall prikker forran navnet)
+CD short    lesefeil  r   Lesefeil fra UT_ReadLine.
+CD
+CD Bruk:
+CD lesefeil = LU_LesULinje(pFil,sMaxTxLen,pszTx,&sNiv);
+CD =============================================================================
+*/
+static short LU_LesULinje(FILE *pKomFil,short sMaxTxLen,char *pszTx,
+                          short *psNiv)
+{
+   char szLinje[100],*cp;
+   short lesefeil;
+
+   if (!(lesefeil = UT_ReadLineNoComm(pKomFil,100,szLinje))) {
+
+      cp = szLinje;
+
+      /* Hopp over ledende blanke */
+      while (UT_IsSpace(*cp)) {
+         cp++;
+      }
+
+      /* Tell opp antall prikker */
+      *psNiv = 0;
+      while (*cp == '.') {
+         (*psNiv)++;
+         cp++;
+      }
+         
+      /* Kopier ut linjen */
+      UT_StrCopy(pszTx,cp,sMaxTxLen);
+   }
+
+   return lesefeil;
+}
+
+
+/*
+AR-920524
+CH LU_AppUtvalg                                      Legg til et nytt utvalg
+CD ==========================================================================
+CD Form�l:
+CD Legg til et nytt utvalg i en av kjedene av utvalg.
+CD
+CD Parametre:
+CD Type              Navn     I/O  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UTVALG_BLOKK  *pUtBlokk  i   Toppblokk for aktuell utvalgstype.
+CD char             *pszNavn   i   Utvalgsnavn
+CD
+CD Bruk:
+CD LU_AppUtvalg(pUtAdm->pGruppe,szNavn);
+CD =============================================================================
+*/
+static void LU_AppUtvalg (LC_UTVALG_BLOKK *pUB,char *pszNavn)
+{
+   LC_UTVALG * pU;
+
+	/* Alloker minne og initier */
+	pU = (LC_UTVALG *)UT_MALLOC(sizeof(LC_UTVALG));
+	memset(pU, 0, sizeof(LC_UTVALG));
+
+	pU->sPrioritet = 0;
+	pU->sOriginalPrioritet = 0;
+   pU->sStatus = LC_UFORANDRET;
+   pU->sTegnes = 1;
+	pU->pszNavn = (char*)UT_MALLOC(strlen(pszNavn)+1);
+	UT_StrCopy(pU->pszNavn, pszNavn, strlen(pszNavn)+1);
+	pU->pszRegel = NULL;
+
+	pU->pForsteUE = NULL;
+   pU->pSisteUE = NULL;
+   pU->pForrigeU = NULL;
+   pU->pNesteU = NULL;
+
+   /* F�rste */
+   if (pUB->pForsteU == NULL) {
+      pUB->pForsteU = pU;
+      pUB->pSisteU = pU;
+
+   } else {
+      pU->pForrigeU = pUB->pSisteU;
+      pUB->pSisteU->pNesteU = pU;
+      pUB->pSisteU = pU;
+   }
+
+   return;
+}
+
+
+/*
+AR-920402
+CH LC_InqMaxPrioritet                                Hent st�rste prioritet
+CD ==========================================================================
+CD Form�l:
+CD Henter st�rste prioritet for gitt utvalgstype.
+CD
+CD Parametre:
+CD Type         Navn          I/U   Forklaring
+CD ----------------------------------------------------------------------
+CD LC_UT_ADM *   pUA            i    Peker til administrasjonsblokk for utvalg.
+CD short        sMaxPrioritet  r    Max prioritet
+CD
+CD Bruk:
+CD sMaxPrioritet = LC_InqMaxPrioritet(pUA);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_InqMaxPrioritet(LC_UT_ADM * pUA)
+{
+   if (pUA != NULL)
+   {
+      return pUA->sMaxPrior;
+   }
+
+   return 0;
+}
+
+
+/*
+AR-920814
+CH LC_TestPrioritetBrukt                     Tester om en prioritet er brukt
+CD ==========================================================================
+CD Form�l:
+CD Tester om en prioritet er brukt.
+CD
+CD Parametre:
+CD Type        Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UT_ADM *  pUtAdm     i    Peker til administrasjonsblokk for utvalg.
+CD short       sPrioritet i    Prioritet som skal testes.
+CD short       sBrukt     r    Status: UT_TRUE=brukt, UT_FALSE=ikke brukt.
+CD
+CD Bruk:
+CD sBrukt = LC_TestPrioritetBrukt(pUtAdm,sPrioritet);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_TestPrioritetBrukt(LC_UT_ADM * pUtAdm,short sPrioritet)
+{
+   LC_UTVALG * pU;
+
+
+   if (pUtAdm != NULL)
+   {
+      /*
+       * Test GRUPPE-UTVALG.
+       */
+      for (pU=pUtAdm->Gruppe.pForsteU; pU != NULL;  pU = pU->pNesteU) {
+         if (sPrioritet == pU->sPrioritet)  return UT_TRUE;   /* ==> Funnet */
+      }
+
+      /*
+       * Test PUNKT-UTVALG.
+       */
+      for (pU=pUtAdm->Punkt.pForsteU; pU != NULL;  pU = pU->pNesteU) {
+         if (sPrioritet == pU->sPrioritet)  return UT_TRUE;   /* ==> Funnet */
+      }
+
+      /*
+       * Test PINFO-UTVALG.
+       */
+      for (pU=pUtAdm->Pinfo.pForsteU; pU != NULL;  pU = pU->pNesteU) {
+         if (sPrioritet == pU->sPrioritet)  return UT_TRUE;   /* ==> Funnet */
+      }
+   }
+
+   return UT_FALSE;   /* ==> Ikke funnet */
+}
+ 
+
+/*
+AR-940110
+CH LU_PakkPrioritet                                    Pakker prioriteten
+CD ==========================================================================
+CD Form�l:
+CD Pakker prioriteten.
+CD
+CD Parametre:
+CD Type        Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UT_ADM *  pUtAdm     i    Peker til administrasjonsblokk for utvalg.
+CD
+CD Bruk:
+CD LU_PakkPrioritet(pUtAdm);
+   ==========================================================================
+*/
+static void LU_PakkPrioritet(LC_UT_ADM * pUtAdm)
+{
+   LC_UTVALG * pU;
+   short s,sFerdig;
+   short NyPrior[LC_MAX_ANT_PRIOR];
+   short sAntNyPrior = 0;
+
+
+   if (pUtAdm != NULL)
+   {
+      /*
+       * Bygger opp tabell over hvilke prioriteter som er brukt.
+       */
+
+      /* GRUPPE-UTVALG. */
+      for (pU=pUtAdm->Gruppe.pForsteU; pU != NULL;  pU = pU->pNesteU) {
+         LU_HuskPrior(NyPrior,&sAntNyPrior,pU->sPrioritet);
+      }
+      /* PUNKT-UTVALG. */
+      for (pU=pUtAdm->Punkt.pForsteU; pU != NULL;  pU = pU->pNesteU) {
+         LU_HuskPrior(NyPrior,&sAntNyPrior,pU->sPrioritet);
+      }
+      /* PINFO-UTVALG. */
+      for (pU=pUtAdm->Pinfo.pForsteU; pU != NULL;  pU = pU->pNesteU) {
+         LU_HuskPrior(NyPrior,&sAntNyPrior,pU->sPrioritet);
+      }
+
+      /* Sorter prioritetene */
+      qsort(NyPrior,sAntNyPrior,sizeof(short),LU_compare);
+
+
+      /*
+       * Legg inn nye prioriteter.
+       */
+
+      /* GRUPPE-UTVALG. */
+      for (pU=pUtAdm->Gruppe.pForsteU; pU != NULL;  pU = pU->pNesteU) {
+         sFerdig = UT_FALSE;
+         for (s=0; sFerdig==UT_FALSE && s<sAntNyPrior; s++) {
+            if (NyPrior[s] == pU->sPrioritet) {
+               pU->sPrioritet = s;
+               sFerdig = UT_TRUE;
+            }
+         }
+      }
+      /* PUNKT-UTVALG. */
+      for (pU=pUtAdm->Punkt.pForsteU; pU != NULL;  pU = pU->pNesteU) {
+         sFerdig = UT_FALSE;
+         for (s=0; sFerdig==UT_FALSE && s<sAntNyPrior; s++) {
+            if (NyPrior[s] == pU->sPrioritet) {
+               pU->sPrioritet = s;
+               sFerdig = UT_TRUE;
+            }
+         }
+      }
+      /* PINFO-UTVALG. */
+      for (pU=pUtAdm->Pinfo.pForsteU; pU != NULL;  pU = pU->pNesteU) {
+         sFerdig = UT_FALSE;
+         for (s=0; sFerdig==UT_FALSE && s<sAntNyPrior; s++) {
+            if (NyPrior[s] == pU->sPrioritet) {
+               pU->sPrioritet = s;
+               sFerdig = UT_TRUE;
+            }
+         }
+      }
+
+      /* Oppdaterer max prioritet */
+      pUtAdm->sMaxPrior = sAntNyPrior-1;
+   }
+
+   return;
+}
+ 
+
+/* ===================================================== */
+int LU_compare (const void *arg1, const void *arg2)
+ {
+    if (*(short*)arg1 == *(short*)arg2)  return  0;
+    if (*(short*)arg1 < *(short*)arg2)   return -1;
+    return 1;
+ }
+
+
+/*
+AR-940110
+CH LU_HuskPrior                          Legg inn prioritet i tabellen
+CD ==========================================================================
+CD Form�l:
+CD Legg inn prioritet i tabellen
+CD
+CD Parametre:
+CD Type        Navn   I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD short *NyPrior     iu   Tabell over nye prioriteter
+CD short *sAntPrior   iu   Antall brukt i NyPrior
+CD short  sPrior      i    Prioritet som skal legges inn.
+CD
+CD
+CD Bruk:
+CD LU_HuskPrior(NyPrior,&sAntPrior,pU->sPrioritet);
+   ==========================================================================
+*/
+static void LU_HuskPrior(short *NyPrior,short *sAntPrior,short sPrior)
+{
+   short s;
+   char szTx[10];
+
+   for (s=0; s<*sAntPrior; s++) {
+      if (sPrior == NyPrior[s]) {
+         return;        /* ==> Prioriteten er brukt f�r, returner */
+      }
+   }
+
+   if (*sAntPrior >= LC_MAX_ANT_PRIOR) {
+      UT_SNPRINTF(szTx,10,"%hd",sPrior);
+      LC_Error(127,"(LU_HuskPrior)",szTx);
+
+   } else {
+      /* Ny prioritet, husk denne */
+      NyPrior[*sAntPrior] = sPrior;
+      (*sAntPrior)++;
+   }
+
+   return;
+}
+
+
+/*
+AR: 1999-11-20
+CH LC_LoggPrioritetUtvalg                        Skriver prioritetsoversikt 
+CD ==========================================================================
+CD Form�l:
+CD Skriver oversikt over prioriteter og utvalg til log-filen.
+CD
+CD Parametre:
+CD Type        Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UT_ADM *  pUtAdm     i    Peker til administrasjonsblokk for utvalg.
+CD
+CD Bruk:
+CD LC_LoggPrioritetUtvalg(pUtAdm);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_LoggPrioritetUtvalg(LC_UT_ADM * pUtAdm)
+{
+   if (pUtAdm != NULL)
+   {
+      short sMaxPrioritet = LC_InqMaxPrioritet(pUtAdm);
+      short sPrioritet;
+      LC_UTVALG * pU;
+      short sG = 0;
+      short sP = 0;
+
+      UT_FPRINTF(stderr,"\n\n***** Prioriteter og utvalg *****\n");
+
+      for (sPrioritet=0; sPrioritet<sMaxPrioritet; sPrioritet++) {
+    
+         UT_FPRINTF(stderr,"\nPrioritet: %hd\n",sPrioritet);
+
+         /* GRUPPE-UTVALG. */
+         for (pU=pUtAdm->Gruppe.pForsteU; pU != NULL;  pU = pU->pNesteU) {
+            if (sPrioritet == pU->sPrioritet) {
+               UT_FPRINTF(stderr,"   Gruppeutvalg: %s (%hd) \n",pU->pszNavn ,pU->sOriginalPrioritet);
+               sG++;
+            }
+         }
+
+         /* PUNKT-UTVALG. */
+         for (pU=pUtAdm->Punkt.pForsteU; pU != NULL;  pU = pU->pNesteU) {
+            if (sPrioritet == pU->sPrioritet) {
+               UT_FPRINTF(stderr,"   Punktutvalg: %s (%hd) \n",pU->pszNavn ,pU->sOriginalPrioritet);
+               sP++;
+            }
+         }
+
+         /* PINFO-UTVALG. */
+   #ifdef TEST
+         for (pU=pUtAdm->Pinfo.pForsteU; pU != NULL;  pU = pU->pNesteU) {
+            if (sPrioritet == pU->sPrioritet) {
+               UT_FPRINTF(stderr,"   Pinfoutvalg: %s (%hd) \n",pU->pszNavn ,pU->sOriginalPrioritet);
+            }
+         }
+   #endif
+      }
+
+      UT_FPRINTF(stderr,"\nTotalt  %hd gruppeutvalg, og  %hd punktutvalg.\n",sG,sP);
+   }
+}
+
+
+/*
+AR-940110
+CH LC_UtvalgPrioritet                                   Finn brukt prioritet
+CD ==========================================================================
+CD Form�l:
+CD Sjekker GINFO og PINFO for � finne hvilke prioriteter som "ber�rer" aktuell
+CD gruppe. Resultatet markeres i Gruppetabellen ulPrior.
+CD
+CD Parametre:
+CD Type           Navn       I/U Forklaring
+CD ---------------------------------------------------------------------------
+CD LC_UT_ADM     *pUtAdm      i  Peker til administrasjonsblokk for utvalg.
+CD
+CD Bruk:
+CD LC_UtvalgPrioritet(pUtAdm);
+   ===========================================================================
+*/
+SK_EntPnt_FYBA void LC_UtvalgPrioritet(LC_UT_ADM *pUtAdm)
+{
+   long lPnr;
+   short sPrior,sKolonne;
+   LC_UTVALG * pU;
+   unsigned long ulPrioritet[4];
+
+
+   if (pUtAdm != NULL)
+   {
+      ulPrioritet[0] = 0x00000000UL;
+      ulPrioritet[1] = 0x00000000UL;
+      ulPrioritet[2] = 0x00000000UL;
+      ulPrioritet[3] = 0x80000000UL; /* Info er bygd opp */
+
+      if (Sys.GrId.lNr != INGEN_GRUPPE) {
+
+         /*
+          * GINFO
+          */
+        
+         /* Initier s�k */
+         pU = pUtAdm->Gruppe.pForsteU;
+         pUtAdm->sGruppeValgt = UT_FALSE;
+        
+         /* S�k */
+         while (pU != NULL) {
+        
+            sKolonne = pU->sPrioritet / 32;
+            sPrior = pU->sPrioritet % 32;
+
+            /* Hvis vi har tilslag p� denne prioriteten trenger vi ikke � sjekke dette utvalget */
+            if ((ulPrioritet[sKolonne] & (0x1UL << sPrior)) == 0UL) {
+        
+               if (LU_GiTestUtvalg(pUtAdm,pU)) {
+                  /* Tilslag */
+                  pUtAdm->sGruppeValgt = UT_TRUE;
+            
+                  /* Husk at prioriteten er brukt */
+                  ulPrioritet[sKolonne]  |=  (0x1UL << sPrior);
+               }
+            }
+        
+            /* Fortsett med neste utvalg */
+            pU = pU->pNesteU;
+         }
+        
+        
+         /*
+          * PINFO
+          *
+          * Sjekker bare hvis :
+          *   - utvalgsmetode "!" (ikke) er brukt,
+          *   - gruppen har PINFO
+          *   - gruppen har KP
+          *   - gruppen har h�yde
+          */
+    
+         if (pUtAdm->Punkt.sTestAllePi == UT_TRUE  ||
+             Sys.pGrInfo->info & GI_PINFO  ||
+             Sys.pGrInfo->info & GI_KP  ||
+             Sys.pGrInfo->info & GI_NAH) {
+
+           for (lPnr=1; lPnr<=Sys.pGrInfo->nko; ++lPnr) {
+               /* Initier s�k */
+               /* Utvalgsmetode "!" (ikke) er brukt, eller
+                  punktet har PINFO mm. */
+               if (pUtAdm->Punkt.sTestAllePi == UT_TRUE  ||
+                   LC_TestPi(lPnr,pUtAdm->Punkt.sHoydeBrukt)) {
+                  pU = pUtAdm->Punkt.pForsteU;
+               } else {
+                  pU = NULL;
+               }
+           
+               /* S�k */
+               while (pU != NULL) {
+
+                  sKolonne = pU->sPrioritet / 32;
+                  sPrior = pU->sPrioritet % 32;
+           
+                  /* Hvis vi har tilslag p� denne prioriteten trenger vi ikke � sjekke dette utvalget */
+                  if ((ulPrioritet[sKolonne] & (0x1UL << sPrior)) == 0UL) {
+           
+                     if (LC_PiTestUtvalg(pUtAdm,pU,lPnr)) {
+                        /* Tilslag */
+                        /* Husk at prioriteten er brukt */
+                        ulPrioritet[sKolonne]  |=  (0x1UL << sPrior);
+                     }
+                  }
+           
+                  /* Fortsett med neste utvalg */
+                  pU = pU->pNesteU;
+               }
+            }
+         }
+
+         Sys.pGrInfo->ulPrior[0] = ulPrioritet[0];
+         Sys.pGrInfo->ulPrior[1] = ulPrioritet[1];
+         Sys.pGrInfo->ulPrior[2] = ulPrioritet[2];
+         Sys.pGrInfo->ulPrior[3] = ulPrioritet[3];
+      }
+   }
+}
+
+
+/*
+AR:2007-08-23
+CH LC_ErLik_Avrundet                 Rund av og sjekk om sammenfallende punkt
+CD ==========================================================================
+CD Form�l:
+CD Runder av til valgt enhet, og sjekker om de to punktene er sammenfallende. 
+CD (Avviket er mindre enn 1/10 enhet b�de nord og �st)
+CD
+CD Parametre:
+CD Type     Navn    I/U Forklaring
+CD ---------------------------------------------------------------------------
+CD double   dA1      i  P1
+CD double   dN1      i
+CD double   dA2      i  P2
+CD double   dN2      i
+CD double   dEnhet   i  Enhet som skal brukes i sammenligningen
+CD bool     bErLike  r  Status: true  = Samme koordinat 
+CD                              false = Ikke samme koordinat
+CD
+CD Bruk:
+CD bSammenfallende = LC_ErLik(dA1,dN1,dA2,dN2,dEnhet);
+   ===========================================================================
+*/
+SK_EntPnt_FYBA bool LC_ErLik_Avrundet(double dA1,double dN1,double dA2, double dN2, double dEnhet)
+{
+   // 2010-01-25: Endret fra UT_RoundDD til UT_RoundHalfUpDD
+   dA1 = UT_RoundHalfUpDD(dA1 / dEnhet) * dEnhet;
+   dN1 = UT_RoundHalfUpDD(dN1 / dEnhet) * dEnhet;
+   dA2 = UT_RoundHalfUpDD(dA2 / dEnhet) * dEnhet;
+   dN2 = UT_RoundHalfUpDD(dN2 / dEnhet) * dEnhet;
+
+   return ((fabs(dA1-dA2) < dEnhet/10.0) && (fabs(dN1-dN2) < dEnhet/10.0));
+}
+
+
+/*
+AR:2007-08-23
+CH LC_ErLik_IkkeAvrundet       Sjekk om sammenfallende punkt (uten avrunding)
+CD ==========================================================================
+CD Form�l:
+CD Sjekker om de to punktene er sammenfallende innen gitt n�yaktighet. 
+CD Det skjer ingen avrunding av koordinatene f�r sammenligningen.
+CD (Avviket er mindre enn 1/10 enhet b�de nord og �st)
+CD
+CD Parametre:
+CD Type     Navn    I/U Forklaring
+CD ---------------------------------------------------------------------------
+CD double   dA1      i  P1
+CD double   dN1      i
+CD double   dA2      i  P2
+CD double   dN2      i
+CD double   dEnhet   i  Enhet som skal brukes i sammenligningen
+CD bool     bErLike  r  Status: true  = Samme koordinat 
+CD                              false = Ikke samme koordinat
+CD
+CD Bruk:
+CD bSammenfallende = LC_ErLik(dA1,dN1,dA2,dN2,dEnhet);
+   ===========================================================================
+*/
+SK_EntPnt_FYBA bool LC_ErLik_IkkeAvrundet(double dA1,double dN1,double dA2, double dN2, double dEnhet)
+{
+   return ((fabs(dA1-dA2) < dEnhet/10.0) && (fabs(dN1-dN2) < dEnhet/10.0));
+}
+
+
+/*
+AR:2007-08-23
+CH LC_ErReferert                                 Sjekk om gruppe er referert
+CD ==========================================================================
+CD Form�l:
+CD Sjekker om aktuell gruppe er referert fra andre grupper.
+CD
+CD Parametre:
+CD Type  Navn      I/U Forklaring
+CD ---------------------------------------------------------------------------
+CD bool  bReferert  r  Det finnes referanser til gruppen
+CD
+CD Bruk:
+CD bReferert = LC_ErReferert();
+===========================================================================
+*/
+SK_EntPnt_FYBA bool LC_ErReferert(void)
+{
+   LC_BGR FlateBgr;
+   double a,n;
+   LC_GEO_STATUS GeoStat;
+   short ngi;
+   long nko;
+   unsigned short info;
+   long lAntRef;
+   short sGiLin,sRefPos;
+   long *plRefArray,*plRef;
+   long l;
+
+   bool bReferert = false;
+
+   /* Husk gruppen */
+   LC_FILADM *pFil = Sys.GrId.pFil;
+   LC_BGR Bgr = Sys.GrId;
+   long lGmlSnr = LC_GetSn();
+
+   LC_GetTK(1,&a,&n);
+   LC_SBFlate(&GeoStat,LC_FRAMGR,a-0.1,n-0.1,a+0.1,n+0.1);
+   if (LC_FFFlate(&GeoStat,&FlateBgr)) {
+      do {
+         if (FlateBgr.pFil == pFil) {
+            /* Funnet flate i rett fil, sjekk referansene */
+            LC_RxGr(&FlateBgr,LES_OPTIMALT,&ngi,&nko,&info);
+            lAntRef = LC_InqAntRef();
+            plRefArray = (long *) UT_MALLOC(lAntRef * sizeof(long));
+            sGiLin = 2;
+            sRefPos = 0;
+            LC_GetRef(plRefArray,lAntRef,&sGiLin,&sRefPos);
+
+            plRef = plRefArray;
+            for (l=0; (!bReferert) && l<lAntRef; l++) {
+               if (labs(*plRef) == lGmlSnr) {
+                  bReferert = true;
+               } 
+               ++plRef;
+            }
+
+            UT_FREE(plRefArray);
+         }
+      } while ((!bReferert)  &&  LC_FNFlate(&GeoStat,&FlateBgr));
+   }
+   LC_AvsluttSok(&GeoStat);
+
+   // Leser inn opprinnelig gruppe igjen
+   LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+
+   return bReferert;
+}
+
+/*
+AR:2009-04-28
+CH LC_ErReferertFraAntall                  Tell antall referanser til gruppe
+CD ==========================================================================
+CD Form�l:
+CD Tell antall referanser til aktuell gruppe.
+CD
+CD Parametre:
+CD Type  Navn    I/U Forklaring
+CD ---------------------------------------------------------------------------
+CD long  lAntall  r  Antall grupper som refererer gruppen
+CD
+CD Bruk:
+CD lAntall = LC_ErReferertFraAntall();
+===========================================================================
+*/
+SK_EntPnt_FYBA long LC_ErReferertFraAntall(void)
+{
+   LC_BGR FlateBgr;
+   double a,n;
+   LC_GEO_STATUS GeoStat;
+   short ngi;
+   long nko;
+   unsigned short info;
+   long lAntRef;
+   short sGiLin,sRefPos;
+   long *plRefArray,*plRef;
+   long l;
+
+   long lAntall = 0;
+
+   /* Husk gruppen */
+   LC_FILADM *pFil = Sys.GrId.pFil;
+   LC_BGR Bgr = Sys.GrId;
+   long lGmlSnr = LC_GetSn();
+
+   LC_GetTK(1,&a,&n);
+   LC_SBFlate(&GeoStat,LC_FRAMGR,a-0.1,n-0.1,a+0.1,n+0.1);
+   if (LC_FFFlate(&GeoStat,&FlateBgr)) {
+      do {
+         if (FlateBgr.pFil == pFil) {
+            /* Funnet flate i rett fil, sjekk referansene */
+            LC_RxGr(&FlateBgr,LES_OPTIMALT,&ngi,&nko,&info);
+            lAntRef = LC_InqAntRef();
+            plRefArray = (long *) UT_MALLOC(lAntRef * sizeof(long));
+            sGiLin = 2;
+            sRefPos = 0;
+            LC_GetRef(plRefArray,lAntRef,&sGiLin,&sRefPos);
+
+            plRef = plRefArray;
+            for (l=0; l<lAntRef; l++) {
+               if (labs(*plRef) == lGmlSnr) {
+                  ++lAntall;
+               } 
+               ++plRef;
+            }
+
+            UT_FREE(plRefArray);
+         }
+      } while (LC_FNFlate(&GeoStat,&FlateBgr));
+   }
+   LC_AvsluttSok(&GeoStat);
+
+   // Leser inn opprinnelig gruppe igjen
+   LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+
+   return lAntall;
+}
diff --git a/FYBA/FYLX.cpp b/FYBA/FYLX.cpp
new file mode 100644
index 0000000..7d2418a
--- /dev/null
+++ b/FYBA/FYLX.cpp
@@ -0,0 +1,4948 @@
+/* === AR-911003 ============================================================ */
+/*  STATENS KARTVERK  -  FYSAK-PC                                             */
+/*  Fil: fylx.c                                                               */
+/*  Innhold: Put og get rutiner til RB                                        */
+/* ========================================================================== */
+
+#include "stdafx.h"
+ 
+#include <math.h>
+
+#include <ctype.h>
+#include <limits.h>
+
+
+/* Globale variabler for FYBA */
+extern LC_SYSTEMADM Sys;             /* Systemadministrasjon */
+extern char retur_str[LC_MAX_SOSI_LINJE_LEN];  /* Returstreng */
+
+/* Statiske variabler */
+
+/* Lokale rutiner */
+static long LX_GetRefOmkrets(LC_GR_STATUS *pGRS,long *ref_array,
+                              unsigned char *ref_status,long max_ref);
+static long LX_GetRefOy(LC_GRF_STATUS * pGS,long *ref_array,
+                         unsigned char *ref_status,long max_ref);
+static void LX_CreatePibuf(long lPnr);
+static double LX_ArealGruppe(LC_BGR * pBgr,short retning);
+static void LX_PutGi(short lin_nr, const char *szGinfo);
+
+
+/*
+AR-920921
+CH LC_InitGetRefFlate                       Initierer status for GetRefFlate
+CD ==========================================================================
+CD Form�l:
+CD Initierer status for GetRefFlate.
+CD
+CD Parametre:
+CD Type           Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GRF_STATUS * pRefStat  iu   Struktur med statusopplysninger.
+CD
+CD Bruk:
+CD     LC_InitGetRefFlate(pGrfStat,pBgr);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_InitGetRefFlate(LC_GRF_STATUS * pGS)
+{
+   pGS->Omkr.sGiLinNr = 2;
+   pGS->Omkr.sRefPos = 0;
+   pGS->Omkr.sRefLin = UT_FALSE;
+
+   pGS->usOmkretsFerdig = UT_FALSE;
+
+   pGS->Bgr.pFil = NULL;
+   pGS->Bgr.lNr  = INGEN_GRUPPE;
+}
+
+
+/*
+AR-920930
+CH LC_GetRefFlate                        Hent referanser for flate fra GINFO
+CD ==========================================================================
+CD Form�l:
+CD Henter ut et array med referanser for flate fra GINFO i aktuell gruppe.
+CD
+CD Parametre:
+CD Type            Navn      I/U  Forklaring
+CD -------------------------------------------------------------------------
+CD LC_GRF_STATUS *  GrfStat    iu  Struktur med statusopplysninger.
+CD unsigned short  usHent     i   Hva skal hentes:
+CD                                 GRF_YTRE  = Ytre avgrensing
+CD                                 GRF_INDRE = Indre avgrensing, �yer
+CD                                     (kan kombineres med | (or).)
+CD long           *ref_array  u   GRUPPENUMMER for refererte grupper.
+CD unsigned char  *ref_status u   Status for gruppene i ref_array.
+CD                                 LC_MED_DIG = Brukes MED dig retning.
+CD                                 LC_MOT_DIG  = Brukes MOT dig retning.
+CD                                 GRF_START_OY     = F�rste gruppe i �y
+CD                                 GRF_SLUTT_OY     = Siste gruppe i �y
+CD long            max_ref    i   Max antall linjer i ref_array og ref_status.
+CD long           ant_ref    r   Antall linjer brukt i ref_array.
+CD                                0 viser at hele flata er behandla.
+CD
+CD Bruk:
+CD    #define  MAX_REF  20
+CD    long ref_arr[MAX_REF];
+CD    char ref_status[MAX_REF];
+CD    long ant_ref;
+CD    LC_GRF_STATUS GrfStat;
+CD
+CD    LC_InitGetRefFlate(&GrfStat);
+CD
+CD    ant_ref = LC_GetRefFlate(&GrfStat,GRF_YTRE,ref_arr,ref_status,MAX_REF);
+CD    do {
+CD       if (ant_ref > 0) {
+CD          .
+CD          Behandle ytre avgrensing            
+CD          .
+CD       }
+CD
+CD       [if (ant_ref < MAX_REF)  break;]
+CD
+CD       ant_ref = LC_GetRefFlate(&GrfStat,GRF_YTRE,ref_arr,ref_status,MAX_REF);
+CD    } while (ant_ref > 0);
+CD
+CD    LC_InitGetRefFlate(&GrfStat);
+CD    ant_ref = LC_GetRefFlate(&GrfStat,GRF_INDRE,ref_arr,ref_status,MAX_REF);
+CD    do {
+CD       if (ant_ref > 0) {
+CD          .
+CD          Behandle indre avgrensing (�y)
+CD          .
+CD       }
+CD
+CD       [if (ant_ref < MAX_REF)  break;]
+CD
+CD       ant_ref = LC_GetRefFlate(&GrfStat,GRF_INDRE,ref_arr,ref_status,MAX_REF);
+CD    } while (ant_ref > 0);
+CD
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA long LC_GetRefFlate(LC_GRF_STATUS * GrfStat,unsigned short usHent,long *ref_array,
+                     unsigned char *ref_status,long max_ref)
+{
+   long antall;
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                  /* Aktuell gruppe OK */
+
+      if ((usHent & GRF_YTRE)  &&  GrfStat->usOmkretsFerdig == UT_FALSE) {
+         /* Ytre avgrensning */
+         antall = LX_GetRefOmkrets(&GrfStat->Omkr,ref_array,ref_status,max_ref);
+         if (antall > 0) {
+            return antall;
+         }
+
+         /* Ferdig med behandling av omkretsen */
+         GrfStat->usOmkretsFerdig = UT_TRUE;
+      }
+
+      if (usHent & GRF_INDRE) {
+         /* Indre avgrensning (�y) */
+         return LX_GetRefOy(GrfStat,ref_array,ref_status,max_ref);
+      }
+   }
+
+   return 0;
+}
+
+
+/*
+AR-920930
+CH LX_GetRefOmkrets                            Hent referanser for omkretsen
+CD ==========================================================================
+CD Form�l:
+CD Henter ut et array med referanser for omkretsen av flate.
+CD ant_ref == 0 eller ant_ref < max_ref viser at hele omkretsen er behandla.
+CD
+CD Parametre:
+CD Type            Navn       I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GR_STATUS   *pGRS       iu   Struktur med statusopplysninger.
+CD long           *ref_array   u    GRUPPENUMMER for refererte grupper.
+CD unsigned char  *ref_status  u    Status for gruppene i ref_array.
+CD                                  LC_MED_DIG = Brukes MED dig retning
+CD                                  LC_MOT_DIG  = Brukes MOT dig retning
+CD long            max_ref     i    Max antall linjer i ref_array.
+CD short           ant_ref     r    Antall linjer brukt i ref_array.
+CD
+CD Bruk:
+CD     ant_ref = LX_GetRefOmkrets(&OmkrStat,ref_array,ref_status,max_ref);
+CD ==========================================================================
+*/
+static long LX_GetRefOmkrets(LC_GR_STATUS *pGRS,long *ref_array,
+                              unsigned char *ref_status,long max_ref)
+{
+   char *gp,ginfo[LC_MAX_SOSI_LINJE_LEN];
+   long snr,grnr;
+   long ant_ref = 0;
+
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                  /* Aktuell gruppe OK */
+                                        /* Finn referanser */
+      while (pGRS->sGiLinNr <= Sys.pGrInfo->ngi) {
+         gp = LX_GetGi(pGRS->sGiLinNr);
+         
+         /* Handter referanselinjer */
+         if ((pGRS->sRefLin = LC_ErLinjeRefLin(gp,pGRS->sRefLin)) == UT_TRUE) {
+            UT_StrCopy(ginfo,gp,LC_MAX_SOSI_LINJE_LEN);
+            gp = ginfo + pGRS->sRefPos;
+            pGRS->sRefPos = 0;
+            while (*gp){                  /* Tolk en linje */
+               if (ant_ref < max_ref) {
+                  if (*gp == ':') {                              /* Tall */
+                     ++gp;
+                     /* Husk retning */
+                     if (*gp == '-') {
+                        *ref_status++ = LC_MOT_DIG;
+                        ++gp;
+                     } else {
+                        *ref_status++ = LC_MED_DIG;
+                     }
+                     /* Hent serienummer og konverter til gruppenummer */
+                     if (isdigit(*gp)) {
+                        snr = strtol(gp,&gp,10);
+                        /* Konverter til gruppenummer */
+                        if ((grnr = LI_GetSnr(Sys.GrId.pFil,snr)) != INGEN_GRUPPE) {
+                           *ref_array++ = grnr;
+                           ++ant_ref;
+
+                        } else {
+                           UT_FPRINTF(stderr,"Snr. %ld er referert i \"%s : %s\", finnes ikke!\n",snr,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+                           Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+                           ref_status--;
+                        }
+
+                     } else {
+                        UT_FPRINTF(stderr,"Ulovlig referanse \"%s\" i \"%s : %s\"\n",ginfo,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+                        Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+                        ref_status--;
+                     }
+
+                  } else if (*gp == '(') {  /* Start �y, ferdig med omkretsen */
+                     pGRS->sRefPos = (short)(gp - ginfo);
+                     return  ant_ref;
+
+                  } else {                                    /* Ukjent tegn */
+                     ++gp;
+                  }
+
+               } else {                                /* Tabellen er full */
+                  pGRS->sRefPos = (short)(gp - ginfo);
+                  return  ant_ref;
+               }
+            }
+         }
+         pGRS->sGiLinNr++;
+      }
+   }
+   return (ant_ref);
+}
+
+
+/*
+AR-920930
+CH LX_GetRefOy                                      Hent referanser for �yer
+CD ==========================================================================
+CD Form�l:
+CD Henter ut et array med referanser for omkretsen av �y.
+CD ant_ref == 0 eller ant_ref < max_ref viser at hele omkretsen er behandla.
+CD
+CD Parametre:
+CD Type            Navn       I/U  Forklaring
+CD -------------------------------------------------------------------------
+CD LC_GRF_STATUS *  pGS        iu  Struktur med statusopplysninger.
+CD long           *ref_array   u   GRUPPENUMMER for refererte grupper.
+CD unsigned char  *ref_status  u   Status for gruppene i ref_array.
+CD                                  LC_MED_DIG = Brukes MED dig retning
+CD                                  LC_MOT_DIG  = Brukes MOT dig retning
+CD                                  GRF_START_OY     = F�rste gruppe i �y
+CD                                  GRF_SLUTT_OY     = Siste gruppe i �y
+CD long            max_ref     i   Max antall linjer i ref_array.
+CD short           ant_ref     r   Antall linjer brukt i ref_array.
+CD
+CD Bruk:
+CD     ant_ref = LX_GetRefOy(&GS,ref_array,ref_status,max_ref);
+CD ==========================================================================
+*/
+static long LX_GetRefOy(LC_GRF_STATUS * pGS,long *ref_array,
+                         unsigned char *ref_status,long max_ref)
+{
+   short ngi;
+   long nko;
+   unsigned short info;
+   char *gp,ginfo[LC_MAX_SOSI_LINJE_LEN];
+   long snr,grnr,antall;
+   unsigned char ucRetning;
+   LC_BGR Bgr,GmlBgr;
+   long ant_ref = 0;
+
+
+   Bgr.pFil = Sys.GrId.pFil;
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                  /* Aktuell gruppe OK */
+      /* Husk aktuell gruppe */
+      GmlBgr = Sys.GrId;
+      
+      /* Les inn resten av p�begynnt refferert flate */
+      if (pGS->Bgr.lNr != INGEN_GRUPPE) {
+         LC_RxGr(&(pGS->Bgr),LES_OPTIMALT,&ngi,&nko,&info);
+
+         ant_ref = LX_GetRefOmkrets(&(pGS->Oy),ref_array,ref_status,max_ref);
+         ref_array  += ant_ref;
+         ref_status += ant_ref;
+
+         /* Les inn igjen aktuell gruppe */
+         LC_RxGr(&GmlBgr,LES_OPTIMALT,&ngi,&nko,&info);
+
+         if (ant_ref < max_ref) {
+            pGS->Bgr.pFil = NULL;
+            pGS->Bgr.lNr  = INGEN_GRUPPE;
+         }
+      }
+
+      /* Finn referanser */
+      while (pGS->Omkr.sGiLinNr <= Sys.pGrInfo->ngi) {
+         gp = LX_GetGi(pGS->Omkr.sGiLinNr);
+         
+         /* Handter referanselinjer */
+         if ((pGS->Omkr.sRefLin = LC_ErLinjeRefLin(gp,pGS->Omkr.sRefLin)) == UT_TRUE) {
+            UT_StrCopy(ginfo,gp,LC_MAX_SOSI_LINJE_LEN);
+            gp = ginfo + pGS->Omkr.sRefPos;
+            pGS->Omkr.sRefPos = 0;
+            while (*gp) {                  /* Tolk en linje */
+               if (ant_ref < max_ref) {
+                  if (*gp == ':') {                              /* Tall */
+                     ++gp;
+                     /* Husk retning */
+                     if (*gp == '-') {
+                        ucRetning = LC_MOT_DIG;
+                        ++gp;
+                     } else {
+                        ucRetning = LC_MED_DIG;
+                     }
+                     /* Hent serienummer og konverter til gruppenummer */
+                     if (isdigit(*gp)) {
+                        snr = strtol(gp,&gp,10);
+                        /* Konverter til gruppenummer */
+                        if ((grnr = LI_GetSnr(Sys.GrId.pFil,snr)) != INGEN_GRUPPE) {
+                           Bgr.lNr = grnr;
+                           /* Referanse til flate, pakk ut denne */
+                           if (LC_GetGrParaBgr(&Bgr,&ngi,&nko,&info)
+                                                               == L_FLATE) {
+                              LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+
+                              pGS->Oy.sGiLinNr = 2;
+                              pGS->Oy.sRefPos = 0;
+                              pGS->Oy.sRefLin = UT_FALSE;
+
+                              antall = LX_GetRefOmkrets(&(pGS->Oy),ref_array,
+                                             ref_status,max_ref-ant_ref);
+                              ref_array  += antall;
+                              ref_status += antall;
+                              ant_ref += antall;
+
+                              /* Les inn igjen aktuell gruppe */
+                              LC_RxGr(&GmlBgr,LES_OPTIMALT,&ngi,&nko,&info);
+
+                              if (ant_ref >= max_ref) {
+                                 pGS->Bgr = Bgr;
+                              } else {
+                                 pGS->Bgr.pFil = NULL;
+                                 pGS->Bgr.lNr  = INGEN_GRUPPE;
+                              }
+
+                           } else {
+                              *ref_status++ = ucRetning;
+                              *ref_array++ = grnr;
+                              ++ant_ref;
+                           }
+
+                        } else {
+                           UT_FPRINTF(stderr,"Snr. %ld er referert i \"%s : %s\", finnes ikke!\n",snr,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+                           Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+                        }
+
+                     } else {
+                        UT_FPRINTF(stderr,"Ulovlig referanse \"%s\" i \"%s : %s\"\n",ginfo,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+                        Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+                     }
+
+                  } else if (*gp == '(') {                     /* Start �y */
+                     *ref_array++ = INGEN_GRUPPE;
+                     *ref_status++ = GRF_START_OY;
+                     ++ant_ref;
+                     ++gp;
+
+                  } else if (*gp == ')') {                     /* Slutt �y */
+                     *ref_array++ = INGEN_GRUPPE;
+                     *ref_status++ = GRF_SLUTT_OY;
+                     ++ant_ref;
+                     ++gp;
+
+                  } else {                                  /* Ukjent tegn */
+                     ++gp;
+                  }
+
+               } else {                                /* Tabellen er full */
+                  pGS->Omkr.sRefPos = (short)(gp - ginfo);
+                  return  ant_ref;                /* ==> Retur */
+               }
+            }
+         }
+         pGS->Omkr.sGiLinNr++;
+      }
+   }
+
+   return  ant_ref;
+}
+
+
+/*
+AR-921012
+CH LC_InqAntRef                                   Sp�rr om antall referanser
+CD ==========================================================================
+CD Form�l:
+CD Sp�rr om antall referanser i GINFO i aktuell gruppe.
+CD Dette kallet kan brukes til � finne hvor stor array som m� allokeres f�r
+CD kall til LC_GetRef.
+CD
+CD Parametre:
+CD Type     Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long    ant_ref     r    Antall referanser i GINFO.
+CD                            OBS! Start- og sluttparantes for �y blir regnet
+CD                            som egne referanser.
+CD
+CD Bruk:
+CD     long lAntRef;
+CD     short sGiLin,sRefPos;
+CD     long *plRefArray;
+CD
+CD     lAntRef = LC_InqAntRef();
+CD     plRefArray = (long *) UT_MALLOC(lAntRef * sizeof(long));
+CD     sGiLin = 2;
+CD     sRefPos = 0;
+CD     LC_GetRef(plRefArray,lAntRef,&sGiLin,&sRefPos);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA long LC_InqAntRef(void)
+{
+   char *gp,ginfo[LC_MAX_SOSI_LINJE_LEN];
+   long lAntRef = 0;
+   short gilin = 2;
+   short sRefLin = UT_FALSE;   /* Viser om aktuel linje inneholder referanser */
+
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                /* Aktuell gruppe OK */
+                                        /* Finn referanser */
+      while (gilin <= Sys.pGrInfo->ngi){
+         gp = LX_GetGi(gilin);
+         
+         /* Handter referanselinjer */
+         if ((sRefLin = LC_ErLinjeRefLin(gp,sRefLin)) == UT_TRUE) {
+            UT_StrCopy(ginfo,gp,LC_MAX_SOSI_LINJE_LEN);
+            gp = ginfo;
+            while (*gp) {                  /* Tolk en linje */
+               if (*gp == ':') {                        /* Tall */
+                  ++gp;
+                  if (isdigit(*gp) || *gp == '-') {
+                     while (*gp  &&  (!UT_IsSpace(*gp)) &&  *gp != ')') {
+                        ++gp;
+                     }
+                     ++lAntRef;
+                  } else {
+                     UT_FPRINTF(stderr,"Ulovlig referanse \"%s\" i gruppe \"%s : %s\"\n",ginfo,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+                     Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+                  }
+
+               } else if (*gp == '('  ||  *gp == ')') { /* Start og slutt �y */
+                  ++lAntRef;
+                  ++gp;
+
+               } else {                                    /* Ukjent tegn */
+                  ++gp;
+               }
+            }
+         }
+         ++gilin;
+      }
+   }
+   return  lAntRef;
+}
+
+
+/*
+AR-900213
+OJ-900213
+CH LC_GetRef                                        Hent referanser fra GINFO
+CD ==========================================================================
+CD Form�l:
+CD Henter ut et array med referanser fra GINFO i aktuell gruppe.
+CD
+CD Parametre:
+CD Type     Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long    *ref_array  u    Serienr. for refererte grupper.
+CD                          Start �y, og slutt �y angis ved fiktive gruppenr.
+CD                          F�lgende konstanter er definert:
+CD                             START_OY =  9999999L = Start �y.
+CD                             SLUTT_OY = -9999999L = Slutt �y.
+CD long     max_ref    i    Max antall linjer i ref_array.
+CD short   *gilin      i/u  linje for start referanselesing
+CD short   *refpos     i/u  posisjon i linja for neste innlegging i array.
+CD long     ant_ref    r    Antall linjer brukt i ref_array.
+CD
+CD Bruk:
+CD     ant_ref = LC_GetRef(ref_array,max_ref,&gilin,&refpos);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA long LC_GetRef(long *ref_array,long max_ref,short *gilin,short *refpos)
+{
+   char *gp,ginfo[LC_MAX_SOSI_LINJE_LEN];
+   long ant_ref = 0;
+   short sRefLin = UT_FALSE;   /* Viser om aktuel linje inneholder referanser */
+
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE){                  /* Aktuell gruppe OK */
+                                        /* Finn referanser */
+      while (*gilin <= Sys.pGrInfo->ngi){
+         gp = LX_GetGi(*gilin);
+         
+         /* Handter referanselinjer */
+         if ((sRefLin = LC_ErLinjeRefLin(gp,sRefLin)) == UT_TRUE) {
+            UT_StrCopy(ginfo,gp,LC_MAX_SOSI_LINJE_LEN);
+            gp = ginfo + *refpos;
+            *refpos = 0;
+            while (*gp){                  /* Tolk en linje */
+               if (ant_ref < max_ref){
+                  if (*gp == ':'){                              /* Tall */
+                     ++gp;
+                     if (isdigit(*gp) || *gp == '-') {
+                        *ref_array++ = strtol(gp,&gp,10);
+                        ++ant_ref;
+                     } else {
+                        UT_FPRINTF(stderr,"Ulovlig referanse \"%s\" i gruppe \"%s : %s\"\n",ginfo,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+                        Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+                     }
+
+                  } else if (*gp == '('){                       /* Start �y */
+                     *ref_array++ = START_OY;
+                     ++ant_ref;
+                     ++gp;
+                  } else if (*gp == ')'){                       /* Slutt �y */
+                     *ref_array++ = SLUTT_OY;
+                     ++ant_ref;
+                     ++gp;
+                  } else{                                    /* Ukjent tegn */
+                     ++gp;
+                  }
+               } else{                                 /* Tabellen er full */
+                  *refpos = (short)(gp - ginfo);
+                  return (ant_ref);
+               }
+            }
+         }
+         (*gilin)++;
+      }
+   }
+   return (ant_ref);
+}
+
+
+/*
+OJ-901016
+AR-930930
+CH LC_PutRef                                    Legger inn referanser i GINFO
+CD ==========================================================================
+CD Form�l:
+CD Legger inn et array med referanser til GINFO i aktuell gruppe.
+CD
+CD Parametre:
+CD Type     Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long     ref_array  i    Gruppenummer for refererte grupper.
+CD                          Start �y, og slutt �y angis ved fiktive gruppenr.
+CD                          F�lgende konstanter er definert:
+CD                             START_OY =  9999999L = Start �y.
+CD                             SLUTT_OY = -9999999L = Slutt �y.
+CD long     ant_ref    i    Antall linjer i ref_array.
+CD short    *ngi       r    Antall linjer GINFO
+CD
+CD Bruk:
+CD     ngi = LC_PutRef(ref_array,ant_ref);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_PutRef(long *ref_array,long ant_ref)
+{
+   #define MAX_LEN  66   /* Ginfolinjen skrives ut n�r den er lengre en 66 tegn */
+   short gilin;
+   long j;
+   char temp[LC_MAX_SOSI_LINJE_LEN],*ginfo,*cp;
+   short ledig_linje = -1;
+
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE){                  /* Aktuell gruppe OK */
+      /* Pakker gammel GINFO */
+      for (gilin=2; gilin <= Sys.pGrInfo->ngi; ++gilin) {
+         ginfo = LX_GetGi(gilin);
+
+         /* Gammel type referanse er funnet */
+         if (strncmp(ginfo,".. ",3) == 0) {
+            if (ledig_linje == -1) {        /* F�rste linje med referanse */
+               ledig_linje = gilin;
+            }
+
+         /* Ny type referanse er funnet */
+         } else if (strncmp(ginfo,"..REF ",6) == 0) {
+            if (ledig_linje == -1) {        /* F�rste linje med referanse */
+               ledig_linje = gilin;
+            }
+            /* S�k over resten av referansene */
+            for (++gilin; gilin <= Sys.pGrInfo->ngi; ++gilin) {
+               ginfo = LX_GetGi(gilin);
+               if (strncmp(ginfo,"..",2) == 0) { /* Annen GINFO er funnet */
+                  gilin--;
+                  break;      /* Avbryt, alle referanser er funnet*/
+               }
+            }
+
+         /* Annen GINFO */
+         } else {
+            if (ledig_linje != -1) {
+                                    /* Funnet linje som skal flyttes opp */
+               LC_PutGi(ledig_linje,ginfo);
+               ++ledig_linje;
+            }
+         }
+      }
+
+      if (ledig_linje == -1)  ledig_linje = Sys.pGrInfo->ngi + 1;
+
+                              /* Legger inn referanser */
+      if (ant_ref > 0) {
+
+         /* Husk at det finnes flate i filen */
+         if ( Sys.GrId.pFil->SosiNiv[1] < 4) {
+            Sys.GrId.pFil->SosiNiv[1] = 4;
+         }
+
+         if (Sys.GrId.pFil->sSosiVer >= 220) {
+            UT_StrCopy(temp,"..REF ",LC_MAX_SOSI_LINJE_LEN);
+            cp = temp + 6;
+         } else {   
+            UT_StrCopy(temp,".. ",LC_MAX_SOSI_LINJE_LEN);
+            cp = temp + 3;
+         }
+
+
+         j=0;
+         while (j < ant_ref) {
+            /* Strengen er full, skriver ut */
+            if (*ref_array != SLUTT_OY  &&  strlen(temp) > MAX_LEN) {
+               if (ledig_linje > Sys.pGrInfo->ngi) {
+                  ledig_linje = LC_AppGiL();
+               }
+               LC_PutGi(ledig_linje,temp);
+               ++ledig_linje;
+
+               if (Sys.GrId.pFil->sSosiVer >= 220) {
+                  *temp = '\0';
+                  cp = temp;
+               } else {   
+                  UT_StrCopy(temp,".. ",LC_MAX_SOSI_LINJE_LEN);
+                  cp = temp + 3;
+               }
+            }
+                                             /* Bygg opp streng */
+            if (*ref_array == START_OY) { 
+               if (! UT_IsSpace(*(cp-1))) {
+                  *cp++ = ' ';
+               }
+               *cp++ = '(';
+               *cp = '\0';
+
+            } else if (*ref_array == SLUTT_OY) {
+               if (*(cp-1) == '.') {
+                  *cp++ = ' ';
+               }
+               *cp++ = ')';
+               *cp = '\0';
+
+            } else {                                /* Referanse */
+               if (! UT_IsSpace(*(cp-1))  &&  *(cp-1) != '(') {
+                  *cp++ = ' ';
+                  *cp = '\0';
+               }
+               char szOrd[50];
+               UT_SNPRINTF(szOrd,50,":%ld",*ref_array);
+               UT_StrCat(temp,szOrd,LC_MAX_SOSI_LINJE_LEN);
+               cp = strchr(temp,'\0');
+            }
+
+            ++j;
+            ++ref_array;
+         }
+
+         if (ledig_linje > Sys.pGrInfo->ngi) {          /* Skriver ut strengen */
+            ledig_linje = LC_AppGiL();
+         }
+         LC_PutGi(ledig_linje,temp);
+         ++ledig_linje;
+
+      } else {
+         Sys.pGrInfo->info &= ~((unsigned short)GI_REF);
+         Sys.pGrInfo->info &= ~((unsigned short)GI_OY_REF);
+      }
+
+      /* Sletter 1. ledige og resten */
+      LC_DelGiL(ledig_linje, (short)(Sys.pGrInfo->ngi - ledig_linje + 1));
+   }
+
+   return Sys.pGrInfo->ngi;
+}
+
+
+/*
+JEK-920918
+CH LC_SirkelTilBuep                        Konverterer en "sirkel" til to BUEP
+CD ============================================================================
+CD Form�l:                                                   fi
+CD Konverterer en SIRKEL/SIRKELP til to BUEP.
+CD Forutsetter at aktuell gruppe er SIRKEL eller SIRKELP.
+CD
+CD Parametre:                                               
+CD Type     Navn        I/U   Forklaring
+CD ----------------------------------------------------------------------------
+CD short    buff_retning i    Buffer-retning (kun for BUE og BUEP)
+CD                                  HENT_FORRFRA  (1) =  Vanlig
+CD                                  HENT_BAKFRA  (-1) =  Buffer skal snues
+CD short    *sfeil       u    Feilstatus, definert dersom ist = 0
+CD                                    1 = Ulovlig geometritype(ikke bue)
+CD                                    2 = Feil ved beregning av bueparametre
+CD short    ist          r    Returstatus
+CD                                    UT_TRUE  = Alt OK
+CD                                    UT_FALSE = Feil, se returvariabel sfeil
+CD
+CD Bruk:
+CD ist = LC_SirkelTilBuep(buff_retning, &as, &ns, &radius, &fi, &dfi, &sfeil )
+   ============================================================================
+*/
+/*
+SK_EntPnt_FYBA short LC_SirkelTilBuep(short antDelingspunkt,double a1,double n1,double h1,double a2,double n2,double h2,
+                                      short *ngi, long *nko, LC_BGR *pNyBgr)
+{
+   double as,ns,da,dn,aNy,nNy,r,fi,dfi,dfi2,fiNy;
+   short gnavn,ngi;
+   long nko;
+   unsigned short info;
+   double fi1,a_ny=0.0,n_ny=0.0;
+   long lGmlSnr,lNyttSnr;
+   short sGiLinje;
+   short sfeil;
+
+
+   if (Sys.pGrInfo->gnavn != L_SIRKEL  &&  Sys.pGrInfo->gnavn != L_SIRKELP)
+      return UT_FALSE;  // ==>  Ikke sirkel
+   
+   lGmlSnr = LC_GetSn();
+   LC_GetBuePar(LC_MED_DIG,&as,&ns,&r,&fi,&dfi,&sfeil);
+
+   LC_PutGi(1,".BUEP");
+
+   sGiLinje = 2;
+   if (LC_GetGP("..RADIUS", &sGiLinje, ngi))  ngi = LC_DelGiL(sGiLinje,1);
+
+   // Sikrer at det er tre koordinater i gruppen
+   if (nko > 3)       nko = LC_DelKoL(4,nko-3);
+   else if (nko < 3)  nko = LC_InsKoL(nko+1,3-nko);
+
+   // Hvis det er bare ett nytt punkt deles sirkelen i to halvsirkler
+   if (antDelingspunkt == 1)
+   {
+      // Beregner et nytt "fiktivt" punkt p� motsatt side av sirkelen   
+      da = a1 - as;
+      dn = n1 - ns;
+      a2 = as - da;
+      n2 = ns - dn;
+      h2 = HOYDE_MANGLER;
+
+   }
+   else if (antDelingspunkt != 2)
+   {
+      // Ikke gitt noe delingspunkt
+      if (Sys.pGrInfo->gnavn == L_SIRKEL)
+      {
+         a1 = as - r;
+         n1 = n2 = ns;
+         a2 = as + r;
+         h1 = h2 = LC_GetTH(1);
+      }
+      else  // L_SIRKELP
+      {
+         LC_GetTK(1,&a1,&n1);
+         h1 = LC_GetTH(1);
+
+
+      }
+
+      a1 = as - r;
+      n1 = n2 = ns;
+      a2 = as + r;
+      h1 = h2 = HOYDE_MANGLER;
+   }
+
+   LC_PutTK(1,a1,n1);
+   LC_PutKp(1,kpdiv.kpnr);
+   if (AntPkt > 1)  LC_PutTH(1,h1);
+   GH_DrawMarks(pGA,1,&a1,&n1,FALSE);
+
+   LC_PutTK(3,a2,n2);
+   LC_PutKp(3,kpdiv.kpnr);
+   if (AntPkt > 1) {
+      LC_PutTH(3,h2);
+      GH_DrawMarks(pGA,1,&a2,&n2,FALSE);
+   }
+
+   // �pningsvinkel for buen fra P1 til P2
+   fi1 = GM_retning(as,ns,a1,n1);
+   GM_PktBue(as,ns,fi1,dfi,a2,n2,&dfi2);
+
+   // Beregner et nytt punkt midt p� buen fra P1 til P2
+   fiNy = fi1 + (dfi2 / 2.0);
+   aNy = as + fabs(r)*cos(fiNy);
+   nNy = ns + fabs(r)*sin(fiNy);
+
+   // OBS! B�r legge inn sjekk mot at punktet faller sammen med noen av de andre punktene
+
+   LC_PutTK(2,aNy,nNy);
+   if (AntPkt > 1) {
+      if (h1 != HOYDE_MANGLER  &&  h2 != HOYDE_MANGLER)  LC_PutTH(2,(h1+h2)/2.0);
+   }
+
+   LC_WxGr(SKRIV_OPTIMALT);
+
+   // ----- Oppretter og tilpasser den andre delen
+   LC_NyGr(pBgr->pFil,".BUEP",&cur.bgr,&lNyttSnr);
+   gnavn = LC_CopyGr(pBgr,OPPDATER_NGIS,&ngi,&nko,&info);
+
+   LC_PutTK(1,a2,n2);
+   LC_PutKp(1,kpdiv.kpnr);
+   if (AntPkt > 1) LC_PutTH(1,h1);
+
+   LC_PutTK(3,a1,n1);
+   LC_PutKp(3,kpdiv.kpnr);
+   if (AntPkt > 1) LC_PutTH(3,h2);
+
+   // Beregner et nytt punkt p� motsatt side av sirkelen av midtpunktet i den andre halvparten av sirkelen  
+   da = aNy - as;
+   dn = nNy - ns;
+   aNy = as - da;
+   nNy = ns - dn;
+
+   LC_PutTK(2,aNy,nNy);
+   if (AntPkt > 1) {
+      if (h1 != HOYDE_MANGLER  &&  h2 != HOYDE_MANGLER)  LC_PutTH(2,(h1+h2)/2.0);
+   }
+
+   LC_WxGr(SKRIV_OPTIMALT);
+
+   cur.gnavn = LC_RxGr(&cur.bgr,LES_OPTIMALT,&cur.ngi,&cur.nko,&cur.info);
+   TegnGruppe(pGA,T_KOMFIL,VIS_FARGE,1,cur.nko);
+
+   if (Utvalg.bPaa) LC_SetBt(&cur.bgr,UTVALG_1);
+   LC_SetBt(&cur.bgr,TMP_TOT_SK);
+   LC_SetBt(&cur.bgr,TOT_SK);
+   LC_SetBt(&cur.bgr,KLADD1);
+
+   OppdaterReferanser(pBgr->pFil,a1,n1,lGmlSnr,lNyttSnr);
+
+   return UT_TRUE;
+}
+*/
+
+
+
+/*
+JEK-920918
+CH LC_GetBuePar                    Beregner parametre som definerer sirkelbue
+CD ============================================================================
+CD Form�l:                                                   fi
+CD Sirkelbue defineres i SOSI ved en av                     /
+CD geometrielementene .SIRKEL, .SIRKELP,                  /
+CD .BUE, .BUEP.                                         /       \
+CD Denne rutina regner om til en intern        as, ns * -radius- )  dfi
+CD bueangivelse med sirkelsentrum, radius               \       /
+CD og retning til buens startpunkt samt                   \
+CD delta for sluttpunktet uansett hvordan                   \
+CD buen er definert i SOSI.
+CD
+CD NB! Alle retninger i radianer, 0-retning i �st-aksen og positiv
+CD oml�psretning mot urviseren.
+CD
+CD Parametre:                                               
+CD Type     Navn        I/U   Forklaring
+CD ----------------------------------------------------------------------------
+CD short    buff_retning i    Buffer-retning (kun for BUE og BUEP)
+CD                                  HENT_FORRFRA  (1) =  Vanlig
+CD                                  HENT_BAKFRA  (-1) =  Buffer skal snues
+CD double   *as          u    �st-koordinat sentrum sirkelbue
+CD double   *an          u    Nord-koordinat sentrum sirkelbue
+CD double   *radius      u    Radius i sirkelbue.
+CD double   *fi          u    Retningsvinkel sentrum -> startpunkt bue
+CD double   *dfi         u    Vinkel mellom fi og sentrum -> sluttpunkt bue
+CD                            dfi > 0  = Positiv oml�psretning(mot klokka)
+CD                            dfi < 0  = Negativ oml�psretning(med klokka)
+CD short    *sfeil       u    Feilstatus, definert dersom ist = 0
+CD                                    1 = Ulovlig geometritype(ikke bue)
+CD                                    2 = Feil ved beregning av bueparametre
+CD short    ist          r    Returstatus
+CD                                    UT_TRUE  = Alt OK
+CD                                    UT_FALSE = Feil, se returvariabel sfeil
+CD
+CD Bruk:
+CD ist = LC_GetBuePar(buff_retning, &as, &ns, &radius, &fi, &dfi, &sfeil )
+   ============================================================================
+*/
+SK_EntPnt_FYBA short LC_GetBuePar(short buff_retning, double *as, double *ns, double *radius,
+                   double *fi, double *dfi, short *sfeil)
+{
+   short ist;
+   short storbue;
+   double a,n,a2,n2,a3,n3;
+
+
+   *sfeil = 0;
+   ist = UT_FALSE;
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {              /* Aktuell gruppe OK */
+      /* ----- Sjekker geometritype og henter parametre for buen */
+
+      if (Sys.pGrInfo->gnavn == L_BUE) {                 /* .BUE */
+         if (LC_GetBue(buff_retning,&a,&n,&a2,&n2,&(*radius),&storbue)){
+            if (GM_KonvBue(a,n,a2,n2,*radius,storbue,&(*as),&(*ns),&(*fi),&(*dfi))){
+               ist = UT_TRUE;
+            } else {
+               *sfeil=2;
+               UT_FPRINTF(stderr,"Ulovlig bue: \"%s : %s\" - mer enn 2*radius mellom endepunktene\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+               Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_BUE;
+            }
+         }
+
+      } else if (Sys.pGrInfo->gnavn == L_BUEP) {         /* .BUEP */
+         if (LC_GetBuep(buff_retning,&a,&n,&a2,&n2,&a3,&n3)) {
+            if (GM_KonvBuep(a,n,a2,n2,a3,n3,&(*as),&(*ns),&(*radius),&(*fi),&(*dfi))){
+               ist = UT_TRUE;
+            } else {
+               *sfeil = 2;
+               UT_FPRINTF(stderr,"Ulovlig bue: \"%s : %s\" - punktene ligger p� rett linje\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+               Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_BUE;
+            }
+         }
+
+      } else if (Sys.pGrInfo->gnavn == L_SIRKEL) {       /* .SIRKEL */
+         if (LC_GetSirkel(&(*as),&(*ns),&(*radius))) {
+            if(GM_KonvSirkel(&(*fi),&(*dfi))) {
+               ist = UT_TRUE;
+            } else {
+               *sfeil = 2;
+               UT_FPRINTF(stderr,"Ulovlig bue: \"%s : %s\"\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+               Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_BUE;
+            }
+         }
+
+      } else if (Sys.pGrInfo->gnavn == L_SIRKELP) {      /* .SIRKELP */
+         if (LC_GetSirkelp(&a,&n,&a2,&n2,&a3,&n3)) {
+            if (GM_KonvSirkelp(a,n,a2,n2,a3,n3,&(*as),&(*ns),&(*radius),&(*fi),&(*dfi))){
+               ist = UT_TRUE;
+            } else {
+               *sfeil = 2;
+               UT_FPRINTF(stderr,"Ulovlig bue: \"%s : %s\"\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+               Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_BUE;
+            }
+         }
+
+      } else {             /* Feil geometritype */
+         *sfeil = 1;
+      }
+
+      if (ist == UT_TRUE) {
+         *radius = fabs(*radius);
+      }
+
+   } else {             /* Feil geometritype (ingen aktuell gruppe) */
+      *sfeil = 1;
+   }
+
+   return ist;
+}
+
+
+/*
+AR-890824
+CH LC_GetBue                                                        Hent bue
+CD ==========================================================================
+CD Form�l:
+CD Henter ut n�dvendige opplysninger om en bue.
+CD
+CD Parametre:
+CD Type     Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD short   retning     i    Buffer-retning:
+CD                                HENT_FORRFRA ( 1) = vanlig,
+CD                                HENT_BAKFRA  (-1) = buffer skal snues.
+CD double  *a1         u    Koordinat i f�rste punkt
+CD double  *n1         u
+CD double  *a2         u    Koordinat i siste punkt
+CD double  *n2         u
+CD double  *radius     u    Radius
+CD short   *storbue    u    0=vanlig bue, 1=storbue
+CD short    ist        r    status: UT_TRUE = OK,
+CD                                  UT_FALSE = feil (Gruppen er ikke OK bue)
+CD
+CD Bruk:
+CD     ist = LC_GetBue(retning,&a1,&n1,&a2,&n2,&radius,&storbue);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetBue(short retning,double *a1,double *n1,double *a2,double *n2,
+                double *radius,short *storbue)
+{
+   short gilin;
+   char *gp;
+   short ist = UT_FALSE;
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                  /* Aktuell gruppe OK */
+      if (Sys.pGrInfo->gnavn == L_BUE  &&  Sys.pGrInfo->nko > 1) {
+                                         /* Hent koordinater */
+         if (retning == HENT_FORRFRA) {
+            LC_GetTK(1,a1,n1);
+            LC_GetTK(Sys.pGrInfo->nko,a2,n2);
+         } else {
+            LC_GetTK(Sys.pGrInfo->nko,a1,n1);
+            LC_GetTK(1,a2,n2);
+         }
+
+                                           /* Finn radius og storbue */
+         gilin = 2;
+         if ((gp = LC_GetGP("..RADIUS",&gilin,Sys.pGrInfo->ngi)) != NULL) {
+            *radius = strtod(gp,&gp);
+            if (retning == HENT_BAKFRA)  *radius = - *radius;
+            gilin = 2;
+            if ((gp = LC_GetGP("..STORBUE",&gilin,Sys.pGrInfo->ngi)) != NULL) {
+               *storbue = (short)strtol(gp,&gp,10);
+            } else {
+               *storbue = 0;
+            }
+            ist = UT_TRUE;          /* Buen er OK */
+
+         } else {
+            UT_FPRINTF(stderr,"Ulovlig bue: \"%s : %s\" - mangler ..RADIUS\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+            Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_BUE;
+         }
+
+      } else {
+         UT_FPRINTF(stderr,"Ulovlig bue: \"%s : %s\" - for f� koordinater\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+         Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_BUE;
+      }                              
+   }
+
+   return ist;
+}
+
+
+/*
+AR-911029
+CH LC_GetBuep                                                      Hent buep
+CD ==========================================================================
+CD Form�l:
+CD Henter ut n�dvendige opplysninger om en buep.
+CD
+CD Parametre:
+CD Type     Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD short   retning     i    Buffer-retning:
+CD                                HENT_FORRFRA ( 1) = vanlig,
+CD                                HENT_BAKFRA  (-1) = buffer skal snues.
+CD double  *a1         u    Koordinat i f�rste punkt
+CD double  *n1         u
+CD double  *a2         u    Koordinat i midtre punkt
+CD double  *n2         u
+CD double  *a3         u    Koordinat i siste punkt
+CD double  *n3         u
+CD short    ist        r    status: UT_TRUE = OK,
+CD                                  UT_FALSE = feil (Gruppen er ikke OK buep)
+CD
+CD Bruk:
+CD     ist = LC_GetBuep(retning,&a1,&n1,&a2,&n2,&a3,&n3);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetBuep(short retning,double *a1,double *n1,double *a2,double *n2,
+                 double *a3,double *n3)
+{
+   short ist = UT_FALSE;
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                  /* Aktuell gruppe OK */
+      if (Sys.pGrInfo->gnavn == L_BUEP  &&  Sys.pGrInfo->nko > 2) {
+                                         /* Hent koordinater */
+         LC_GetTK((1+Sys.pGrInfo->nko)/2, a2, n2);
+         if (retning == HENT_FORRFRA) {
+            LC_GetTK(1,a1,n1);
+            LC_GetTK(Sys.pGrInfo->nko,a3,n3);
+         } else {
+            LC_GetTK(1,a3,n3);
+            LC_GetTK(Sys.pGrInfo->nko,a1,n1);
+         }
+
+         ist = UT_TRUE;          /* Buen er OK */
+
+      } else {
+         UT_FPRINTF(stderr,"Ulovlig bue: \"%s : %s\" - for f� koordinater\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+         Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_BUE;
+      }                              
+   }
+
+   return ist;
+}
+
+
+/*
+AR-911029
+CH LC_GetSirkel                                                  Hent silkel
+CD ==========================================================================
+CD Form�l:
+CD Henter ut n�dvendige opplysninger om en sirkel.
+CD
+CD Parametre:
+CD Type     Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double  *as         u    Koordinat i sentrum
+CD double  *ns         u
+CD double  *radius     u    Radius
+CD short    ist        r    status: UT_TRUE = OK,
+CD                                  UT_FALSE = Feil (Gruppen er ikke OK sirkel)
+CD
+CD Bruk:
+CD     ist = LC_GetSirkel(&as,&ns,&radius);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetSirkel(double *as,double *ns,double *radius)
+{
+   short gilin;
+   char *gp;
+   short ist = UT_FALSE;
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                  /* Aktuell gruppe OK */
+      if (Sys.pGrInfo->gnavn == L_SIRKEL  &&  Sys.pGrInfo->nko > 0) {
+                                         /* Hent koordinater */
+         LC_GetTK(1,as,ns);
+
+         /* Finn radius */
+         gilin = 2;
+         if ((gp = LC_GetGP("..RADIUS",&gilin,Sys.pGrInfo->ngi)) != NULL) {
+            *radius = strtod(gp,&gp);
+            ist = UT_TRUE;          /* Sirkelen er OK */
+
+         } else {
+            UT_FPRINTF(stderr,"Ulovlig bue: \"%s : %s\" - mangler ..RADIUS\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+            Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_BUE;
+         }
+
+      } else {
+         UT_FPRINTF(stderr,"Ulovlig bue: \"%s : %s\" - mangler koordinat\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+         Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_BUE;
+      }
+   }
+
+   return ist;
+}
+
+
+/*
+AR-911029
+CH LC_GetSirkelp                                               Hent silkelp
+CD ==========================================================================
+CD Form�l:
+CD Henter ut n�dvendige opplysninger om en sirkelp.
+CD
+CD Parametre:
+CD Type     Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double  *a1         u    Koordinat i P1
+CD double  *n1         u
+CD double  *a2         u    Koordinat i P2
+CD double  *n2         u
+CD double  *a3         u    Koordinat i P3
+CD double  *n3         u
+CD short    ist        r    status: UT_TRUE = OK,
+CD                                  UT_FALSE = Feil (Gruppen er ikke OK sirkelp)
+CD
+CD Bruk:
+CD     ist = LC_GetSirkelp(&a1,&n1,&a2,&n2,&a3,&n3);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetSirkelp(double *a1,double *n1,double *a2,double *n2,
+                double *a3,double *n3)
+{
+   short ist = UT_FALSE;
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                  /* Aktuell gruppe OK */
+      if (Sys.pGrInfo->gnavn == L_SIRKELP  &&  Sys.pGrInfo->nko > 2) {
+                                         /* Hent koordinater */
+         LC_GetTK(1,a1,n1);
+         LC_GetTK((1+Sys.pGrInfo->nko)/2, a2, n2);
+         LC_GetTK(Sys.pGrInfo->nko,a3,n3);
+
+         ist = UT_TRUE;          /* Buen er OK */
+
+      } else {
+         UT_FPRINTF(stderr,"Ulovlig bue: \"%s : %s\" - for f� koordinater\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+         Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_BUE;
+      }                              
+   }
+
+   return ist;
+}
+
+
+/*
+OJ-891126
+CH LC_GetCurEnhet                                  Hent enhet p� angitt niv�
+CD ==========================================================================
+CD Form�l:
+CD Henter ut enhet fra filhode eller GINFO
+CD
+CD Parametre:
+CD Type        Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM * pFil     i    Peker til FilAdm
+CD short      *nivaa    iu   angir niv� for henting, returnerer aktuelt niv�
+CD                             1 = filhode
+CD                             2 = GINFO
+CD double     *enhet    u    Aktuell enhet
+CD double     *enhet_h  u    Aktuell enhet-H
+CD double     *enhet_d  u    Aktuell enhet-D
+CD
+CD Bruk:
+CD     LC_GetCurEnhet(pFil,&nivaa,&enhet,&enhet_h,&enhet_d);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_GetCurEnhet(LC_FILADM * pFil,short *nivaa, double *enhet,
+                    double *enhet_h, double *enhet_d)
+{
+   LO_TestFilpeker(pFil,"GetCurEnhet");
+
+   *enhet = pFil->TransPar.dEnhet;
+   *enhet_h = pFil->TransPar.dEnhet_h;
+   *enhet_d = pFil->TransPar.dEnhet_d;
+
+   /* Enhet fra GINFO */
+   if (*nivaa == 2)
+   {
+      short lin = 2;
+      char *para;
+      double enhet_temp;
+
+      para = LC_GetGP("..ENHET",&lin,Sys.pGrInfo->ngi);
+      if (para == NULL) {
+         *nivaa = 1;
+      } else {
+         UT_AtoD(para,'.',&enhet_temp);
+         if (enhet_temp > LC_ACCY)  *enhet = enhet_temp;
+      }
+ 
+      lin=2;
+      para = LC_GetGP("...ENHET-H",&lin,Sys.pGrInfo->ngi);
+      if (para != NULL) {
+         UT_AtoD(para,'.',&enhet_temp);
+         if (enhet_temp > LC_ACCY)  *enhet_h = enhet_temp;
+      }
+
+      lin=2;
+      para = LC_GetGP("...ENHET-D",&lin,Sys.pGrInfo->ngi);
+      if (para != NULL) {
+         UT_AtoD(para,'.',&enhet_temp);
+         if (enhet_temp > LC_ACCY)  *enhet_d = enhet_temp;
+      }
+   }
+}
+
+
+/*
+AR-890515
+CH LC_UpdateGiEnhet                                  Oppdater ..ENHET i GINFO
+CD ==========================================================================
+CD Form�l:
+CD Setter koordinat-enhet for gruppen.
+CD Oppdaterer ..ENHET / ..ENHET-H / ..ENHET-D i GINFO.
+CD Rutinen handterer selv tildeling eller sletting av GINFO-linje.
+CD Hvis verdien er lik filhodets verdi blir det ikke lagt inn verdi i GINFO.
+CD Enhet = 0.0 = bruk filhodets enhet, og f�rer til at det ikke legges inn
+CD i GINFO. Eventuell eksisterende linje jgernes.
+CD
+CD Parametre:
+CD Type        Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM * pFil     i    Peker til FilAdm
+CD double      enhet    i    Grunnriss-enhet
+CD double      enhet_h  i    H�yde-enhet
+CD double      enhet_d  i    Dybde-enhet
+CD ngi         short    r    Antall GINFO-linjer etter oppdatering
+CD
+CD Bruk:
+CD ngi = LC_UpdateGiEnhet(pFil,enhet,enhet_h,enhet_d);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_UpdateGiEnhet(LC_FILADM *pFil,double enhet,double enhet_h,double enhet_d)
+{
+   short linje;
+   char tx[80];
+
+   LO_TestFilpeker(pFil,"UpdateGiEnhet");
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                  /* Aktuell gruppe OK */
+
+      // ----- ..ENHET
+      linje = 2;
+
+       // Ikke spesiell ..ENHET
+       if (fabs(enhet - pFil->TransPar.dEnhet) < LC_ACCY  ||  fabs(enhet) < LC_ACCY)
+       {
+          if (LC_GetGP("..ENHET",&linje,Sys.pGrInfo->ngi) != NULL)
+          {
+             LC_DelGiL(linje,1);                 /* Funnet, fjern linjen */
+          }
+       }
+
+       // Spesiell ..ENHET
+       else
+       {
+          if (LC_GetGP("..ENHET",&linje,Sys.pGrInfo->ngi) == NULL)
+          {
+             linje = LC_AppGiL();         /* Ikke funnet, tildel ny linje */
+          }
+          LC_PutGi(linje,LB_FormaterEnhet(tx,80,"..ENHET",enhet));
+       }
+
+       // ----- ..ENHET-H
+       linje = 2;
+
+       // Ikke spesiell ..ENHET-H
+       if (fabs(enhet_h - pFil->TransPar.dEnhet_h) < LC_ACCY  ||  fabs(enhet_h) < LC_ACCY)
+       {
+          if (LC_GetGP("..ENHET-H",&linje,Sys.pGrInfo->ngi) != NULL)
+          {
+             LC_DelGiL(linje,1);                 /* Funnet, fjern linjen */
+          }
+       }
+
+       // Spesiell ..ENHET-H
+       else
+       {
+          if (LC_GetGP("..ENHET-H",&linje,Sys.pGrInfo->ngi) == NULL)
+          {
+             linje = LC_AppGiL();         /* Ikke funnet, tildel ny linje */
+          }
+          LC_PutGi(linje,LB_FormaterEnhet(tx,80,"..ENHET-H",enhet_h));
+       }
+
+       // ----- ..ENHET-D
+       linje = 2;
+
+       // Ikke spesiell ..ENHET-D
+       if (fabs(enhet_d - pFil->TransPar.dEnhet_d) < LC_ACCY  ||  fabs(enhet_d) < LC_ACCY)
+       {
+          if (LC_GetGP("..ENHET-D",&linje,Sys.pGrInfo->ngi) != NULL)
+          {
+             LC_DelGiL(linje,1);                 /* Funnet, fjern linjen */
+          }
+       }
+
+       // Spesiell ..ENHET-D
+       else
+       {
+          if (LC_GetGP("..ENHET-D",&linje,Sys.pGrInfo->ngi) == NULL)
+          {
+             linje = LC_AppGiL();         /* Ikke funnet, tildel ny linje */
+          }
+          LC_PutGi(linje,LB_FormaterEnhet(tx,80,"..ENHET-D",enhet_d));
+       }
+   }
+
+   return Sys.pGrInfo->ngi;
+}
+
+
+/*
+OJ-891123
+CH LC_GetKvalitet                               Finner kvalitetsopplysninger
+CD ==========================================================================
+CD Form�l:
+CD Finne kvalitetsopplysninger i filhode eller vanlig gruppe.
+CD (Tolker aktuell gruppe.)
+CD
+CD Parametre:
+CD Type     Navn       I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD short  *psMetode           u  Hvordan data er registrert.
+CD                                 KVAL_MET_UNDEF  metode er udefinert.
+CD                                 KVAL_MET_STD    standard metode fra niv� over.
+CD long   *pLNnoyaktighet     u  Registreringsn�yaktighet
+CD                                 KVAL_NOY_UKJENT n�yaktighet er ukjent.
+CD                                 KVAL_NOY_STD    standard n�yaktighet fra niv� over
+CD short  *psSynbarhet        u  Synbarhet i bilde
+CD                                 KVAL_SYN_UNDEF  synbarhet er udefinert.
+CD                                 KVAL_SYN_STD    standard metode fra niv� over.
+CD short  *psHoydeMetode      u  Hvordan h�yden er registrert.
+CD                                 KVAL_MET_UNDEF  metode er udefinert.
+CD                                 KVAL_MET_STD    standard metode fra niv� over.
+CD long   *plHoydeNoyaktighet u  Registreringsn�yaktighet
+CD                                 KVAL_NOY_UKJENT n�yaktighet er ukjent.
+CD                                 KVAL_NOY_STD    standard n�yaktighet fra niv� over
+CD short    ist               r  Status: UT_TRUE  = OK, ..KVALITET er funnet
+CD                                       UT_FALSE = ikke funnet
+CD
+CD Bruk:
+CD      ist = LC_GetKvalitet(&sMetode,&lNoyaktighet,&sSynbarhet,
+CD                           &sHoydeMetode,&lHoydeNoyaktighet);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetKvalitet(short *psMetode,long *plNoyaktighet,short *psSynbarhet,
+                     short *psHoydeMetode,long *plHoydeNoyaktighet)
+{
+   short lin;
+   char *cp;
+   short ist = UT_FALSE;
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {            /* Aktuell gruppe OK */
+       lin=2;
+       /* S�k i GINFO */
+       if ((cp = LC_GetGP("..KVALITET",&lin,Sys.pGrInfo->ngi)) != NULL) {
+           ist = UT_TRUE;
+       }
+
+       LN_TolkKvalitet(cp,psMetode,plNoyaktighet,psSynbarhet,
+                       psHoydeMetode,plHoydeNoyaktighet);
+   }
+
+   return ist;
+}
+
+
+/*
+OJ-900103
+CH LC_GetCurKvalitet             Finner kvalitetsopplysninger p� angitt niv�
+CD ==========================================================================
+CD Form�l:
+CD Finne kvalitetsopplysninger p� angitt niv�, hode ginfo eller pinfo.
+CD
+CD Parametre:
+CD Type        Navn          I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM * pFil           i   Peker til FilAdm
+CD short      *nivaa         iu   Hvor skal det letes.
+CD                                 0 = ikke funnet
+CD                                 1 = hode
+CD                                 2 = ginfo
+CD                                 3 = pinfo
+CD                                 Returnerer aktuelt niv�.
+CD long        pnr            i    punktnr. ved sp�rring p� pinfo
+CD short  *psMetode           u   Hvordan data er registrert.
+CD                                 KVAL_MET_UNDEF  metode er udefinert.
+CD long   *pLNnoyaktighet     u   Registreringsn�yaktighet
+CD                                 KVAL_NOY_UKJENT n�yaktighet er ukjent.
+CD short  *psSynbarhet        u   Synbarhet i bilde
+CD                                 KVAL_SYN_UNDEF  synbarhet er udefinert.
+CD short  *psHoydeMetode      u   Hvordan h�yden er registrert.
+CD                                 KVAL_MET_UNDEF  metode er udefinert.
+CD long   *plHoydeNoyaktighet u   Registreringsn�yaktighet
+CD                                 KVAL_NOY_UKJENT n�yaktighet er ukjent.
+CD short   ist                r   Statusvariabel:
+CD                                 UT_TRUE = OK, KVALITET er funnet
+CD                                 UT_FALSE = KVALITET er ikke funnet
+CD
+CD Bruk:
+CD  ist = LC_GetCurKvalitet(pFil,&nivaa,pnr,&sMetode,&lNoyaktighet,
+CD                          &sSynbarhet,&sHoydeMetode,&lHoydeNoyaktighet);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetCurKvalitet(LC_FILADM *pFil,short *nivaa,long pnr,
+                        short *psMetode,long *plNoyaktighet,short *psSynbarhet,
+                        short *psHoydeMetode,long *plHoydeNoyaktighet)
+{
+   short lin;
+   char *cp;
+   short sMetode, sHoydeMetode, sSynbarhet;
+   long lNoyaktighet, lHoydeNoyaktighet;
+   LC_GETPP_STATUS  pp_stat;
+   short sFunnetNivaa = 0;
+
+   short sStatus = UT_FALSE;
+
+   LO_TestFilpeker(pFil,"GetCurKvalitet");
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {         /* Aktuell gruppe OK */
+
+      *psMetode           = KVAL_MET_STD;
+      *plNoyaktighet      = KVAL_NOY_STD;
+      *psSynbarhet        = KVAL_SYN_STD;
+      *psHoydeMetode      = KVAL_MET_STD;
+      *plHoydeNoyaktighet = KVAL_NOY_STD;
+
+
+      /* S�k i PINFO */
+      if (*nivaa == 3) {
+         LC_InitPP("...KVALITET",pnr,pnr,&pp_stat);
+         if ((cp = LC_GetPP(&pnr,&pp_stat)) != NULL) {
+            LN_TolkKvalitet(cp,psMetode,plNoyaktighet,psSynbarhet,
+                            psHoydeMetode,plHoydeNoyaktighet);
+            sStatus = UT_TRUE;
+            sFunnetNivaa = 3;
+         }
+      }
+
+      /* S�k i GINFO */
+      if (*nivaa >= 2) {
+         lin=2;
+         if ((cp = LC_GetGP("..KVALITET",&lin,Sys.pGrInfo->ngi)) != NULL){       /* Kvalitet */
+            LN_TolkKvalitet(cp,&sMetode,&lNoyaktighet,&sSynbarhet,
+                            &sHoydeMetode,&lHoydeNoyaktighet);
+
+            /* Oppdater med kvalitet fra GINFO */
+            if (*psMetode == KVAL_MET_STD)  *psMetode = sMetode;
+            if (*plNoyaktighet == KVAL_NOY_STD)  *plNoyaktighet = lNoyaktighet;
+            if (*psSynbarhet == KVAL_SYN_STD)  *psSynbarhet = sSynbarhet;
+            if (*psHoydeMetode == KVAL_MET_STD)  *psHoydeMetode = sHoydeMetode;
+            if (*plHoydeNoyaktighet == KVAL_NOY_STD)  *plHoydeNoyaktighet = lHoydeNoyaktighet;
+
+            sStatus = UT_TRUE;
+            if (sFunnetNivaa == 0)  sFunnetNivaa = 2;
+         }
+      }
+
+      /* Hent fra hodet */
+      /* Oppdater med kvalitet fra HODE */
+      if (*psMetode == KVAL_MET_STD)  *psMetode = pFil->Kvalitet.sMetode;
+      if (*plNoyaktighet == KVAL_NOY_STD)  *plNoyaktighet = pFil->Kvalitet.lNoyaktighet;
+      if (*psSynbarhet == KVAL_SYN_STD)  *psSynbarhet = pFil->Kvalitet.sSynbarhet;
+      if (*psHoydeMetode == KVAL_MET_STD)  *psHoydeMetode = pFil->Kvalitet.sHoydeMetode;
+      if (*plHoydeNoyaktighet == KVAL_NOY_STD)  *plHoydeNoyaktighet = pFil->Kvalitet.lHoydeNoyaktighet;
+
+      /* Handter eventuell standardverdi */
+      if (*psMetode == KVAL_MET_STD)  *psMetode = KVAL_MET_UNDEF;
+      if (*plNoyaktighet == KVAL_NOY_STD)  *plNoyaktighet = KVAL_NOY_UKJENT;
+      if (*psSynbarhet == KVAL_SYN_STD)  *psSynbarhet = KVAL_SYN_GOD;
+      if (*psHoydeMetode == KVAL_MET_STD)  *psHoydeMetode = KVAL_MET_UNDEF;
+      if (*plHoydeNoyaktighet == KVAL_NOY_STD)  *plHoydeNoyaktighet = KVAL_NOY_UKJENT;
+
+      if (*psMetode           != KVAL_MET_UNDEF  ||
+          *plNoyaktighet      != KVAL_NOY_UKJENT ||
+          *psSynbarhet        != KVAL_SYN_GOD    ||
+          *psHoydeMetode      != KVAL_MET_UNDEF  ||
+          *plHoydeNoyaktighet != KVAL_NOY_UKJENT ) {
+
+          sStatus = UT_TRUE;
+         if (sFunnetNivaa == 0)  sFunnetNivaa = 1;
+      }
+   }  
+
+   *nivaa = sFunnetNivaa;
+
+   return sStatus;
+}
+
+
+/*
+CH OJ-891205
+CH LC_UpdateGiKvalitet                         Oppdaterer ..KVALITET i Ginfo
+CD ==========================================================================
+CD Form�l:
+CD Oppdaterer GINFO med ..KVALITET
+CD
+CD Parametre:
+CD Type       Navn            I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD Parametre:
+CD LC_FILADM *pFil              i  Peker til FilAdm for sosifil kvalitet skal
+CD                                 testes mot.
+CD short      sMetode           i  Metode i ..KVALITET
+CD long       lNoyaktighet      i  N�yaktighet i ..KVALITET
+CD short      sSynbarhet        i  Synbarhet i ..KVALITET
+CD short      sHoydeMetode      i  H�ydeMetode i ..KVALITET
+CD long       lHoydeNoyaktighet i  H�ydeN�yaktighet i ..KVALITET
+CD short      ngi               r  Antall linjer i ginfo.
+CD
+CD Bruk:
+CD      ngi = LC_UpdateGiKvalitet(pFil,sMetode,lNoyaktighet,sSynbarhet,
+CD                                sHoydeMetode,lHoydeNoyaktighet);
+CD
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_UpdateGiKvalitet(LC_FILADM *pFil,short sMetode,long lNoyaktighet,
+                          short sSynbarhet,short sHoydeMetode,long lHoydeNoyaktighet)
+{
+   // Endret slik at ..KVALITET blir skrevet ut til gruppen bare hvis den er
+   // forskjellig fra kvalitet i filhodet.
+   // Fjerner aldri eksisterende kvalitet fra GINFO.
+
+   short ho_metode,ho_hmetode,ho_synbarhet;
+   long  ho_noyaktighet,ho_hnoyaktighet;
+   short linje_nr,nivaa;
+   short pnr = 1;
+   short ngi = Sys.pGrInfo->ngi;
+
+
+   LO_TestFilpeker(pFil,"UpdateGiKvalitet");
+
+   // Hent kvalitet fra hode
+   nivaa = 1;
+   LC_GetCurKvalitet(pFil,&nivaa,pnr,&ho_metode,&ho_noyaktighet,
+                     &ho_synbarhet,&ho_hmetode,&ho_hnoyaktighet);
+
+   // Hvis ulik kvalitet i gruppen og filhodet
+   if ((sMetode != ho_metode) ||
+       (lNoyaktighet != ho_noyaktighet) ||
+       (sSynbarhet != ho_synbarhet) ||
+       (sHoydeMetode != ho_hmetode) ||
+       (lHoydeNoyaktighet != ho_hnoyaktighet))
+   {
+      // Formatterer strengen og oppdater GINFO
+      ngi = LC_PutGP("..KVALITET",
+                     LC_FormatterKvalitet(sMetode,lNoyaktighet,sSynbarhet,
+                                          sHoydeMetode,lHoydeNoyaktighet),&linje_nr);
+   }
+
+   //else
+   //{
+   //   // Samme kvalitet som i filhodet, fjern eventuell GI-linje
+   //   linje_nr = 2;
+   //   if (LC_GetGP("..KVALITET",&linje_nr,ngi) != NULL) {
+   //      ngi = LC_DelGiL(linje_nr,1);
+   //   }
+   //}
+
+   return Sys.pGrInfo->ngi;
+}
+
+
+/*
+OJ-891208
+AR-920312
+CH LC_UpdatePiKvalitet                        Oppdaterer ...KVALITET i Pinfo
+CD ==========================================================================
+CD Form�l:
+CD Oppdaterer PINFO med ...KVALITET
+CD
+CD Parametre:
+CD Type        Navn             I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM * pFil              i  Peker til FilAdm for sosifil kvalitet
+CD                                  skal testes mot.
+CD long        pnr               i  Punktnummer som skal oppdateres.
+CD short       sMetode           i  Metode i ..KVALITET
+CD long        lNoyaktighet      i  N�yaktighet i ..KVALITET
+CD short       sSynbarhet        i  Synbarhet i ..KVALITET
+CD short       sHoydeMetode      i  H�ydeMetode i ..KVALITET
+CD long        lHoydeNoyaktighet i  H�ydeN�yaktighet i ..KVALITET
+CD short       sStatus           r  UT_TRUE = OK,
+CD                                  UT_FALSE = ikke utf�rt (for lite plass tilgjengelig)
+CD
+CD Bruk:
+CD sStatus = LC_UpdatePiKvalitet(pFil,pnr,sMetode,lNoyaktighet,sSynbarhet,
+CD                               sHoydeMetode,lHoydeNoyaktighet)
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_UpdatePiKvalitet(LC_FILADM *pFil,long pnr,short sMetode,long lNoyaktighet,
+                          short sSynbarhet,short sHoydeMetode,long lHoydeNoyaktighet)
+{
+   char  temp[LC_MAX_SOSI_LINJE_LEN],*pp,*neste,*cp;
+   short nivaa;
+   short gi_metode,gi_hmetode,gi_synbarhet;
+   long  gi_noyaktighet,gi_hnoyaktighet;
+
+   LO_TestFilpeker(pFil,"UpdatePiKvalitet");
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {            /* Aktuell gruppe OK */
+
+      /* Fjern eksisterende KVALITET fra PINFO */
+      pp = LC_GetPi(pnr);
+      if ((neste = strstr(pp,"...KVALITET")) != NULL) {    /* Finn SOSI-navnet */
+         cp = neste - 1;                    /* Avslutt f�rste del av pinfo */
+         while (UT_IsSpace(*cp) && cp >= pp) {
+            cp--;
+         }
+         *(cp+1) = '\0';
+         UT_StrCopy(temp,pp,LC_MAX_SOSI_LINJE_LEN);
+
+         /* Hopp over KVALITETen */
+         if ((cp = strstr(neste+3,"...")) != NULL) {   /* Neste SOSI-navn */
+            /* Heng p� resten av den gamle PINFOen */
+            if (*temp)  UT_StrCat(temp," ",LC_MAX_SOSI_LINJE_LEN);
+            UT_StrCat(temp,cp,LC_MAX_SOSI_LINJE_LEN);
+         }
+
+      /* KVALITET er ikke funnet, ta vare p� hele strengen */
+      } else {
+         UT_StrCopy(temp,pp,LC_MAX_SOSI_LINJE_LEN);
+      }
+
+      /* Hent kvalitet fra ginfo/hode */
+      nivaa = 2;
+      LC_GetCurKvalitet(pFil,&nivaa,pnr,&gi_metode,&gi_noyaktighet,
+                        &gi_synbarhet,&gi_hmetode,&gi_hnoyaktighet);
+
+      /* Hvis Kvaliteten avviker fra ginfo/hode, heng den p� PINFO */                                          /* Legg inn endringen */
+      if (sMetode != gi_metode  ||
+          lNoyaktighet != gi_noyaktighet  ||
+          sSynbarhet != gi_synbarhet  ||
+          sHoydeMetode != gi_hmetode  ||
+          lHoydeNoyaktighet != gi_hnoyaktighet ) {
+
+         if (*temp)  UT_StrCat(temp," ",LC_MAX_SOSI_LINJE_LEN);
+         UT_StrCat(temp,"...KVALITET ",LC_MAX_SOSI_LINJE_LEN);
+         UT_StrCat(temp,LC_FormatterKvalitet(sMetode,lNoyaktighet,sSynbarhet,sHoydeMetode,lHoydeNoyaktighet),
+                   LC_MAX_SOSI_LINJE_LEN);
+      }
+
+      if(strlen(temp) > LC_MAX_SOSI_LINJE_LEN) {
+         LC_Error(131,"(LC_UpdatePiKvalitet)",temp);
+      }
+
+      /* Lagre strengen */
+      return LC_PutPi(pnr,temp);
+   }
+
+   return UT_FALSE;
+}
+
+
+/*
+AR-930609
+CH LC_GetGP                                               Get GINFO-parameter
+CD ==========================================================================
+CD Form�l:
+CD Henter parametrene til et SOSI-navn.
+CD Strengen ligger i et felles "returbuffer" for alle get-rutiner i fyba.
+CD Dette blir �delagt ved neste kall til en "get-rutine". For � ta vare p�
+CD strengen m� den kopieres over til egen streng. (Bruk UT_StrCopy).
+CD
+CD Leddnummer, delstreng,skilletegn og formateringskode kan inng� som
+CD forlengelse av SOSI-navnet.
+CD
+CD Leddnummer for flerleddet parameter angis ved #n.
+CD Eks: ..GID#2 er bruksnummer.
+CD
+CD Delstreng angis ved: [start:slutt].
+CD NB! 1 er f�rste tegn.
+CD Sluttposisjon 0 betyr at resten av strengen skal brukes.      
+CD Eks: ..STRENG[2:0]  Posisjon 2 og resten av strengen.
+CD
+CD Skilletegn for flerleddet GINFO. Dette angis ved ^x hvor x er det tegnet
+CD som skal skrives ut mellom leddene.
+CD
+CD Formateringskode. Dette brukes for � angi plassering av komma og antall
+CD desimaler i desimaltall.
+CD Eks: ..AREAL%-3.2    Betyr at ..AREAL fra GINFO skal formateres slik:
+CD Komma flyttes 3 posisjoner til venstre (divisjon med tusen) og resultatet
+CD presenteres avrundet til 2 desimaler.
+CD
+CD Eks: ..DYBDE�-1.2    Betyr at ..DYBDE fra GINFO skal formateres slik:
+CD Komma flyttes 1 posisjon til venstre (divisjon med ti) og resultatet
+CD presenteres med 2 desimaler uten avrunding. Spesielt for dybdeverdier.
+CD
+CD Disse tilleggene kan kombineres, slik at  ..GID#2[1:2] betyr at det er
+CD tegn nummer 1 og 2 i det andre leddet (bruksnumret) som skal brukes.
+CD
+CD
+CD Parametre:
+CD Type     Navn        I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD char     sosi_navn    i    SOSI-navn det skal finnes verdi til.
+CD                            Leddnummer, posisjon, skilletegn
+CD                            og formateringskode kan inng�
+CD                            som forlengelse av navnet.
+CD                            OBS! Store og sm� bokstaver er signifikante.
+CD
+CD short   *forste_linje iu   GINFO-linjenummer for start s�king
+CD                            (1 er f�rste linje i GINFO.)
+CD                            Ved tilslag returneres linjenummer for tilslaget.
+CD short    siste_linje  i    Siste GINFO-linje det skal s�kes i.
+CD char    *para_peker   r    Peker til parameter-streng avslutta med '\0'.
+CD                            Hvis SOSI-navnet ikke er funnet returneres NULL.
+CD
+CD Bruk:
+CD para_peker = LC_GetGP(sosi_navn,&forste_linje,siste_linje);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA char *LC_GetGP(const char *sosi_navn,short *forste_linje,short siste_linje)
+{
+   short gi_lin,sAntallBlank,sSosiLen,sFortegn,s;
+   char *ginfo,*cp,*nt,*cs,szSosiNavn[LC_MAX_SOSINAVN_LEN];
+   double d;
+   char cSkilleTegn = '\0';
+   short sLedd = 0;
+   short sStart = 0;
+   short sSlutt = 0;
+   short funnet = 0;
+   short sFormater = UT_FALSE;
+   short sFlyttKomma = 0; /* Flytting av komma ( <0 flytt til venstre) */
+   short sAntDes = 2;     /* Antall desimaler */
+
+   char *rp = NULL;          /* Retur peker */
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                /* Aktuell gruppe OK */
+      /* Sjekk at det er lovlige linjenummer */
+      if (*forste_linje < 1)        *forste_linje = 1;
+      if (siste_linje > Sys.pGrInfo->ngi)  siste_linje   = Sys.pGrInfo->ngi;
+
+      /* Plukk ut info om ledd, delstreng og formatering */
+      UT_StrCopy(szSosiNavn,sosi_navn,LC_MAX_SOSINAVN_LEN);
+      UT_StrUpper(szSosiNavn);
+
+      if ((cs = strpbrk(szSosiNavn,"#[^%�")) != NULL) {
+         cp = cs;
+         while (*cp != '\0') {
+            if (*cp == '#') {
+               ++cp;
+               sLedd = (short) strtol(cp,&cp,10);       /* Ledd-nummer */
+            } else if (*cp == '^') {
+               ++cp;
+               cSkilleTegn = *cp;                       /* Skilletegn */
+               ++cp;
+            } else if (*cp == '[') {
+               ++cp;
+               sStart = (short) strtol(cp,&cp,10);      /* Startposisjon */
+               ++cp;
+               sSlutt = (short) strtol(cp,&cp,10);      /* Sluttposisjon */
+            } else if ((*cp == '%') || (*cp == '�')) {
+               if(*cp == '�')
+                  sFormater = 2;
+               else
+                  sFormater = UT_TRUE;
+               ++cp;
+               if (*cp == '-') {
+                  sFortegn = -1;
+                  ++cp;
+               } else {
+                  sFortegn = 1;
+               }
+               if (isdigit(*cp)) sFlyttKomma = (short) strtol(cp,&cp,10); /* Flytting av komma */
+               sFlyttKomma *= sFortegn;                
+               if (*cp == '.')  ++cp;
+               if (isdigit(*cp)) sAntDes = (short) strtol(cp,&cp,10); /* Ant. des */
+            } else {
+               ++cp;
+            }
+         }
+         /* Fjern tilleggsinfo fra SOSI-navnet */
+         *cs = '\0';
+      }
+
+      /* S�k etter SOSI-navnet */
+      sSosiLen = (short)strlen(szSosiNavn);
+      gi_lin = *forste_linje;
+      while (gi_lin <= siste_linje) {
+         /* Les ny linje */
+         ginfo = LX_GetGi(gi_lin);
+
+         /* Er dette rett navn? */
+         if ((strncmp(ginfo,szSosiNavn,sSosiLen) == 0) &&
+             ( (UT_IsSpace(*(ginfo+sSosiLen))  ||  *(ginfo+sSosiLen) == '\0'))) {
+
+            /* Hopp over blanke mellom navn og verdi */
+            cp = ginfo + sSosiLen;
+            while (UT_IsSpace(*cp)) {
+               ++cp;
+            }
+            // Kopier parameter
+            UT_StrCopy(retur_str,cp,LC_MAX_SOSI_LINJE_LEN);
+            rp = retur_str;
+
+            // Har ikke ledd , funnet OK
+            if (sLedd == 0) {
+
+               
+               //Fjerner hermetegn " eller ' foran
+               while (*rp == '"' || *rp == '\'')
+                  ++rp;
+
+               //Finner enden av strengen
+               cp = strchr(rp+1,'\0');
+
+               //G�r framover fra enden og fjerner anf�rselstegn
+               while (cp-- && (*cp == '"' || *cp == '\'') && cp != NULL)
+                  *cp = '\0';
+
+               funnet = 1;
+               // Husk linjenummeret
+               *forste_linje = gi_lin;
+               break;           // Funnet, ==> hopp ut av l�kken
+
+            // Handter leddnummer
+            } else {
+               s = sLedd;
+               cs = rp+strlen(rp); // Markerer slutten av parameterstrengen
+               while(s > 0) {
+                  if(s-- == sLedd) {  // F�rste ledd leses
+                     cp = UT_strtok(rp," ",&nt);
+                  }
+                  else {            // Neste ledd leses
+                     cp = UT_strtok(NULL," ",&nt);
+                  }
+                  if (cp != NULL) {
+                     // Test p� hermetegn
+                     if (*cp == '"') {
+                        if((cp+strlen(cp)) != cs)  { // Dersom ikke slutten av parameterstrengen
+                           *(cp+strlen(cp)) = ' ';  // Setter tilbake space for NULL
+                        }
+                        rp = cp+1;              // Unng�r start-hermetegnet
+                        cp = UT_strtok(rp,"\"",&nt);   // Leser til slutt-hermetegnet eller \0
+                     }  
+                     else if (*cp == '\'') {
+                        if((cp+strlen(cp)) != cs)  { // Dersom ikke slutten av parameterstrengen
+                           *(cp+strlen(cp)) = ' ';  // Setter tilbake space for NULL
+                        }
+                        rp = cp+1;              // Unng�r start-hermetegnet
+                        cp = UT_strtok(rp,"'",&nt);    // Leser til slutt-hermetegnet eller \0
+                     }
+                  }
+                  else { // cp == NULL
+                     break;
+                  }
+               }
+
+               /* Leddet er funnet */
+               if (cp != NULL) {
+                  /* Aktuelt ledd huskes */
+                  rp = cp;
+                  funnet = 1;
+                  /* Husk linjenummeret */
+                  *forste_linje = gi_lin;
+                  break;           /* Funnet, ==> hopp ut av l�kken */
+               
+               } else {
+                                    /* AR-950901 */
+                  /* rp = NULL; */  /* Det aktuelle leddet finnes ikke */
+                  /* Aktuellt ledd huskes */
+                  rp = strchr(rp,'\0');
+                  funnet = 1;
+                  /* Husk linjenummeret */
+                  *forste_linje = gi_lin;
+                  break;           /* Funnet, ==> hopp ut av l�kken */
+               }
+            }
+         }
+
+         ++gi_lin;
+      }
+
+      /* Spesialnavn */
+      if ( ! funnet  &&  (*szSosiNavn != '.'  &&  ((*forste_linje <= siste_linje) || (siste_linje == 1)))) {
+         /* Handter AREAL spesielt*/
+         if (strcmp(szSosiNavn,"AREAL") == 0) {
+            d = LC_BerAreal();
+            d *= pow((double)10.0,(int)sFlyttKomma);
+            UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%.*f",sAntDes,d);
+            *forste_linje = siste_linje + 1;
+            rp = retur_str;
+            sFormater = UT_FALSE;     /* Formatering er utf�rt */
+
+         /* Handter LENGDE spesielt */
+         } else if (strcmp(szSosiNavn,"LENGDE") == 0) {
+            if ( ! LC_BerLengde3D(&d)){
+               d = LC_BerLengde();
+            }
+            d *= pow((double)10.0,(int)sFlyttKomma);
+            UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%.*f",sAntDes,d);
+            *forste_linje = siste_linje + 1;
+            rp = retur_str;
+            sFormater = UT_FALSE;     /* Formatering er utf�rt */
+            
+         /* Handter LENGDE_HORISONTAL spesielt */
+         } else if (strcmp(szSosiNavn,"LENGDE_HORISONTAL") == 0) {
+            d = LC_BerLengde();
+            d *= pow((double)10.0,(int)sFlyttKomma);
+            UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%.*f",sAntDes,d);
+            *forste_linje = siste_linje + 1;
+            rp = retur_str;
+            sFormater = UT_FALSE;     /* Formatering er utf�rt */
+
+         /* Handter LENGDE_AVGRENS spesielt */
+         } else if (strcmp(szSosiNavn,"LENGDE_AVGRENS") == 0) {
+            d = LC_BerAvgrensLengde();
+            d *= pow((double)10.0,(int)sFlyttKomma);
+            UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%.*f",sAntDes,d);
+            *forste_linje = siste_linje + 1;
+            rp = retur_str;
+            sFormater = UT_FALSE;     /* Formatering er utf�rt */
+
+         /* Handter LENGDE_YTRE_AVGRENS spesielt */
+         } else if (strcmp(szSosiNavn,"LENGDE_YTRE_AVGRENS") == 0) {
+            d = LC_BerYtreAvgrensLengde();
+            d *= pow((double)10.0,(int)sFlyttKomma);
+            UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%.*f",sAntDes,d);
+            *forste_linje = siste_linje + 1;
+            rp = retur_str;
+            sFormater = UT_FALSE;     /* Formatering er utf�rt */
+
+         /* Handter LENGDE_INDRE_AVGRENS spesielt */
+         } else if (strcmp(szSosiNavn,"LENGDE_INDRE_AVGRENS") == 0) {
+            d = LC_BerIndreAvgrensLengde();
+            d *= pow((double)10.0,(int)sFlyttKomma);
+            UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%.*f",sAntDes,d);
+            *forste_linje = siste_linje + 1;
+            rp = retur_str;
+            sFormater = UT_FALSE;     /* Formatering er utf�rt */
+
+         /* Handter SNR spesielt */
+         } else if (strcmp(szSosiNavn,"SNR") == 0) {
+            UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%ld",LC_GetSn());
+            *forste_linje = siste_linje + 1;
+            rp = retur_str;
+
+         /* Handter NPT spesielt */
+         } else if (strcmp(szSosiNavn,"NPT") == 0) {
+            UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%ld", Sys.pGrInfo->nko);
+            *forste_linje = siste_linje + 1;
+            rp = retur_str;
+
+         // Handter REF_FRA spesielt (referert fra antall grupper)
+         } else if (strcmp(szSosiNavn,"REF_FRA") == 0) {
+            UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%ld", LC_ErReferertFraAntall());
+            rp = retur_str;
+
+         // Handter NPT_REF spesielt antall punkt referert
+         } else if (strcmp(szSosiNavn,"NPT_REF") == 0) {
+
+            if(Sys.pGrInfo->info & GI_REF)
+            {                
+               // Gruppen har referanser
+               short ngi;
+               long nko;
+               unsigned short info;
+               LC_POLYGON Polygon;
+               LC_POL_ELEMENT * pPE;
+               LC_OY_ELEMENT * pOE;
+               long lSumNko = 0;
+
+               LC_POL_InitPolygon(&Polygon);
+               LC_POL_GetRef(&Polygon);
+
+               // Ytre avgrensning
+               for(pPE = Polygon.HovedPO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+                  LC_GetGrParaBgr(&pPE->Bgr,&ngi,&nko,&info);
+                  lSumNko += nko;
+               }
+
+               // Indre avgrensning
+               for (pOE = Polygon.OyOA.pForsteOE; pOE != NULL; pOE = pOE->pNesteOE) {
+                for (pPE = pOE->PO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+                   LC_GetGrParaBgr(&pPE->Bgr,&ngi,&nko,&info);
+                   lSumNko += nko;
+                }
+               }
+
+               // Frigi allokerte kjeder
+               LC_POL_FrigiPolygon(&Polygon);
+
+               //Lag returstrengen
+               UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%ld", lSumNko);
+            }
+
+            else
+            {
+               // Har ikke referanser
+               UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%hd", 0);
+            }
+
+            *forste_linje = siste_linje + 1;
+            rp = retur_str;
+
+
+         /* Handter KVALITET spesielt */
+         } else if (strcmp(szSosiNavn,"KVALITET") == 0) {
+            short sMetode, sSynbarhet, sHoydeMetode;
+            long lNoyaktighet, lHoydeNoyaktighet;
+            short nivaa = 2;
+            /* Funnet kvalitet? */
+            if (LC_GetCurKvalitet(Sys.GrId.pFil,&nivaa,1,
+                                  &sMetode,&lNoyaktighet,&sSynbarhet,
+                                  &sHoydeMetode,&lHoydeNoyaktighet) == UT_TRUE) {
+               /* Formater kvaliteten */
+               UT_StrCopy(retur_str,
+                          LC_FormatterKvalitet(sMetode,lNoyaktighet,sSynbarhet,sHoydeMetode,lHoydeNoyaktighet),
+                          LC_MAX_SOSI_LINJE_LEN);
+               rp = retur_str;
+            }
+            *forste_linje = siste_linje + 1;
+         }
+      }
+
+      /* Har funnet navnet */
+      //if (rp != NULL) {
+      if ((rp != NULL) && (*rp != '\0')) { //22.11.2007 AR/�E Stopper tom variabel som har adresse
+         /* Handter delstreng */
+         if (sStart != 0) {
+            if (sSlutt != 0  &&  sSlutt < (short)strlen(rp)) {
+               *(rp+sSlutt) = '\0';
+            }
+            sStart = min(sStart,((short)strlen(rp)));
+            rp += (sStart-1);
+         }
+
+         /* Handter skilletegn */
+         if (cSkilleTegn != '\0') {
+            /* Skann hele strengen */
+            sAntallBlank = 0;
+            cp = cs = rp;
+            while (*cp) {
+               if (*cp == ' ') {    /* Funnet blank */
+                  if (sAntallBlank == 0) {    /* F�rste i dette mellomrommet */
+                     *(cs++) = cSkilleTegn;
+                  }
+                  ++cp;
+                  ++sAntallBlank;
+
+               }  else {          /* Kopier og pakk strengen */
+                  *(cs++) = *(cp++);
+                  sAntallBlank = 0;
+               }
+            }
+            *cs = '\0';
+         }
+
+         /* Handter formateringskode */
+         if (sFormater == 2) { // Desimaltallet skal ikke avrundes
+            // Fjerner un�dvendige desimaler fra tall for � unng� avrunding
+            cp = rp;
+            short sTeller=-99;
+            while (*cp) {               
+               if (*cp == '.')    // Funnet skilletegn
+                  sTeller = -1;                          
+               if(sTeller>-99)
+                  if(sTeller++==sAntDes) {
+                     *cp = '\0';
+                     break;
+                  }
+               ++cp;
+            }
+         }
+         if (sFormater) {
+            UT_AtoD (rp,'.',&d);
+            d *= pow((double)10.0,(int)sFlyttKomma);
+            UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%.*f",sAntDes,d);
+            rp = retur_str;
+         }
+
+      }
+   }
+
+   return  rp;
+}
+
+
+/*
+AR-920615
+CH LC_GetPiVerdi                                             Get PINFO-verdi
+CD ==========================================================================
+CD Form�l:
+CD Henter parametrene til et SOSI-navn.
+CD Strengen ligger i et felles "returbuffer" for alle get-rutiner i fyba.
+CD Dette blir �delagt ved neste kall til en "get-rutine". For � ta vare p�
+CD strengen m� den kopieres over til egen streng. (Bruk UT_StrCopy).
+CD
+CD Leddnummer, delstreng og formateringskode kan inng� som
+CD forlengelse av SOSI-navnet.
+CD
+CD Leddnummer for flerleddet parameter angis ved #n.
+CD Eks: ...KVALITET#2 er n�yaktighet.
+CD
+CD Delstreng angis ved: [start:slutt].
+CD NB! 1 er f�rste tegn.
+CD Sluttposisjon 0 betyr at resten av strengen skal brukes.
+CD Eks: ..STRENG[2:0]  Posisjon 2 og resten av strengen.
+CD
+CD Formateringskode kan angi skilletegn for flerleddet PINFO. Dette
+CD angis ved ^x hvor x er det tegnet som skal skrives ut mellom leddene.
+CD
+CD Disse tilleggene kan kombineres, slik at  ...KVALITET#2[1:2] betyr at
+CD det er tegn nummer 1 og 2 i det andre leddet (n�yaktigheten) som skal
+CD brukes.
+CD
+CD
+CD Parametre:
+CD Type     Navn        I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD char     pszSosiNavn  i    SOSI-navn det skal finnes verdi til.
+CD                            Leddnummer posisjon og formateringskode kan
+CD                            inng� som forlengelse av navnet.
+CD                            OBS! Store og sm� bokstaver er signifikante.
+CD                            H�YDE er spesialverdi som henter formatert
+CD                            h�yde fra punktet eller GINFO.
+CD                            KVALITET er spesialverdi som henter formatert
+CD                            kvalitet fra punktet, GINFO eller hode.
+CD long     lPnr         i    Punktnummer
+CD short   *sSettNr      iu   PINFO-nummer   (1 er f�rste sett i PINFO.)
+CD                            Ved tilslag returneres settnummer for tilslaget.
+CD char    *pszVerdi     r    Peker til verdien avslutta med '\0'.
+CD                            Hvis SOSI-navnet ikke er funnet returneres NULL.
+CD
+CD Bruk:
+CD pszVerdi = LC_GetPiVerdi(pszSosiNavn,lPnr,&sSettNr);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA char *LC_GetPiVerdi(const char *pszSosiNavn,long lPnr,short *sSettNr)
+{
+   short lin,i,sAntallBlank;
+   char *cp,*cs,*nt,szSosiNavn[LC_MAX_SOSINAVN_LEN];
+   short sAntDes,niv;
+   char format[20];
+   double enhet,enhet_h,enhet_d,h;
+   char cSkilleTegn = '\0';
+   short sLedd = 0;
+   short sStart = 0;
+   short sSlutt = 0;
+   short funnet = UT_FALSE;
+   char *rp = NULL;          /* Retur peker */
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                /* Aktuell gruppe OK */
+      if (lPnr > 0  &&  lPnr <= Sys.pGrInfo->nko) {    /* Lovlig punkt ? */
+         /* Er s�kebuffer oppbygd ? */
+         if (Sys.sPibufStatus != LC_PIBUF_OK  ||  Sys.lPibufPnr != lPnr) {
+            LX_CreatePibuf(lPnr);
+         }
+      
+         if (Sys.sPibufStatus != LC_PIBUF_OK) {
+            UT_SNPRINTF(err().tx,LC_ERR_LEN," \"%s\"  pnr: %ld",LX_GetGi(1),lPnr);
+            LC_Error(55,"(LC_GetPiVerdi)",err().tx);
+            return NULL;
+
+         }  else {
+
+            /* Sjekk at det er lovlige linjenummer */
+            if (*sSettNr < 1) {
+               *sSettNr = 1;
+            }
+            lin = *sSettNr - 1;
+
+            /* Plukk ut info om ledd, delstreng og formatering */
+            UT_StrCopy(szSosiNavn,pszSosiNavn,LC_MAX_SOSINAVN_LEN);
+            if ((cs = strpbrk(szSosiNavn,"#[^")) != NULL) {
+               cp = cs;
+               for (i=0;i<3;++i) {
+                  if (*cp == '#') {
+                     ++cp;
+                     sLedd = (short) strtol(cp,&cp,10);       /* Ledd-nummer */
+                  } else if (*cp == '^') {
+                     ++cp;
+                     cSkilleTegn = *cp;                       /* Skilletegn */
+                     ++cp;
+                  } else if (*cp == '[') {
+                     ++cp;
+                     sStart = (short) strtol(cp,&cp,10);      /* Startposisjon */
+                     ++cp;
+                     sSlutt = (short) strtol(cp,&cp,10);      /* Sluttposisjon */
+                  }	
+               }
+               /* Fjern tilleggsinfo fra SOSI-navnet */
+               *cs = '\0';
+            }
+
+
+                                           /* -------- Vanlig PINFO */
+            /* S�k etter SOSI-navnet */
+            while (lin < Sys.sPibufAntPi) {
+               if (strcmp(Sys.pcPibufNavn[lin],szSosiNavn) == 0) {
+                  funnet = UT_TRUE;
+                  /* Kopier parameter */
+                  UT_StrCopy(retur_str,Sys.pcPibufVerdi[lin],LC_MAX_SOSI_LINJE_LEN);
+                  break;           /* Funnet, ==> hopp ut av l�kken */
+               }
+               ++lin;
+            }
+
+                                             /* -------- Knutepunkt */
+            if (!funnet) {
+               if (lin < (Sys.sPibufAntPi+1)  &&
+                           strcmp(szSosiNavn,"...KP") == 0) {
+                  if ((i = LC_GetKp(lPnr)) != 0) {        /* Funnet KP */
+                     UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%hd",i);
+                     funnet = UT_TRUE;
+                  }
+                  lin = Sys.sPibufAntPi + 1;
+
+                                             /* -------- H�yde */
+               } else if (lin < (Sys.sPibufAntPi+2)  &&
+                          strcmp(szSosiNavn,"H�YDE") == 0) {
+                  if ((h = LC_GetHoyde(lPnr)) != HOYDE_MANGLER) { /* Funnet h�yde */
+
+                     /* Hent enhet og formater h�yden */
+                     niv = 2;
+                     LC_GetCurEnhet(Sys.GrId.pFil,&niv,&enhet,&enhet_h,&enhet_d);
+                     sAntDes = UT_RoundDS(fabs(min(0.0,log10(enhet_h))));
+                     UT_SNPRINTF(format,20,"%%.%dlf",sAntDes);
+                     UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,format,h);
+                     funnet = UT_TRUE;
+                  }
+                  lin = Sys.sPibufAntPi + 2;
+
+                                             /* -------- Kvalitet */
+               } else if (lin < (Sys.sPibufAntPi+3)  &&
+                          strcmp(szSosiNavn,"KVALITET") == 0) {
+                  short sMetode, sSynbarhet, sHoydeMetode;
+                  long lNoyaktighet, lHoydeNoyaktighet;
+                  short nivaa = 3;
+                  /* Funnet kvalitet? */
+                  if (LC_GetCurKvalitet(Sys.GrId.pFil,&nivaa,lPnr,
+                                        &sMetode,&lNoyaktighet,&sSynbarhet,
+                                        &sHoydeMetode,&lHoydeNoyaktighet) == UT_TRUE) {
+                     /* Formater kvaliteten */
+                     UT_StrCopy(retur_str,
+                               LC_FormatterKvalitet(sMetode,lNoyaktighet,sSynbarhet,sHoydeMetode,lHoydeNoyaktighet),
+                               LC_MAX_SOSI_LINJE_LEN);
+                     funnet = UT_TRUE;
+                  }
+                  lin = Sys.sPibufAntPi + 3;
+               }
+            }
+
+            /* Klargj�r for retur */
+            *sSettNr = lin+1;
+            if (funnet) {
+               rp = retur_str;
+
+               /* Handter leddnummer */
+               if (sLedd != 0) {
+                  cp = UT_strtok(rp," ",&nt);
+                  while(cp != NULL  &&  --sLedd > 0){
+                     cp = UT_strtok(NULL," ",&nt);
+                  }
+                  if (cp == NULL) {
+                     *rp = '\0';
+                  } else {
+                     rp = cp;
+                  }
+               }
+
+               /* Handter delstreng */
+               if (sStart != 0) {
+                  if (sSlutt != 0  &&  sSlutt < (short)strlen(rp)) {
+                     *(rp+sSlutt) = '\0';
+                  }
+                  sStart = min(sStart,((short)strlen(rp)));
+                  rp += (sStart-1);
+               }
+
+               /* Handter skilletegn */
+               if (cSkilleTegn != '\0') {
+                  /* Skann hele strengen */
+                  sAntallBlank = 0;
+                  cp = cs = rp;
+                  while (*cp) {
+                     if (*cp == ' ') {    /* Funnet blank */
+                        if (sAntallBlank == 0) {    /* F�rste i dette mellomrommet */
+                           *(cs++) = cSkilleTegn;
+                        }
+                        ++cp;
+                        ++sAntallBlank;
+
+                     }  else {          /* Kopier og pakk strengen */
+                        *(cs++) = *(cp++);
+                        sAntallBlank = 0;
+                     }
+                  }
+                  *cs = '\0';
+               }
+            }
+         }
+
+      } else {                           /* Ulovlig punktnummer */
+         UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),lPnr);
+         LC_Error(51,"(LC_GetPiVerdi)",err().tx);
+      }
+   }
+
+   return  rp;
+}
+
+
+/*
+AR-920614
+CH LX_CreatePibuf                                       Generer PINFO-buffer
+CD ==========================================================================
+CD Form�l:
+CD Henter PINFO for gitt punkt og legger den inn i et buffer.
+CD Det bygges opp en tabell med pekere til starten av hvert SOSI-navn og
+CD hver verdi.
+CD
+CD Parametre:
+CD Type    Navn  I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long   lPnr   i    Punktnummer.
+CD
+CD Bruk:
+CD LX_CreatePibuf(lPnr);
+   ==========================================================================
+*/
+static void LX_CreatePibuf(long lPnr)
+{
+   short sAntPi;
+   char *pp,*cp;
+   char *bp = Sys.cPibuf ;
+
+   *Sys.cPibuf = '\0';
+
+   sAntPi = 0;
+   pp = LC_GetPi(lPnr);
+
+   /* For lang pinfo */
+   if (strlen(pp) > LC_MAX_PIBUF_TEGN) {
+      Sys.sPibufStatus = LC_PIBUF_FULL;
+      return;
+   }
+
+   /* Finn f�rste/neste SOSI-navn */
+   while ((cp = strstr(pp,"...")) != NULL) {  /* SOSI-navn */
+      ++sAntPi;
+
+      /* Sjekk om det er nok plass i tabell for peker til PINFO-linje */
+      if (sAntPi > LC_MAX_PIBUF_LIN){
+         Sys.sPibufStatus = LC_PIBUF_FULL;
+         return;
+      }
+
+      pp = cp;
+      Sys.pcPibufNavn[sAntPi-1] = bp;
+      while (!UT_IsSpace(*pp)  &&  *pp != '\0') {
+         *bp++ = *pp++;
+      }
+      *bp++ = '\0';
+
+      /* Hopp over blanke mellom navn og verdi */
+      while (UT_IsSpace(*pp)) {
+         ++pp;
+      }
+
+      /* Ta vare p� verdien */
+
+      if (*pp == '"') {                 /* Hermetegn */
+         if ((cp = strchr(pp+1,'"')) != NULL) {      /* Slutt-hermetegn */
+            ++pp;
+            *cp++ = '\0';
+            cp = strstr(cp," ..."); /* Neste SOSI-navn */
+
+         } else {
+            UT_ClrTrailsp(pp);         /* Fjern blanke p� slutten */
+         }
+
+      } else if ((cp = strstr(pp," ...")) != NULL) {  /* SOSI-navn */
+         *cp++ = '\0';
+         UT_ClrTrailsp(pp);         /* Fjern blanke p� slutten */
+
+      } else if ((cp = strchr(pp,'!')) != NULL) {    /* Kommentar */
+         *cp = '\0';
+         UT_ClrTrailsp(pp);         /* Fjern blanke p� slutten */
+         cp = NULL;
+
+      } else {
+         /* Linjeslutt  cp = NULL*/
+         UT_ClrTrailsp(pp);         /* Fjern blanke p� slutten */
+      }
+
+      /* Kopier strengen */
+      Sys.pcPibufVerdi[sAntPi-1] = bp;
+      while (*pp) {
+         *bp++ = *pp++;
+      }
+      *bp++ = '\0';
+
+      /* Neste sett */
+      if (cp != NULL) {
+         pp = cp;
+      }
+   }
+
+   Sys.lPibufPnr = lPnr;
+   Sys.sPibufAntPi = sAntPi;            /* Antall elementer brukt i Pibuf */
+   Sys.sPibufStatus = LC_PIBUF_OK;
+}
+
+
+/*
+AR-891001
+CH LC_PutGP                                               Put GINFO-parameter
+CD ==========================================================================
+CD Form�l:
+CD Legger inn et SOSI-navn med verdi.
+CD Denne rutinen kan brukes til � legge inn ginfo med nytt SOSI-navn.
+CD Rutinen kan endre antall ginfo-linjer.
+CD
+CD Parametre:
+CD Type     Navn        I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD char     sosi_navn    i    Sosi-navn det skal legges inn verdi til
+CD char     verdi        i    Streng som skal legges inn.
+CD short   *linje_nr     u    Linjenummer for endringen.
+CD short    ngi          r    Ant. ginfo-linjer etter  endringen.
+CD
+CD Bruk:
+CD ngi = LC_PutGP(sosi_navn,verdi,&linje_nr);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_PutGP(const char *sosi_navn,const char *verdi,short *linje_nr)
+{
+   char temp[LC_MAX_SOSI_LINJE_LEN];
+
+
+
+#ifdef TEST
+
+************************************************************
+   short sLedd = 0;
+   short funnet = 0;
+
+   char *rp = NULL;          /* Retur peker */
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                /* Aktuell gruppe OK */
+
+      /* Plukk ut info om ledd */
+      UT_StrCopy(szSosiNavn,sosi_navn,LC_MAX_SOSINAVN_LEN);
+      UT_StrUpper(szSosiNavn);
+
+      if ((cs = strchr(szSosiNavn,'#')) != NULL) {
+         cp = cs;
+         ++cp;
+         sLedd = (short) strtol(cp,&cp,10);       /* Ledd-nummer */
+         /* Fjern tilleggsinfo fra SOSI-navnet */
+         *cs = '\0';
+      }
+
+      /* S�k etter SOSI-navnet */
+      sSosiLen = strlen(szSosiNavn);
+      gi_lin = *forste_linje;
+      while (gi_lin <= siste_linje) {
+         /* Les ny linje */
+         ginfo = LX_GetGi(gi_lin);
+
+         /* Er dette rett navn? */
+         if ((strncmp(ginfo,szSosiNavn,sSosiLen) == 0) &&
+             ( (UT_IsSpace(*(ginfo+sSosiLen))  ||  *(ginfo+sSosiLen) == '\0'))) {
+
+            /* Hopp over blanke mellom navn og verdi */
+            cp = ginfo + sSosiLen;
+            while (UT_IsSpace(*cp)) {
+               ++cp;
+            }
+            /* Kopier parameter */
+            rp = strcpy(retur_str,cp);
+
+            /* Fjern hermetegn (") */
+            if (*rp == '"') {
+               if ((cp = strchr(rp+1,'"')) != NULL) {   /* Slutt-hermetegn */
+                  ++rp;
+                  *cp = '\0';
+               }
+            }
+
+            /* Fjern hermetegn (') */
+            if (*rp == '\'') {
+               if ((cp = strchr(rp+1,'\'')) != NULL) {   /* Slutt-hermetegn */
+                  ++rp;
+                  *cp = '\0';
+               }
+            }
+
+            /* Har ikke ledd , funnet OK */
+            if (sLedd == 0) {
+               funnet = 1;
+               /* Husk linjenummeret */
+               *forste_linje = gi_lin;
+               break;           /* Funnet, ==> hopp ut av l�kken */
+
+            /* Handter leddnummer */
+            } else {
+               cp = strtok(rp," ");
+               s = sLedd;
+               while(cp != NULL  &&  --s > 0){
+                  cp = strtok(NULL," ");
+               }
+
+               /* Leddet er funnet */
+               if (cp != NULL) {
+                  /* Aktuellt ledd huskes */
+                  rp = cp;
+                  funnet = 1;
+                  /* Husk linjenummeret */
+                  *forste_linje = gi_lin;
+                  break;           /* Funnet, ==> hopp ut av l�kken */
+               
+               } else {
+                                    /* AR-950901 */
+                  /* rp = NULL; */  /* Det aktuelle leddet finnes ikke */
+                  /* Aktuellt ledd huskes */
+                  rp = strchr(rp,'\0');
+                  funnet = 1;
+                  /* Husk linjenummeret */
+                  *forste_linje = gi_lin;
+                  break;           /* Funnet, ==> hopp ut av l�kken */
+               }
+            }
+         }
+
+         ++gi_lin;
+      }
+
+      /* Har funnet navnet */
+      if (rp != NULL) {
+
+         /* Handter delstreng */
+         if (sStart != 0) {
+            if (sSlutt != 0  &&  sSlutt < (short)strlen(rp)) {
+               *(rp+sSlutt) = '\0';
+            }
+            sStart = min(sStart,((short)strlen(rp)));
+            rp += (sStart-1);
+         }
+
+*****************************************************************
+#endif
+
+
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE){                    /* Aktuell gruppe OK */
+       *linje_nr = 2;
+       if (LC_GetGP(sosi_navn,linje_nr,Sys.pGrInfo->ngi) != NULL){     /* Finn linjen */
+                                                      /* Legg inn endringen */
+           LC_UpdateGP(*linje_nr,sosi_navn,verdi);
+
+       } else{                             /* Ikke funnet, ny linje */
+           *linje_nr = LC_AppGiL();
+           UT_StrCopy(temp,sosi_navn,LC_MAX_SOSI_LINJE_LEN);
+           UT_StrCopy(temp," ",LC_MAX_SOSI_LINJE_LEN);
+           UT_StrCopy(temp,verdi,LC_MAX_SOSI_LINJE_LEN);
+           LC_PutGi(*linje_nr,temp);
+       }
+
+   } else{                              /* Ingen aktuell gruppe */
+       LC_Error(49,"(LC_PutGP)","");
+   }
+
+   return Sys.pGrInfo->ngi;
+}
+
+
+/*
+AR:2010-02-09
+CH LC_AppGP                                         Legg til GINFO-parameter
+CD ==========================================================================
+CD Form�l:
+CD Legger til et SOSI-navn med verdi i GINFO.
+CD Lik LC_PutGP, men legger alltid til ny linje i ginfo.
+CD
+CD Parametre:
+CD Type     Navn        I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD char     sosi_navn    i    Sosi-navn det skal legges inn verdi til
+CD char     verdi        i    Streng som skal legges inn.
+CD short   *linje_nr     u    Linjenummer for endringen.
+CD short    ngi          r    Ant. ginfo-linjer etter  endringen.
+CD
+CD Bruk:
+CD ngi = LC_AppGP(sosi_navn,verdi,&linje_nr);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_AppGP(const char *sosi_navn,const char *verdi,short *linje_nr)
+{
+   char temp[LC_MAX_SOSI_LINJE_LEN];
+
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE){                    /* Aktuell gruppe OK */
+        *linje_nr = LC_AppGiL();
+        UT_StrCopy(temp,sosi_navn,LC_MAX_SOSI_LINJE_LEN);
+        UT_StrCopy(temp," ",LC_MAX_SOSI_LINJE_LEN);
+        UT_StrCopy(temp,verdi,LC_MAX_SOSI_LINJE_LEN);
+        LC_PutGi(*linje_nr,temp);
+
+   } else{                              /* Ingen aktuell gruppe */
+       LC_Error(49,"(LC_AppGP)","");
+   }
+
+   return Sys.pGrInfo->ngi;
+}
+
+
+/*
+AR-891001
+CH LC_UpdateGP                                          Endre GINFO-parameter
+CD ==========================================================================
+CD Form�l:
+CD Legger inn parametren til et SOSI-navn.
+CD Rutinen handterer at det er flere SOSI-navn p� samme linje.
+CD OBS! Denne rutinen kan ikke brukes til � legge inn nytt SOSI-navn.
+CD
+CD Parametre:
+CD Type     Navn        I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD short    linje_nr     i    Linjenummer som skal endres.
+CD char     sosi_navn    i    Sosi-navn det skal legges inn verdi til
+CD char     verdi        i    Streng som skall legges inn
+CD short    ist          r    1=ok, 0=navnet er ikke funnet
+CD
+CD Bruk:
+CD ist = LC_UpdateGP(linje_nr,sosi_navn,verdi);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_UpdateGP(short linje_nr,const char *sosi_navn,const char *verdi)
+{
+   char temp[LC_MAX_SOSI_LINJE_LEN],*gp,*neste,*cp;
+   short ist=0;
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE){                    /* Aktuell gruppe OK */
+       gp = LC_GetGi(linje_nr);
+       if ((neste = strstr(gp,sosi_navn)) != NULL){    /* Finn SOSI-navnet */
+
+           cp = neste - 1;                    /* Avslutt f�rste del av ginfo */
+           while (cp >= gp && UT_IsSpace(*cp)){
+               cp--;
+           }
+           *(cp+1) = '\0';
+
+           neste += strlen(sosi_navn);      /* Hopp over SOSI-navnet */
+
+           while (UT_IsSpace(*neste))                 /* Ledende blanke */
+               ++neste;
+
+           if (*neste == '"' &&  (cp = strchr(neste+1,'"')) != NULL){   /* Hermetegn */
+               neste = cp + 1;
+               while (UT_IsSpace(*neste)){          /* Blanke */
+                   ++neste;
+               }
+
+           } else if ((cp = strstr(neste-1," ..")) != NULL) { /* SOSI-navn */
+               neste = cp + 1;
+
+           } else if ((cp = strchr(neste,'!')) != NULL) { /* Kommentar */
+               neste = cp;
+
+           } else{                                 /* Slutten av strengen */
+               neste = strchr(neste,'\0');
+           }
+
+                                                 /* Legg inn endringen */
+           *temp = '\0';
+           if (*gp){                      /* F�rste del */
+               UT_StrCat(temp,gp,LC_MAX_SOSI_LINJE_LEN);
+               UT_StrCat(temp," ",LC_MAX_SOSI_LINJE_LEN);
+           }
+           UT_StrCat(temp,sosi_navn,LC_MAX_SOSI_LINJE_LEN);        /* Aktuellt navn */
+           UT_StrCat(temp," ",LC_MAX_SOSI_LINJE_LEN);
+           UT_StrCat(temp,verdi,LC_MAX_SOSI_LINJE_LEN);
+           if (*neste){                   /* Siste del */
+               UT_StrCat(temp," ",LC_MAX_SOSI_LINJE_LEN);
+               UT_StrCat(temp,neste,LC_MAX_SOSI_LINJE_LEN);
+           }
+
+           LC_PutGi(linje_nr,temp);
+           ist = 1;
+       }
+
+   } else{                              /* Ingen aktuell gruppe */
+       LC_Error(49,"(LC_UpdateGP)","");
+   }
+
+   return ist;
+}
+
+
+/*
+AR-881113
+CH LC_InitPP                                                Initier PINFO-s�k
+CD ==========================================================================
+CD Form�l:
+CD Initierer s�k etter PINFO.
+CD
+CD Parametre:
+CD Type            Navn        I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD char            sosi_navn    i   Sosi-navn det skal finnes verdi til
+CD long            forste_punkt i   F�rste punkt. (1 er f�rste pkt i gr)
+CD long            siste_punkt  i   Siste punkt det skal s�kes i
+CD LC_GETPP_STATUS pp_stat      iu  Struktur med statusvariabler. Denne er
+CD                                  bare for intern bruk i InitPP / GetPP.
+CD
+CD Bruk:
+CD   Se under LC_GetPP.
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_InitPP(char *sosi_navn,long forste_punkt,long siste_punkt,
+               LC_GETPP_STATUS *pp_stat)
+{
+   short itxu;
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE){                 /* Aktuell gruppe OK */
+
+       UT_StrToken(sosi_navn,0,&itxu,LC_MAX_SOSINAVN_LEN,pp_stat->pinfo_navn);  /* SOSI-navnet */
+       UT_StrUpper(pp_stat->pinfo_navn);
+       pp_stat->slutt_punkt = min(siste_punkt,Sys.pGrInfo->nko) + 1;
+
+       /* -------- Knutepunkt */
+       if (strcmp(pp_stat->pinfo_navn,"...KP") == 0){
+           pp_stat->type = LC_GETPP_KP;
+           pp_stat->curr_punkt = max(forste_punkt,1) -1;  /* Sjekk punktnummer */
+
+       /* -------- H�yde */
+       } else if (strcmp(pp_stat->pinfo_navn,"H�YDE") == 0) {
+           pp_stat->type = LC_GETPP_HOYDE;
+           pp_stat->curr_punkt = max(forste_punkt,1) -1;  /* Sjekk punktnummer */
+
+       /* -------- Kvalitet */
+       } else if (strcmp(pp_stat->pinfo_navn,"KVALITET") == 0) {
+           pp_stat->type = LC_GETPP_KVALITET;
+           pp_stat->curr_punkt = max(forste_punkt,1) -1;  /* Sjekk punktnummer */
+
+       /* -------- Annen PINFO */
+       } else {
+           pp_stat->type = LC_GETPP_VANLIG;
+           pp_stat->neste_tegn = 0;
+           pp_stat->curr_punkt = max(forste_punkt,1);  /* Sjekk punktnummer */
+       }
+   }
+}
+
+
+/*
+AR-890511
+CH LC_GetPP                                                   Utf�r PINFO-s�k
+CD ==========================================================================
+CD Form�l:
+CD Henter parametrene til et SOSI-navn definert i LC_InitPP.
+CD Strengen ligger i et felles "returbuffer" for alle get-rutiner i fyba.
+CD Dette blir �delagt ved neste kall til en "get-rutine". For � ta vare p�
+CD strengen m� den kopieres over til egen streng. (Bruk strcpy).
+CD
+CD Parametre:
+CD Type     Navn               I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long    *punkt             u  Ved tilslag returneres punktnummer for
+CD                               tilslaget.
+CD LC_GETPP_STATUS pp_stat iu  Struktur med statusvariabler. Denne er
+CD                               bare for intern bruk i InitPP / GetPP.
+CD char    *para_peker        r  Peker til para.-streng avslutta med '\0'.
+CD                               Hvis ingenting er funnet returneres NULL.
+CD
+CD Bruk:
+CD .
+CD   LC_GETPP_STATUS pp_stat;
+CD .
+CD LC_InitPP(sosi_navn,forste_punkt,siste_punkt,pp_stat);
+CD para_peker = LC_GetPP(&punkt,pp_stat);
+CD   .
+   =============================================================================
+*/
+SK_EntPnt_FYBA char *LC_GetPP(long *punkt,LC_GETPP_STATUS *pp_stat)
+{
+   short nt,kp_type,sAntDes,niv;
+   char format[20];
+   char *pinfo,*cp,*parameter;
+   char funnet_sosi[LC_MAX_SOSINAVN_LEN];
+   double enhet,enhet_h,enhet_d,h;
+
+
+   /* -------- Knutepunkt */
+   if (pp_stat->type == LC_GETPP_KP) {
+      pp_stat->curr_punkt++;
+      if (LC_FinnKp(&(pp_stat->curr_punkt), pp_stat->slutt_punkt-1, &kp_type))  {      /* S�k */
+         *punkt = pp_stat->curr_punkt;
+                                     /* Lag parameter */
+         UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%hd",kp_type);
+         return  retur_str;               /* OBS! RETURNERER HER! */
+
+      } else {                                         /* Ikke funnet */
+         return  NULL;                           /* OBS! RETURNERER HER! */
+      }
+
+   /* -------- H�yde */
+   } else if (pp_stat->type == LC_GETPP_HOYDE) {
+      pp_stat->curr_punkt++;
+
+      while (pp_stat->curr_punkt < pp_stat->slutt_punkt) {  /* S�k etter navnet */
+         h = LC_GetHoyde(pp_stat->curr_punkt);
+         if (h != HOYDE_MANGLER) {    /* Funnet h�yde */
+            *punkt = pp_stat->curr_punkt;
+
+            /* Hent enhet og formater h�yden */
+            niv = 2;
+            LC_GetCurEnhet(Sys.GrId.pFil,&niv,&enhet,&enhet_h,&enhet_d);
+            
+            sAntDes = UT_RoundDS(fabs(min(0.0,log10(enhet_h))));
+            UT_SNPRINTF(format,20,"%%.%dlf",sAntDes);
+            UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,format,h);
+
+            return retur_str;              /* OBS! RETURNERER HER! */
+
+         } else {                 /* Neste punkt */
+            pp_stat->curr_punkt++;
+         }
+      }
+
+      return NULL;                             /* Ikke funnet */
+
+   /* -------- Kvalitet */
+   } else if (pp_stat->type == LC_GETPP_KVALITET) {
+      short sMetode, sSynbarhet, sHoydeMetode;
+      long lNoyaktighet, lHoydeNoyaktighet;
+      short nivaa = 3;
+
+      pp_stat->curr_punkt++;
+
+      while (pp_stat->curr_punkt < pp_stat->slutt_punkt) {  /* S�k etter navnet */
+
+         /* Funnet kvalitet? */
+         if (LC_GetCurKvalitet(Sys.GrId.pFil,&nivaa,pp_stat->curr_punkt,
+                               &sMetode,&lNoyaktighet,&sSynbarhet,
+                               &sHoydeMetode,&lHoydeNoyaktighet) == UT_TRUE) {
+            *punkt = pp_stat->curr_punkt;
+           
+            /* Formater kvaliteten */
+            UT_StrCopy(retur_str,
+                       LC_FormatterKvalitet(sMetode,lNoyaktighet,sSynbarhet,sHoydeMetode,lHoydeNoyaktighet),
+                       LC_MAX_SOSI_LINJE_LEN);
+            return retur_str;              /* OBS! RETURNERER HER! */
+
+         } else {                 /* Neste punkt */
+            pp_stat->curr_punkt++;
+         }
+      }
+
+      return NULL;                             /* Ikke funnet */
+
+   /* -------- Annen PINFO */
+   } else {
+       nt = pp_stat->neste_tegn;
+       while (pp_stat->curr_punkt < pp_stat->slutt_punkt){  /* S�k etter navnet */
+           pinfo = LC_GetPi(pp_stat->curr_punkt);
+           if (*pinfo){                        /* Punktet har PINFO */
+               *punkt = pp_stat->curr_punkt;
+               while (*punkt == pp_stat->curr_punkt){
+                   UT_StrToken(pinfo,nt,&nt,LC_MAX_SOSINAVN_LEN,funnet_sosi); /* SOSI-navn */
+                   parameter = pinfo + nt;
+
+                   if (strcmp(pp_stat->pinfo_navn,funnet_sosi) == 0){  /* Tilslag */
+                                                        /* Finn parameter */
+                       while (*parameter == ' ')        /* Ledende blanke */
+                           ++parameter;
+
+                       if (*parameter == '"'){                 /* Hermetegn */
+                           if ((cp = strchr(parameter+1,'"')) != NULL){ /* Slutt-hermetegn */
+                               ++parameter;
+                               *cp = '\0';
+                           }
+                       } else if ((cp = strstr(parameter," ..")) != NULL){ /* SOSI-navn */
+                           *cp = '\0';
+                           nt = (short)(cp - pinfo + 1);
+
+                       } else if ((cp = strchr(parameter,'!')) != NULL){ /* Kommentar */
+                           *cp = '\0';
+                           pp_stat->curr_punkt++;
+                           nt = 0;
+                       } else{                             /* Linjeslutt */
+                           pp_stat->curr_punkt++;
+                           nt = 0;
+                       }
+
+                       pp_stat->neste_tegn = nt;               /* Klargj�r for retur */
+                       return parameter;              /* OBS! RETURNERER HER! */
+
+                   } else{                /* Ikke tilslag, neste PINFO */
+                       if ((cp = strstr(parameter," ..")) != NULL){  /* SOSI-navn */
+                           nt = (short)(cp - pinfo + 1);
+                       } else{                             /* Linjeslutt */
+                           pp_stat->curr_punkt++;
+                           nt = 0;
+                       }
+                   }
+               }
+
+           } else {
+               pp_stat->curr_punkt++;
+           }
+       }
+   }
+
+   return NULL;                             /* Ikke funnet */
+}
+
+
+/*
+AR-930609
+CH LC_FinnKp                                                  Finn knutepunkt
+CD ==========================================================================
+CD Form�l:
+CD Skanner gruppe, og finner punkt som er knutepunkt.
+CD
+CD Parametre:
+CD Type     Navn        I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long    *forste_punkt iu   Punktnummer for start s�king.
+CD                            (1 er f�rste punkt i gruppen.)
+CD                            Ved tilslag returneres punktnummer for tilslaget.
+CD long     siste_punkt  i    Siste punkt det skal s�kes i.
+CD short   *kp           u    Knutepunkt.
+CD short    status       r    S�kestatus (1=funnet, 0=ikke funnet)
+CD
+CD Bruk:
+CD status = LC_FinnKp(&forste_punkt,siste_punkt,kp);
+   ==========================================================================
+*/
+short LC_FinnKp(long *forste_punkt,long siste_punkt,short *kp)
+{
+   long punkt;
+
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE){                 /* Aktuell gruppe OK */
+      if(Sys.pGrInfo->info & GI_KP){                 /* Gruppen har knutepunkt */
+         punkt = max(*forste_punkt,1);               /* Sjekk punktnummer */
+         siste_punkt = min(siste_punkt,Sys.pGrInfo->nko);
+
+         /* Skann gruppen */
+         for (punkt--; punkt<siste_punkt; ++punkt) {
+            if ((Sys.pInfo+punkt)->sKp != 0) {         /* KP ? */
+               *kp = (Sys.pInfo+punkt)->sKp;
+               *forste_punkt = punkt+1;
+               return(1);
+            }
+         }
+      }
+   }
+   return(0);
+}
+
+
+/*
+AR-890520
+CH LC_PutSn                                                   Put Serienummer
+CD ==========================================================================
+CD Form�l:
+CD Legger inn nytt serienummer p� aktuell gruppe.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long     snr      i    Serienummer
+CD
+CD Bruk:
+CD LC_PutSn(snr);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_PutSn(long snr)
+{
+   if (Sys.GrId.lNr != INGEN_GRUPPE){               /* Aktuell gruppe OK */
+                    /* Legger inn SNR og marker for endring */
+       LX_PutSn(snr);
+       Sys.sGrEndra = END_ENDRA;
+
+   } else{                              /* Ingen aktuell gruppe */
+       LC_Error(49,"(LC_PutSn)","");
+   }
+}
+
+
+/*
+AR-930609
+CH LX_PutSn                                           Lavniv� Put Serienummer
+CD ==========================================================================
+CD Form�l:
+CD Legger inn nytt serienummer p� aktuell gruppe, uten � sette flagg for at
+CD aktuell gruppe er oppdatert. Sjekker ikke om det er noen aktuell gruppe.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long     snr      i    Serienummer
+CD
+CD Bruk:
+CD LX_PutSn(snr);
+   ==========================================================================
+*/
+void LX_PutSn(long snr)
+{
+   char szGinfo[LC_MAX_SOSI_LINJE_LEN],*cp;
+
+   /* Legger ikke inn serienr i hodet */
+   if (Sys.GrId.lNr > 0L) {
+      /* Kobler gml SOSI-navn med nytt SNR */
+      UT_StrCopy(szGinfo,Sys.Ginfo.pszTx,LC_MAX_SOSI_LINJE_LEN);
+
+      cp = szGinfo;
+      while (! UT_IsSpace(*cp) && *cp) {
+         ++cp;
+      }
+      *cp = '\0';
+     
+      /* Heng p� serienummer */
+      if (snr != 0L) {
+         char szOrd[50];
+         UT_SNPRINTF(szOrd, 50, " %ld:", snr);
+         UT_StrCat(szGinfo,szOrd,LC_MAX_SOSI_LINJE_LEN);
+      }
+     
+      /* Linjen lagres */
+      LX_PutGi(1,szGinfo);
+   }
+}
+
+
+/*
+AR-930609
+CH LC_GetSn                                                  Get serienummer
+CD ==========================================================================
+CD Form�l:
+CD Henter serienummer for aktuell gruppe.
+CD
+CD Parametre:
+CD Type  Navn  I/U  Forklaring
+CD --------------------------------------------------------------------
+CD long  snr    r   Serienr.  (INGEN_GRUPPE = ingen aktuell gruppe)
+CD
+CD Bruk:
+CD snr = LC_GetSn();
+   ==========================================================================
+*/
+SK_EntPnt_FYBA long LC_GetSn(void)
+{
+   char *cp;
+
+   /* Aktuell gruppe OK */
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {
+       cp = strchr(LX_GetGi(1),' ');
+       if (cp != NULL) {
+         return  atol(cp);                              /* ==> */
+      } else {
+         return  0L;                                    /* ==> */
+      }
+   }
+
+   /* Ingen aktuell gruppe */
+   return  INGEN_GRUPPE;                                /* ==> */
+}
+
+
+/*
+AR-930609
+CH LC_PutGi                                                   Put GINFO-linje
+CD ==========================================================================
+CD Form�l:
+CD Legger inn GINFO-linje rent generellt.
+CD Dette omfatter ogs� nytt gruppenavn (GINFO-linje 1)
+CD �nsker du � endre serienummer m� LC_PutSn benyttes.
+CD Referansenummer legges inn med LC_PutRef.
+CD Blanke p� starten og slutten blir skrella vekk, og SOSI-navnet blir
+CD konvertert til "store" bokstaver, .ellers lagres det slik det er.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD short    lin_nr   i    Linjenummer i GINFO   (1 er f�rste linje)
+CD char     *ginfo   i    GINFO-streng avslutta med '\0'
+CD
+CD Bruk:
+CD LC_PutGi(lin_nr,ginfo);
+	==========================================================================
+*/
+SK_EntPnt_FYBA void LC_PutGi(short lin_nr, const char *pszGinfo)
+{
+   // Aktuell gruppe OK
+	if (Sys.GrId.lNr != INGEN_GRUPPE)
+   {   
+      // Lovlig linje ?
+		if (lin_nr > 0 && lin_nr <= Sys.pGrInfo->ngi)
+      {                          
+         // Gruppestart h�ndteres spesielt
+			if (lin_nr == 1)
+         {                   
+            char ginfo[LC_MAX_SOSI_LINJE_LEN];
+            char *ct;
+
+				/* Husk gammelt SNR */
+            long  lGmlSnr = LC_GetSn();
+
+				// Fjern ledende blanke og kopier til lokal variabel
+            while (UT_IsSpace(*pszGinfo)) {
+					++pszGinfo;
+				}
+				UT_StrCopy(ginfo,pszGinfo,LC_MAX_SOSI_LINJE_LEN);
+
+				/* Finn SOSI-navnet */
+				ct = ginfo;
+				while (*ct  &&  ! UT_IsSpace(*ct)) {
+					++ct;
+				}
+				*ct = '\0';
+
+				/* Heng p� serienummer */
+				if (lGmlSnr != 0L) {
+               char szOrd[50];
+               UT_SNPRINTF(szOrd, 50, " %ld:", lGmlSnr);
+               UT_StrCat(ginfo,szOrd,LC_MAX_SOSI_LINJE_LEN);
+				}
+            LX_PutGi(lin_nr,ginfo);
+         }
+
+         else
+         {
+            LX_PutGi(lin_nr,pszGinfo);
+         }
+
+			/* Linjen lagres */
+
+      } else {                                 /* Ulovlig linjenummer */
+         UT_SNPRINTF(err().tx,LC_ERR_LEN," %d",lin_nr);
+         LC_Error(52,"(LC_PutGi)",err().tx);
+      }
+   }
+}
+
+
+
+/*
+AR-930609
+CH LX_PutGi                                          Lavniv� put GINFO-linje
+CD ==========================================================================
+CD Form�l:
+CD Lavniv� innlegging GINFO-linje rent generellt.
+CD Blanke p� starten og slutten blir skrella vekk, og SOSI-navnet blir
+CD konvertert til "store" bokstaver, ellers lagres det slik det er.
+CD Sjekker ogs� at det aktuelle SOSI-navnet er lovlig � oppdatere.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD short    lin_nr   i    Linjenummer i GINFO   (1 er f�rste linje)
+CD char     *ginfo   i    GINFO-streng avslutta med '\0'
+CD
+CD Bruk:
+CD LX_PutGi(lin_nr,ginfo);
+   ==========================================================================
+*/
+static void LX_PutGi(short lin_nr, const char *szGinfo)
+{
+   short navn_nr,gr_start,dummy,sGmlLen,sNyLen;
+   char *cs,tmp,*ct;
+   double enhet,dNord,dAust;
+   char* pszNgisLag;
+   char ginfo[LC_MAX_SOSI_LINJE_LEN];
+   short sLagre = UT_TRUE;
+
+
+   Sys.sGrEndra = END_ENDRA;
+
+   /* Fjern blanke i starten og p� slutten */
+   UT_StrCopy(ginfo,szGinfo,LC_MAX_SOSI_LINJE_LEN);
+   UT_ClrTrailsp(ginfo);
+
+   cs = ginfo;
+   while (UT_IsSpace(*cs))
+   {
+      ++cs;
+   }
+
+   // Sjekk at linjen ikke er for lang
+   if (strlen(cs) > (LC_MAX_SOSI_LINJE_LEN - 10))
+   {
+      *(cs + LC_MAX_SOSI_LINJE_LEN -10) = '\0';
+      UT_StrCat(ginfo, " ?????", LC_MAX_SOSI_LINJE_LEN);
+      LC_Error(134,"(LX_PutGi)",LX_GetGi(1));
+   }
+
+   /* Finn SOSI-navnet */
+   ct = cs;
+   while (*ct  &&  ! UT_IsSpace(*ct))
+   {
+      ++ct;
+   }
+
+   /* Konv. SOSI-navnet til stor-bokstaver og finn navnenummer */
+   tmp = *ct;
+   *ct = '\0';
+   UT_StrUpper(cs);
+   gr_start = LN_FinnNavn(&(Sys.GrId.pFil->SosiNavn),cs,&navn_nr);
+   *ct = tmp;
+
+   /* Gruppestart */
+   if (lin_nr == 1) {
+      if (gr_start == 1) {
+         Sys.pGrInfo->gnavn = navn_nr;          /* Husk gruppenavnet */
+
+      } else {
+         /* Melding om ukjent gruppestart */
+         LC_Error(54,"(LC_PutGi)",ginfo);
+         sLagre = UT_FALSE;
+      }
+
+   /* Annen GINFO */
+   } else { 
+      if (gr_start > 0) {
+         /* ...ENHET i filhode p� fil med data */
+         if (Sys.GrId.lNr == 0L  &&  Sys.GrId.pFil->lAntGr > 1  &&  navn_nr == L_ENHET3) {
+
+            /* Sjekk at enhet ikke er endret */
+            UT_StrDbl(ct,1,&dummy,'.',&enhet);
+            if (fabs(enhet - Sys.GrId.pFil->TransPar.dEnhet) > LC_ACCY) {
+               LB_FormaterEnhet(err().tx,LC_ERR_LEN,
+                                LN_GetNavn(&(Sys.GrId.pFil->SosiNavn),navn_nr),
+                                Sys.GrId.pFil->TransPar.dEnhet);
+               LC_Error(57,"(LX_PutGi)",err().tx);
+               sLagre = UT_FALSE;
+            }
+         }
+
+         /* ...ENHET-H i filhode p� fil med data */
+         if (Sys.GrId.lNr == 0L  &&  Sys.GrId.pFil->lAntGr > 1  &&  navn_nr == L_ENHET3H) {
+            /* Sjekk at enhet ikke er endret */
+            UT_StrDbl(ct,1,&dummy,'.',&enhet);
+            if (fabs(enhet - Sys.GrId.pFil->TransPar.dEnhet_h) > LC_ACCY) {
+               LB_FormaterEnhet(err().tx,LC_ERR_LEN,
+                                LN_GetNavn(&(Sys.GrId.pFil->SosiNavn),navn_nr),
+                                Sys.GrId.pFil->TransPar.dEnhet_h);
+               LC_Error(57,"(LX_PutGi)",err().tx);
+               sLagre = UT_FALSE;
+            }
+         }
+
+         /* ...ENHET-D i filhode p� fil med data */
+         if (Sys.GrId.lNr == 0L  &&  Sys.GrId.pFil->lAntGr > 1  &&  navn_nr == L_ENHET3D) {
+            /* Sjekk at enhet ikke er endret */
+            UT_StrDbl(ct,1,&dummy,'.',&enhet);
+            if (fabs(enhet - Sys.GrId.pFil->TransPar.dEnhet_d) > LC_ACCY) {
+               LB_FormaterEnhet(err().tx,LC_ERR_LEN,
+                                LN_GetNavn(&(Sys.GrId.pFil->SosiNavn),navn_nr),
+                                Sys.GrId.pFil->TransPar.dEnhet_d);
+               LC_Error(57,"(LX_PutGi)",err().tx);
+               sLagre = UT_FALSE;
+            }
+         }
+
+         /* ..NGIS-LAG i filhode p� fil med data */
+         if (Sys.GrId.lNr == 0L  &&  Sys.GrId.pFil->lAntGr > 1  &&  navn_nr == L_NGISLAG) {
+
+            /* Sjekk at ..NGIS-LAG ikke er endret */
+            pszNgisLag = ct; 
+         
+            // Filen har ikke NGIS-LAG eller NGIS-LAG er endret
+            //if (lNgisLag != Sys.GrId.pFil->lNgisLag) {
+            if (*(Sys.GrId.pFil->szNgisLag) == '\0'  ||
+                strcmp(pszNgisLag,Sys.GrId.pFil->szNgisLag) != 0) {
+            
+               UT_SNPRINTF(err().tx,LC_ERR_LEN," %s %s",
+                       LN_GetNavn(&(Sys.GrId.pFil->SosiNavn),navn_nr),
+                       Sys.GrId.pFil->szNgisLag);
+               LC_Error(58,"(LX_PutGi)",err().tx);
+               sLagre = UT_FALSE;
+            }
+         }
+
+         /* ..ORIGO-N� i filhode p� fil med data */
+         if (Sys.GrId.lNr == 0L  &&  Sys.GrId.pFil->lAntGr > 1  &&  navn_nr == L_ORIGONO) {
+
+            /* Sjekk at ..ORIGO-N� ikke er endret */
+            UT_StrDbl(ct,1,&dummy,'.',&dNord);
+            UT_StrDbl(ct,dummy,&dummy,'.',&dAust);
+        
+            if (fabs(dNord - Sys.GrId.pFil->TransPar.Origo.dNord) > 0.1 ||
+                fabs(dAust - Sys.GrId.pFil->TransPar.Origo.dAust) > 0.1  ) {
+         
+               UT_SNPRINTF(err().tx,LC_ERR_LEN," %s %.0f %.0f",
+                       LN_GetNavn(&(Sys.GrId.pFil->SosiNavn),navn_nr),
+                       Sys.GrId.pFil->TransPar.Origo.dNord, Sys.GrId.pFil->TransPar.Origo.dAust);
+               LC_Error(60,"(LX_PutGi)",err().tx);
+               sLagre = UT_FALSE;
+            }
+         }
+
+         // ..OBJTYPE
+         if (navn_nr == L_OBJTYPE) {
+            UT_StrCopy(Sys.pGrInfo->szObjtype,ct,LC_MAX_OBJTYPE_LEN);
+         }
+
+         /* Referanser */
+         if (navn_nr == L_REF1  ||  navn_nr == L_REF2) {
+            Sys.pGrInfo->info |= GI_REF;
+            if (LN_TestOy(ginfo))  Sys.pGrInfo->info |= GI_OY_REF;
+
+#ifdef UTGAAR
+         /* Gruppen har h�yde informasjon */
+         } else if (navn_nr == L_HOYDE) {
+            Sys.pGrInfo->info |= GI_NAH;   /* Husk at gruppen har h�yde */
+#endif
+         }
+      }
+   }
+
+
+   if (sLagre == UT_TRUE) {
+      /* Linjen lagres */
+      sGmlLen = (short)strlen(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[lin_nr - 1]);
+      sNyLen = (short)strlen(cs);
+
+      /* Samme lengde, trenger ikke � flytte noe i buffer */
+      if (sNyLen == sGmlLen) {
+         //strcpy(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[lin_nr - 1], cs);
+         UT_memcpy(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[lin_nr - 1], sNyLen+1, cs, sNyLen+1);
+
+      /* Siste linje i GINFO, trenger ikke � flytte noe i buffer */
+      } else if (lin_nr == Sys.pGrInfo->ngi) {
+         //strcpy(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[lin_nr - 1],cs);
+         UT_memcpy(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[lin_nr - 1], sNyLen+1, cs, sNyLen+1);
+
+         /* Oppdater antall tegn brukt i GINFO-buffer */
+         Sys.pGrInfo->ulGiLen = Sys.pGrInfo->ulGiLen - sGmlLen + sNyLen;
+
+      /* M� flytte resten av buffer for � tilpasse plassen */
+      } else {
+         memmove(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[lin_nr] - sGmlLen + sNyLen,
+                 Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[lin_nr],
+                 Sys.pGrInfo->ulGiLen - Sys.Ginfo.ulOfset[lin_nr]);
+         //strcpy(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[lin_nr - 1],cs);
+         UT_memcpy(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[lin_nr - 1], sNyLen+1, cs, sNyLen+1);
+
+         /* Oppdater antall tegn brukt i GINFO-buffer */
+         Sys.pGrInfo->ulGiLen += (sNyLen - sGmlLen);
+         /* Oppdater pekere til GINFO linjene */
+         LX_CreGiPeker(&Sys.Ginfo,Sys.pGrInfo->ngi);
+      }
+   }
+}
+
+/*
+AR-930609
+CH LX_CreGiPeker                              Bygg opp pekertabell til GINFO
+CD ==========================================================================
+CD Form�l:
+CH Bygg opp pekertabell til GINFO buffer.
+CD
+CD Parametre:
+CD Type            Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GINFO       *pGinfo     i    Peker til GINFO struktur
+CD short           ngi        i    Ant. GINFO linjer
+CD
+CD Bruk:
+CD LX_CreGiPeker(&Sys.Ginfo,Sys.pGrInfo->ngi);
+   ==========================================================================
+*/
+void LX_CreGiPeker(LC_GINFO_BUFFER * pGinfo,short ngi)
+{
+   short i;
+   unsigned long *pulOfset = pGinfo->ulOfset;
+   char *cp = pGinfo->pszTx;
+
+   /* F�rste GINFO starter alltid i posisjon 0 */
+   *pulOfset++ = 0;
+
+   /* Skanner strengen og finner startposisjonen for resten av GINFO */
+   for (i=1; i<ngi; ++i) {
+      cp = strchr(cp,'\0') + 1;
+      *pulOfset++ = (unsigned long) (cp - pGinfo->pszTx);
+   }
+}
+
+
+/*
+AR-930609
+CH LX_GetGi                                           Intern get GINFO-linje
+CD ==========================================================================
+CD Form�l:
+CD Henter en GINFO-linje som en streng rent generellt.
+CD Dette omfatter ogs� serienummer og referansenummer.
+CD Returnerer peker til den aktuelle strengen i GINFO-buffer.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD short    lin_nr   i    Linjenummer i GINFO   (1 er f�rste linje)
+CD char    *ginfo    r    Peker til GINFO-streng avslutta med '\0'
+CD
+CD Bruk:
+CD ginfo = LX_GetGi(lin_nr);
+   ==========================================================================
+*/
+char *LX_GetGi(short lin_nr)
+{
+   return  Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[lin_nr - 1];
+}
+
+
+/*
+AR-930609
+CH LC_GetGi                                                  Get GINFO-linje
+CD ==========================================================================
+CD Form�l:
+CD Henter en GINFO-linje som en streng rent generellt.
+CD Dette omfatter ogs� serienummer og referansenummer.
+CD Strengen ligger i et felles "returbuffer" for alle get-rutiner i fyba.
+CD Dette blir �delagt ved neste kall til en "get-rutine". For � ta vare p�
+CD strengen m� den kopieres over til egen streng. (Bruk strcpy).
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD short    lin_nr   i    Linjenummer i GINFO   (1 er f�rste linje)
+CD char    *ginfo    r    Peker til GINFO-streng avslutta med '\0'
+CD
+CD Bruk:
+CD ginfo = LC_GetGi(lin_nr);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA char *LC_GetGi(short lin_nr)
+{
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                  /* Aktuell gruppe OK */
+
+      if (lin_nr > 0 && lin_nr <= Sys.pGrInfo->ngi) {       /* Lovlig linje ?  */
+
+         UT_StrCopy(retur_str,LX_GetGi(lin_nr),LC_MAX_SOSI_LINJE_LEN);
+
+      } else {                              /* Ulovlig linjenummer */
+         *retur_str = '\0';
+      }
+
+   } else {                              /* Ingen aktuell gruppe */
+       LC_Error(49,"(LC_GetGi)","");
+       *retur_str = '\0';
+   }
+
+   return retur_str;
+}
+
+
+/*
+AR-910219
+CH LC_PutTK                                                     Put koordinat
+CD ==========================================================================
+CD Form�l:
+CD Legger inn et punkts koordinater (n,�) i meter i terreng
+CD
+CD Parametre:
+CD Type    Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long   punkt_nr   i    Punktnummer (1 er f�rste punkt)
+CD double  aust       i    �st-koordinat i meter i terreng
+CD double  nord       i    Nord-koordinat i meter i terreng
+CD
+CD Bruk:
+CD LC_PutTK(punkt_nr,aust,nord);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_PutTK(long punkt_nr,double aust,double nord)
+{
+   if (Sys.GrId.lNr != INGEN_GRUPPE){                  /* Aktuell gruppe OK */
+
+      if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) {    /* Lovlig punkt ? */
+
+         *(Sys.pdAust + punkt_nr - 1) = aust;    /* �st */
+         *(Sys.pdNord + punkt_nr - 1) = nord;    /* Nord */
+
+         Sys.sGrEndra = END_ENDRA;
+
+      } else {                                     /* Ulovlig punktnummer */
+         UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+         LC_Error(51,"(LC_PutTK)",err().tx);
+      }
+
+   } else {                              /* Ingen aktuell gruppe */
+       LC_Error(49,"(LC_PutTK)","");
+   }
+}
+
+
+/*
+AR-930609
+CH LC_GetTK                                                     Get koordinat
+CD ==========================================================================
+CD Form�l:
+CD Henter et punkts koordinater (�,n) i meter i terreng
+CD
+CD Parametre:
+CD Type    Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long   punkt_nr   i    Punktnummer (1 er f�rste punkt)
+CD double  *aust      u    �st-koordinat i meter i terreng
+CD double  *nord      u    Nord-koordinat i meter i terreng
+CD
+CD Bruk:
+CD LC_GetTK(punkt_nr,&aust,&nord);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_GetTK(long punkt_nr,double *aust,double *nord)
+{
+   /* Aktuell gruppe OK? */
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {
+      /* Lovlig punkt ? */
+      if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) {
+         *aust = *(Sys.pdAust + punkt_nr - 1);    /* �st */
+         *nord = *(Sys.pdNord + punkt_nr - 1);    /* Nord */
+
+      /* Ulovlig punktnummer */
+      } else {
+         UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+         LC_Error(51,"(LC_GetTK)",err().tx);
+      }
+   }
+}
+
+
+/*
+AR-930617
+CH LC_GetArrayTK                                  Hent tabell med koordinater
+CD ==========================================================================
+CD Form�l:
+CD Henter tabell med koordinater (�,n) i meter i terreng
+CD
+CD Parametre:
+CD Type    Navn       I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD short   retning     i    Buffer-retning:
+CD                                HENT_FORRFRA ( 1) = vanlig,
+CD                                HENT_BAKFRA  (-1) = buffer skal snues.
+CD long    max_antall  i    Max antall punkt som kan hentes
+CD long    fra_punkt   i    Fra punktnummer (1 eller nko  er f�rste punkt)
+CD double  *aust       u    Peker til tab. for �st-koordinater
+CD double  *nord       u    Peker til tab. for nord-koordinater
+CD long    *antall     u    Antall punkt hentet
+CD
+CD Bruk:
+CD LC_GetArrayTK(retning,max_antall,fra_punkt,aust,nord,&lest);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_GetArrayTK(short retning,long max_antall,long fra_punkt,
+                   double *aust,double *nord,long *antall)
+{
+   long ant = 0;
+   long pt;
+   double *pdA,*pdN;
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                  /* Aktuell gruppe OK */
+
+      /* Hent bakfra */
+      if (retning == HENT_BAKFRA) {
+         if (fra_punkt > Sys.pGrInfo->nko)  fra_punkt = Sys.pGrInfo->nko;
+         pt = fra_punkt - 1;
+         pdA = Sys.pdAust + pt;
+         pdN = Sys.pdNord + pt;
+         while (ant < max_antall  &&  pt >= 0) {
+            ++ant;
+            *aust++ = *pdA--;    /* �st */
+            *nord++ = *pdN--;    /* Nord */
+            --pt;
+         }
+
+      /* Hent forrfra */
+      } else {
+         if (fra_punkt < 1)  fra_punkt = 1;
+         pt = fra_punkt - 1;
+         pdA = Sys.pdAust + pt;
+         pdN = Sys.pdNord + pt;
+         while (ant < max_antall  &&  pt < Sys.pGrInfo->nko) {
+            ++ant;
+            *aust++ = *pdA++;    /* �st */
+            *nord++ = *pdN++;    /* Nord */
+            ++pt;
+         }
+      }
+   }
+
+   *antall = ant;
+}
+
+
+/*
+AR-940630
+CH LC_GetArrayTH                                  Hent tabell med h�yder
+CD ==========================================================================
+CD Form�l:
+CD Henter tabell med h�yder
+CD
+CD Parametre:
+CD Type    Navn       I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD short   retning     i    Buffer-retning:
+CD                                HENT_FORRFRA ( 1) = vanlig,
+CD                                HENT_BAKFRA  (-1) = buffer skal snues.
+CD long    max_antall  i    Max antall punkt som kan hentes
+CD long    fra_punkt   i    Fra punktnummer (1 eller nko  er f�rste punkt)
+CD double  *aust       u    Peker til tab. for h�yder
+CD long   *antall     u    Antall punkt hentet
+CD
+CD Bruk:
+CD LC_GetArrayTH(retning,max_antall,fra_punkt,hoyde,&lest);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_GetArrayTH(short retning,long max_antall,long fra_punkt,
+                   double *hoyde,long *antall)
+{
+   short gilin;
+   char *gp;
+   long pt;
+   double dGiHoyde;
+   long ant = 0;
+
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                  /* Aktuell gruppe OK */
+      /* Hent h�yde fra GINFO */
+      gilin = 2;
+      gp = LC_GetGP(LN_GetNavn(&Sys.GrId.pFil->SosiNavn,L_HOYDE),
+                    &gilin,Sys.pGrInfo->ngi);
+      if (gp != NULL) {
+         dGiHoyde = strtod(gp,&gp);
+
+      } else {
+         dGiHoyde = HOYDE_MANGLER;
+      }
+
+      /* Hent aktuelle h�yder i punktene */
+
+      /* Hent bakfra */
+      if (retning == HENT_BAKFRA) {
+         if (fra_punkt > Sys.pGrInfo->nko)  fra_punkt = Sys.pGrInfo->nko;
+         pt = fra_punkt - 1;
+         while (ant < max_antall  &&  pt >= 0) {
+            ++ant;
+
+            if ((Sys.pGrInfo->info & GI_NAH) != 0  &&
+                (Sys.pInfo + pt)->dHoyde != HOYDE_MANGLER) {
+               *hoyde++ = (Sys.pInfo + pt)->dHoyde;
+
+            } else {
+               *hoyde++ = dGiHoyde;
+            }
+
+            pt--;
+         }
+
+      /* Hent forrfra */
+      } else {
+         if (fra_punkt < 1)  fra_punkt = 1;
+         pt = fra_punkt - 1;
+         while (ant < max_antall  &&  pt < Sys.pGrInfo->nko) {
+            ++ant;
+
+            if ((Sys.pGrInfo->info & GI_NAH) != 0  &&
+                (Sys.pInfo + pt)->dHoyde != HOYDE_MANGLER) {
+               *hoyde++ = (Sys.pInfo + pt)->dHoyde;
+
+            } else {
+               *hoyde++ = dGiHoyde;
+            }
+
+            ++pt;
+         }
+      }
+   }
+
+   *antall = ant;
+}
+
+
+/*
+AR-940630
+CH LC_PutTH                                                        Put h�yde
+CD ==========================================================================
+CD Form�l:
+CD Legger inn et punkts h�yde i meter i terreng
+CD
+CD Parametre:
+CD Type    Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long    punkt_nr   i    Punktnummer (1 er f�rste punkt)
+CD double  hoyde      i    H�yde i meter i terreng. Konstanten
+CD                         HOYDE_MANGLER (-999.999) angir at punktet ikke
+CD                         har h�ydeverdi.
+CD
+CD Bruk:
+CD LC_PutTH(punkt_nr,hoyde);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_PutTH(long punkt_nr, double hoyde)
+{
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                  /* Aktuell gruppe OK */
+
+      if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) {   /* Lovlig punkt ? */
+
+         if ((Sys.pGrInfo->info & GI_NAD) == 0) {
+
+             if (hoyde != HOYDE_MANGLER)  Sys.pGrInfo->info |= GI_NAH; // Husker at gruppen har h�yde
+                
+             (Sys.pInfo + punkt_nr - 1)->dHoyde = hoyde;
+         
+             Sys.sGrEndra = END_ENDRA;
+             if (punkt_nr == Sys.lPibufPnr)  Sys.sPibufStatus = LC_PIBUF_TOM;
+
+         /* Gruppen har ..NAD fra f�r og det pr�ves � legge inne en h�yde */
+         } else if (hoyde != HOYDE_MANGLER) {
+            LC_Error(132,"(LC_PutTH)",LC_GetGi(1));
+         }
+
+      } else {
+         UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+         LC_Error(51,"(LC_PutTH)",err().tx);
+      }
+   }
+}
+
+
+/*
+AR-9930609
+CH LC_GetTH                                                        Get h�yde
+CD ==========================================================================
+CD Form�l:
+CD Henter et punkts h�yde i meter i terreng. (Henter BARE FRA PUNKTET.)
+CD
+CD Parametre:
+CD Type    Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long    punkt_nr   i    Punktnummer (1 er f�rste punkt)
+CD double *hoyde      r    H�yde i meter i terreng. Konstanten
+CD                         HOYDE_MANGLER (-999.999) angir at punktet ikke
+CD                         har h�ydeverdi.
+CD
+CD Bruk:
+CD hoyde = LC_GetTH(punkt_nr);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA double LC_GetTH(long punkt_nr)
+{
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                /* Aktuell gruppe OK */
+      if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) {  /* Lovlig punkt ? */
+         /* Gruppen har ..NAH */
+         if ((Sys.pGrInfo->info & GI_NAH) != 0) {
+            return (Sys.pInfo + punkt_nr - 1)->dHoyde;
+         }
+
+      } else {                           /* Ulovlig punktnummer */
+         UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+         LC_Error(51,"(LC_GetTH)",err().tx);
+      }
+   }
+
+   return  HOYDE_MANGLER;
+}
+
+
+/*
+AR-940630
+CH LC_GetHoyde                                                     Get h�yde
+CD ==========================================================================
+CD Form�l:
+CD Henter et punkts h�yde i meter i terreng. (Henter fra punktet eller fra
+CD GINFO.)
+CD
+CD Parametre:
+CD Type    Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long    punkt_nr   i    Punktnummer (1 er f�rste punkt)
+CD double *hoyde      r    H�yde i meter i terreng. Konstanten
+CD                         HOYDE_MANGLER (-999.999) angir at punktet ikke
+CD                         har h�ydeverdi.
+CD
+CD Bruk:
+CD hoyde = LC_GetHoyde(punkt_nr);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA double LC_GetHoyde(long punkt_nr)
+{
+   short gilin;
+   char *gp;
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                /* Aktuell gruppe OK */
+      if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) {  /* Lovlig punkt ? */
+         /* Gruppen har ..NAH */
+         if ((Sys.pGrInfo->info & GI_NAH) != 0) {
+            /* Punktet har h�yde */
+            if ((Sys.pInfo + punkt_nr - 1)->dHoyde != HOYDE_MANGLER) {
+               return (Sys.pInfo + punkt_nr - 1)->dHoyde;
+            }
+         }
+
+         /* Punktet har ikke h�yde, sjekk GINFO */
+         gilin = 2;
+         gp = LC_GetGP(LN_GetNavn(&Sys.GrId.pFil->SosiNavn,L_HOYDE),
+                       &gilin,Sys.pGrInfo->ngi);
+         if (gp != NULL) {
+            return  strtod(gp,&gp);
+         }
+
+      } else {                           /* Ulovlig punktnummer */
+         UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+         LC_Error(51,"(LC_GetHoyde)",err().tx);
+      }
+   }
+
+   return  HOYDE_MANGLER;
+}
+
+
+/*
+AR-940630
+CH LC_PutTD                                                        Put dybde
+CD ==========================================================================
+CD Form�l:
+CD Legger inn et punkts dybde i meter i terreng
+CD
+CD Parametre:
+CD Type    Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long    punkt_nr   i    Punktnummer (1 er f�rste punkt)
+CD double  hoyde      i    Dybde i meter i terreng. Konstanten
+CD                         HOYDE_MANGLER (-999.999) angir at punktet ikke
+CD                         har dybdeverdi.
+CD
+CD Bruk:
+CD LC_PutTD(punkt_nr,dybde);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_PutTD(long punkt_nr, double dybde)
+{
+   if (Sys.GrId.lNr != INGEN_GRUPPE){                  /* Aktuell gruppe OK */
+
+      if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko){    /* Lovlig punkt ? */
+
+         if ((Sys.pGrInfo->info & GI_NAH) == 0) {
+
+             if (dybde != HOYDE_MANGLER)  Sys.pGrInfo->info |= GI_NAD;
+
+             (Sys.pInfo + punkt_nr - 1)->dHoyde = dybde;
+         
+             Sys.sGrEndra = END_ENDRA;
+             if (punkt_nr == Sys.lPibufPnr)  Sys.sPibufStatus = LC_PIBUF_TOM;
+
+         /* Gruppen har ..NAH fra f�r og det pr�ves � legge inn en dybde */
+         } else if (dybde != HOYDE_MANGLER) {
+            LC_Error(133,"(LC_PutTD)",LC_GetGi(1));
+         }
+
+      } else {
+         UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+         LC_Error(51,"(LC_PutTD)",err().tx);
+      }
+   }
+}
+
+
+/*
+AR-940630
+CH LC_GetTD                                                        Get dybde
+CD ==========================================================================
+CD Form�l:
+CD Henter et punkts dybde i meter i terreng. (Henter BARE FRA PUNKTET.)
+CD
+CD Parametre:
+CD Type    Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long    punkt_nr   i    Punktnummer (1 er f�rste punkt)
+CD double *dybde      r    Dybde i meter i terreng. Konstanten
+CD                         HOYDE_MANGLER (-999.999) angir at punktet ikke
+CD                         har dybdeverdi.
+CD
+CD Bruk:
+CD dybde = LC_GetTD(punkt_nr);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA double LC_GetTD(long punkt_nr)
+{
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                /* Aktuell gruppe OK */
+      if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) {  /* Lovlig punkt ? */
+         /* Gruppen har ..NAD */
+         if ((Sys.pGrInfo->info & GI_NAD) != 0) {
+            return (Sys.pInfo + punkt_nr - 1)->dHoyde;
+         }
+
+      } else {                           /* Ulovlig punktnummer */
+         UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+         LC_Error(51,"(LC_GetTD)",err().tx);
+      }
+   }
+
+   return  HOYDE_MANGLER;
+}
+
+
+/*
+AR-940630
+CH LC_GetDybde                                                     Get dybde
+CD ==========================================================================
+CD Form�l:
+CD Henter et punkts dybde i meter i terreng. (Henter fra punktet eller fra
+CD GINFO.)
+CD
+CD Parametre:
+CD Type    Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long    punkt_nr   i    Punktnummer (1 er f�rste punkt)
+CD double *hoyde      r    Dybde i meter i terreng. Konstanten
+CD                         HOYDE_MANGLER (-999.999) angir at punktet ikke
+CD                         har h�ydeverdi.
+CD
+CD Bruk:
+CD dybde = LC_GetHoyde(punkt_nr);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA double LC_GetDybde(long punkt_nr)
+{
+   short gilin;
+   char *gp;
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                /* Aktuell gruppe OK */
+      if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) {  /* Lovlig punkt ? */
+         /* Gruppen har ..NAD */
+         if ((Sys.pGrInfo->info & GI_NAD) != 0) {
+            /* Punktet har dybde */
+            if ((Sys.pInfo + punkt_nr - 1)->dHoyde != HOYDE_MANGLER) {
+               return (Sys.pInfo + punkt_nr - 1)->dHoyde;
+            }
+         }
+
+         /* Punktet har ikke dybde, sjekk GINFO */
+         gilin = 2;
+         gp = LC_GetGP(LN_GetNavn(&Sys.GrId.pFil->SosiNavn,L_DYBDE),
+                       &gilin,Sys.pGrInfo->ngi);
+         if (gp != NULL) {
+            return  strtod(gp,&gp);
+         }
+
+      } else {                           /* Ulovlig punktnummer */
+         UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+         LC_Error(51,"(LC_GetHoyde)",err().tx);
+      }
+   }
+
+   return  HOYDE_MANGLER;
+}
+
+
+/*
+AR-930609
+CH LC_GetPi                                                        Get PINFO
+CD ==========================================================================
+CD Form�l:
+CD Henter punktinformasjon i angitte punkt som en streng.
+CD Strengen ligger i et felles "returbuffer" for alle get-rutiner i fyba.
+CD Dette blir �delagt ved neste kall til en "get-rutine". For � ta vare p�
+CD strengen m� den kopieres over til egen streng. (Bruk strcpy).
+CD
+CD Parametre:
+CD Type    Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long   punkt_nr   i    Punktnummer (1 er f�rste punkt)
+CD char   *pinfo      r    Peker til punktinformasjon eksklusiv knutepunkt
+CD
+CD Bruk:
+CD pinfo = LC_GetPi(punkt_nr);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA char *LC_GetPi(long punkt_nr)
+{
+   unsigned long ulOfset;
+
+   *retur_str = '\0';
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                   /* Aktuell gruppe OK */
+      if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) {    /* Lovlig punkt ? */
+
+         ulOfset = (Sys.pInfo+punkt_nr-1)->ulPiOfset;
+
+         if (ulOfset != LC_INGEN_PINFO) {
+            UT_StrCopy(retur_str,Sys.pszPinfo+ulOfset,LC_MAX_SOSI_LINJE_LEN);
+
+         }
+
+      } else {                           /* Ulovlig punktnummer */
+         UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+         LC_Error(51,"(LC_GetPi)",err().tx);
+      }
+   }
+
+   return retur_str;
+}
+
+
+/*
+AR-930609
+CH LC_PutPi                                                         Put PINFO
+CD ==========================================================================
+CD Form�l:
+CD Legger inn hele punktinformasjonen p� angitte punkt
+CD Ny verdi skriver over eksisterende verdi.
+CD Verdi "" fjerner eksisterende PINFO.
+CD Knutepunkt legges inn med LC_PutKp.
+CD
+CD Parametre:
+CD Type    Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long    punkt_nr   i    Punktnummer (1 er f�rste punkt)
+CD char   *pinfo      i    PINFO-streng som skal legges inn
+CD                         (Knutepunkt regnes ikke som pinfo)
+CD short   sStatus    r    UT_TRUE = OK,
+CD                         UT_FALSE = ikke utf�rt (for lite plass tilgjengelig)
+CD
+CD Bruk:
+CD sStatus = LC_PutPi(punkt_nr,pinfo);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_PutPi(long punkt_nr, const char *pinfo)
+{
+   short sNyLen, sGmlLen;
+   long pt;
+   unsigned long ulOfset;
+   char *pszBuffer = NULL;
+   short sStatus = UT_FALSE;
+
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                  /* Aktuell gruppe OK */
+
+      if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) {    /* Lovlig punkt ? */
+
+         /* Fjern blanke i starten */
+         while (UT_IsSpace(*pinfo)) {
+            ++pinfo;
+         }
+         sNyLen = (short)strlen(pinfo);
+         
+         if (sNyLen > 0) {
+            /* Ta kopi av strengen */
+         	pszBuffer = (char*)UT_MALLOC(sNyLen+1);
+         	UT_StrCopy(pszBuffer,pinfo,sNyLen+1);
+            pinfo = pszBuffer;
+
+            /* Fjern blanke p� slutten */
+            UT_ClrTrailsp(pszBuffer);
+            sNyLen = (short)strlen(pszBuffer);
+         }
+
+         /* Gammel lengde av PINFO */
+         ulOfset = (Sys.pInfo+punkt_nr-1)->ulPiOfset;
+         if (ulOfset == LC_INGEN_PINFO) {
+            sGmlLen = 0;
+         } else {
+            sGmlLen = (short)strlen(Sys.pszPinfo+ulOfset);
+         }
+
+         /* --------------------- Blank ut PINFO */
+         if (sNyLen == 0) {
+            /* Punktet har PINFO fra f�r */
+            if (sGmlLen > 0) {
+               /* Merk at punktet ikke har PINFO */
+               (Sys.pInfo+punkt_nr-1)->ulPiOfset = LC_INGEN_PINFO;
+                  
+               /* Pakk innholdet i bufferet */
+               memmove(Sys.pszPinfo + ulOfset,
+                       Sys.pszPinfo + ulOfset + sGmlLen + 1,
+                       Sys.pGrInfo->ulPiLen - ulOfset - sGmlLen - 1);
+ 
+               /* Oppdater ofset for resten av gruppen */
+               /* if (Sys.pGrInfo->ulPiLen > ulOfset + sGmlLen + 1) { */
+                  for (pt=punkt_nr; pt < Sys.pGrInfo->nko; ++pt) {
+                     if ((Sys.pInfo+pt)->ulPiOfset != LC_INGEN_PINFO) {
+                        (Sys.pInfo+pt)->ulPiOfset -= (sGmlLen + 1);
+                     }
+                  }
+               /* } */
+
+               /* Ny totallengde av PINFO i denne gruppen */
+               Sys.pGrInfo->ulPiLen -= sGmlLen;
+            }
+
+
+         /* --------------------- Legg inn PINFO */
+         } else {
+         
+            /* Sjekk om det blir plass til den nye PINFO'en */
+            if (((long)Sys.pGrInfo->ulPiLen - (long)sGmlLen + (long)sNyLen) < LC_MAX_PINFO_BUFFER) {
+               sStatus = UT_TRUE;
+            
+               /* Punktet har ikke PINFO fra f�r */
+               if (sGmlLen == 0) {
+                  /* S�k mot starten av gruppen for � finne slutten av forrige PINFO */
+                  ulOfset = 0;
+                  for (pt=punkt_nr-2; pt>=0; pt--) {
+                     if ((Sys.pInfo+pt)->ulPiOfset != LC_INGEN_PINFO) {
+                        /* ulOfset = (strlen(Sys.pszPinfo+(Sys.pInfo+pt)->ulPiOfset) + 1); */
+                        ulOfset = (Sys.pInfo+pt)->ulPiOfset +
+                                  strlen(Sys.pszPinfo+(Sys.pInfo+pt)->ulPiOfset) + 1;
+                        break;  /* ---> avbryter for-l�kka */
+                     } /* endif */
+                  } /* endfor */
+
+                  /* Husk ofset */
+                  (Sys.pInfo+punkt_nr-1)->ulPiOfset = ulOfset;
+
+                  /* Flytt innholdet i bufferet */
+                  memmove(Sys.pszPinfo + ulOfset + sNyLen + 1,
+                          Sys.pszPinfo + ulOfset,
+                          Sys.pGrInfo->ulPiLen - ulOfset);
+
+                  /* Oppdater ofset for resten av gruppen */
+                  /* if (Sys.pGrInfo->ulPiLen > ulOfset + sGmlLen + 1) { */
+                     for (pt=punkt_nr; pt < Sys.pGrInfo->nko; ++pt) {
+                        if ((Sys.pInfo+pt)->ulPiOfset != LC_INGEN_PINFO) {
+                           (Sys.pInfo+pt)->ulPiOfset += (sNyLen + 1);
+                        }
+                     }
+                  /* } */
+
+                  /* Kopier inn strengen */
+                  //strcpy(Sys.pszPinfo+ulOfset, pinfo);
+                  UT_memcpy(Sys.pszPinfo+ulOfset, sNyLen+1, pinfo, sNyLen+1);
+
+                  /* Ny totallengde */
+                  Sys.pGrInfo->ulPiLen += (sNyLen + 1);
+
+               /* Samme lengde, trenger ikke � flytte noe i buffer */
+               } else if (sNyLen == sGmlLen) {
+                  //strcpy(Sys.pszPinfo+ulOfset, pinfo);
+                  UT_memcpy(Sys.pszPinfo+ulOfset, sNyLen+1, pinfo, sNyLen+1);
+
+               /* Punktet har PINFO, men med annen lengde */
+               } else {
+                  /* Flytt innholdet i bufferet */
+                  memmove(Sys.pszPinfo + ulOfset + sNyLen + 1,
+                          Sys.pszPinfo + ulOfset + sGmlLen + 1,
+                          Sys.pGrInfo->ulPiLen - ulOfset - sGmlLen - 1);
+
+                  /* Kopier inn strengen */
+                  //strcpy(Sys.pszPinfo+ulOfset, pinfo);
+                  UT_memcpy(Sys.pszPinfo+ulOfset, sNyLen+1, pinfo, sNyLen+1);
+
+                  /* Oppdater ofset for resten av gruppen */
+                  /* if (Sys.pGrInfo->ulPiLen > ulOfset + sGmlLen + 1) { */
+                     for (pt=punkt_nr; pt < Sys.pGrInfo->nko; ++pt) {
+                        if ((Sys.pInfo+pt)->ulPiOfset != LC_INGEN_PINFO) {
+                           (Sys.pInfo+pt)->ulPiOfset += (sNyLen - sGmlLen);
+                        }
+                     }
+                  /* } */
+
+                  /* Ny totallengde */
+                  Sys.pGrInfo->ulPiLen += (sNyLen - sGmlLen);
+               }
+            }
+ 
+            /* Husk at gruppen har PINFO */
+            Sys.pGrInfo->info |= GI_PINFO;
+         }
+
+         /* Husk at gruppen er endret */
+         Sys.sGrEndra = END_ENDRA;
+         if (punkt_nr == Sys.lPibufPnr)  Sys.sPibufStatus = LC_PIBUF_TOM;
+
+         /* Frigir midlertidig buffer */
+         if (pszBuffer != NULL)  UT_FREE(pszBuffer);
+
+      } else {                            /* Ulovlig punktnummer */
+         UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+         LC_Error(51,"(LC_PutPi)",err().tx);
+      }
+
+   } else {                              /* Ingen aktuell gruppe */
+      LC_Error(49,"(LC_PutPi)","");
+   }
+
+   return sStatus;
+}
+
+
+/*
+AR-930609
+CH LC_TestPi                                        Sjekk om punkt har PINFO
+CD ==========================================================================
+CD Form�l:
+CD Sjekker om et punkt har PINFO i en eller annen form.
+CD (PINFO, KP, h�yde.)
+CD H�yde handteres ikke forel�pig.
+CD
+CD Parametre:
+CD Type    Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long    punkt_nr   i    Punktnummer (1 er f�rste punkt)
+CD short   sTestHoyde i    Bryter for � si om h�yde skal regnes med i sjekken.
+CD short   sStatus    r    UT_TRUE=har "pinfo", UT_FALSE=har ikke "pinfo"
+CD
+CD Bruk:
+CD sStatus = LC_TestPi(punkt_nr,UT_TRUE);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_TestPi(long punkt_nr,short sTestHoyde)
+{
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                 /* Aktuell gruppe OK */
+      if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) {   /* Lovlig punkt ? */
+
+         /* ==> H�yde skal behandles */
+         if (sTestHoyde) {
+            /* if (Sys.pGrInfo->info & GI_NAH)  return UT_TRUE; */
+            return UT_TRUE;
+         }
+
+         /* ==> Har PINFO */
+         if ((Sys.pInfo+punkt_nr-1)->ulPiOfset != LC_INGEN_PINFO) {
+            return UT_TRUE;
+
+         /* ==> Har KP */
+         } else if ((Sys.pInfo+punkt_nr-1)->sKp != 0) {
+            return UT_TRUE;
+         }
+
+      } else {                           /* Ulovlig punktnummer */
+         UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+         LC_Error(51,"(LC_GetPi)",err().tx);
+      }
+   }
+
+   return UT_FALSE;
+}
+
+
+/*
+AR-930609
+CH LC_GetKp                                                    Get knutepunkt
+CD ==========================================================================
+CD Form�l:
+CD Henter knutepunktverdi i punktet.
+CD
+CD Parametre:
+CD Type    Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long   punkt_nr   i    Punktnummer (1 er f�rste punkt)
+CD short   kp_type    r    Knutepunkttype (1-4095)
+CD                         (0 = punktet har ikke knutepunkt)
+CD
+CD Bruk:
+CD kp = LC_GetKp(punkt_nr);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetKp(long punkt_nr)
+{
+   if (Sys.GrId.lNr != INGEN_GRUPPE){                  /* Aktuell gruppe OK */
+
+      if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko){    /* Lovlig punkt ? */
+         return  (Sys.pInfo+punkt_nr-1)->sKp;
+
+      } else{                            /* Ulovlig punktnummer */
+         UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+         LC_Error(51,"(LC_GetKp)",err().tx);
+      }
+   }
+
+   return (0);
+}
+
+
+/*
+AR-930609
+CH LC_PutKp                                                    Put knutepunkt
+CD ==========================================================================
+CD Form�l:
+CD Legger inn knutepunktverdi i punktet. Ny verdi skrives over eksisterende
+CD verdi. (Multiple KP er ikke mulig.)
+CD
+CD Parametre:
+CD Type    Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long   punkt_nr   i    Punktnummer (1 er f�rste punkt)
+CD short   kp         i    Knutepunkt (lovlig verdi 0 - SHRT_MAX)
+CD                         kp == 0 fjerner knutepunkt.
+CD
+CD Bruk:
+CD LC_PutKp(punkt_nr,kp);
+   ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_PutKp(long punkt_nr, short kp)
+{
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {                 /* Aktuell gruppe OK */
+      if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) {   /* Lovlig punkt ? */
+         if (kp >= 0  &&  kp < SHRT_MAX) {
+            if (kp != 0)  Sys.pGrInfo->info |= GI_KP;   /* Merk at gruppen har KP */
+
+            (Sys.pInfo+punkt_nr-1)->sKp = kp;
+
+            Sys.sGrEndra = END_ENDRA;
+            if (punkt_nr == Sys.lPibufPnr)  Sys.sPibufStatus = LC_PIBUF_TOM;
+
+            /* Husk at det finnes KP i filen */
+            if (kp > 0) {
+               if ( Sys.GrId.pFil->SosiNiv[1] < 3) {
+                  Sys.GrId.pFil->SosiNiv[1] = 3;
+               }
+            }
+
+         } else {
+            UT_SNPRINTF(err().tx,LC_ERR_LEN," %d",kp);
+            LC_Error(53,"(LC_PutKp)",err().tx);
+         }
+
+      } else {
+         UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+         LC_Error(51,"(LC_PutKp)",err().tx);
+      }
+
+   } else {                              /* Ingen aktuell gruppe */
+      LC_Error(49,"(LC_PutKp)","");
+   }
+}
+
+
+/*
+AR-911106
+CH LC_BerAreal                                 Beregn areal av aktuell FLATE
+CD ==========================================================================
+CD Form�l:
+CD Beregner arealet av aktuell gruppe hvis denne er flate.
+CD Referansene brukes for arealberegningen.
+CD Tar hensyn til fradrag for �yer.
+CD
+CD Parametre:
+CD Type     Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   areal     u    Beregnet areal
+CD
+CD Bruk:
+CD areal = LC_BerAreal();
+   =============================================================================
+*/
+SK_EntPnt_FYBA double LC_BerAreal(void)
+{
+   short ngi;
+   long nko;
+   unsigned short info;
+   #define  MAX_REFERANSE  20
+   long ref_arr[MAX_REFERANSE];
+   unsigned char ref_status[MAX_REFERANSE];
+   long ant_ref;
+   short s,retning;
+   LC_GRF_STATUS GrfStat;
+   LC_BGR BgrFlate,Bgr;
+
+   double dTotalAreal = 0.0;
+   double dDelAreal = 0.0;
+
+   /* Husk gruppenummer for flaten */
+   LC_GetGrNr(&BgrFlate);
+   Bgr.pFil = BgrFlate.pFil;
+
+
+   /* Behandle ytre avgrensing */
+   LC_InitGetRefFlate(&GrfStat);
+   ant_ref = LC_GetRefFlate(&GrfStat,GRF_YTRE,ref_arr,ref_status,MAX_REFERANSE);
+   do {
+      for (s=0; s<ant_ref; ++s) {
+         Bgr.lNr = ref_arr[s];
+         retning = (ref_status[s] & LC_MED_DIG)?
+                                            HENT_FORRFRA : HENT_BAKFRA;
+         dTotalAreal += LX_ArealGruppe(&Bgr,retning);
+      }
+      /* Les inn flaten igjen */    
+      LC_RxGr(&BgrFlate,LES_OPTIMALT,&ngi,&nko,&info);
+
+      if (ant_ref < MAX_REFERANSE)  break;
+
+      ant_ref = LC_GetRefFlate(&GrfStat,GRF_YTRE,ref_arr,ref_status,MAX_REFERANSE);
+   } while (ant_ref > 0);
+
+   /* Beregn endelig areal innenfor yttergrensen */
+   dTotalAreal = fabs(dTotalAreal / 2.0);
+
+
+   /* Behandler indre avgrensing (�y) */
+   LC_InitGetRefFlate(&GrfStat);
+   ant_ref = LC_GetRefFlate(&GrfStat,GRF_INDRE,ref_arr,ref_status,MAX_REFERANSE);
+   do {
+      for (s=0; s<ant_ref; ++s) {
+         if (ref_status[s] & GRF_START_OY) {
+            dDelAreal = 0.0;
+
+         } else if (ref_status[s] & GRF_SLUTT_OY) {
+            /* Beregn endelig areal innenfor yttergrensen */
+            dTotalAreal -= fabs(dDelAreal / 2.0);
+
+         } else {
+            Bgr.lNr = ref_arr[s];
+            retning = (ref_status[s] & LC_MED_DIG)?
+                                             HENT_FORRFRA : HENT_BAKFRA;
+            dDelAreal += LX_ArealGruppe(&Bgr,retning);
+         }
+      }
+      /* Les inn flaten igjen */    
+      LC_RxGr(&BgrFlate,LES_OPTIMALT,&ngi,&nko,&info);
+
+      if (ant_ref < MAX_REFERANSE)  break;
+
+      ant_ref = LC_GetRefFlate(&GrfStat,GRF_INDRE,ref_arr,ref_status,MAX_REFERANSE);
+   } while (ant_ref > 0);
+
+   return  dTotalAreal;
+}
+
+
+/*
+AR-900731
+CH LX_BerArealGruppe             Beregn areal "arealandel" av aktuell gruppe
+CD ==========================================================================
+CD Form�l:
+CD Beregner areal av polygon angitt av yttergrensen av aktuell gruppe.
+CD Forutsetter .FLATE og det er referansene som brukes i arealberegningen.
+CD
+CD Parametre:
+CD Type     Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR *  pBgr      i    Gruppepeker
+CD short    retning   i    HENT_FORRFRA eller HENT_BAKFRA 
+CD double   areal     u    Beregnet areal
+CD
+CD Bruk:
+CD areal = LX_ArealGruppe(&Bgr,retning);
+   =============================================================================
+*/
+static double LX_ArealGruppe(LC_BGR * pBgr,short retning)
+{
+   #define  ARR_LEN  50
+   short ngi, gruppenavn;
+   long nko, pt, antall, punkt;
+   unsigned short info;
+   short storbue;
+   double a1,n1,a2,n2,a3,n3,radius,as,ns,fi,dfi;
+   double n_arr[ARR_LEN],a_arr[ARR_LEN];
+   double a_forrige=0.0, n_forrige=0.0, a, n;
+   short forste;
+   double areal_seg = 0.0; 
+   double areal_poly = 0.0;
+
+   gruppenavn = LC_RxGr(pBgr,LES_OPTIMALT,&ngi,&nko,&info);
+   if (nko > 0) {
+      if (gruppenavn == L_BUE) {   /* .BUE */
+         if (LC_GetBue(retning,&a1,&n1,&a2,&n2,&radius,&storbue)){
+            areal_poly += (a1 - a2) * (n1 + n2);
+            /* Sektoren */
+            if (GM_KonvBue(a1,n1,a2,n2,radius,storbue,
+                           &as,&ns,&fi,&dfi)){
+               areal_seg += (radius*radius*(dfi-sin(dfi)));
+            }
+         }
+
+      } else if (gruppenavn == L_BUEP){   /* .BUEP */
+         if (LC_GetBuep(retning,&a1,&n1,&a2,&n2,&a3,&n3)) {
+            areal_poly += (a1 - a3) * (n1 + n3);
+            /* Sektoren */
+            if (GM_KonvBuep(a1,n1,a2,n2,a3,n3,
+                            &as,&ns,&radius,&fi,&dfi)) {
+               areal_seg += (radius*radius*(dfi-sin(dfi)));
+            }
+         }
+
+      } else if (gruppenavn == L_SIRKEL) {   /* .SIRKEL */
+         if (LC_GetSirkel(&as,&ns,&radius)) {
+            /* Dobbelt areal av sirkelen */
+            areal_seg = 2.0 * PI * radius * radius;
+         }
+
+      } else if (gruppenavn == L_SIRKELP) {   /* .SIRKELP */
+         if (LC_GetSirkelp(&a1,&n1,&a2,&n2,&a3,&n3)) {
+            if (GM_KonvSirkelp(a1,n1,a2,n2,a3,n3,
+                            &as,&ns,&radius,&fi,&dfi)) {
+               /* Dobbelt areal av sirkelen */
+               areal_seg = 2.0 * PI * radius * radius;
+            }
+         }
+
+      } else {                    /* Annen gruppe */
+         punkt = (retning == HENT_FORRFRA)?  1 : nko;
+         forste = UT_TRUE;
+
+         do {                       /* Beregn areal */
+            LC_GetArrayTK(retning,ARR_LEN,punkt,a_arr,n_arr,&antall);/* Henter */
+            if (antall > 0) {
+               if (forste) {
+                  a_forrige = a_arr[0];
+                  n_forrige = n_arr[0];
+                  forste = UT_FALSE;
+               }
+               for (pt=1; pt<antall; ++pt) {
+                  a = a_arr[pt];
+                  n = n_arr[pt];
+                  areal_poly += (a_forrige - a) * (n_forrige + n);
+                  a_forrige = a;
+                  n_forrige = n;
+               }
+
+               if (retning == HENT_FORRFRA) {
+                  punkt += (antall-1);
+                  if (punkt >= nko)   antall = 0;
+               } else{
+                  punkt -= (antall-1);
+                  if (punkt <= 1)   antall = 0;
+               }
+            }
+         } while (antall == ARR_LEN);
+      }
+   }
+
+   return  (areal_poly + areal_seg);
+}
+
+
+/*
+AR-911106
+CH LC_BerLengde                   Beregn horisontal lengde av aktuell gruppe
+CD ==========================================================================
+CD Form�l:
+CD Beregn horisontal lengde av aktuell gruppe.
+CD Tar ikke hensyn til h�yde/dybde.
+CD Referansene brukes IKKE i beregningen.
+CD
+CD Parametre:
+CD Type     Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   lengde    u    Beregnet lengde
+CD
+CD Bruk:
+CD areal = LC_BerLengde();
+=============================================================================
+*/
+SK_EntPnt_FYBA double LC_BerLengde(void)
+{
+   short sfeil;
+   long l;
+   double a1,n1,a2,n2,rx,as,ns,fi,dfi;
+   double lengde = 0.0;
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE) {
+      if (Sys.pGrInfo->gnavn == L_LINJE  ||  Sys.pGrInfo->gnavn == L_KURVE) {
+         for (l=2; l<=Sys.pGrInfo->nko; ++l) {
+            LC_GetTK(l-1,&a1,&n1);
+            LC_GetTK(l,&a2,&n2);
+            lengde += sqrt((n2-n1)*(n2-n1)+(a2-a1)*(a2-a1));
+         }
+
+                  // Handterer "bue"
+      } else if (Sys.pGrInfo->gnavn == L_BUE  ||  Sys.pGrInfo->gnavn == L_BUEP ||
+            Sys.pGrInfo->gnavn == L_SIRKEL  ||  Sys.pGrInfo->gnavn == L_SIRKELP) {
+
+         if (LC_GetBuePar(HENT_FORRFRA,&as,&ns,&rx,&fi,&dfi,&sfeil)) {
+            lengde = fabs (rx * dfi);
+         }
+      }
+   }
+
+   return lengde;
+}
+
+
+/*
+AR-911106
+CH LC_BerLengde3D                       Beregn skr� lengde av aktuell gruppe
+CD ==========================================================================
+CD Form�l:
+CD Beregn skr� lengde av aktuell gruppe.
+CD Krever at det finnes h�yde/dybde i alle punkt.
+CD Referansene brukes IKKE i beregningen.
+CD Beregner bare for LINJE og KURVE.
+CD
+CD Parametre:
+CD Type     Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   lengde    u    Beregnet lengde
+CD bool     beregnet  r    Status som viser om lengde er beregnet
+CD
+CD Bruk:
+CD beregnet = LC_BerLengde3D(&skraa_lengde);
+=============================================================================
+*/
+SK_EntPnt_FYBA bool LC_BerLengde3D(double *skraa_lengde)
+{
+   long s;
+   double a1,n1,a2,n2,h1,h2,da,dn,dh;
+  
+   bool beregnet = false;
+
+   *skraa_lengde = 0.0;
+   
+
+   if (Sys.GrId.lNr != INGEN_GRUPPE)
+   {
+
+      // Beregn skr� lengde
+      if (Sys.pGrInfo->gnavn == L_LINJE  ||  Sys.pGrInfo->gnavn == L_KURVE) 
+      {
+         // Husk om gruppen har h�yde/dybde
+         beregnet = ((Sys.pGrInfo->info & GI_NAH) || (Sys.pGrInfo->info & GI_NAD))?  true : false;
+
+         for (s=2; beregnet && s<=Sys.pGrInfo->nko; s++)
+         {
+            LC_GetTK(s-1,&a1,&n1);
+            if (Sys.pGrInfo->info & GI_NAD)
+            {
+               h1 = LC_GetDybde(s-1);
+            }
+            else
+            {
+               h1 = LC_GetHoyde(s-1);
+            }
+
+            LC_GetTK(s,&a2,&n2);
+            if (Sys.pGrInfo->info & GI_NAD)
+            {
+               h2 = LC_GetDybde(s);
+            }
+            else
+            {
+               h2 = LC_GetHoyde(s);
+            }
+
+
+            if (h1 != HOYDE_MANGLER  && h2 != HOYDE_MANGLER)
+            {
+               da = a2 - a1;
+               dn = n2 - n1;
+               dh = h2 - h1;
+               (*skraa_lengde) += sqrt(dn*dn + da*da + dh*dh);
+            }
+            else
+            {
+               beregnet = false;
+            }
+         }
+      }
+   }
+
+   return beregnet;
+}
+
+
+/*
+AR:2009-04-28
+CH LC_BerAvgrensLengde                Beregn lengden av avgrensning av FLATE
+CD ==========================================================================
+CD Form�l:
+CD Beregn lengden av avgrensningen av aktuell gruppe hvis denne er flate.
+CD B�de indre og ytre avgrensning beregnes.
+CD
+CD Parametre:
+CD Type     Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   lengde     u    Beregnet areal
+CD
+CD Bruk:
+CD lengde = LC_BerAvgrensLengde();
+=============================================================================
+*/
+SK_EntPnt_FYBA double LC_BerAvgrensLengde(void)
+{
+   short ngi;
+   long nko;
+   unsigned short info;
+   LC_BGR BgrFlate;
+   double dSumLengde = 0.0;
+
+   if (Sys.pGrInfo->info & GI_REF)
+   {        
+      // Husk gruppenummer for flaten
+      LC_GetGrNr(&BgrFlate);
+
+      LC_POLYGON Polygon;
+      LC_POL_InitPolygon(&Polygon);
+      LC_POL_GetRef(&Polygon);
+
+      LC_POL_ELEMENT * pPE;
+      // Ytre avgrensning
+      for(pPE = Polygon.HovedPO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+         LC_RxGr(&pPE->Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+         dSumLengde += LC_BerLengde();
+      }
+
+      // Indre avgrensning
+      LC_OY_ELEMENT * pOE;
+      for (pOE = Polygon.OyOA.pForsteOE; pOE != NULL; pOE = pOE->pNesteOE) {
+         for (pPE = pOE->PO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+            LC_RxGr(&pPE->Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+            dSumLengde += LC_BerLengde();
+         }
+      }
+
+      // Frigi allokerte kjeder
+      LC_POL_FrigiPolygon(&Polygon);
+
+      // Les inn flaten igjen
+      LC_RxGr(&BgrFlate,LES_OPTIMALT,&ngi,&nko,&info);
+   }
+
+   return  dSumLengde;
+}
+
+
+/*
+AR:2009-04-28
+CH LC_BerIndreAvgrensLengde      Beregn lengden av indre avgrensning av FLATE
+CD ==========================================================================
+CD Form�l:
+CD Beregn lengden av indre avgrensningen av aktuell gruppe hvis denne er flate.
+CD Bare indre avgrensning beregnes.
+CD
+CD Parametre:
+CD Type     Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   lengde     u    Beregnet lengde
+CD
+CD Bruk:
+CD lengde = LC_BerIndreAvgrensLengde();
+=============================================================================
+*/
+SK_EntPnt_FYBA double LC_BerIndreAvgrensLengde(void)
+{
+   short ngi;
+   long nko;
+   unsigned short info;
+   LC_BGR BgrFlate;
+   double dSumLengde = 0.0;
+
+   if (Sys.pGrInfo->info & GI_REF)
+   {        
+      // Husk gruppenummer for flaten
+      LC_GetGrNr(&BgrFlate);
+
+      LC_POLYGON Polygon;
+      LC_POL_InitPolygon(&Polygon);
+      LC_POL_GetRef(&Polygon);
+
+      // Indre avgrensning
+      LC_OY_ELEMENT * pOE;
+      LC_POL_ELEMENT * pPE;
+      for (pOE = Polygon.OyOA.pForsteOE; pOE != NULL; pOE = pOE->pNesteOE) {
+         for (pPE = pOE->PO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+            LC_RxGr(&pPE->Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+            dSumLengde += LC_BerLengde();
+         }
+      }
+
+      // Frigi allokerte kjeder
+      LC_POL_FrigiPolygon(&Polygon);
+
+      // Les inn flaten igjen
+      LC_RxGr(&BgrFlate,LES_OPTIMALT,&ngi,&nko,&info);
+   }
+
+   return  dSumLengde;
+}
+
+
+
+/*
+AR:2009-04-28
+CH LC_BerYtreAvgrensLengde      Beregn lengden av ytre avgrensning av FLATE
+CD ==========================================================================
+CD Form�l:
+CD Beregn lengden av ytre avgrensningen av aktuell gruppe hvis denne er flate.
+CD Bare ytre avgrensning beregnes.
+CD
+CD Parametre:
+CD Type     Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   lengde     u    Beregnet lengde
+CD
+CD Bruk:
+CD lengde = LC_BerYtreAvgrensLengde();
+=============================================================================
+*/
+SK_EntPnt_FYBA double LC_BerYtreAvgrensLengde(void)
+{
+   short ngi;
+   long nko;
+   unsigned short info;
+   LC_BGR BgrFlate;
+   double dSumLengde = 0.0;
+
+   if (Sys.pGrInfo->info & GI_REF)
+   {        
+      // Husk gruppenummer for flaten
+      LC_GetGrNr(&BgrFlate);
+
+      LC_POLYGON Polygon;
+      LC_POL_InitPolygon(&Polygon);
+      LC_POL_GetRef(&Polygon);
+
+      LC_POL_ELEMENT * pPE;
+      // Ytre avgrensning
+      for(pPE = Polygon.HovedPO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+         LC_RxGr(&pPE->Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+         dSumLengde += LC_BerLengde();
+      }
+
+      // Frigi allokerte kjeder
+      LC_POL_FrigiPolygon(&Polygon);
+
+      // Les inn flaten igjen
+      LC_RxGr(&BgrFlate,LES_OPTIMALT,&ngi,&nko,&info);
+   }
+
+   return  dSumLengde;
+}
+
+
+/*
+AR-911106
+CH LC_DumpTab                               Dump interne tabeller til stderr
+CD ==========================================================================
+CD Form�l:
+CD Dump interne tabeller til stderr
+CD
+CD Parametre:
+CD Type     Navn     I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD
+CD Bruk:
+CD LC_DumpTab();
+   =============================================================================
+*/
+SK_EntPnt_FYBA void LC_DumpTab(void)
+{
+   short ngi,s;
+   long nko;
+   unsigned short info;
+   LC_BGR Bgr,AktBgr;
+
+   LC_GetGrNr(&AktBgr);
+
+   UT_FPRINTF(stderr,"\n=================================================\n");
+   UT_FPRINTF(stderr,"Dump av interne tabeller i FYBA\n");
+   UT_FPRINTF(stderr,"=================================================\n");
+
+   UT_FPRINTF(stderr,"\nLC_INGEN_PINFO = %lu\n", LC_INGEN_PINFO);
+
+   UT_FPRINTF(stderr,"\n    Snr    sosi_st     rb_st  rb_fgr  rb_ngr gna ngi  nko info    GiLen    PiLen\n");
+   LC_InitNextBgr(&Bgr);
+
+   /* Alle gruppene i framgrunn */
+   while (LC_NextBgr(&Bgr,LC_FRAMGR)) {
+      LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+      UT_FPRINTF(stderr,"%7ld: %9lld %9lld %7ld %7ld %3hd %3hd %5ld %4hx %8lu %8lu\n",
+           Sys.GrId.lNr,
+           Sys.pGrInfo->sosi_st,
+           Sys.pGrInfo->rb_st,
+           Sys.pGrInfo->rb_forrige_gr,
+           Sys.pGrInfo->rb_neste_gr,
+           Sys.pGrInfo->gnavn,
+           Sys.pGrInfo->ngi,
+           Sys.pGrInfo->nko,
+           Sys.pGrInfo->info,
+           Sys.pGrInfo->ulGiLen,
+           Sys.pGrInfo->ulPiLen);
+      /* List ut PINFO-pekerene */
+      if (ngi > 0) {
+         for (s=1; s<=Sys.pGrInfo->nko; ++s) {
+            if ((Sys.pInfo+s-1)->ulPiOfset != LC_INGEN_PINFO) {
+               UT_FPRINTF(stderr,"PI ofset %4hd: %8lu\n", s, (Sys.pInfo+s-1)->ulPiOfset);
+            }
+         }
+      }
+   }
+
+   if (AktBgr.lNr != INGEN_GRUPPE) {
+      LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+   }
+}
diff --git a/FYBA/FYTA.cpp b/FYBA/FYTA.cpp
new file mode 100644
index 0000000..85d5301
--- /dev/null
+++ b/FYBA/FYTA.cpp
@@ -0,0 +1,199 @@
+/* === 900607 ============================================================= */
+/*  STATENS KARTVERK  -  FYSAK-PC                                           */
+/*  Fil: fyta.c                                                             */
+/*  Innhold: Lagring og henting av "fil"-tabeller                           */
+/* ======================================================================== */
+
+#include "stdafx.h"
+
+#include <fcntl.h>
+
+
+/* Div. styrevariabler */
+#define NY    0
+#define LES   1
+#define SKRIV 2
+
+/* Tabellsystem */
+static short fytab_open = 0;
+static struct {
+   FILE   *fpek;
+   size_t recl;
+   short  modus;
+   long   cur_lin;
+} fytab;
+
+
+/*
+AR-900105
+CH LC_InitTabel                                           �pner tabellsystemet
+CD =============================================================================
+CD Form�l:
+CD Initierer tabellsystemet og �pner filen.
+CD
+CD Parametre:
+CD Type     Navn      I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD long     n_rec      i    Antall reckords som skal nullstilles. Disse kan
+CD                          etterp� brukes til tilfeldig aksess. Utvidelse
+CD                          av filen kan senere bare skje i fortl�pende
+CD                          rekkef�lge.
+CD short    rec_len    i    Reckordlengde. (Bruk sizeof for � finne lengden.)
+CD void    *buffer     i    Peker til buffer som skal brukes for nullstilling.
+CD short    ist        r    Status. (0=OK, -1=feil)
+CD
+CD Bruk:
+CD  .
+CD  struct{
+CD     long snr;
+CD     short ngi;
+CD     short nko;
+CD  } buffer;
+CD  .   
+CD  .
+CD  ist = LC_InitTabel(10000L,sizeof buffer,(void *)(&buffer));
+CD  .   
+CD  ist = LC_PutTabel(linje,(void *)&buffer);
+CD  .   
+CD  ist = LC_GetTabel(linje,(void *)&buffer);
+CD  .   
+CD  LC_CloseTabel();
+   =============================================================================
+*/
+SK_EntPnt_FYBA short LC_InitTabel(long n_rec,short rec_len,void *buffer)
+{
+   short ierr;
+
+   if (fytab_open){                    /* Systemet er allerede i bruk */
+      return -1;
+   }
+                                       /* �pner tabellfilen */
+   fytab.fpek = UT_OpenFile("fytabell.tmp","",UT_UPDATE,UT_UNKNOWN,&ierr);
+   if (ierr != UT_OK){                 /* �pningsfeil */
+      return -1;
+   }
+
+   fytab.recl = rec_len;
+
+                                  /* Nullstill tabellen */
+   if (fseek(fytab.fpek,0L,SEEK_SET) != 0){
+      return -1;
+   }
+   for (; n_rec>0; n_rec--){
+      if (fwrite(buffer,fytab.recl,1,fytab.fpek) != 1){
+         return  -1;
+      }
+   }
+
+   fytab.modus = NY;
+   fytab_open = 1;                /* Merke for at systemet aktivisert */
+
+   return 0;
+}
+
+
+/*
+AR-900106
+CH LC_GetTabel                                               Get tabell-linje
+CD =============================================================================
+CD Form�l:
+CD Henter en linje fra tabellfilen.
+CD
+CD Parametre:
+CD Type      Navn   I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD long      linje   i    Linjenummer som skal hentes.  (0 er f�rste linje)
+CD void     *buffer  i    Peker til struktur som skal ta mot lest reckord.
+CD short     ist     r    Status (0=OK, -1=feil)
+CD
+CD Bruk:
+CD ist = LC_GetTabel(linje,(void *)&buffer);
+   =============================================================================
+*/
+SK_EntPnt_FYBA short LC_GetTabel(long linje,void *buffer)
+{
+   if ( ! fytab_open){        /* Systemet er ikke aktivisert */
+      return -1;
+   }
+
+   if (fytab.modus != LES || fytab.cur_lin != linje){       /* Posisjoner */
+      if (fseek(fytab.fpek,(long)(linje * fytab.recl),SEEK_SET) != 0){
+         return  -1;
+      }
+   }
+
+   if (fread(buffer,fytab.recl,1,fytab.fpek) != 1){               /* Les */
+       return  -1;
+   }
+
+   fytab.modus = LES;
+   fytab.cur_lin = linje + 1L;
+
+   return 0;
+}
+
+
+/*
+AR-900106
+CH LC_PutTabel                                               Put tabell-linje
+CD =============================================================================
+CD Form�l:
+CD Legg inn en linje fra tabellfilen.
+CD
+CD Parametre:
+CD Type      Navn   I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD long      linje   i    Linjenummer som skal legges inn. (0 er f�rste linje)
+CD                        (St�rste lovlige er 1 st�rre enn det st�rste hittil.)
+CD void     *buffer  i    Peker til struktur som skal legges inn.
+CD short     ist     r    Status (0=OK, -1=feil)
+CD
+CD Bruk:
+CD ist = LC_PutTabel(linje,(void *)&buffer);
+   =============================================================================
+*/
+SK_EntPnt_FYBA short LC_PutTabel(long linje,void *buffer)
+{
+   if ( ! fytab_open){        /* Systemet er ikke aktivisert */
+      return -1;
+   }
+
+   if (fytab.modus != SKRIV || linje != fytab.cur_lin){    /* Posisjoner */
+      if (fseek(fytab.fpek,(long)(linje * fytab.recl),SEEK_SET) != 0){
+         return -1;
+      }
+   }
+
+   if (fwrite(buffer,fytab.recl,1,fytab.fpek) != 1){  /* Skriv */
+      return  -1;
+   }
+
+   fytab.modus = SKRIV;
+   fytab.cur_lin = linje + 1L;
+
+   return 0;
+}
+
+
+/*
+AR-900106
+CH LC_CloseTabel                                        Stenge tabellsystemet
+CD =============================================================================
+CD Form�l:
+CD Avslutter tabellsystemet og stenger og sletter filen.
+CD Tabellen kan n� �pnes p� nytt for annen bruk.
+CD
+CD Parametre: ingen
+CD    
+CD Bruk:
+CD LC_CloseTabel();
+   =============================================================================
+*/
+SK_EntPnt_FYBA void LC_CloseTabel(void)
+{
+   if (fytab_open){
+      fclose(fytab.fpek);            /* Stenger tabellfilen */
+      UT_DeleteFile("fytabell.tmp");        /* Sletter tabellfilen */
+      fytab_open = 0;                /* Merke for at systemet er stengt */
+   }
+}
diff --git a/FYBA/Fyba_Callback.cpp b/FYBA/Fyba_Callback.cpp
new file mode 100644
index 0000000..639da52
--- /dev/null
+++ b/FYBA/Fyba_Callback.cpp
@@ -0,0 +1,233 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// Fil: Fyba_Callback.cpp
+// Eier: Statens kartverk, FYSAK-prosjektet
+//
+//////////////////////////////////////////////////////////////////////////
+//
+// Denne filen inneholder eksempel p� callback-rutiner som kalles
+// av FYBA for feilmeldings-handtering og visning av framdrift under
+// indeksoppbygging.
+//
+// For � f� et godt brukergrensesnitt b�r disse rutinene endres til
+// det meldings og feilhandteringssystemet som brukes av hovedprogrammet.
+//
+// En tilsvarende enkel feilmeldingshandtering ligger i FYBA_DLL.DLL.
+// Denne (DLL'ens) meldingshandtering blir brukt hvis meldingsingsrutinene
+// ikke blir registrert av hovedprogrammet.
+//
+// Meldingsrutinene registreres med f�lgende rutiner:
+//  - LC_SetErrorHandler
+//  - LC_SetStartMessageHandler
+//  - LC_SetShowMessageHandler
+//  - LC_SetEndMessageHandler
+//  - LC_SetCancelHandler
+//
+//////////////////////////////////////////////////////////////////////////
+
+
+#include "stdafx.h"
+
+#include <fyba.h>
+
+#ifdef WIN32
+#  include <windows.h>
+#endif
+
+#ifdef LINUX
+
+#include <termios.h>
+#include <stropts.h>
+#include <stdio.h>
+#include <sys/select.h>
+#include <sys/ioctl.h>
+
+  int _kbhit() {
+    static const int STDIN = 0;
+    static bool bInit = false;
+
+    if (! bInit) {
+      termios term;
+      tcgetattr(STDIN, &term);
+      term.c_lflag &= ~ICANON;
+      tcsetattr(STDIN, TCSANOW, &term);
+      setbuf(stdin, NULL);
+      bInit = true;
+    }
+
+    int bytesWaiting;
+    ioctl(STDIN, FIONREAD, &bytesWaiting);
+    return bytesWaiting;
+  }
+#else
+#  include <conio.h>
+#endif
+
+/*
+AR-930907
+CH LC_ErrorHandler                                             Feilmelding
+CD ==========================================================================
+CD Form�l:
+CD Feilmelding.
+CD
+CD Parametre:
+CD Type     Navn        I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD short    feil_nr      i   Feilmeldingsnummer
+CD char    *logtx        u   Peker til feilmeldingstekst avslutta med '\0'.
+CD char    *vartx        u   Peker til feilmeldingstekst avslutta med '\0'.
+CD
+CD Bruk:
+CD LC_SetErrorHandler(LC_ErrorHandler);
+   ==========================================================================
+*/
+void LC_ErrorHandler (short feil_nr, const char logtx[], const char vartx[])
+{
+	short strategi;
+	char *feilmelding;
+
+                    /* Hent feilmeldingstekst og strategi */
+    strategi = LC_StrError(feil_nr,&feilmelding);
+
+                             /* Meldingen skrives */
+    if (strategi > 0) {
+       printf("\n%s %s\n",feilmelding,vartx);
+       switch(strategi) {                           /* Velg strategi */
+           case 1:
+           case 2:
+               break;
+           case 3:
+               printf("\aTrykk [Enter] for � fortsette:");
+					if (getchar() == 0)  getchar();
+               break;
+			  case 4:
+					printf("\aTrykk [Enter] for � avbryte programmet:");
+					if (getchar() == 0)  getchar();
+					exit(2);
+					break;
+		 }
+	}
+}
+
+
+/*
+AR-900609
+CH LC_StartMessageHandler                                    Starte meldingsvisning
+CD =============================================================================
+CD Form�l:
+CD Starter vising av melding om baseoppbygging.
+CD
+CD Her skal brukerprogrammet legge inn sin egen initiering av visning av framdrift
+CD under indeksoppbygging.
+CD
+CD Denne rutinen blir kallt fra FYBA under indeksoppbygging, og den skal
+CD ikke kalles fra brukerprogramvaren.
+CD
+CD
+CD
+CD Parametre:
+CD Type     Navn        I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD char    *cfil         i   Ekstra meldingstekst  (filnavn)
+CD
+CD Bruk:
+CD LC_SetStartMessageHandler(LC_StartMessageHandler);
+   =============================================================================
+*/
+void LC_StartMessageHandler(const char *fnam)
+{
+#ifndef LINUX
+      printf("\nLeser: %s ",fnam);
+      printf("\n0%%");
+      fflush(stdout);
+#endif
+}
+
+
+/*
+AR-900609
+CH LC_ShowMessageHandler                                          Vise melding
+CD =============================================================================
+CD Form�l:
+CD Vising av melding om baseoppbygging.
+CD
+CD Her skal brukerprogrammet legge inn sin egen av visnig av framdrift
+CD under indeksoppbygging.
+CD
+CD Denne rutinen blir kalt fra FYBA under indeksoppbygging, og den skal
+CD ikke kalles fra brukerprogramvaren.
+CD
+CD Parametre:
+CD Type     Navn        I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD double   prosent      i   Prosent ferdig (0.0 - 100.0)
+CD
+CD Bruk:
+CD LC_SetShowMessageHandler(LC_ShowMessageHandler);
+   =============================================================================
+*/
+void LC_ShowMessageHandler(double prosent)
+{
+#ifndef LINUX
+      printf("\r%d%%",(short)prosent);
+      fflush(stdout);
+#endif
+}
+
+
+/*
+AR-900609
+CH LC_EndMessageHandler                                          Avslutt melding
+CD =============================================================================
+CD Form�l:
+CD Avslutt melding om baseoppbygging.
+CD
+CD Her skal brukerprogrammet legge inn sin egen avslutning av visning av framdrift
+CD under indeksoppbygging.
+CD
+CD Denne rutinen blir kalt fra FYBA under indeksoppbygging, og den skal
+CD ikke kalles fra brukerprogramvaren.
+CD
+CD Parametre:
+Dette CD Type     Navn        I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD
+CD Bruk:
+CD LC_SetEndMessageHandler(LC_EndMessageHandler);
+   =============================================================================
+*/
+void LC_EndMessageHandler(void)
+{
+#ifndef LINUX
+      printf("\r100%% ferdig.");
+      fflush(stdout);
+#endif
+}
+
+
+/*
+AR-910402
+CH LC_CancelHandler                                  Sjekk om Esc er trykket
+CD ==========================================================================
+CD Form�l:
+CD Sjekk om det er trykt p� Esc (Avbryte indeksoppbygging).
+CD
+CD Parametre:
+CD Type   Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD short  sAvbrutt   r    UT_TRUE  = Cancel
+CD                        UT_FALSE = ikke avbrudd
+CD
+CD Bruk:
+CD LC_SetCancelHandler(LC_CancelHandler);
+   ==========================================================================
+*/
+short LC_CancelHandler(void)
+{
+   int tast = 0;
+
+   if (_kbhit()) {
+      tast = getchar();
+   }
+   return ((tast == 27)?  UT_TRUE : UT_FALSE );
+}
diff --git a/FYBA/Fyba_melding.cpp b/FYBA/Fyba_melding.cpp
new file mode 100644
index 0000000..7e80234
--- /dev/null
+++ b/FYBA/Fyba_melding.cpp
@@ -0,0 +1,201 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// Fil: Fyba_melding.cpp
+// Eier: Statens kartverk, FYSAK-prosjektet
+//
+//////////////////////////////////////////////////////////////////////////
+//
+// Denne filen inneholder eksempel p� callback-rutiner som kalles
+// av FYBA for feilmeldings-handtering og visning av framdrift under
+// indeksoppbygging.
+//
+// For � f� et godt brukergrensesnitt b�r disse rutinene endres til
+// det meldings og feilhandteringssystemet som brukes av hovedprogrammet.
+//
+// Rutinene m� kompileres og linkes sammen med hovedprogrammet n�r
+// FYBA brukes som LIB.
+//
+//////////////////////////////////////////////////////////////////////////
+
+
+//
+// Innholdet i rutinene m� byttes ut med meldingshandtering som er tilpasset
+// det aktuelle hovedprogrammet.
+//////////////////////////////////////////////////////////////////////////
+
+
+//////////////////////////////////////////////////////////////////////////
+// Fyba_melding.cpp
+//
+// Denne filen inneholder eksempel p� rutiner som m� linkes inn i
+// hovedprogrammet n�r FYBA brukes som LIB.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#include <fyba.h>
+
+static short sProsent;
+
+
+/*
+AR-890911
+CH LC_Error                                                  Feilmeldingsrutine
+CD =============================================================================
+CD Form�l:
+CD Standard feilmeldingsrutine.
+CD
+CD Parametre:
+CD Type     Navn        I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD short    feil_nr      i   Feil-nummer
+CD char    *logtx        i   Tekst som bare skrives til logfil.
+CD                           Eks:"(utf�rt i LC_RxGr)"
+CD char    *vartx        i   Denne tekststreng henges etter feilmeldingsteksten.
+CD
+CD Bruk:
+CD LC_Error(35,"(Kallt i LC_Error)","");
+   =============================================================================
+*/
+void LC_Error(short feil_nr,const char *logtx,const char *vartx)
+{
+   char szErrMsg[260];
+   short strategi;
+   char *pszFeilmelding;
+
+
+   // Egen enkel implementasjon av feilhandtering
+   /* Hent feilmeldingstekst og strategi */
+   strategi = LC_StrError(feil_nr,&pszFeilmelding);
+   switch(strategi) {
+      case 2:  UT_SNPRINTF(szErrMsg,260,"%s","Observer f�lgende! \n\n");  break;
+      case 3:  UT_SNPRINTF(szErrMsg,260,"%s","Det er oppst�tt en feil! \n\n");  break;
+      case 4:  UT_SNPRINTF(szErrMsg,260,"%s","Alvorlig feil avslutt programmet! \n\n");  break;
+      default: szErrMsg[0]='\0';
+   }
+
+   #ifdef WIN32
+   if (strategi > 2) {
+      Beep(100,500);
+   }
+
+   if (UT_StrCat (szErrMsg,pszFeilmelding, sizeof(szErrMsg))) {
+      if (UT_StrCat (szErrMsg,&vartx[0], sizeof(szErrMsg))) {
+         MessageBox(NULL, szErrMsg, "Melding fra FYBA ", MB_ICONHAND | MB_OK);
+
+      } else {
+         MessageBox(NULL, "Klarer ikke � vise teksten", "Melding fra FYBA ", MB_ICONHAND | MB_OK);
+      }
+
+   } else {
+      MessageBox(NULL, "Klarer ikke � vise teksten", "Melding fra FYBA ", MB_ICONHAND | MB_OK);
+   }
+   #else 
+      printf("\nError: %s ",pszFeilmelding);
+      fflush(stdout);
+   #endif
+}
+
+
+/*
+AR-900609
+CH LC_StartMess                                          Vise melding
+CD =============================================================================
+CD Form�l:
+CD Starter vising av melding om baseoppbygging.
+CD
+CD Parametre:
+CD Type     Navn        I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD char    *pszFilnavn   i   Ekstra meldingstekst  (filnavn)
+CD
+CD Bruk:
+CD LC_StartMess(pszFilnavn);
+   =============================================================================
+*/
+void LC_StartMessage(char const *pszFilnavn)
+{
+#ifndef LINUX
+      printf("\nLeser: %s ",pszFilnavn);
+      printf("\n0%%");
+      fflush(stdout);
+#endif
+}
+
+
+/*
+AR-900609
+CH LC_ShowMess                                          Vise melding
+CD =============================================================================
+CD Form�l:
+CD Vising av melding om baseoppbygging.
+CD
+CD Parametre:
+CD Type     Navn        I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD double   prosent      i   Prosent ferdig (0.0 - 100.0)
+CD
+CD Bruk:
+CD LC_ShowMess(prosent);
+   =============================================================================
+*/
+void LC_ShowMessage(double prosent)
+{
+#ifndef LINUX
+      printf("\r%d%%",(short)prosent);
+      fflush(stdout);
+#endif
+}
+
+
+/*
+AR-900609
+CH LC_EndMess                                          Avslutt melding
+CD =============================================================================
+CD Form�l:
+CD Avslutt melding om baseoppbygging.
+CD
+CD Parametre:
+CD Type     Navn        I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD
+CD Bruk:
+CD LC_EndMess();
+   =============================================================================
+*/
+void LC_EndMessage(void)
+{
+#ifndef LINUX
+      printf("\r100%% ferdig.");
+      fflush(stdout);
+#endif
+}
+
+
+/*
+AR-910402
+CH LC_Cancel                                         Sjekk om Esc er trykket
+CD ==========================================================================
+CD Form�l:
+CD Sjekk om det er trykkt p� Esc (Avbryte indeksoppbygging).
+CD
+CD
+CD Parametre:
+CD Type   Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD short  sAvbrutt   r    UT_TRUE  = Cancel
+CD                        UT_FALSE = ikke avbrudd
+CD
+CD Bruk:
+CD sAvbrutt = LC_Cancel();
+   ==========================================================================
+*/
+short LC_Cancel(void)
+{
+      /* Ikke mulig � avbryte */
+      return UT_FALSE;
+}
+
diff --git a/FYBA/Fyba_melding_dll.cpp.bak b/FYBA/Fyba_melding_dll.cpp.bak
new file mode 100644
index 0000000..0da5310
--- /dev/null
+++ b/FYBA/Fyba_melding_dll.cpp.bak
@@ -0,0 +1,368 @@
+//////////////////////////////////////////////////////////////////////////
+// Fil: fyba_melding_dll.cpp
+//////////////////////////////////////////////////////////////////////////
+#include "stdafx.h"
+
+#include "fyba.h"
+
+extern void  (*LC_ErrorAdr) (short ifeilnr, const char *logtx, const char *vartx);
+extern void  (*LC_StartMessageAdr)(const char *cfil);
+extern void  (*LC_ShowMessageAdr)(double prosent);
+extern void  (*LC_EndMessageAdr)(void);
+extern short (*LC_CancelAdr)(void);
+
+static short sProsent;
+
+// Rutiner for � definere callback-rutiner for informasjon til brukeren.
+
+/*
+AR:2006-03-21
+CH LC_SetErrorHandler                              Registrer feilmeldingsrutine
+CD =============================================================================
+CD Form�l:
+CD Registrer feilmeldingsrutine.
+CD Feilmeldingsrutinen blir kallt hvis det oppst�r feil.
+CD
+CD Parametre:
+CD Type   Navn                       I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD void  (*f) (short ,char *,char *)  i   Peker til feilmeldingsrutine
+CD
+CD Bruk:
+CD LC_SetErrorHandler(ErrorHandler);
+CD
+CD
+CD Feilmeldingsrutinen skal ha f�lgende definisjon:
+CD
+CD void ErrorHandler(short feil_nr,const char *logtx,const char *vartx);
+CD
+CD Med f�lgende parametre:
+CD Type    Navn     I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD short   feil_nr   i   Feil-nummer
+CD char   *logtx     i   Tekst som bare skrives til logfil.
+CD                       Eks:"(utf�rt i LC_RxGr)"
+CD char   *vartx     i   Denne tekststreng henges etter feilmeldingsteksten.
+CD =============================================================================
+*/
+SK_EntPnt_FYBA void LC_SetErrorHandler(void (*f) (short,const char*,const char*))
+{
+   LC_ErrorAdr = f;
+}
+
+
+/*
+AR:2006-03-21
+CH LC_SetStartMessageHandler                           Registrer initieringsrutine
+CD =============================================================================
+CD Form�l:
+CD Registrer initieringsrutine.
+CD Initieringsrutinen blir kalt for � starte visning av framdrift.
+CD
+CD Parametre:
+CD Type   Navn       I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD void  (*f)(char*)  i   Peker til initieringsrutine
+CD
+CD Bruk:
+CD LC_SetStartMessageHandler(StartMessageHandler);
+CD
+CD Initieringsrutinen skal ha f�lgende definisjon:
+CD
+CD void StartMessageHandler(char *pszFilnavn);
+CD
+CD Med f�lgende parametre:
+CD Type     Navn        I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD char    *pszFilnavn   i   Ekstra meldingstekst  (filnavn)
+CD =============================================================================
+*/
+SK_EntPnt_FYBA void LC_SetStartMessageHandler(void (*f)(const char*)) 
+{ 
+   LC_StartMessageAdr = f;
+}
+
+
+/*
+AR:2006-03-21
+CH LC_SetShowMessageHandler                               Registrer visningsrutine
+CD =============================================================================
+CD Form�l:
+CD Registrer visningsrutine.
+CD Visningsrutine blir kalt for � vise framdrift ved indeks-oppbygging.
+CD
+CD Parametre:
+CD Type   Navn       I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD void  (*f)(double)  i   Peker til visningsrutine
+CD
+CD Bruk:
+CD LC_SetShowMessageHandler(ShowMessageHandler);
+CD
+CD Visningsrutinen skal ha f�lgende definisjon:
+CD
+CD void ShowMessageHandler(double prosent);
+CD
+CD Med f�lgende parametre:
+CD Type     Navn        I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD double   prosent      i   Prosent ferdig (0.0 - 100.0)
+CD =============================================================================
+*/
+SK_EntPnt_FYBA void LC_SetShowMessageHandler(void (*f)(double))
+{
+   LC_ShowMessageAdr = f;
+}
+
+
+/*
+AR:2006-03-21
+CH LC_SetEndMessageHandler                             Registrer avslutningsrutine
+CD =============================================================================
+CD Form�l:
+CD Registrer avslutningsrutine.
+CD Avslutningsrutinen blir kalt for � avslutte visning av framdrift ved indeksoppbygging.
+CD
+CD Parametre:
+CD Type   Navn       I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD void  (*f)(void)  i   Peker til avslutningsrutine
+CD
+CD Bruk:
+CD LC_SetEndMessageHandler(EndMessageHandler);
+CD
+CD Avslutningsrutinen skal ha f�lgende definisjon:
+CD
+CD void EndMessageHandler(void);
+CD =============================================================================
+*/
+SK_EntPnt_FYBA void LC_SetEndMessageHandler(void (*f)(void))
+{
+   LC_EndMessageAdr = f;
+}
+
+
+/*
+AR:2006-03-21
+CH LC_SetCancelHandler                                Registrer avbruddsstyring
+CD =============================================================================
+CD Form�l:
+CD Registrer avbruddsstyring.
+CD Rutine for avbruddsstyring blir kalt for � sjekke om bruker �nsker
+CD � avbryte beregningen.
+CD
+CD Parametre:
+CD Type   Navn       I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD short  (*f)(void)  i   Peker til rutine for avbruddsstyring.
+CD
+CD Bruk:
+CD LC_SetCancelHandler(CancelHandler);
+CD
+CD Rutine for avbruddsstyring skal ha f�lgende definisjon:
+CD
+CD short CancelHandler(void);
+CD
+CD Med f�lgende parametre:
+CD Type   Navn      I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD short  sAvbrutt   r   UT_TRUE  = Cancel
+CD                       UT_FALSE = ikke avbrudd
+CD =============================================================================
+*/
+SK_EntPnt_FYBA void LC_SetCancelHandler(short (*f)(void))
+{
+   LC_CancelAdr = f;
+}
+
+
+/*
+AR-890911
+CH LC_Error                                                  Feilmeldingsrutine
+CD =============================================================================
+CD Form�l:
+CD Standard feilmeldingsrutine.
+CD
+CD Parametre:
+CD Type     Navn        I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD short    feil_nr      i   Feil-nummer
+CD char    *logtx        i   Tekst som bare skrives til logfil.
+CD                           Eks:"(utf�rt i LC_RxGr)"
+CD char    *vartx        i   Denne tekststreng henges etter feilmeldingsteksten.
+CD
+CD Bruk:
+CD LC_Error(35,"(Kallt i LC_Xxxx)","");
+CD =============================================================================
+*/
+void LC_Error(short feil_nr,const char *logtx,const char *vartx)
+{
+   char szErrMsg[260];
+   short strategi;
+   char *pszFeilmelding;
+
+
+   // Kaller hovedprogrammets implementasjon av feilhandteringen
+   if (LC_ErrorAdr != NULL) {
+      (*LC_ErrorAdr) (feil_nr,logtx,vartx);
+
+
+   // Egen enkel implementasjon av feilhandtering   
+   } else {
+      /* Hent feilmeldingstekst og strategi */
+      strategi = LC_StrError(feil_nr,&pszFeilmelding);
+      switch(strategi) {
+         case 2:  UT_SNPRINTF(szErrMsg,260,"%s","Observer f�lgende! \n\n");break;
+         case 3:  UT_SNPRINTF(szErrMsg,260,"%s","Det er oppst�tt en feil! \n\n");break;
+         case 4:  UT_SNPRINTF(szErrMsg,260,"%s","Alvorlig feil avslutt programmet! \n\n");break;
+         default: szErrMsg[0]='\0';
+      }
+
+#ifdef WIN32
+      if (strategi > 2) {
+         Beep(100,500);
+      }
+
+      if (UT_StrCat (szErrMsg,pszFeilmelding, sizeof(szErrMsg))) {
+         if (UT_StrCat (szErrMsg,&vartx[0], sizeof(szErrMsg))) {
+            MessageBox(NULL, szErrMsg, "Melding fra FYBA ", MB_ICONHAND | MB_OK);
+
+         } else {
+            MessageBox(NULL, "Klarer ikke � vise teksten", "Melding fra FYBA ", MB_ICONHAND | MB_OK);
+         }
+
+      } else {
+         MessageBox(NULL, "Klarer ikke � vise teksten", "Melding fra FYBA ", MB_ICONHAND | MB_OK);
+      }
+#endif
+   }
+}
+
+
+/*
+AR-900609
+CH LC_StartMessage                                          Vise melding
+CD =============================================================================
+CD Form�l:
+CD Starter vising av melding om baseoppbygging.
+CD
+CD Parametre:
+CD Type     Navn        I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD char    *pszFilnavn   i   Ekstra meldingstekst  (filnavn)
+CD
+CD Bruk:
+CD LC_StartMessage(pszFilnavn);
+CD =============================================================================
+*/
+void LC_StartMessage(const char *pszFilnavn)
+{
+   // Kaller hovedprogrammets implementasjon
+   if (LC_StartMessageAdr != NULL) {
+      (*LC_StartMessageAdr) (pszFilnavn);
+
+   // Egen enkel implementasjon  
+   } else {
+#ifndef LINUX
+      printf("\nLeser: %s ",pszFilnavn);
+      printf("\n0%%");
+      fflush(stdout);
+#endif
+   }
+}
+
+
+/*
+AR-900609
+CH LC_ShowMessage                                          Vise melding
+CD =============================================================================
+CD Form�l:
+CD Vising av melding om baseoppbygging.
+CD
+CD Parametre:
+CD Type     Navn        I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD double   prosent      i   Prosent ferdig (0.0 - 100.0)
+CD
+CD Bruk:
+CD LC_ShowMessage(prosent);
+CD =============================================================================
+*/
+void LC_ShowMessage(double prosent)
+{
+   // Kaller hovedprogrammets implementasjon
+   if (LC_ShowMessageAdr != NULL) {
+      (*LC_ShowMessageAdr) (prosent);
+
+   // Egen enkel implementasjon  
+   } else {
+#ifndef LINUX
+      printf("\r%d%%",(short)prosent);
+      fflush(stdout);
+#endif
+   }
+}
+
+
+/*
+AR-900609
+CH LC_EndMessage                                          Avslutt melding
+CD =============================================================================
+CD Form�l:
+CD Avslutt melding om baseoppbygging.
+CD
+CD Parametre:
+CD Type     Navn        I/U  Forklaring
+CD -----------------------------------------------------------------------------
+CD
+CD Bruk:
+CD LC_EndMessage();
+CD =============================================================================
+*/
+void LC_EndMessage(void)
+{
+   // Kaller hovedprogrammets implementasjon
+   if (LC_EndMessageAdr != NULL) {
+      (*LC_EndMessageAdr) ();
+
+   // Egen enkel implementasjon  
+   } else {
+#ifndef LINUX
+      printf("\r100%% ferdig.");
+      fflush(stdout);
+#endif
+   }
+}
+
+
+/*
+AR-910402
+CH LC_Cancel                                         Sjekk om Esc er trykket
+CD ==========================================================================
+CD Form�l:
+CD Sjekk om det er trykkt p� Esc (Avbryte indeksoppbygging).
+CD
+CD
+CD Parametre:
+CD Type   Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD short  sAvbrutt   r    UT_TRUE  = Cancel
+CD                        UT_FALSE = ikke avbrudd
+CD
+CD Bruk:
+CD sAvbrutt = LC_Cancel();
+CD ==========================================================================
+*/
+short LC_Cancel(void)
+{
+   // Kaller hovedprogrammets implementasjon
+   if (LC_CancelAdr != NULL) {
+      return (*LC_CancelAdr) ();
+
+   // Egen enkel implementasjon  
+   } else {
+      /* Ikke mulig � avbryte */ 
+      return UT_FALSE;
+   }
+}
+
diff --git a/FYBA/LICENSE b/FYBA/LICENSE
new file mode 100644
index 0000000..642f5d5
--- /dev/null
+++ b/FYBA/LICENSE
@@ -0,0 +1,24 @@
+/******************************************************************************
+* STATENS KARTVERK  -  FYSAK
+*
+* Copyright (c) 1990-2011 Statens kartverk
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+* DEALINGS IN THE SOFTWARE.
+******************************************************************************/
+
diff --git a/FYBA/fyba.h b/FYBA/fyba.h
new file mode 100644
index 0000000..c75f19e
--- /dev/null
+++ b/FYBA/fyba.h
@@ -0,0 +1,1484 @@
+/******************************************************************************
+*
+* STATENS KARTVERK  -  FYSAK
+*
+* Filename: fyba.h
+*
+* Content: Prototyper for rutiner for les/skriv av SOSI-fil.
+*
+* Copyright (c) 1990-2011 Statens kartverk
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+* DEALINGS IN THE SOFTWARE.
+******************************************************************************/
+
+#pragma once
+
+//
+// N�r FYBA brukes som DLL, defineres FYBA_DLL_IMPORTS
+// N�r FYBA brukes som lib er det ikke n�dvendig med noen spesiell definisjon.
+// (N�r FYBA skal kompileres/lages som DLL defineres FYBA_DLL_EXPORTS)
+//
+
+
+#ifdef WIN32
+#ifdef FYBA_DLL_IMPORTS /* FYBA brukes som DLL */
+#  pragma comment (lib, "FYBA_DLL.lib")
+//#  ifdef _DEBUG
+//#     pragma comment (lib, "FYBA_DLLD.lib")
+//#  else
+//#     pragma comment (lib, "FYBA_DLL.lib")
+//#  endif
+#else
+#   ifndef FYBA_DLL_EXPORTS  /* FYBA brukes som LIB */
+#     ifdef _DEBUG
+#        pragma comment (lib, "FYBAD.lib")
+#     else
+#        pragma comment (lib, "FYBA.lib")
+#     endif
+#   endif
+#endif
+
+
+#  ifndef DllExport
+#    define DllExport __declspec(dllexport)
+#    define DllImport __declspec(dllimport)
+#  endif /* !DllExport */
+#else
+#  define DllExport
+#  define DLLImport
+#  define __cdecl
+#endif
+
+
+#ifndef SK_EntPnt_FYBA
+
+#   ifdef FYBA_DLL_EXPORTS /* FYBA kompileres til DLL ==> FYBA_DLL.DLL */
+#      define SK_EntPnt_FYBA DllExport
+
+#   else 
+#      ifdef FYBA_DLL_IMPORTS /* FYBA brukes som DLL */
+#         define SK_EntPnt_FYBA DllImport
+
+#      else /* FYBA kompileres eller brukes som LIB */
+#         define SK_EntPnt_FYBA
+#      endif
+#   endif
+#endif
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <fygm.h>
+#include <fyut.h>
+
+
+/* ======================================================= */
+/*  Definerer konstanter                                   */
+/* ======================================================= */
+   /* Max-verdier for basen */
+#define LC_MAX_GRU        10000000  /* Max grupper i en base */
+#define LC_MAX_GINFO          6000  /* Max linjer GINFO i en gruppe */
+#define LC_MAX_GINFO_BUFFER 250000  /* GINFO-buffer */
+#define LC_MAX_KOORD         90000  /* Max antall koordinater i en gruppe */
+#define LC_MAX_PINFO_BUFFER 250000  /* PINFO-buffer */
+#define LC_MAX_ANT_PRIOR       128  /* Max antall prioriteter */
+#define LC_DATO_LEN              9  /* Max lengde dato (inkl. '\0') */
+#define LC_BASEVER_LEN          50  /* Max lengde av szBaseVer (inkl. '\0') */
+#define LC_MAX_SOSINAVN_LEN     50  /* Max lengde for SOSI-navn (inkl. '\0') */
+#define LC_MAX_NAVN            500  /* Max linjer i navnetabellen (pr. fil) */
+#define LC_NGISLAG_LEN          50  /* Max lengde av NGIS-LAG fra filhodet */
+#define LC_MAX_SOSI_LINJE_LEN 1024  /* Max linjelengde for lesing fra SOSI-filen */
+#define LC_MAX_OBJTYPE_LEN      33  // Max lengde av objettypenavn (inkl. '\0')
+
+#define  LC_INTERNT_TEGNSETT TS_ISO8859
+        
+
+   /* Konstanter for basetype */
+#define  LC_KLADD  3   /* Kladdebase */
+#define  LC_BASE   1   /* Vanlig base */
+
+   /* Konstanter for �pning av eksisterende base */
+#define  UKJENT_BASE     -1
+#define  FEIL_VERSJON    -2
+#define  IKKE_STENGT     -3
+#define  IDX_MANGLER     -4
+#define  IDX_FEIL_DATO   -5
+#define  SOS_MANGLER     -6
+#define  SOS_FEIL_DATO   -7
+#define  SOS_FEIL_AKSESS -8
+
+	/* Konstanter for LC_CloseBase */
+#define RESET_IDX   0   /* Fjern indeksfilene */
+#define SAVE_IDX    1   /* Lagrer indeksfilene */
+
+   /* Konstanter for LC_OpenSos */
+#define LC_BASE_FRAMGR 1  /* Framgrunnsfil i basen */
+#define LC_BASE_BAKGR  2  /* Bakgrunnsfil i basen (Bare les) */
+#define LC_SEKV_LES    3  /* Sekvensiell, les */
+#define LC_SEKV_SKRIV  4  /* Sekvensiell, skriv */
+#define LC_SEKV_UTVID  5  /* Sekvensiell, utvid gammel fil */
+
+#define LC_NY_IDX      1  /* Tvungen nygenerering */
+#define LC_GML_IDX     0 /* Bruk gammel .idx hvis den er OK */
+
+#define LC_VIS_STATUS   1  /* Vis status under indeksoppbygging */
+#define LC_INGEN_STATUS 0  /* Ikke vis status */
+
+   /* Lag i basen */
+#define LC_SEKV     0x0001   /* Sekvensiell fil */
+#define LC_BAKGR    0x0002   /* Bakgrunnsfil i base */
+#define LC_FRAMGR   0x0004   /* Framgrunnsfil i base */
+
+   /* Status fra LC_OpenSos */
+#define LC_CANCEL   -3  // Avbrutt med [Esc], eller lesefeil
+#define LC_DUBLIKAT -4  // Filen er i basen fra f�r
+#define LC_OPPTATT  -5  // Filen er �pen i annet program 
+
+	/* Konstanter for LC_SetNgisModus */
+#define NGIS_NORMAL   0   /* Vanlig modus */
+#define NGIS_SPESIAL  1   /* Spesialmodus der det er mulig � finne og
+                                lese grupper som er merka som sletta */
+
+	/* Konstanter for LC_SetUtvidModus */
+#define LC_UTVID_SIKKER 0 /* SOSI-filen stenges og filst�rrelsen oppdateres */
+                          /* etter hver gruppe som er skrevet p� slutten av filen */
+#define LC_UTVID_RASK   1 /* SOSI-filen stenges IKKE etter hver oppdatering*/
+
+   /* Konstanter til QueryGP mfl. */
+#define LC_HODE   1
+#define LC_GINFO  2
+#define LC_PINFO  4
+
+/* Konstanter til bruk ved kombinert flates�k. JA�-20000516 */
+#define LC_INGEN 0
+#define LC_NOEN  1
+#define LC_ALLE  2
+
+   /* Gruppenummer n�r det ikke er noen aktuell gruppe */
+#define INGEN_GRUPPE  -1L    /* bgr n�r det ikke er noen akt. gruppe */
+
+   /* Lesemetode for LC_RxGr */
+#define LES_OPTIMALT   0     /* Les mest effektivt base/SOSI */
+#define LES_SOSI       1     /* Les alltid fra SOSI-filen */
+
+   /* Skrivemetode for LC_WxGr */
+#define SKRIV_OPTIMALT 0     /* Skriv mest effektivt k�/SOSI */
+#define SKRIV_SOSI     1     /* Skriv direkte til SOSI-filen */
+
+   /* Handteringmetode for NGIS-n�kkel for LC_CopyGr */
+#define OPPDATER_NGIS 0  /* NGIS-n�kkel oppdateres i henhold til hodet i filen det kopieres til */
+#define BEVAR_NGIS    1  /* NGIS-n�kkel bevares uforandret i kopien */
+
+   /* Manglende kvalitetsopplysninger */
+#define KVAL_MET_UNDEF  -1   /* Udefinert metode */
+#define KVAL_MET_STD    -2   /* Standard metode fra niv� over */
+
+#define KVAL_NOY_UNDEF  -1L  // Udefinert n�yaktighet. -  OBS! Denne skal utg�
+#define KVAL_NOY_STD    -2L  /* Standard n�yaktighet fra niv� over */
+#define KVAL_NOY_UKJENT  999999L  // Ukjent n�yaktighet 
+
+
+#define KVAL_SYN_GOD     0   /* Godt synlig */
+#define KVAL_SYN_UNDEF  -1   /* Udefinert synbarhet */
+#define KVAL_SYN_STD    -2   /* Standard synbarhet fra niv� over */
+
+   /* For LC_GetTH og LC_PutTH */
+   /* Konstant for � si at punktet ikke har h�yde */
+   /* OBS! Denne m� stemme med definisjonen i filen port.h */
+#ifndef HOYDE_MANGLER
+#   define HOYDE_MANGLER        -9999.999   /* H�yde mangler i punktet */
+#endif
+
+#define KOORD_MANGLER           -9999.999   /* Koordinat mangler i punktet */
+
+   /* Gruppeinformasjon */
+#define GI_PINFO     ((unsigned short)0x0001) /* Har PINFO */
+#define GI_NAH       ((unsigned short)0x0002) /* Gruppen har h�yde informasjon (..N�H) */
+#define GI_KP        ((unsigned short)0x0004) /* Har knutepunkt (...KP n) */
+#define GI_REF       ((unsigned short)0x0008) /* Har referanser (.. :n) */
+#define GI_OY_REF    ((unsigned short)0x0010) /* Har referanser med �y */
+#define GI_SLETTA    ((unsigned short)0x0020) /* Er sletta (merka som sletta) */
+#define GI_NGIS      ((unsigned short)0x0040) /* Er tatt ut fra NGIS */
+#define GI_NAD       ((unsigned short)0x0080) /* Har dybde informasjon (..N�D) */
+#define GI_READ_ONLY ((unsigned short)0x0100) /* Bare leseaksess (kan ikke endres) */
+
+   /* Avgrensing av brukttabellen */
+#define  BT_MIN_BT    0       /* F�rste kolonne i brukttabellen */
+#define  BT_MAX_BT   31       /* Siste kolonne i brukttabellen */
+#define  BT_MIN_USER  1       /* F�rste tilgjengelig for brukerprogram */
+#define  BT_MAX_USER 26       /* Siste tilgjengelig for brukerprogram */
+   /* Spesielle posisjoner i brukttabellen */
+#define  BT_SKRKO     0       /* I skrivek� */
+#define  BT_REFBOX   27       /* Referanser er brukt i omskrevet boks */
+#define  BT_X        28       /* Reserve systemposisjon */
+#define  BT_SNRSOK   29       /* Funnet ved SNR-s�k */
+#define  BT_GISOK    30       /* Funnet ved GINFO-s�k */
+#define  BT_GEOSOK   31       /* Funnet ved geografisk s�k */
+
+   /* Logiske operasjoner mellom kolonner i brukttabellen */
+#define BC_AND      0
+#define BC_OR       1
+#define BC_COPY     2
+#define BC_INVERT   3
+#define BC_EXCHANGE 4
+
+
+   /* Konstanter for get og put referansenummer */
+#define START_OY   9999999L      /* Start �y */
+#define SLUTT_OY  -9999999L      /* Slutt �y */
+
+   /* Konstanter for GetArrayTK() */
+#define HENT_FORRFRA  1          /* Vanlig */
+#define HENT_BAKFRA  -1          /* Snu buferet */
+
+/* UTVALG */
+
+// Utvalgskommandoer 
+#define LC_U_OG          1     // ..OG 
+#define LC_U_ELLER       2     // ..VELG og ..ELLER
+
+
+ // Utvalgsmetoder
+#define LC_U_IKKE         0     //  !     Ikke (Tilslag n�r SOSI-navnet     
+                             //             ikke finnes. Bare GINFO.)    
+#define LC_U_ALLE         1     //  AL    Alle                              
+#define LC_U_FRATIL       2     //  <>    Fra-til                           
+#define LC_U_UTENFOR      3     //  ><    Utenfor                           
+#define LC_U_MINDRE       4     //  <     Mindre-enn                        
+#define LC_U_STORRE       5     //  >     St�rre-enn                        
+#define LC_U_DELELIG      6     //  /     Delelig-med, eventuellt med       
+                                //        sjekk p� om restverdi er 2. verdi 
+#define LC_U_UDELELIG     7     //  !/    Ikke-delelig-med                  
+#define LC_U_CONTEIN      8     //  ()    Inneholder                        
+#define LC_U_IKKECONTEIN  9     //  !()   Inneholder ikke (Tilslag n�r      
+                                //        denne navn og verdi kombinasjonen 
+                                //        ikke finnes)                      
+#define LC_U_LIK         10     //  =     Lik                               
+#define LC_U_IKKEVALGT   11     //  IV    Ikke valgt (Tilslag n�r gruppen   
+                                //        ikke er tegnet enn�. Kombineres   
+                                //        med SOSI-navnet "..*")            
+#define LC_U_IKKELIK     12     //  !=    Ikke lik (Tilslag n�r denne       
+                                //        navn og verdi kombinasjonen ikke  
+                                //        finnes)                           
+#define LC_U_FLERE       13     //  FL    Flere (Tilslag n�r SOSI-navnet    
+                                //        forekommer flere ganger.)         
+#define LC_U_IKKEFLERE   14     //  !FL   Ikke flere enn (Tilslag n�r       
+                                //        SOSI-navnet IKKE forekommer       
+                                //        flere ganger enn gitt antall.)    
+
+
+
+ // Parametertyper 
+#define LC_U_TALL          1     // Heltall     
+#define LC_U_FLYT          2     // Flyttall    
+#define LC_U_ALFA          4     // Tekststreng 
+#define LC_U_DEFINERT      8     // Type definert i utvalgsregel
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Kvalitet                                                     !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_KVALITET {  /* Standard Kvalitet */
+   short sMetode;
+   long  lNoyaktighet;
+   short sSynbarhet;
+   short sHoydeMetode;
+   long  lHoydeNoyaktighet;
+} LC_KVALITET;
+
+/*
+ *!--------------------------------------------------------------!
+ *! Buffer for lesing av SOSI-fil                                !
+ *!--------------------------------------------------------------!
+ */
+
+typedef struct dLB_LESEBUFFER {
+   char tx[LC_MAX_SOSI_LINJE_LEN];  /* Lesebuffer */
+   UT_INT64 filpos;                 /* Filposisjon for starten av bufret */
+   UT_INT64 startpos;               /* Startposisjon i filen for aktuellt SOSI-navn */
+   char *cp;                        /* Peker til aktuell posisjon i bufret */
+   char *pp;                        /* Peker til start parameter */
+   char *ep;                        /* Peker til posisjon etter aktuellt ord */
+	char *np;                        /* Peker til posisjon etter parameter (neste cp) */
+   short cur_navn[6];               /* Aktuellt SOSI-navn p� dette niv� */
+   short cur_niv;                   /* Aktuellt niv� (der cp peker) (Ant. prikker) */
+   short cur_ant_par;               /* Antall parametre p� aktuellt niv� */
+   short cur_type;                  /* Viser hva aktuellt set inneholder */
+   short set_brukt;                 /* Status som viser om aktuellt "sett" er brukt */
+   short sTegnsett;                 /* SOSI-filens tegnsett */
+   short sStatus;                   /* Status, viser om buffer har brukbart innhold */
+} LB_LESEBUFFER;
+
+
+/*
+ *!----------------------------------------------------------!
+ *! BUFFER for koordinater og GINFO i minne                  !
+ *!----------------------------------------------------------!
+*/
+
+/*
+CH SOSI-buffer                 Bin�r kopi av SOSI-filen
+CD For � �ke hastigheten holder FYBA en bin�r kopi av SOSI-filen.
+CD Denne kopien ligger delevis i minne og delevis p� disk.
+CD
+CD Denne kopien best�r av gruppeinformasjon, koordinater og punktinformasjon.
+CD
+CD Gruppeinformasjonen for en gruppe handteres som en lang streng med pekere
+CD til startposisjon for hver GINFO-linje.
+CD
+CD !-----------:-----------:----------:----------------------------------!
+CD !  GINFO 1  !  GINFO 2  ! GINFO 3  ! .....                            !
+CD !-----------:-----------:----------:----------------------------------!
+CD  !            !           !
+CD  !---------!  !           !
+CD            !  !           !
+CD !--------! !  !           !
+CD ! GINFO  ! !  !           !
+CD !--------! !  !           !
+CD ! ofset  !-!  !           !
+CD !        !-----           !
+CD !        !-----------------
+CD
+CD Koordinatene lagres i egne array. Punktinformasjonen lagres som
+CD en lang streng for hele gruppen med peker for hvert punkt til startposisjon
+CD for PINFO for hvert punkt p� samme m�te som GINFO.
+CD
+CD !--------! !--------! !--------:-------:--------!
+CD ! �st    ! ! Nord   ! ! H�yde  !  KP   ! PINFO  !
+CD !--------! !--------! !--------!-------!--------!
+CD ! double ! ! double ! ! double ! short ! ushort !
+CD !   m    ! !   m    ! !   m    !       !  ofset !
+*/
+typedef struct d_LB_INFO {
+   double dHoyde;            // H�yde
+   short sKp;                // Knutepunkt (0=ikke knutepunkt)
+   unsigned long ulPiOfset;  // PINFO ofset i eget buffer
+} LB_INFO;
+
+
+#   define LC_INGEN_PINFO ULONG_MAX     /* Offset ved tom PINFO */
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Navnetabell                                                  !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dSOSINAVN {            /* Navnetabellen */
+   char szNavn[LC_MAX_SOSINAVN_LEN];   /* Sosi-navn */
+   unsigned char ucAntPar;      /* Antall parametre til dette navnet */
+   char cNivo;                  /* "Prikk-niv�"  (1 = Gruppenavn) */
+   bool bBrukt;                 // Viser om navnet er v�rt brukt
+} SOSINAVN;
+
+typedef struct dLC_NAVNETABELL {
+   short sAntNavn;              /* Antall navn totalt i navnetabellen */
+   SOSINAVN sosi[LC_MAX_NAVN];  /* Navnetabellen */
+} LC_NAVNETABELL;
+
+
+#  define LC_ANT_PAR_UKJENT  255  /* Antall parametre til dette navnet er
+                                     ukjent, ta med fram til neste " ."  */
+
+  /* Definerte navn */
+#define L_SLUTT       0
+#define L_PUNKT       1
+#define L_LINJE       2
+#define L_KURVE       3
+#define L_BUE         4
+#define L_BUEP        5
+#define L_SIRKEL      6
+#define L_SIRKELP     7
+#define L_KLOTOIDE    8
+#define L_SVERM       9
+#define L_TEKST      10
+#define L_TRASE      11
+#define L_FLATE      12
+#define L_BEZIER     13
+#define L_RASTER     14
+#define L_DEF        15 
+#define L_OBJDEF     16
+#define L_MLINJE     17
+#define L_STRUKTUR   18
+#define L_OBJEKT     19
+#define L_SYMBOL     20
+#define L_HODE       21  /* L_HODE m� alltid ligge sist av gruppenavnene */
+
+#define L_NA         22  /* Andre definerte navn */
+#define L_NAH        23
+#define L_REF1       24
+#define L_REF2       25
+#define L_RADIUS     26
+#define L_ENHET2     27
+#define L_ENHET2H    28
+#define L_ENHET2D    29
+#define L_ENHET3     30
+#define L_ENHET3H    31
+#define L_ENHET3D    32
+#define L_ORIGONO    33
+#define L_HOYDE      34
+#define L_DYBDE      35
+#define L_NAD        36
+#define L_NGISFLAGG  37
+#define L_NGISLAG    38
+#define L_OBJTYPE    39
+#define L_KP         40   /* L_KP m� alltid ligge sist av de forh�ndsdefierte navnene */
+
+
+
+/* ======= INDEKS-TABELLER =================== */
+
+/*
+CH Serienummer-tabell
+CD !-------------*
+CD ! Gruppenummer!
+CD !-------------!       Linjenummer i tabellen er serienummer.
+CD !  lGrNr      !
+CD !  (long)     !
+CD *-------------*
+*/
+
+
+
+/*
+CH Geografisk-s�ketabell                               Geografisk s�ketabell
+CD
+CD Geografisk s�k er basert p� omskrevet boks.
+CD Boksene organiseres i et R-tre. 
+CD
+CD !-----------------------------------*
+CD !      Omskreven boks               !
+CD !                                   !
+CD ! min-N  ! min-�  ! max-N  ! max-�  !
+CD !        !        !        !        !
+CD !--------!--------!--------!--------!
+CD !dMinNord!dMinAust!dMaxNord!dMaxAust!
+CD !  d     !   d    !   d    !   d    !
+CD !        !        !        !        !
+CD *-----------------------------------*
+*/
+
+/*
+ *!--------------------------------------------------------------!
+ *! Boks for geografisk s�k                                      !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_BOKS{
+   double dMinAust;
+	double dMinNord;
+   double dMaxAust;      
+   double dMaxNord;      
+} LC_BOKS;
+
+#define LC_R_MAX_SON  3      /* Max antall s�nner for hver node i R-treet */
+
+typedef struct dLC_R_NODE{
+   struct dLC_R_NODE *pFar;  /* Far i treet (node) */
+   LC_BOKS Boks;             /* Sum av omskreven boks for s�nnene */
+   short sSonType;  /* Hvilken type s�nner har denne noden LC_NODE / LC_LEAF */
+   short sSonAnt;   /* Antall s�nner */
+   union {
+      struct dLC_R_NODE *pNode[LC_R_MAX_SON];  /* S�nner i treet (node) */
+      struct dLC_R_LEAF *pLeaf[LC_R_MAX_SON];  /* S�nner i treet (l�v) */
+   } Son;
+} LC_R_NODE;
+
+#define LC_NODE 0
+#define LC_LEAF 1
+
+
+typedef struct dLC_R_LEAF{
+   LC_R_NODE *pFar;  /* Far i treet (node) */
+   LC_BOKS Boks;     /* Omskreven boks for gruppen */
+   long lNr;         /* Gruppenummer i filen  */
+} LC_R_LEAF;
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Gruppetabel                                                  !
+ *!--------------------------------------------------------------!
+ */
+/*
+CH Gruppetabell                                     Gruppetabell
+CD Dette er hovedtabellen med informasjon om hver enkelt gruppe p� SOSI-filen. 
+CD
+CD !------------------------------:-----------------------------------------------*
+CD !Start  !Start !Ant.   !Ant.   !            Gruppeinnhold                      !
+CD ! p�    ! i    !tegn   !tegn   !-----------------------------------------------!
+CD !SOSI-  ! RB   !GINFO- !PINFO- !Gruppe!ant. !ant. !Kvali-  !Enhet ! Div. info  !
+CD !fil    !      !buffer !buffer !navn  !GINFO! N�  ! tet    !      ! (bit def.) !
+CD !-------!------!-------!-------!------!-----!-----!--------!------!------------!
+CD !sosi_st!rb_st !ulGiLen!ulPiLen!gnavn !ngi  !nko  !Kvalitet!dEnhet! info       !
+CD !  n64  ! n64  !  ul   !  ul   ! s    !  s  ! l   ! struct !  d   ! us         !
+CD !       !      !       !       !      !     !     !        !      !0=i         !
+CD !       !      !       !       !      !     !     !        !      !1=H         !
+CD !       !      !       !       !      !     !     !        !      !2=KP        !
+CD !       !      !       !       !      !     !     !        !      !3=REF       !
+CD !       !      !       !       !      !     !     !        !      !4=REF med �Y!
+CD !       !      !       !       !      !     !     !        !      !5=sletta    !
+CD !       !      !       !       !      !     !     !        !      !6=NGIS oppd !
+CD *------------------------------------------------------------------------------*
+*/
+typedef struct dLC_GRTAB_LINJE{
+   unsigned long ulPrior[4]; /* Bitfelt for prioriteter. */
+									  /* Siste bit viser om feltet er bygd opp. */
+   UT_INT64 sosi_st;     /* Startposisjon i SOSI-filen */
+   UT_INT64 rb_st;       /* Peker til start av gruppen i buffer-fil */
+   long  rb_forrige_gr;  /* Forrige gruppe i buffer-filen */
+   long  rb_neste_gr;    /* Neste gruppe i buffer-filen */
+   short gnavn;          /* Gruppenavn. Eks. .HODE, .PUNKT, mm */
+   short ngi;            /* Antall GINFO-linjer */
+   long nko;             /* Antall koordinater */
+   unsigned short info;  /* Info, se under gruppetabellen */
+	LC_KVALITET Kvalitet; /* Aktuell kvalitet fra GINFO */
+   char szObjtype[LC_MAX_OBJTYPE_LEN]; /* ..OBJTYPE fra GINFO */
+   double dEnhet;        /* Aktuell enhet for gruppen i bufferet */
+   double dEnhetHoyde;   /* Aktuell enhet-H for gruppen i bufferet */
+   double dEnhetDybde;   /* Aktuell enhet-D for gruppen i bufferet */
+   unsigned long ulGiLen; /* Antall tegn i GINFO-buffer (inkl. \0) */
+   unsigned long ulPiLen; /* Antall tegn i PINFO-buffer (inkl. \0) */
+   LC_R_LEAF *pRL;        /* Peker inn i geografisk s�ketre */
+
+} LC_GRTAB_LINJE;
+
+
+/*
+CH Brukttabell                                            Merking av grupper
+CD Denne tabellen brukes delevis internt av FYBA, og delevis av brukerprogrammet.
+CD
+CD F�lgende bit er definert:
+CD -------------------------------------------------------------------------
+CD  31  Gruppen er funnet ved geografisk s�k   -----! Brukere kan lese/bruke
+CD  30  Gruppen er funnet ved GINFO-utvalg          ! disse, men det er ikke
+CD  29  Gruppen er funnet ved serienummer-s�k       ! lov til � endre dem.
+CD  28  Gruppen er i ringbufferet                   !
+CD  27  Referanser er brukt i omskrevet blokk ------!
+CD  26                              -----!
+CD   .                                   ! Brukere har
+CD   .                                   ! full tilgang
+CD   2                                   ! til disse.
+CD   1                              -----!
+CD   0  Gruppen ligger i k� for skriving til SOSI-filen
+*/
+
+
+   /*
+    *!--------------------------------------------------------------!
+    *! Overordnet blokk med pekere til de ulike indekstabellene     !
+    *!--------------------------------------------------------------!
+    */
+#define LC_IDX_LIN_BLOKK 5000
+#define LC_ANT_IDX_BLOKK  (LC_MAX_GRU / LC_IDX_LIN_BLOKK)
+typedef struct dLC_IDX_TABELL{
+	/* Array med pekere til starten av blokk med Gruppetabell-linjer */
+   LC_GRTAB_LINJE * GtAdm[LC_MAX_GRU / LC_IDX_LIN_BLOKK];
+
+   /* Array med pekere til starten av blokk med Gruppenummer for gitt SNR */
+   long             *SnrAdm[LC_MAX_GRU / LC_IDX_LIN_BLOKK];
+
+   /* Array med pekere til starten av blokk med Brukttabell-linjer */
+   unsigned long    *BtAdm[LC_MAX_GRU / LC_IDX_LIN_BLOKK];
+
+	/* Array med pekere til starten av blokk med Geo-tabell-linjer */
+   /* LC_GEOSOK_BOKS *GeoAdm[LC_MAX_GRU / LC_IDX_LIN_BLOKK]; */
+} LC_IDX_TABELL;
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Koordinat 2D                                                 !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_KOORD_2D {  /* (�,n) Koordinatpar */
+   double dAust;     /* �st-koordinat */
+   double dNord;     /* nord-koordinat */
+} LC_KOORD_2D;
+
+/*
+ *!--------------------------------------------------------------!
+ *! Koordinat 3D                                                 !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_KOORD_3D {  /* (�,n,h) Koordinatpar */
+   double dAust;     /* �st-koordinat */
+   double dNord;     /* nord-koordinat */
+   double dHoyde;    /* H�yde */
+} LC_KOORD_3D;
+
+/*
+ *!--------------------------------------------------------------!
+ *! Rektangel                                                    !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_REKT {
+   double dMinAust;
+	double dMinNord;
+   double dMaxAust;      
+   double dMaxNord;      
+} LC_REKT;
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Kontanter og struktur for handtering av TRANSPAR i filhodet  !
+ *!--------------------------------------------------------------!
+ */
+// Maske som styrer hvilke elementer i LC_TRANSPAR som benyttes
+#define LC_TR_KOORDSYS  ((unsigned short)0x0001)  /* Koordsys */  
+#define LC_TR_TRANSSYS  ((unsigned short)0x0002)  /* Transsys */
+#define LC_TR_GEOSYS    ((unsigned short)0x0004)  /* Geosys   */  
+#define LC_TR_GEOKOORD  ((unsigned short)0x0008)  /* Geokoord */  
+#define LC_TR_ORIGO     ((unsigned short)0x0010)  /* Origo-n� */  
+#define LC_TR_ENHET     ((unsigned short)0x0020)  /* Enhet    */  
+#define LC_TR_ENHETH    ((unsigned short)0x0040)  /* Enhet-h  */  
+#define LC_TR_ENHETD    ((unsigned short)0x0080)  /* Enhet-d  */  
+#define LC_TR_VERTDATUM ((unsigned short)0x0100)  /* Vert-datum */
+#define LC_TR_VERTINT   ((unsigned short)0x0200)  /* Vert-int   */
+#define LC_TR_VERTDELTA ((unsigned short)0x0400)  /* Vert-delta */
+
+#define LC_TR_ALLT      ((unsigned short)0xFFFF)  /* Alle deler av ..TRANSPAR */  
+
+
+// Definerer struktur for ..TRANSPAR
+typedef struct dLC_TRANSPAR {
+   /* ...KOORDSYS */
+   short   sKoordsys;
+   char    szKoordsysDatum[36];
+   char    szKoordsysProjek[36];
+   /* ...TRANSSYS */
+   short sTranssysTilsys;
+   double dTranssysKonstA1;
+   double dTranssysKonstB1;
+   double dTranssysKonstA2;
+   double dTranssysKonstB2;
+   double dTranssysKonstC1;
+   double dTranssysKonstC2;
+   /* ...GEOSYS */
+   short sGeosysDatum;
+   short sGeosysProj;
+   short sGeosysSone;
+   /*...GEOKOORD */
+   short sGeoKoord;
+   /* ...ORIGO-N� */
+   LC_KOORD_2D Origo;
+   //double dOrigoAust;
+   //double dOrigoNord;
+   /* ...ENHET */
+   double  dEnhet;
+   /* ...ENHET-H */
+   double  dEnhet_h;
+   /* ...ENHET-D */
+   double  dEnhet_d;      
+   /* ...VERT-DATUM */ 
+   char szVertdatHref[7];
+   char szVertdatDref[6];
+   char szVertdatFref[6];
+   char szVertdatHtyp[2];
+   /* ...VERT-INT */ 
+   short sVertintHref;
+   short sVertintDref;
+   short sVertintFref;
+   /* ...VERT-DELTA */ 
+   short sVdeltaMin;
+   short sVdeltaMax;
+} LC_TRANSPAR;
+
+
+#define LC_TR_GEOSYS_INGEN_VERDI  -9999  // Brukes  for � angi at projeksjon og sone under geosys ikke er gitt
+
+// Konstanter for definering av filtype (prim�rt for bruk i GabEdit) JA�-20010306
+#define LC_FILTYPE_UKJENT        0
+#define LC_FILTYPE_INAKTIV       1
+#define LC_FILTYPE_GAB_EIENDOM   2
+#define LC_FILTYPE_GAB_ADRESSE   3
+#define LC_FILTYPE_GAB_BYGNING   4
+#define LC_FILTYPE_BYGG          5
+#define LC_FILTYPE_DEK           6
+#define LC_FILTYPE_DEK_ENDRING   7
+#define LC_FILTYPE_GRUNNKRETS    8
+#define LC_FILTYPE_POSTKRETS     9
+#define LC_FILTYPE_SKOLEKRETS   10
+#define LC_FILTYPE_KIRKESOGN    11
+#define LC_FILTYPE_TETTSTED     12
+#define LC_FILTYPE_VALGKRETS    13
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Filadministrasjon                                            !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_FILADM{
+   char     szBaseVer[LC_BASEVER_LEN]; // Versjon og dato for aktuell versjon av FYBA
+   char     szIdxVer[5];    // Indeksfil-versjon
+   short    sIdxOpen;       // UT_FALSE/UT_TRUE - Flagg som viser at indeks er �pnet
+   unsigned long ulPid;     // Prosess ID for programmet som har �pnet filen
+   short    sFilType;       // Prim�rt tenkt brukt i GabEdit, definerer hvilken type arbeidsfil dette er.
+   unsigned short  usLag;   // Lag: (LC_SEKV,LC_FRAMGR,LC_BAKGR)
+   char     szNgisLag[LC_NGISLAG_LEN]; // Ngislag i filhodet
+   short    sAccess;        // Aksess: (READ / UPDATE)
+	/* short    sDisk; */          // Disk for SOSI-filen (1=A, 2=B, osv.)
+   char    *pszNavn;        // Filnavn (SOSI-filens navn, inkl. sti
+   UT_INT64 SosiBytes;      // Antall byte i SOSI-filen
+   FTID     SosiTid;        // Oppdateringstidspunkt for SOSI-filen
+   LC_TRANSPAR TransPar;       // Transformasjonsparametre fra filhodet
+   unsigned short TransMaske;  // Maske som viser hvilke deler av TransPar som inneholder data
+   LC_REKT Omr;                // ..OMR�DE fra filhodet
+   short   sTegnsett;          // Tegnsett fra filhodet eller standardverdi
+   char    szDato[LC_DATO_LEN]; // ..DATO fra fil-hodet
+   short   sSosiVer;            // ..SOSI-VERSJON fra fil-hodet * 100
+   char    SosiNiv[2];          // ..SOSI-NIV� fra fil-hodet
+                                 // SosiNiv[0] = niv� fra fil�pningen
+                                 // SosiNiv[1] = niv� fra senere handtering
+                                 // Filhodet oppdateres n�r filen stenges
+   // short usUlovligRef;  // Bryter som viser om det er ulovlige
+   //                      // referanser i filen (Indeksoppbygging)
+   unsigned short usDataFeil;  // Flagg som viser om det er datafeil
+                               // i filen (Indeksoppbygging)
+   LC_KVALITET Kvalitet;   // Kvalitet fra filhodet
+
+   UT_INT64 n64AktPos;        // Aktuell posisjon for sekv. skriv / les
+	UT_INT64 n64NesteLedigRbPos; // Neste ledige posisjon i buffer-filen
+   long lSisteGrRb;       // Siste gruppe i buffer-filen
+
+   long lMaxSnr;        // St�rste serienummer brukt i filen
+   long    lAntGr;      // Antall grupper i filen
+
+   struct dLC_NAVNETABELL  SosiNavn;   // Navnetabell
+
+	LC_IDX_TABELL *pIdx; // Starten av indekstabellen
+   LC_R_NODE *pGeoRN;   // Peker til starten av trestruktur for geografisk s�k
+   LC_BOKS Omraade;     // Omr�de angitt i filhodet ved �pning
+
+   struct dLC_FILADM *pNesteFil;  // Peker til neste fil-adm.
+   struct dLC_BASEADM *pBase;     // Peker til base-adm. for denne filen
+} LC_FILADM;
+
+
+/* Konstanter for flagg som viser om det er datafeil i filen (Indeksoppbygging) */
+#define LC_DATAFEIL_REF  1   /* Ulovlig referanse (referanse til gruppe som ikke finnes)*/
+#define LC_DATAFEIL_BUE  2   /* Ulovlige buer i filen */
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Baseadministrasjon                                           !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_BASEADM{
+   short  sType;        // Basetype: LC_BASE / LC_START_KLADD / LC_KLADD
+
+   long   lAntGr;       // Antall grupper i basen
+   LC_BOKS Omraade;     // Summert omr�de fra filhodene
+   short sAntFramgrFil; // Antall filer i framgrunn
+   short sAntBakgrFil;  // Antall filer i bakgrunn
+
+   LB_LESEBUFFER BufAdm;  // Vanlig lesebuffer mot SOSI-fil
+
+   LC_FILADM *pCurSos;    // Fil-adm for �pen SOSI-fil
+   FILE      *pfSos;      // Filhandel for �pen SOSI-fil
+
+   LC_FILADM *pCurRb;    // Fil-adm for �pen Rb-fil
+	FILE      *pfRb;      // Filhandel for �pen Rb-fil
+   short      sModusRb;  // LES eller SKRIV til buffer-filen
+   UT_INT64    n64FilPosRb; // Aktuell posisjon i buffer-filen 
+
+   LC_FILADM *pForsteFil;    // Peker til f�rste fil-adm.
+   LC_FILADM *pSisteFil;     // Peker til siste fil-adm.
+
+   struct dLC_BASEADM *pNesteBase;      // Peker til neste base-adm
+} LC_BASEADM;
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Gruppenummer                                                 !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_BGR {
+   LC_FILADM *pFil;   /* Peker til FilAdm for SOSI-fil */
+   long lNr;          /* Gruppenummer innen filen */
+} LC_BGR;
+
+/*
+ *!--------------------------------------------------------------!
+ *! Hent flate-referanser, status                                !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_GR_STAT {  
+   short sGiLinNr;  /* Aktuell GINFO-linjenummer referanselesing */
+   short sRefPos;   /* Aktuell posisjon i GINFO-linja */
+   short sRefLin;   /* Viser om aktuel linje inneholder referanser */
+} LC_GR_STATUS;
+
+typedef struct dLC_GRF_STAT {
+   LC_GR_STATUS Omkr;
+   unsigned short usOmkretsFerdig;
+   LC_GR_STATUS Oy;
+   LC_BGR Bgr;      /* Aktuell �y-gruppe */
+} LC_GRF_STATUS;
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Geografisk s�k, status mm.                                   !
+ *!--------------------------------------------------------------!
+ */
+
+/* Kjede med resultatet av s�ket */
+typedef struct dLC_KJEDE_BGR {
+   LC_BGR Bgr;
+   struct dLC_KJEDE_BGR *pNesteKB;
+} LC_KJEDE_BGR;
+
+/* S�kemetode i basen */
+#define LC_GEO_SEKV  0x0000   /* S�ker sekvensiellt gjennom gruppene */
+#define LC_GEO_RTRE  0x0001   /* Bruker R-tre-srukturene i s�ket */
+
+/* Status */
+typedef struct dLC_GEO_STAT {
+   unsigned short usMetode; /* S�kemetode (LC_GEO_SEKV eller LC_GEO_RTRE) */ 
+   double nvn,nva,ohn,oha; /* Rektangel for s�keomr�de. */
+   unsigned short usLag; /* Lag det skal s�kes i. (LC_FRAMGR | LC_BAKGR) */
+   LC_BGR Bgr;           /* Aktuell gruppe */
+   /* Kjede med resultatet av s�ket */
+   LC_KJEDE_BGR *pForsteKB;
+   LC_KJEDE_BGR *pSisteKB;
+   LC_KJEDE_BGR *pAktuellKB;
+} LC_GEO_STATUS;
+
+   
+/*
+CH Utvalgstabell
+CD .===============================================================================.
+CD !Ginfo/!Utvalgs-!Prio-!SOSI-!Utvalgs-!Para-!Ledd-!Start !Slutt !Min !Max !Regel-!
+CD !Pinfo !kommando!ritet!navn !metode  !type !nr   !i str !i str !    !    !navn  !
+CD !------!--------!-----!-----!--------!-----!-----!------!------!----!----!------!
+CD !gi_pi !kommando!sPri-!sosi !metode  !type !ledd !start !slutt !min !max !regel !
+CD !      !        !orit-!     !        !     !     !      !      !    !    !      !
+CD !  c   !  c     !et   !c[]  ! c      !  c  !  c  !  c   !  c   !c[] !c[] ! c[]  !
+CD !      !        !     !     !        !     !     !      !      !    !    !      !
+CD !      !        ! s   !     !        !     !     !      !      !    !    !      !
+CD !Def. se under  !     !     !Def. se !se   !     !      !      !Def. se nedenfor!
+CD !      !        !     !     !nedenfor!nedf.!     !      !      !    !    !      !
+CD *-------------------------------------------------------------------------------*
+*/
+
+   /* Gruppe, punkt eller pinfo-uvalg */
+#define U_GRUPPE   1   /* GRUPPE-UTVALG */
+#define U_PUNKT    2   /* PUNKT-UTVALG */
+#define U_PINFO    3   /* PINFO-UTVALG */
+
+/* Struktur for statusopplysninger for LC_InitPP / LC_GetPP */
+typedef struct {
+   short type;         /* LC_GETPP_KP, LC_GETPP_HOYDE, LC_GETPP_KVALITET, LC_GETPP_VANLIG */
+   char pinfo_navn[LC_MAX_SOSINAVN_LEN]; /* Sosi-navn det skal finnes verdi til */
+   long curr_punkt;        /* Aktuellt punkt */
+   long slutt_punkt;       /* F�rste punkt etter s�keomr�det */
+	short neste_tegn;       /* Neste tegn (Ved flere PINFO i punktet) */
+} LC_GETPP_STATUS;
+/* Bruk:  LC_GETPP_STATUS  pp_stat; */
+
+#define LC_GETPP_VANLIG   0
+#define LC_GETPP_KP       1
+#define LC_GETPP_HOYDE    2
+#define LC_GETPP_KVALITET 3
+
+   /* Konstant for sAktuellPrioritet */
+#define LC_OVERSE_PRIORITET  -1
+
+/* Utvalgslinje */
+typedef struct sLC_UTVALG_ELEMENT {
+   char kommando;
+   char sosi[LC_MAX_SOSINAVN_LEN];
+   char metode;
+   //char type;
+   short type;
+   char ledd;         /* Ledd-nr for flerleddet parameter */
+	char start;        /* Startposisjon i tegnstreng (0=hele) */
+   char slutt;        /* Sluttposisjon i tegnstreng (0=resten) */
+   char *min;
+   char *max;
+   struct sLC_UTVALG_ELEMENT *pNesteUE;       /* Neste p� dette niv� */
+   struct sLC_UTVALG_ELEMENT *pForsteUE; /* F�rste p� niv�et under */
+   struct sLC_UTVALG_ELEMENT *pSisteUE;  /* Siste p� niv�et under */
+} LC_UTVALG_ELEMENT;
+
+typedef struct sLC_LAG {
+   char  *pszLagNavn;           /* Lagnavn */
+   short  sLagAktiv;            /* Lag aktiv for tegning */
+   struct sLC_LAG *pNesteLag;   /* Neste lag */
+} LC_LAG;
+
+#define LC_UFORANDRET 0
+#define LC_ENDRET     1
+#define LC_NY         2
+#define LC_SLETTET    3
+
+typedef struct sLC_UTVALG {
+   char  *pszNavn;
+   short  sPrioritet;
+   short  sOriginalPrioritet;
+   short sStatus;
+   short sTegnes;                 // Flagg for � styre om utvalgsregelen skal brukes ved tegning
+   LC_UTVALG_ELEMENT *pForsteUE; /* F�rste utvalgslinje p� �verste niv� */
+   LC_UTVALG_ELEMENT *pSisteUE;  /* Siste utvalgslinje p� �verste niv� */
+
+   struct sLC_UTVALG *pForrigeU;  /* Forrige utvalg */
+   struct sLC_UTVALG *pNesteU;    /* Neste utvalg */
+   struct sLC_LAG *pLag;          /* Lag */
+   char *pszRegel;                /* Regel */
+} LC_UTVALG;
+
+/* Toppblokk for GRUPPE-, PUNKT- og PINFO-utvalg */
+typedef struct dLC_UTVALG_BLOKK {
+   short sHoydeBrukt;
+   short sTestAllePi;    /* "!" er brukt, m� sjekke alle punkt */
+   LC_UTVALG *pForsteU;
+   LC_UTVALG *pSisteU;
+   LC_UTVALG *pAktU;
+} LC_UTVALG_BLOKK;
+
+/* Administrasjonsblokk for utvalg */
+typedef struct dLC_UT_ADM {
+   short            sMaxPrior;       /* St�rste prioritet */
+   LC_UTVALG_BLOKK  Gruppe;
+   LC_UTVALG_BLOKK  Punkt;
+   LC_UTVALG_BLOKK  Pinfo;
+   LC_UTVALG_BLOKK *pAktUB;
+	short            sGruppeValgt;
+   LC_LAG *pForsteLag;
+   LC_LAG *pSisteLag;
+} LC_UT_ADM;
+
+/* Administrasjonsblokk for serienummers�k */
+typedef struct dLC_SNR_ADM {
+   LC_FILADM *pFil;
+	long lMinSnr;
+   long lMaxSnr;
+   long lAktSnr;
+} LC_SNR_ADM;
+
+/*
+CH Polygonbeskrivelse                        Strukturer for polygonbeskrivelse.
+CD 
+CD Dette er et sett med strukturer som er kjedet sammen til en komplett
+CD beskrielse av en flate. Eksempel p� bruk er gitt under $LENKE<LC_POL_GetRef>.
+CD
+CD
+CD   !-----------------!
+CD   ! LC_POLYGON      !
+CD   !                 !       !-------------------------!
+CD   ! !- Omkrets --!  !       !   !-----------------!   !---------------!
+CD   ! !LC_POL_OMKR !  !       ! !-!LC_POL_ELEMENT   ! !-!LC_POL_ELEMENT !
+CD   ! !            !  !       ! ! ! - Bgr           ! ! ! - Bgr         !
+CD   ! !- Siste     !--!-------! ! ! - Snr           ! ! ! - Snr         !
+CD   ! !- F�rste    !--!---------! ! - Retning       ! ! ! - Retning     !
+CD   ! !------------!  !           ! - Forrige (NULL)! ! ! - Forrige     !
+CD   ! !- Hull ------! !           ! - Neste         !-! ! - Neste (NULL)!
+CD   ! !LC_OY_ADM    ! !           !-----------------!   !---------------!
+CD   ! !             ! !
+CD   ! !- F�rste �y  !-!-!
+CD !-!-!- Siste �y   ! ! !
+CD ! ! !-------------! ! !
+CD ! !-----------------! !
+CD !   !-----------------!
+CD !   !                                 !------------------------!
+CD !   !                  !------------! !   !-----------------! !---------------!
+CD !  !--------------!  !-!LC_POL_OMKR ! ! !-!LC_POL_ELEMENT   !!!LC_POL_ELEMENT !
+CD !  !LC_OY_ELEMENT !  ! !            ! ! ! ! - Bgr           !!! - Bgr         !
+CD !  !- Omkrets     !--! !- Siste     !-! ! ! - Snr           !!! - Snr         !
+CD !  !- Neste       !-!  !- F�rste    !---! ! - Retning       !!! - Retning     !
+CD !  !--------------! !  !------------!     ! - Forrige (NULL)!!! - Forrige     !
+CD !                   !                     ! - Neste         !!! - Neste (NULL)!
+CD !                   !                     !-----------------! !---------------!
+CD !                   !
+CD !   !---------------!                 !--------------------------!
+CD !   !                  !------------! !   !-----------------!   !---------------!
+CD !  !--------------!  !-!LC_POL_OMKR ! ! !-!LC_POL_ELEMENT   ! !-!LC_POL_ELEMENT !
+CD !--!LC_OY_ELEMENT !  ! !            ! ! ! ! - Bgr           ! ! ! - Bgr         !
+CD    !- Omkrets     !--! !- Siste     !-! ! ! - Snr           ! ! ! - Snr         !
+CD    !- Neste (NULL)!    !- F�rste    !---! ! - Retning       ! ! ! - Retning     !
+CD    !--------------!    !------------!     ! - Forrige (NULL)! ! ! - Forrige     !
+CD                                           ! - Neste         !-! ! - Neste (NULL)!
+CD                                           !-----------------!   !---------------!
+*/
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Polygon element (ett for hver gruppe i polygonbeskrivelsen)  !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_POL_ELEMENT {
+   LC_BGR Bgr;       /* Gruppenummer */
+   short  sRetning;  /* LC_MED_DIG eller LC_MOT_DIG */
+   long   lSnr;      /* Serienummer */
+   LC_KOORD_2D Pkt;     /* (�,n) Representasjonspunkt (Brukes ikke av FYBA. Til disp.) */
+   struct dLC_POL_ELEMENT *pNestePE;  /* Peker til neste element i polygonet */
+   struct dLC_POL_ELEMENT *pForrigePE;  /* Peker til forrige element i polygonet */
+} LC_POL_ELEMENT;
+
+/*
+ *!----------------------------------------------------------------------!
+ *! Adm. blokk for polygon (en for hver lukket "del", omkrets eller �y)  !
+ *!----------------------------------------------------------------------!
+ */
+typedef struct dLC_POL_OMKR {
+   LC_POL_ELEMENT *pForstePE;
+   LC_POL_ELEMENT *pSistePE;
+} LC_POL_OMKR;
+
+/*
+ *!--------------------------------------------------------------!
+ *! �y (i polygon) element  (en for hver �y)                    !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_OY_ELEMENT{
+	LC_POL_OMKR PO;  /* Administrasjonsblokk til kjede som beskriv �yavgrensinga */
+   struct dLC_OY_ELEMENT *pNesteOE;  /* Peker til neste �yelement i polygonet */
+   struct dLC_OY_ELEMENT *pForrigeOE;  /* Peker til forrige �yelement i polygonet */
+} LC_OY_ELEMENT;
+
+/*
+ *!------------------------------------------------------------------------!
+ *! Adm. blokk for �y (i polygon) element (en for alle �yene i en flate)  !
+ *!------------------------------------------------------------------------!
+ */
+typedef struct dLC_OY_ADM{
+   LC_OY_ELEMENT *pForsteOE;   /* F�rste �y (hull) */
+   LC_OY_ELEMENT *pSisteOE;    /* Siste �y  (hull) */
+} LC_OY_ADM;
+
+/*
+ *!--------------------------------------------------------------!
+ *! Adm blokk for Polygon  (En for hver flate, inkl �yer)        !
+ *!--------------------------------------------------------------!
+ */
+
+typedef struct dLC_POLYGON {
+   LC_POL_OMKR HovedPO;      /* Adm blokk for kjede som beskriver ytre avgrensing */
+   LC_OY_ADM  OyOA;        /* Kjede som beskriver hull i flata */
+} LC_POLYGON;
+
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fyho.c                       */
+/* ======================================================= */
+SK_EntPnt_FYBA short HO_New(const char *pszFil,short koosys,double origo_a,double origo_n,
+                            double enhet,double enhet_h,double enhet_d,
+                            double nv_a,double nv_n,double oh_a,double oh_n);
+SK_EntPnt_FYBA short HO_TestSOSI(const char *pszFil,UT_INT64 *sluttpos);
+SK_EntPnt_FYBA char *HO_GetVal(const char *pszFil,char *sosi_navn,short *sett_nr);
+SK_EntPnt_FYBA short HO_GetKvalitet(const char *pszFil,short *psMetode,long *plNoyaktighet,
+                                    short *psSynbarhet,short *psHoydeMetode,long *plHoydeNoyaktighet);
+SK_EntPnt_FYBA short HO_GetTrans(const char *pszFil,short *koosys,double *origo_a,
+                                 double *origo_n,double *enhet,double *enhet_h,double *enhet_d);
+SK_EntPnt_FYBA short HO_GetTransEx(const char *pszFil,unsigned short *pusMaske, LC_TRANSPAR *pTrans);
+SK_EntPnt_FYBA short HO_GetOmr(const char *pszFil,double *nv_a,double *nv_n,double *oh_a,double *oh_n);
+SK_EntPnt_FYBA short HO_GetTegnsett(const char *pszFil,short *psTegnsett);
+SK_EntPnt_FYBA short HO_SjekkTegnsett(const char *pszFil,short *psTegnsett);
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fylh.c                       */
+/* ======================================================= */
+SK_EntPnt_FYBA short LC_GetTrans(short *koosys,double *origo_a,double *origo_n,double *enhet,
+						               double *enhet_h,double *enhet_d);
+SK_EntPnt_FYBA short LC_GetTransEx(unsigned short *pusMaske, LC_TRANSPAR *pTrans);
+SK_EntPnt_FYBA short LC_PutTrans(short koosys,double origo_a,double origo_n,
+                                 double enhet,double enhet_h,double enhet_d);
+SK_EntPnt_FYBA short LC_PutTransEx(unsigned short usMaske, LC_TRANSPAR *pTrans);
+SK_EntPnt_FYBA short LC_GetTegnsett(short *psTegnsett);
+SK_EntPnt_FYBA short LC_GetOmr(double *nv_a,double *nv_n,double *oh_a,double *oh_n);
+SK_EntPnt_FYBA short LC_PutOmr(double nv_a,double nv_n,double oh_a,double oh_n);
+SK_EntPnt_FYBA void  LC_NyttHode(void);
+SK_EntPnt_FYBA short LC_TestHode(void);
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fylo.c                       */
+/* ======================================================= */
+SK_EntPnt_FYBA void			LC_Init(void);
+SK_EntPnt_FYBA void			LC_Close(void);
+SK_EntPnt_FYBA LC_BASEADM* LC_OpenBase(short sBaseType);
+SK_EntPnt_FYBA void			LC_CloseBase(LC_BASEADM *pBase,short s_stat);
+SK_EntPnt_FYBA short			LC_OpenSos(const char *fil,short sModus,short sNyIdx,short sVisStatus,
+                                      LC_FILADM **ppFil, short *o_stat);
+SK_EntPnt_FYBA void			LC_CloseSos(LC_FILADM *pFil,short s_stat);
+SK_EntPnt_FYBA void        LC_FcloseSos(LC_FILADM *pFil);
+SK_EntPnt_FYBA void    LC_SetDefLpfi(short ant_tegn);
+SK_EntPnt_FYBA short   LC_InqDefLpfi(void);
+SK_EntPnt_FYBA short   LC_InqLag(unsigned short *usLag);
+SK_EntPnt_FYBA unsigned short LC_InqFilLag(LC_FILADM *pFil);
+SK_EntPnt_FYBA void    LC_SetFilLag(LC_FILADM *pFil,unsigned short usLag);
+SK_EntPnt_FYBA short   LC_Backup(LC_FILADM *pFil,const char *pszBackupPath);
+SK_EntPnt_FYBA void    LC_MaxSkriv(long);
+SK_EntPnt_FYBA long    LC_InqMaxSkriv(void);
+SK_EntPnt_FYBA void    LC_SetNgisModus(short modus);
+SK_EntPnt_FYBA short   LC_GetNgisModus(void);
+SK_EntPnt_FYBA void    LC_SetUtvidModus(short modus);
+SK_EntPnt_FYBA short   LC_GetUtvidModus(void);
+SK_EntPnt_FYBA LC_BASEADM* LC_InqCurBase(void);
+SK_EntPnt_FYBA void    LC_SelectBase(LC_BASEADM *pBase);
+SK_EntPnt_FYBA short   LC_GetBaOm(unsigned short usLag,double *nva,double *nvn,double *oha,double *ohn);
+SK_EntPnt_FYBA short   LC_GetFiOm(LC_FILADM *pFil,double *nva,double *nvn,double *oha,double *ohn);
+SK_EntPnt_FYBA LC_FILADM * LC_GetFiNr(const char *fil_navn);
+SK_EntPnt_FYBA char   *LC_GetFiNa(LC_FILADM *pFil);
+SK_EntPnt_FYBA short   LC_ErFilBase(const char *fil);
+SK_EntPnt_FYBA short   LC_ErKoordsysLik(void);
+SK_EntPnt_FYBA short   LC_ErVertdatumLik(void);
+SK_EntPnt_FYBA char*   LC_GetNgisLag(LC_FILADM *pFil);
+SK_EntPnt_FYBA void    LC_SetEndringsstatus(short sStatus);
+SK_EntPnt_FYBA void    LC_SetFilType(LC_FILADM *pFil, short sType);
+SK_EntPnt_FYBA short   LC_GetFilType(LC_FILADM *pFil);
+SK_EntPnt_FYBA short   LC_SetIdxPath(const char *pszIdxPath);
+SK_EntPnt_FYBA const char* LC_GetIdxPath(void);
+/* Konstanter for intgt.sEndra (aktuell gruppe er endra) */
+#define END_UENDRA  0   /* Ikke endra */
+#define END_KOPI    1   /* Endra ved totalkopi fra annen gruppe */
+#define END_ENDRA   2   /* Endra ved normal Put fra program */
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fylx.c                       */
+/* ======================================================= */
+#define GRF_YTRE   0x01  /* Ytre avgrensing */
+#define GRF_INDRE   0x02  /* Indre avgrensing, �yer */
+#define LC_MED_DIG 0x01  /* Brukes MED dig retning */
+#define LC_MOT_DIG 0x02  /* Brukes MOT dig retning */
+#define GRF_START_OY    0x04  /* F�rste gruppe i �y */
+#define GRF_SLUTT_OY    0x08  /* Siste gruppe i �y */
+
+SK_EntPnt_FYBA long   LC_InqAntRef(void);
+SK_EntPnt_FYBA void   LC_InitGetRefFlate(LC_GRF_STATUS *pGrfStat);
+SK_EntPnt_FYBA long   LC_GetRefFlate(LC_GRF_STATUS *RefStat,unsigned short sHent,long *ref_array,
+                                     unsigned char *ref_status,long max_ref);
+SK_EntPnt_FYBA short  LC_PutRef(long *ref_array,long ant_ref);
+SK_EntPnt_FYBA long   LC_GetRef(long *ref_array,long max_ref,short *gilin,short *refpos);
+
+SK_EntPnt_FYBA short  LC_GetBuePar(short buff_retning, double *as, double *ns, double *radius,
+                                   double *fi, double *dfi, short *sfeil);
+SK_EntPnt_FYBA short  LC_GetBue(short retning,double *a1,double *n1,double *a2,double *n2,
+                                double *radius,short *storbue);
+SK_EntPnt_FYBA short  LC_GetBuep(short retning,double *a1,double *n1,double *a2,double *n2,
+                                 double *a3,double *n3);
+SK_EntPnt_FYBA short  LC_GetSirkel(double *as,double *ns,double *radius);
+SK_EntPnt_FYBA short  LC_GetSirkelp(double *a1,double *n1,double *a2,double *n2,
+                                    double *a3,double *n3);
+
+SK_EntPnt_FYBA void   LC_GetCurEnhet(LC_FILADM * pFil,short *nivaa, double *enhet,
+                                     double *enhet_h, double *enhet_d);
+SK_EntPnt_FYBA short  LC_UpdateGiEnhet(LC_FILADM *pFil,double enhet,double enhet_h,double enhet_d);
+
+SK_EntPnt_FYBA short  LC_GetKvalitet(short *psMetode,long *plNoyaktighet,short *psSynbarhet,
+                                     short *psHoydeMetode,long *plHoydeNoyaktighet);
+SK_EntPnt_FYBA short  LC_GetCurKvalitet(LC_FILADM *pFil,short *nivaa,long pnr,
+                                        short *psMetode,long *plNoyaktighet,short *psSynbarhet,
+                                        short *psHoydeMetode,long *plHoydeNoyaktighet);
+SK_EntPnt_FYBA short  LC_UpdateGiKvalitet(LC_FILADM *pFil,short sMetode,long lNoyaktighet,
+                                          short sSynbarhet,short sHoydeMetode,long lHoydeNoyaktighet);
+SK_EntPnt_FYBA short  LC_UpdatePiKvalitet(LC_FILADM *pFil,long pnr,short sMetode,long lNoyaktighet,
+                                          short sSynbarhet,short sHoydeMetode,long lHoydeNoyaktighet);
+
+SK_EntPnt_FYBA char * LC_GetGP(const char *,short *,short);
+SK_EntPnt_FYBA short LC_PutGP(const char *sosi_navn,const char *verdi,short *linje_nr);
+SK_EntPnt_FYBA short LC_AppGP(const char *sosi_navn,const char *verdi,short *linje_nr);
+SK_EntPnt_FYBA short  LC_UpdateGP(short linje_nr,const char *sosi_navn,const char *verdi);
+SK_EntPnt_FYBA void   LC_InitPP(char *sosi_navn,long forste_punkt,long siste_punkt,
+                                LC_GETPP_STATUS *pp_status);
+SK_EntPnt_FYBA char * LC_GetPP(long *punkt,LC_GETPP_STATUS *pp_stat);
+SK_EntPnt_FYBA char * LC_GetPiVerdi(const char *pszSosiNavn,long sPnr,short *sSettNr);
+SK_EntPnt_FYBA short  LC_TestPi(long punkt_nr,short sTestHoyde);
+SK_EntPnt_FYBA short  LC_FinnKp(long *forste_punkt,long siste_punkt,short *kp);
+SK_EntPnt_FYBA long   LC_GetSn(void);
+SK_EntPnt_FYBA void   LC_PutSn(long snr);
+SK_EntPnt_FYBA char * LC_GetGi(short gilin);
+SK_EntPnt_FYBA void   LC_PutGi(short gilin,const char *ginfo);
+SK_EntPnt_FYBA void   LC_GetTK(long pkt,double *aust,double *nord);
+SK_EntPnt_FYBA void   LC_GetArrayTK(short retning,long max_antall,long fra_punkt,
+                                    double *aust,double *nord,long *antall);
+SK_EntPnt_FYBA void   LC_GetArrayTH(short retning,long max_antall,long fra_punkt,
+                                    double *hoyde,long *antall);
+SK_EntPnt_FYBA void   LC_PutTK(long punkt_nr,double aust,double nord);
+SK_EntPnt_FYBA double LC_GetTH(long pkt);
+SK_EntPnt_FYBA void   LC_PutTH(long pkt,double hoyde);
+SK_EntPnt_FYBA double LC_GetHoyde(long punkt_nr);
+SK_EntPnt_FYBA void   LC_PutTD(long punkt_nr, double dybde);
+SK_EntPnt_FYBA double LC_GetTD(long punkt_nr);
+SK_EntPnt_FYBA double LC_GetDybde(long punkt_nr);
+SK_EntPnt_FYBA char * LC_GetPi(long pkt);
+SK_EntPnt_FYBA short  LC_PutPi(long pkt,const char *pi);
+SK_EntPnt_FYBA short  LC_GetKp(long pkt);
+SK_EntPnt_FYBA void   LC_PutKp(long pkt,short kp);
+SK_EntPnt_FYBA double LC_BerAreal(void);
+SK_EntPnt_FYBA double LC_BerLengde(void);
+SK_EntPnt_FYBA bool   LC_BerLengde3D(double *skraa_lengde);
+SK_EntPnt_FYBA double LC_BerAvgrensLengde(void);
+SK_EntPnt_FYBA double LC_BerIndreAvgrensLengde(void);
+SK_EntPnt_FYBA double LC_BerYtreAvgrensLengde(void);
+SK_EntPnt_FYBA void   LC_DumpTab(void);
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fylb.c                       */
+/* ======================================================= */
+SK_EntPnt_FYBA short  LC_GetGrFi(LC_FILADM **ppFil);
+SK_EntPnt_FYBA void   LC_InitNextFil(LC_FILADM **ppFil);
+SK_EntPnt_FYBA short  LC_NextFil(LC_FILADM **ppFil,unsigned short usLag);
+SK_EntPnt_FYBA void   LC_InitNextBgr(LC_BGR * pBgr);
+SK_EntPnt_FYBA short  LC_NextBgr(LC_BGR * pBgr,unsigned short usLag);
+SK_EntPnt_FYBA short  LC_InqAntFiler(unsigned short usLag);
+SK_EntPnt_FYBA short  LC_GetGrNr(LC_BGR * pBgr);
+SK_EntPnt_FYBA const char *LC_GetObjtypeBgr(LC_BGR * pBgr);
+SK_EntPnt_FYBA short  LC_GetGrPara(short *ngi,long *nko,unsigned short *info);
+SK_EntPnt_FYBA short  LC_GetGrParaBgr(LC_BGR * pBgr,short *ngi,long *nko,unsigned short *info);
+SK_EntPnt_FYBA short  LC_RsGr(short *rstat,LC_FILADM *pFil,short *ngi,long *nko,
+                              unsigned short *info,long *gml_snr);
+SK_EntPnt_FYBA short  LC_RsHode(LC_FILADM *pFil,short *ngi,long *nko,unsigned short *info);
+SK_EntPnt_FYBA void   LC_WsGr(LC_FILADM *pFil);
+SK_EntPnt_FYBA void   LC_WsGrPart(LC_FILADM *pFil,long fra_punkt,long antall);
+SK_EntPnt_FYBA short  LC_EndreHode(LC_FILADM *pFil);
+SK_EntPnt_FYBA short  LC_RxGr(LC_BGR * pBgr,short les_sosi,short *ngi,long *nko,unsigned short *info);
+SK_EntPnt_FYBA short  LC_WxGr(short k_stat);
+SK_EntPnt_FYBA void   LC_RoundKoord(void);
+SK_EntPnt_FYBA long   LC_FiLastGr(LC_FILADM *pFil);
+SK_EntPnt_FYBA short  LC_NyGr (LC_FILADM *pFil,char *sosi,LC_BGR * pBgr,long *snr);
+SK_EntPnt_FYBA short  LC_CopyGr (LC_BGR * pBgr,short ngis,short *ngi,long *nko,unsigned short *info);
+SK_EntPnt_FYBA short  LC_CopyCoord(LC_BGR * pBgr,short retning,long til_linje,short *ngi,
+                                   long *nko,unsigned short *info);
+SK_EntPnt_FYBA short  LC_DelGr(void);
+SK_EntPnt_FYBA void   LC_SnuGr(void);
+SK_EntPnt_FYBA short  LC_SplittGr (long p1,long p2,LC_BGR * pBgr2);
+SK_EntPnt_FYBA short  LC_SammenfoyGr(LC_BGR * pFraBgr,short retning,short plassering,short metode,
+                      short *ngi,long *nko,unsigned short *info);
+SK_EntPnt_FYBA void   LC_ErstattReferanse (LC_FILADM *pFil,long lGmlSnr,long lNyttSnr, bool bSammeRetning);
+
+
+   /* Konstanter for SammenfoyGr() */
+#define LC_SG_FORRAN 1   /* Heng den andre gruppen inn forran f�rste koordinat */
+#define LC_SG_BAK    2   /* Heng den andre gruppen inn etter siste koordinat */
+#define LC_SG_BEHOLD 3   /* Begge sammenf�yings-punktene beholdes */
+#define LC_SG_FJERN  4   /* Bare det ene av sammenf�yings-punktene beholdes */
+
+
+SK_EntPnt_FYBA short  LC_InsGiL (short linje, short antall);
+SK_EntPnt_FYBA short  LC_AppGiL (void);
+SK_EntPnt_FYBA short  LC_DelGiL (short linje, short antall);
+SK_EntPnt_FYBA short  LC_DelGiNavn(char *pszEgenskapNavn);
+SK_EntPnt_FYBA long  LC_InsKoL (long linje, long antall);
+SK_EntPnt_FYBA long  LC_AppKoL (void);
+SK_EntPnt_FYBA long  LC_DelKoL (long linje, long antall);
+SK_EntPnt_FYBA void   LC_Save (void);
+SK_EntPnt_FYBA void   LC_OppdaterEndret(short endring);
+  #define O_GINFO   0  /* Oppdater tabeller i forhold til GINFO */
+  #define O_ENDRET  1  /* Merk for endret og oppdat. tab. */
+  #define O_SLETTET 2  /* Merk for slettet og oppdat. tab. */
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fyli.c                       */
+/* ======================================================= */
+/* Brukttabellen */
+SK_EntPnt_FYBA void  LC_SetBt(LC_BGR * pGr,short kolonne);
+SK_EntPnt_FYBA void  LC_ClrBt(LC_BGR * pGr,short kolonne);
+SK_EntPnt_FYBA short LC_GetBt(LC_BGR * pGr,short kolonne);
+SK_EntPnt_FYBA void  LC_EraseBt(short fra_kol,short til_kol);
+SK_EntPnt_FYBA void  LC_CopyBt(short fra_kol,short til_kol,short operasjon);
+SK_EntPnt_FYBA void  LC_SetModusMerk(unsigned short usModus);
+SK_EntPnt_FYBA long  LC_MerkGr(short sKolonne,short sBryter);
+SK_EntPnt_FYBA void  LC_ClrPrioritet(LC_BGR * pGr,short kolonne);
+SK_EntPnt_FYBA void  LC_SetPrioritet(LC_BGR * pGr,short kolonne);
+SK_EntPnt_FYBA short LC_InqPrioritet(LC_BGR * pGr,short kolonne);
+SK_EntPnt_FYBA void  LC_ErasePrioritet(LC_BGR * pGr);
+SK_EntPnt_FYBA void  LC_EraseAllPrioritet(LC_FILADM *pFil);
+SK_EntPnt_FYBA void  LC_DumpBt(const char *pszMelding);
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fyld.c                       */
+/* ======================================================= */
+SK_EntPnt_FYBA void   LC_DelIdx(char *szSosFil);
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fyta.c                       */
+/* ======================================================= */
+/* Tabellsystemet */
+SK_EntPnt_FYBA short  LC_InitTabel(long n_rec,short rec_len,void *buffer);
+SK_EntPnt_FYBA short  LC_PutTabel(long linje,void *buffer);
+SK_EntPnt_FYBA short  LC_GetTabel(long linje,void *buffer);
+SK_EntPnt_FYBA void   LC_CloseTabel(void);
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fyln.c                       */
+/* ======================================================= */
+SK_EntPnt_FYBA char *LC_FormatterKvalitet(short sMetode,long lNoyaktighet,short sSynbarhet,
+                           short sHoydeMetode,long lHoydeNoyaktighet);
+SK_EntPnt_FYBA short LC_FinnNivo(const char *pszNavn);
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fyls.c                       */
+/* ======================================================= */
+SK_EntPnt_FYBA void   LC_SBSn(LC_SNR_ADM *pSnrAdm,LC_FILADM *pFil,long lMinSnr,long lMaxSnr);
+SK_EntPnt_FYBA short  LC_MoveSn(LC_SNR_ADM *pSnrAdm,long lSnr,LC_BGR * pBgr);
+SK_EntPnt_FYBA short  LC_FiSn(LC_FILADM *pFil,long lSnr,LC_BGR * pBgr);
+SK_EntPnt_FYBA void   LC_FiArraySn(LC_FILADM *pFil,short antall,long *snr,long *bgr);
+SK_EntPnt_FYBA long   LC_FASn(LC_SNR_ADM *pSnrAdm);
+SK_EntPnt_FYBA short  LC_FFSn(LC_SNR_ADM *pSnrAdm,LC_BGR *pBgr);
+SK_EntPnt_FYBA short  LC_FNSn(LC_SNR_ADM *pSnrAdm,LC_BGR *pBgr);
+SK_EntPnt_FYBA short  LC_FPSn(LC_SNR_ADM *pSnrAdm,LC_BGR *pBgr);
+SK_EntPnt_FYBA short  LC_FLSn(LC_SNR_ADM *pSnrAdm,LC_BGR *pBgr);
+SK_EntPnt_FYBA short  LC_FFSnBt(LC_SNR_ADM *pSnrAdm,short kolonne,LC_BGR *pBgr);
+SK_EntPnt_FYBA short  LC_FNSnBt(LC_SNR_ADM *pSnrAdm,short kolonne,LC_BGR *pBgr);
+SK_EntPnt_FYBA short  LC_FPSnBt(LC_SNR_ADM *pSnrAdm,short kolonne,LC_BGR *pBgr);
+SK_EntPnt_FYBA short  LC_FLSnBt(LC_SNR_ADM *pSnrAdm,short kolonne,LC_BGR *pBgr);
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fylr.c                       */
+/* ======================================================= */
+SK_EntPnt_FYBA short  LC_GetGrWin(LC_BGR *pBgr,double *nva,double *nvn,double *oha,double *ohn);
+/* Flate-s�k */
+SK_EntPnt_FYBA void   LC_SBFlate(LC_GEO_STATUS *pGeoStat,unsigned short usLag,
+                                 double nv_a,double nv_n,double oh_a,double oh_n);
+SK_EntPnt_FYBA short  LC_FFFlate(LC_GEO_STATUS *pGeoStat,LC_BGR * pBgr);
+SK_EntPnt_FYBA short  LC_FNFlate(LC_GEO_STATUS *pGeoStat,LC_BGR * pBgr);
+/* Geografisk s�k prim�r gruppe */
+SK_EntPnt_FYBA void   LC_SBGeo(LC_GEO_STATUS *pGeoStat,unsigned short usLag,
+                               double nv_a,double nv_n,double oh_a,double oh_n);
+SK_EntPnt_FYBA short  LC_FFGeo(LC_GEO_STATUS *pGeoStat,LC_BGR *pBgr);
+SK_EntPnt_FYBA short  LC_FNGeo(LC_GEO_STATUS *pGeoStat,LC_BGR *pBgr);
+SK_EntPnt_FYBA long   LC_FAGeo(LC_GEO_STATUS *pGeoStat);
+SK_EntPnt_FYBA short LC_FFGeoFil(LC_GEO_STATUS *pGeoStat,LC_FILADM *pFil,LC_BGR *pBgr);
+SK_EntPnt_FYBA short LC_FNGeoFil(LC_GEO_STATUS *pGeoStat,LC_FILADM *pFil,LC_BGR *pBgr);
+SK_EntPnt_FYBA void LC_AvsluttSok(LC_GEO_STATUS *pGeoStat);
+
+/* Vindustest mm */
+SK_EntPnt_FYBA short  LC_WTst(double nva,double nvn,double oha,double ohn);
+SK_EntPnt_FYBA short  LC_PTst(double a,double n);
+SK_EntPnt_FYBA short  LC_PTstOmkrets(double a,double n);
+
+/* Debugform�l */
+SK_EntPnt_FYBA void LC_DumpGeoRtre(LC_FILADM *pFil);
+
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fylu.c                       */
+/* ======================================================= */
+SK_EntPnt_FYBA LC_UT_ADM *  LC_OpenQuery(void);
+SK_EntPnt_FYBA void    LC_CloseQuery(LC_UT_ADM *pUtAdm);
+//SK_EntPnt_FYBA short   LC_PutQueryLine(LC_UT_ADM *pUtAdm,char *qulin);
+SK_EntPnt_FYBA short   LC_PutQueryLine(LC_UT_ADM *pUtAdm,const char *qulin,short sType);
+SK_EntPnt_FYBA void    LC_PutQueryRegel(LC_UTVALG *pU,const char *navn);
+SK_EntPnt_FYBA short   LC_LesUtvalg(LC_UT_ADM *pUtAdm,const char *pszKomFil);
+SK_EntPnt_FYBA char   *LC_GetUtRegelNavn(LC_UT_ADM *pUtAdm,short *ist);
+SK_EntPnt_FYBA char   *LC_GruppeUtvalg(LC_UT_ADM *pUtAdm,short sPrior,short *sstat,char **regelnavn);
+SK_EntPnt_FYBA short   LU_GiTestUtvalg(LC_UT_ADM *pUtAdm,LC_UTVALG * pU);
+SK_EntPnt_FYBA void    LC_PunktUtvalg(LC_UT_ADM *pUtAdm,short sPrior,short *psStat,long lPnr,char **ppszRegel);
+SK_EntPnt_FYBA LC_UTVALG *LC_FinnPinfoUtvalg(LC_UT_ADM *pUtAdm,const char *pszNavn);
+SK_EntPnt_FYBA short   LC_PiTestUtvalg(LC_UT_ADM *pUtAdm,LC_UTVALG * pU,long lPnr);
+SK_EntPnt_FYBA short   LC_GiQuery(LC_UT_ADM  *pUtAdm);
+SK_EntPnt_FYBA long    LC_FAGiQuery(LC_UT_ADM *pUtAdm,unsigned short usLag);
+SK_EntPnt_FYBA long    LC_FAPiQuery(LC_UT_ADM *pUtAdm,unsigned short usLag);
+SK_EntPnt_FYBA long    LC_FAGiKombinertFlateQuery(LC_UT_ADM *pUtAdmFlate,LC_UT_ADM *pUtAdmOmkrets,
+											                 unsigned short usLag,short sMetode);
+SK_EntPnt_FYBA short   LC_QueryGP(char *qulin,unsigned short iniv,unsigned short *univ,short *ulin,char **para);
+SK_EntPnt_FYBA short   LC_InqMaxPrioritet(LC_UT_ADM *pUA);
+SK_EntPnt_FYBA short   LC_TestPrioritetBrukt(LC_UT_ADM *pUtAdm,short sPrioritet);
+SK_EntPnt_FYBA void    LC_UtvalgPrioritet(LC_UT_ADM *pUtAdm);
+SK_EntPnt_FYBA void    LC_LoggPrioritetUtvalg(LC_UT_ADM *pUtAdm);
+SK_EntPnt_FYBA void    LU_FrigiUE(LC_UTVALG_ELEMENT *pUE);
+SK_EntPnt_FYBA short   LU_AppUE (LC_UTVALG *pU,short sNiv,const char *pszTx);
+SK_EntPnt_FYBA void    LC_PutLag(LC_UT_ADM *pUtAdm,LC_UTVALG *pU,const char *navn);
+SK_EntPnt_FYBA bool    LC_ErLik_Avrundet(double dA1,double dN1,double dA2, double dN2, double dEnhet);
+SK_EntPnt_FYBA bool    LC_ErLik_IkkeAvrundet(double dA1,double dN1,double dA2, double dN2, double dEnhet);
+SK_EntPnt_FYBA bool    LC_ErReferert(void);
+SK_EntPnt_FYBA long    LC_ErReferertFraAntall(void);
+
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fylp.c                       */
+/* ======================================================= */
+SK_EntPnt_FYBA void LC_POL_InitPolygon(LC_POLYGON *pPolygon);
+SK_EntPnt_FYBA void LC_POL_FrigiPolygon(LC_POLYGON *pPolygon);
+
+SK_EntPnt_FYBA void LC_POL_InitOmkrets(LC_POL_OMKR *pPO);
+SK_EntPnt_FYBA LC_POL_ELEMENT * LC_POL_LeggTilGruppeOmkrets(LC_POL_OMKR *pPO,LC_BGR *pBgr,short sRetning,long lSnr);
+SK_EntPnt_FYBA void LC_POL_FjernSisteGruppeOmkrets(LC_POL_OMKR *pPO);
+SK_EntPnt_FYBA void LC_POL_FjernGruppeOmkrets(LC_POL_OMKR *pPO, LC_POL_ELEMENT *pPE);
+SK_EntPnt_FYBA void LC_POL_FrigiOmkrets(LC_POL_OMKR *pPO);
+
+SK_EntPnt_FYBA void LC_POL_InitOy(LC_OY_ADM *pOA);
+SK_EntPnt_FYBA void LC_POL_FrigiAlleOyer(LC_OY_ADM *pOA);
+SK_EntPnt_FYBA void LC_POL_FjernOy(LC_OY_ADM *pOA,LC_OY_ELEMENT *pOE);
+SK_EntPnt_FYBA void LC_POL_LeggTilOy(LC_OY_ADM *pOA,LC_POL_OMKR *pPO);
+
+SK_EntPnt_FYBA short LC_POL_TestBrukt(LC_POLYGON *pPolygon,LC_BGR *pBgr);
+SK_EntPnt_FYBA short LC_POL_PutRef(LC_POLYGON *pPolygon);
+SK_EntPnt_FYBA void  LC_POL_GetRef(LC_POLYGON *pPolygon);
+SK_EntPnt_FYBA void  LC_POL_GetRefOmkrets(LC_POL_OMKR *pPO);
+SK_EntPnt_FYBA short LC_POL_PTst(LC_POLYGON *pPolygon,double a,double n);
+SK_EntPnt_FYBA short LC_POL_PTstOmkrets(LC_POL_OMKR *pPO,double a,double n);
+SK_EntPnt_FYBA short LC_POL_OmkretsSkjaering(LC_POL_OMKR *pPO,double a,double n);
+SK_EntPnt_FYBA void  LC_POL_Box(LC_POL_OMKR *pPO,double *nva,double *nvn, double *oha,double*ohn);
+SK_EntPnt_FYBA short LC_ErLinjeRefLin(char *pszSosiLin, short sRefLin);
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fyln.c                       */
+/* ======================================================= */
+SK_EntPnt_FYBA const char *LC_GetElementNavn(LC_FILADM *pFil,short sNavnNr,bool *bBrukt);
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fyba.c                       */
+/* ======================================================= */
+SK_EntPnt_FYBA char *LC_InqVer(void);
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fyle.c                       */
+/* ======================================================= */
+SK_EntPnt_FYBA short LC_StrError(short feil_nr,char **feilmelding);
+
+SK_EntPnt_FYBA void LC_SetErrorHandler(void (*f) (short,const char*,const char*));
+SK_EntPnt_FYBA void LC_SetStartMessageHandler(void (*f)(const char*));
+SK_EntPnt_FYBA void LC_SetShowMessageHandler(void (*f)(double));
+SK_EntPnt_FYBA void LC_SetEndMessageHandler(void (*f)(void));
+SK_EntPnt_FYBA void LC_SetCancelHandler(short (*f)(void));
+
+//////////////////////////////////////////////////////////////////////////
+//
+// N�r FYBA brukes som LIB m� f�lgende funksjoner finnes definert
+//
+//////////////////////////////////////////////////////////////////////////
+void  LC_Error (short ifeilnr, const char logtx[], const char vartx[]);
+void  LC_StartMessage(const char *cfil);
+void  LC_ShowMessage(double prosent);
+void  LC_EndMessage(void);
+short LC_Cancel(void);
+
+//////////////////////////////////////////////////////////////////////////
+//
+// N�r FYBA brukes som DLL m� f�lgende funksjoner finnes definert.
+// Eksempel finnes i filen Fyba_Callback.cpp
+// Funksjonene aktiveres med LC_SetXxxxxHandler rutinene.
+// Hvis disse ikke blir aktivert brukes enkle rutiner som ligger i DLL-en.
+//
+//////////////////////////////////////////////////////////////////////////
+void   LC_ErrorHandler (short ifeilnr, const char* logtx, const char* vartx);
+void   LC_StartMessageHandler(const char *cfil);
+void   LC_ShowMessageHandler(double prosent);
+void   LC_EndMessageHandler(void);
+short  LC_CancelHandler(void);
+
+
diff --git a/FYBA/fyba_strings.h b/FYBA/fyba_strings.h
new file mode 100644
index 0000000..ebd8461
--- /dev/null
+++ b/FYBA/fyba_strings.h
@@ -0,0 +1,221 @@
+# ifdef FYBA_STRINGS_EN
+/* =========== ENGLISH FYBA_STRINGS  ================== */
+
+#define FYBA_STRING_BASE_UNKNOWN_TYPE    "Unknown base type, cannot open base."
+#define FYBA_STRING_BASE_TOO_MANY_GROUPS "Too many groups in base."
+#define FYBA_STRING_FILE_NOT_FOUND       "No .sos file found by the name:"
+#define FYBA_STRING_BASE_FYBA_NOT_INITD  "Cannot open base - FYBA has not been initialized."
+#define FYBA_STRING_BASE_NOT_OPEN        "Cannot open SOSI-file. Base has not been opened."
+#define FYBA_STRING_FILE_OPEN_FAILED     "Error opening file:"
+#define FYBA_STRING_FILE_OMRAADE_MISSING "..OMRÅDE missing in file header:"
+#define FYBA_STRING_FILE_MIN_NOE_MISSING "...MIN-NØ missing in file header:"
+#define FYBA_STRING_FILE_MAX_NOE_MISSING "...MAX-NØ missing in file header:"
+#define FYBA_STRING_BASE_INDEX_ABORTED   "Index construction aborted."
+#define FYBA_STRING_BASE_OPEN_FAILED     "Error opening:"
+#define FYBA_STRING_FILE_NEW_HEADER      "New header in:"
+#define FYBA_STRING_FILE_NOT_SOSI        "Not a SOSI file:"
+#define FYBA_STRING_FILE_OMRAADE_INVALID "Invalid OMRÅDE in file header! (No dimensions.)"
+#define FYBA_STRING_SAVE_INVALID_FILEPTR "Invalid file pointer while saving."
+#define FYBA_STRING_OPEN_BASE_IS_KLADDE  "Cannot open SOSI file. Base was opened as KLADDE. This can only be combined with sequential reading/writing."
+#define FYBA_STRING_FILE_READ_ERROR_HODE "Reading error in header line."
+#define FYBA_STRING_FILE_TRANSPAR_MISSING "..TRANSPAR missing in file header."
+#define FYBA_STRING_FILE_KOORDSYS_MISSING "...KOORDSYS missing in file header."
+#define FYBA_STRING_FILE_ORIGO_MISSING   "...ORIGO-NØ missing in file header. (Check the encoding!)"
+#define FYBA_STRING_FILE_ENHET_MISSING   "...ENHET missing in file header."
+#define FYBA_STRING_NAME_TABLE_FULL      "Name table is full."
+#define FYBA_STRING_INVALID_GROUP_NAME   "Invalid group name:"
+#define FYBA_STRING_FILE_NO_CURRENT_GROUP "No current group - nothing read."
+#define FYBA_STRING_OPEN_INVALID_EXTERN  "Invalid external file - nothing read."
+#define FYBA_STRING_SAVE_INVALID_EXTERN  "Invalid external file - nothing written."
+#define FYBA_STRING_SAVE_NO_WRITE_ACCESS "No write access, nothing written to the file:"
+#define FYBA_STRING_GROUP_DELETED        "Group is deleted."
+#define FYBA_STRING_FILE_INVALID_GROUP_NR "Invalid group number, nothing read."
+#define FYBA_STRING_NEW_INVALID_FILE     "Invalid file, cannot create new group."
+#define FYBA_STRING_NEW_NO_WRITE_ACCESS  "No write access, cannot create new group."
+#define FYBA_STRING_NEW_TOO_MANY_GROUPS  "Too many groups in base, cannot create new group."
+#define FYBA_STRING_NEW_INVALID_LINE_GI  "Invalid line number for new GINFO"
+#define FYBA_STRING_NEW_INVALID_LINE_COO "Invalid line number for new coordinates."
+#define FYBA_STRING_SLUTT_MISSING        ".SLUTT missing in SOSI file."
+#define FYBA_STRING_READ_ERROR           "Error reading SOSI file."
+#define FYBA_STRING_GROUP_REFERRED_TO    "Group is referenced by another group, cannot be deleted."
+#define FYBA_STRING_INVALID_GI_LINE_1    "Invalid GINFO line nr. 1."
+#define FYBA_STRING_CANT_REMOVE_HEADER   "You cannot remove the file header."
+#define FYBA_STRING_NO_CURRENT_GROUP     "No current group, nothing changed."
+#define FYBA_STRING_DEL_UNKNOWN_FLAG     "Group has an unknown NGIS change flag, cannot be removed."
+#define FYBA_STRING_DEL_NO_WRITE_ACCESS  "No write access, group cannot be removed."
+#define FYBA_STRING_ERR_FILESIZE_CHANGE  "Error changing file size."
+#define FYBA_STRING_DISK_SOON_FULL       "Your disk is soon full. Make some room at : "
+#define FYBA_STRING_NOT_A_HEADER         "Current group is not a file header - nothing changed."
+#define FYBA_STRING_DEL_NOT_SEQUENTIAL   "You cannot delete groups in sequential mode."
+#define FYBA_STRING_NO_CHANGE_HEADERS    "Cannot change KOORDSYS, ENHET, ORIGO or NGIS-LAG in a file with data."
+#define FYBA_STRING_CANT_REWRITE_HEADER  "No room to write back header."
+#define FYBA_STRING_SAVE_NOT_A_HEADER    "Group is not a header, cannot save it as such."
+#define FYBA_STRING_CANT_COPY_COORD      "Cannot copy coordinates from current group to another."
+#define FYBA_STRING_CANT_COPY_COORD_ROOM "Cannot copy coordinates: Not enough room in ring buffer."
+#define FYBA_STRING_ENHET_NOT_SET        "ENHET is set to 0.0 in the file header, or header is missing:"
+#define FYBA_STRING_CANT_READ_FILE_SIZE  "Error while retrieving file size:"
+#define FYBA_STRING_PINFO_LONG_OR_NO_NOE "PINFO too long -OR- ..NØ missing after PINFO:"
+#define FYBA_STRING_LOGIC_FAIL           "Logic error in SOSI-file\nLine order error, property among coordinates:\n"
+#define FYBA_STRING_MAX_1_KP_OR_NO_NOE   "Max. 1 KP per point -OR- ..NØ missing after KP:"
+#define FYBA_STRING_NO_ROOM_IN_HEADER    "No room in header or corrupt:"
+#define FYBA_STRING_INVALID_GAP          "Invalid gap in point-indentation:"
+#define FYBA_STRING_TOO_MANY_COORDINATES "Too many coordinates in group:"
+#define FYBA_STRING_TOO_MANY_GINFO       "GINFO-line lost.  Too many GINFO lines in:"
+#define FYBA_STRING_TOO_MUCH_GINFO       "GINFO-line lost.  Too much GINFO in:"
+#define FYBA_STRING_TOO_MUCH_PINFO       "PINFO lost. Too much PINFO in:"
+#define FYBA_STRING_CANT_EXTEND_GROUP    "Cannot extend group (too many coordinates):"
+#define FYBA_STRING_READ_NO_WRITE_ACCESS "Cannot read new group. No write access to save current, changed group. File:"
+#define FYBA_STRING_READ_LINE_TOO_LONG   "Cannot read SOSI file. Line too long: "
+#define FYBA_STRING_INVALID_POINT        "Invalid point number:"
+#define FYBA_STRING_INVALID_GINFO        "Invalid GINFO line number:"
+#define FYBA_STRING_INVALID_NODE         "Invalid Node type:"
+#define FYBA_STRING_INVALID_GROUP_NAME   "Invalid group name:"
+#define FYBA_STRING_PINFO_TOO_LONG       "PINFO too long, cannot fetch value. (Contact support/developers)"
+#define FYBA_STRING_INVALID_REF          "Invalid REF in file:"
+#define FYBA_STRING_CANT_CHANGE_ENHET    "Cannot change ENHET in a file with data:"
+#define FYBA_STRING_CANT_CHANGE_NGIS_LAG "Cannot change ..NGIS-LAG in a file with data:"
+#define FYBA_STRING_INVALID_BUE          "Invalid curve (BUE) in file:"
+#define FYBA_STRING_CANT_CHANGE_ORIGO_NOE "Cannot change ..ORIGO-NØ in a file with data:"
+#define FYBA_STRING_PROB_TOO_LONG_PINFO  "PINFO (probably) too long."
+#define FYBA_STRING_NO_HOEYDE_WITH_NAD   "Group has ..NAD, cannot store height per point:"
+#define FYBA_STRING_NO_HOEYDE_WITH_NAH   "Group has ..NAH, cannot store depth per point: "
+#define FYBA_STRING_LINE_TOO_LONG        "SOSI-line too long (max. 1024 characters), line stripped. Group: "
+#define FYBA_STRING_INVALID_SERIAL       "Invalid serial number:"
+#define FYBA_STRING_INVALID_LINE_NR      "Invalid line number in table to unpack info:" /* check */
+#define FYBA_STRING_INVALID_GROUP_NR     "Invalid group number, identifier corrupt:"
+#define FYBA_STRING_ERR_READING_BUFFER   "Error reading from ring buffer."
+#define FYBA_STRING_ERR_WRITING_BUFFER   "Error writing to ring buffer."
+#define FYBA_STRING_MUST_INIT_INDEX      "Must initialize index table before saving."
+#define FYBA_STRING_ERR_READING_SEARCHT  "Error reading geographic search table."
+#define FYBA_STRING_ERR_WRITING_SEARCHT  "Error writing geographic search table."
+#define FYBA_STRING_ERR_READING_GROUPT   "Error reading group table."
+#define FYBA_STRING_ERR_WRITING_GROUPT   "Error writing group table."
+#define FYBA_STRING_ERR_READING_SERIALT  "Error reading serial number table."
+#define FYBA_STRING_ERR_WRITING_SERIALT  "Error writing serial number table."
+#define FYBA_STRING_ERR_READING_INFOT    "Error reading info table."
+#define FYBA_STRING_ERR_WRITING_INFOT    "Error writing info table."
+#define FYBA_STRING_ERR_INFOT_FULL       "Info storage table is full."
+#define FYBA_STRING_ERR_READING_BRUKT    "Error reading 'brukt'-table." /* check */
+#define FYBA_STRING_ERR_WRITING_BRUKT    "Error writing 'brukt'-table."
+#define FYBA_STRING_NO_BLANKS_FILENAME   "Cannot create catalog for index files with spaces in file name.\n"
+#define FYBA_STRING_TOO_MANY_CHOICES     "Too many selections, no room for:"
+#define FYBA_STRING_MISPLACED_CHOICE     "Misplaced selection line:"
+#define FYBA_STRING_GROUP_CHOICE_MISSING "Included group selection not found:"
+#define FYBA_STRING_INVALID_CHOICE       "Invalid selection line:"
+#define FYBA_STRING_NO_COMPLEX_CHOICE    "Complex selections (with OG or ELLER) do not work on PINFO."
+#define FYBA_STRING_GAP_IN_LEVEL         "Invalid gap in indentation:"
+#define FYBA_STRING_TOO_MANY_PRIORITIES  "Too many priorities, ignoring:"
+#define FYBA_STRING_DUPLICATE_DEFINITION "Level is defined twice in:" /* check */
+#define FYBA_STRING_UNKNOWN_ERROR        "Unknown error message. Nr.: %d"
+
+# else 
+/* =========== NORWEGIAN FYBA_STRINGS (DEFAULT) ======= */
+
+#define FYBA_STRING_BASE_UNKNOWN_TYPE    "Ukjent BaseType er gitt, kan derfor ikke åpne base!"
+#define FYBA_STRING_BASE_TOO_MANY_GROUPS "For mange grupper i basen:"
+#define FYBA_STRING_FILE_NOT_FOUND       "Finner ingen .SOS fil med navnet:"
+#define FYBA_STRING_BASE_FYBA_NOT_INITD  "Kan ikke åpne base, FYBA er ikke initiert!"
+#define FYBA_STRING_BASE_NOT_OPEN        "Kan ikke åpne SOSI-fil, fordi det ikke er åpnet noen base!"
+#define FYBA_STRING_FILE_OPEN_FAILED     "Åpningsfeil på filen:"
+#define FYBA_STRING_FILE_OMRAADE_MISSING "..OMRÅDE mangler i filhodet på filen:"
+#define FYBA_STRING_FILE_MIN_NOE_MISSING "...MIN-NØ mangler i filhodet på filen:"
+#define FYBA_STRING_FILE_MAX_NOE_MISSING "...MAX-NØ mangler i filhodet på filen:"
+#define FYBA_STRING_BASE_INDEX_ABORTED   "Indeksoppbygging er avbrutt!"
+#define FYBA_STRING_BASE_OPEN_FAILED     "Åpningsfeil på:"
+#define FYBA_STRING_FILE_NEW_HEADER      "Nytt hode på:"
+#define FYBA_STRING_FILE_NOT_SOSI        "Ikke SOSI-fil:"
+#define FYBA_STRING_FILE_OMRAADE_INVALID "Ulovlig OMRÅDE-angivelse i filhodet! (Ingen utstrekning.)"
+#define FYBA_STRING_SAVE_INVALID_FILEPTR "Ulovlig filpeker ved kall til lagringssystemet, rutine"
+#define FYBA_STRING_OPEN_BASE_IS_KLADDE  "Kan ikke åpne SOSI-fil. Basen er åpnet som kladdebase. Dette kan bare kombineres med sekvensiell les/skriv av SOSI-fil."
+#define FYBA_STRING_FILE_READ_ERROR_HODE "Lesefeil ved lesing av hodelinje."
+#define FYBA_STRING_FILE_TRANSPAR_MISSING "..TRANSPAR mangler i filhodet."
+#define FYBA_STRING_FILE_KOORDSYS_MISSING "...KOORDSYS mangler i filhodet."
+#define FYBA_STRING_FILE_ORIGO_MISSING   "...ORIGO-NØ mangler i filhodet. (Feil tegnsett?)"
+#define FYBA_STRING_FILE_ENHET_MISSING   "...ENHET mangler i filhodet."
+#define FYBA_STRING_NAME_TABLE_FULL      "Navnetabellen er full."
+#define FYBA_STRING_INVALID_GROUP_NAME   "Ulovlig gruppenavn:"
+#define FYBA_STRING_FILE_NO_CURRENT_GROUP "Ingen aktuell gruppe, ingenting er lest!"
+#define FYBA_STRING_OPEN_INVALID_EXTERN  "Ulovlig ekstern fil, ingenting er lest!"
+#define FYBA_STRING_SAVE_INVALID_EXTERN  "Ulovlig ekstern fil, ingenting er skrevet!"
+#define FYBA_STRING_SAVE_NO_WRITE_ACCESS "Du har ikke skriveaksess, ingenting er skrevet til filen:"
+#define FYBA_STRING_GROUP_DELETED         "Gruppen er sletta."
+#define FYBA_STRING_FILE_INVALID_GROUP_NR "Ulovlig gruppenummer, ingenting er lest!"
+#define FYBA_STRING_NEW_INVALID_FILE     "Ulovlig fil, kan ikke lage ny gruppe!"
+#define FYBA_STRING_NEW_NO_WRITE_ACCESS  "Du har ikke skriveaksess, kan ikke lage ny gruppe!"
+#define FYBA_STRING_NEW_TOO_MANY_GROUPS  "For mange grupper i basen, kan ikke lage ny gruppe:"
+#define FYBA_STRING_NEW_INVALID_LINE_GI  "Ulovlig linjenummer for ny GINFO:"
+#define FYBA_STRING_NEW_INVALID_LINE_COO "Ulovlig linjenummer for ny koordinat:"
+#define FYBA_STRING_SLUTT_MISSING        ".SLUTT mangler på SOSI-filen"
+#define FYBA_STRING_READ_ERROR           "Lesefeil på SOSI-filen"
+#define FYBA_STRING_GROUP_REFERRED_TO    "Gruppen er referert fra annen gruppe, kan ikke slette gruppen!"
+#define FYBA_STRING_INVALID_GI_LINE_1    "Ulovlig GINFO-linje nr 1:"
+#define FYBA_STRING_CANT_REMOVE_HEADER   "Det er ikke mulig å slette filhodet!"
+#define FYBA_STRING_NO_CURRENT_GROUP     "Det er ingen aktuell gruppe, ingenting er utført!"
+#define FYBA_STRING_DEL_UNKNOWN_FLAG     "Gruppen har ukjent NGIS endringsflagg, kan ikke slette gruppen!"
+#define FYBA_STRING_DEL_NO_WRITE_ACCESS  "Du har ikke skriveaksess, kan ikke slette gruppen!"
+#define FYBA_STRING_ERR_FILESIZE_CHANGE  "Feil ved endring av filstørrelse!"
+#define FYBA_STRING_DISK_SOON_FULL       "Disken er snart full. Rydd plass til : "
+#define FYBA_STRING_NOT_A_HEADER         "Aktuell gruppe er ikke SOSI-filhode, ingenting er utført"
+#define FYBA_STRING_DEL_NOT_SEQUENTIAL   "Det er ikke mulig å slette gruppe på sekvensiell fil!"
+#define FYBA_STRING_NO_CHANGE_HEADERS    "Kan ikke endre KOORDSYS, ENHET, ORIGO eller NGIS-LAG på fil med data!"
+#define FYBA_STRING_CANT_REWRITE_HEADER  "Det er ikke plass til å skrive tilbake filhodet!"
+#define FYBA_STRING_SAVE_NOT_A_HEADER    "Gruppen er ikke filhode, kan ikke lagre den som filhode!"
+#define FYBA_STRING_CANT_COPY_COORD      "Kan ikke kopiere koord. fra akt. gruppe til akt.gruppe!"
+#define FYBA_STRING_CANT_COPY_COORD_ROOM "Kan ikke kopiere koordinater:  (ikke nok plass i ringbuffer)!"
+#define FYBA_STRING_ENHET_NOT_SET        "ENHET er 0.0 i filhodet, eller filhode mangler på filen:"
+#define FYBA_STRING_CANT_READ_FILE_SIZE  "Feil ved hent av filstørrelse på filen:"
+#define FYBA_STRING_PINFO_LONG_OR_NO_NOE "For lang PINFO / ..NØ mangler etter PINFO! :"
+#define FYBA_STRING_LOGIC_FAIL           "Logisk feil i SOSI-fil.\nNivåfeil, egenskap mellom koordinatene:\n"
+#define FYBA_STRING_MAX_1_KP_OR_NO_NOE   "Max. 1 KP pr. punkt / ..NØ mangler etter KP! :"
+#define FYBA_STRING_NO_ROOM_IN_HEADER    "Ikke plass til hodet, ødelagt på filen :"
+#define FYBA_STRING_INVALID_GAP          "Ulovlig sprang i prikk-nivå!:"
+#define FYBA_STRING_TOO_MANY_COORDINATES "For mange koordinater i gruppe:"
+#define FYBA_STRING_TOO_MANY_GINFO       "GINFO-linje mistes!  For mange GINFO linjer i:"
+#define FYBA_STRING_TOO_MUCH_GINFO       "GINFO-linje mistes!  For mye GINFO i:"
+#define FYBA_STRING_TOO_MUCH_PINFO       "PINFO mistes!  For mye PINFO i:"
+#define FYBA_STRING_CANT_EXTEND_GROUP    "Kan ikke utvide gruppe (for mange koordinater):"
+#define FYBA_STRING_READ_NO_WRITE_ACCESS "Kan ikke lese ny gruppe. Du har ikke skriveaksess for å lagre aktuell gruppe som er endret. Fil :"
+#define FYBA_STRING_READ_LINE_TOO_LONG   "Kan ikke lese SOSI-fil. For lang SOSI-linje: "
+#define FYBA_STRING_INVALID_POINT        "Ulovlig punktnummer:"
+#define FYBA_STRING_INVALID_GINFO        "Ulovlig GINFO-linje nummer:"
+#define FYBA_STRING_INVALID_NODE         "Ulovlig Knutepunkt-type:"
+#define FYBA_STRING_INVALID_GROUP_NAME   "Ulovlig gruppenavn:"
+#define FYBA_STRING_PINFO_TOO_LONG       "For lang PINFO, klarer ikke å hente verdi. (Kontakt FYSAK-support)"
+#define FYBA_STRING_INVALID_REF          "OBS! Ulovlig ref. i filen:"
+#define FYBA_STRING_CANT_CHANGE_ENHET    "Kan ikke endre ENHET på fil med data, bruker:"
+#define FYBA_STRING_CANT_CHANGE_NGIS_LAG "Kan ikke endre ..NGIS-LAG på fil med data, bruker:"
+#define FYBA_STRING_INVALID_BUE          "OBS! Ulovlig bue i filen:"
+#define FYBA_STRING_CANT_CHANGE_ORIGO_NOE "Kan ikke endre ..ORIGO-NØ på fil med data, bruker:"
+#define FYBA_STRING_PROB_TOO_LONG_PINFO  "Sannsynligvis for lang PINFO !"
+#define FYBA_STRING_NO_HOEYDE_WITH_NAD   "Gruppen har ..NAD, kan ikke legge inn høyde på punktnivå i:"
+#define FYBA_STRING_NO_HOEYDE_WITH_NAH   "Gruppen har ..NAH, kan ikke legge inn dybde på punktnivå i: "
+#define FYBA_STRING_LINE_TOO_LONG        "For lang SOSI-linje (max 1024 tegn), linjen forkortes. Gruppe: "
+#define FYBA_STRING_INVALID_SERIAL       "Ulovlig serienummer:"
+#define FYBA_STRING_INVALID_LINE_NR      "Ulovlig linjenummer i tabell for upakka info:"
+#define FYBA_STRING_INVALID_GROUP_NR     "Ulovlig gruppenummer, merking fungerer ikke :"
+#define FYBA_STRING_ERR_READING_BUFFER   "Feil ved les fra ringbuffer!"
+#define FYBA_STRING_ERR_WRITING_BUFFER   "Feil ved skriv til ringbuffer!"
+#define FYBA_STRING_MUST_INIT_INDEX      "Indekstabellene må initieres før lagring"
+#define FYBA_STRING_ERR_READING_SEARCHT  "Feil ved les fra geografisk søketabell!"
+#define FYBA_STRING_ERR_WRITING_SEARCHT  "Feil ved skriv til geografisk søketabell!"
+#define FYBA_STRING_ERR_READING_GROUPT   "Feil ved les fra gruppetabell!"
+#define FYBA_STRING_ERR_WRITING_GROUPT   "Feil ved skriv til gruppetabell!"
+#define FYBA_STRING_ERR_READING_SERIALT  "Feil ved les fra serienummer-tabell!"
+#define FYBA_STRING_ERR_WRITING_SERIALT  "Feil ved skriv til serienummer-tabell!"
+#define FYBA_STRING_ERR_READING_INFOT    "Feil ved les fra info-tabell!"
+#define FYBA_STRING_ERR_WRITING_INFOT    "Feil ved skriv til info-tabell!"
+#define FYBA_STRING_ERR_INFOT_FULL       "Tabell for upakka info er full!"
+#define FYBA_STRING_ERR_READING_BRUKT    "Feil ved les fra brukt-tabell!"
+#define FYBA_STRING_ERR_WRITING_BRUKT    "Feil ved skriv til brukt-tabell!"
+#define FYBA_STRING_NO_BLANKS_FILENAME   "Kan ikke opprette katalog for indeksfiler når det er blanke sist i filnavnet!\n"
+#define FYBA_STRING_TOO_MANY_CHOICES     "For mange utvalg, ikke plass til:"
+#define FYBA_STRING_MISPLACED_CHOICE     "Feilplasert utvalgslinje:"
+#define FYBA_STRING_GROUP_CHOICE_MISSING "Inkludert gruppeuvtalg finnes ikke:"
+#define FYBA_STRING_INVALID_CHOICE       "Ulovlig utvalgslinje:"
+#define FYBA_STRING_NO_COMPLEX_CHOICE    "Komplekse utvalg (..OG og ..ELLER) fungerer ikke for PINFO!"
+#define FYBA_STRING_GAP_IN_LEVEL         "Ulovlig sprang i nivå!:"
+#define FYBA_STRING_TOO_MANY_PRIORITIES  "For mange prioriteter, mister prioritet :"
+#define FYBA_STRING_DUPLICATE_DEFINITION "Lag er dobbeltdefinert i utvalg :"
+#define FYBA_STRING_UNKNOWN_ERROR        "Ukjent feilmelding. Nr.: %d"
+
+# endif
diff --git a/FYBA/fybax.h b/FYBA/fybax.h
new file mode 100644
index 0000000..92eef6f
--- /dev/null
+++ b/FYBA/fybax.h
@@ -0,0 +1,344 @@
+/* == AR-991012 =========================================================== */
+/*   STATENS KARTVERK  -  FYSAK-PC                                          */
+/*   Fil: fybax.h                                                           */
+/*   Innhold: Interne prototyper for fysak-pc                               */
+/*            Def. av typer og bufferst�rrelser                             */
+/*            Definisjon av filtabellen, ringbuffer mm.                     */
+/* ======================================================================== */
+
+#pragma once
+
+#include "fyba.h"
+
+
+/* ======================================================= */
+/*  Definerer konstanter                                   */
+/* ======================================================= */
+#ifndef _FYBAX_DEFINED
+
+#   define  FYBA_IDENT  "FYBA - G2.0  2011-03-10"
+#   define  FYBA_INDEKS_VERSJON  "G009"
+#   define  FYBA_SOSI_VERSJON  400
+
+ /* Definerer PI */
+//#   ifndef PI
+////#      define PI  (3.14159265358979324)
+//#      define PI  (3.14159265358979323846)
+//#   endif
+
+/* --- Konstant for testing av likhet p� desimaltall -- */
+#define LC_ACCY  1.0E-9
+
+
+ /* Basetype */
+ /* #define LC_START_KLADD       2  */  /* �pning av kladdebase */
+ /* (LC_BASE og LC_KLADD er definert i FYBA.H) */
+
+ /* Filtabell */
+ /* #define NO_OPEN_SOS   -1 */  /* Ingen �pen SOSI-fil */
+
+ /* Kommando til LB_Wgru */
+#   define KONTROLLER_PLASS    1   /* Bare kontroller plass, (ikke skriv SOSI) */
+#   define SKRIV_VANLIG        2   /* Skriv til SOSI, vanlig */
+#   define SKRIV_SISTE         3   /* Skriv til SOSI, med .SLUTT og bytepointer */
+
+  /* Diverse */
+#   define NYTT_SNR              -1L  /* Startverdi for akt.snr i filtabellen */
+
+#   define NY_SOSI_ST            -1L  /* Start.sosi n�r gruppe ikke er skrevet */
+#   define NY_RB_ST              -1L  /* Start.rb n�r gruppe ikke er skrevet */
+#   define NY_UI_ST              -1L  /* Start.UI n�r gruppe ikke er skrevet */
+
+/*
+ * Diverse for intern mellomlagring av hele PINFO
+ */
+ /* Statusverdier */
+#   define LC_PIBUF_TOM   0
+#   define LC_PIBUF_OK    1
+#   define LC_PIBUF_FULL  2
+ /* Ant. tegn i buffer */
+#   define LC_MAX_PIBUF_TEGN  LC_MAX_SOSI_LINJE_LEN
+ /* Ant linjer i tabell med pekere til startposisjoner i strengen */
+#   define LC_MAX_PIBUF_LIN 50
+
+#   define LI_LESEFEIL           -1  // Filen er �pen i annet program 
+#   define LI_OPPTATT            -2  // Filen er �pen i annet program 
+#   define LI_FEIL_INDEKSVERSJON -3  // Feil indeksversjon 
+#   define LI_FEIL_STORRELSE     -4  // Feil st�rrelse p� SOSI-filen 
+#   define LI_FEIL_OPPDATTID     -5  // Feil oppdateringstid p� SOSI-filen 
+
+
+#   define _FYBAX_DEFINED
+#endif
+
+
+/* ================================================ */
+/*  Definerer data-strukturer                       */
+/* ================================================ */
+
+/* Lesebuffer */
+/* Konstanter for set_brukt */
+#define SET_UBRUKT 0
+#define SET_BRUKT  1
+
+/* Konstanter for sStatus */
+#define LESEBUFFER_TOM   0          /* (Tom eller ikke ajour) */
+#define LESEBUFFER_OK    1
+
+ /* Verdier for cur_type */
+                          /*  >= 0 : Gruppenavn,linjenummer i navnetab. */
+#define  LEST_KOORD  -1   /* Koordinatlinje */
+#define  LEST_BLANK  -2   /* "blank linje" (!!!, mm) */
+#define  LEST_GINFO  -3   /* GINFO */
+#define  LEST_KOM    -4   /* Kommentar-linje */
+
+
+/* Felles streng for feilmeldinger */
+#define LC_ERR_LEN 300
+typedef struct dLC_FEILMELDING {
+   short nr;
+   short strategi;
+   char tx[LC_ERR_LEN];
+} LC_FEILMELDING;
+
+
+/* UTVALG */
+/*
+ // Utvalgskommandoer 
+#define U_OG          1     // ..OG 
+#define U_ELLER       2     // ..VELG og ..ELLER
+
+
+ // Utvalgsmetoder
+#define U_IKKE         0     //  !     Ikke (Tilslag n�r SOSI-navnet     
+                             //             ikke finnes. Bare GINFO.)    
+#define U_ALLE         1     //  AL    Alle                              
+#define U_FRATIL       2     //  <>    Fra-til                           
+#define U_UTENFOR      3     //  ><    Utenfor                           
+#define U_MINDRE       4     //  <     Mindre-enn                        
+#define U_STORRE       5     //  >     St�rre-enn                        
+#define U_DELELIG      6     //  /     Delelig-med, eventuellt med       
+                             //        sjekk p� om restverdi er 2. verdi 
+#define U_UDELELIG     7     //  !/    Ikke-delelig-med                  
+#define U_CONTEIN      8     //  ()    Inneholder                        
+#define U_IKKECONTEIN  9     //  !()   Inneholder ikke (Tilslag n�r      
+                             //        denne navn og verdi kombinasjonen 
+                             //        ikke finnes)                      
+#define U_LIK         10     //  =     Lik                               
+#define U_IKKEVALGT   11     //  IV    Ikke valgt (Tilslag n�r gruppen   
+                             //        ikke er tegnet enn�. Kombineres   
+                             //        med SOSI-navnet "..*")            
+#define U_IKKELIK     12     //  !=    Ikke lik (Tilslag n�r denne       
+                             //        navn og verdi kombinasjonen ikke  
+                             //        finnes)                           
+#define U_FLERE       13     //  FL    Flere (Tilslag n�r SOSI-navnet    
+                             //        forekommer flere ganger.)         
+#define U_IKKEFLERE   14     //  !FL   Ikke flere enn (Tilslag n�r       
+                             //        SOSI-navnet IKKE forekommer       
+                             //        flere ganger enn gitt antall.)    
+
+
+
+ // Parametertyper 
+#define U_TALL          1     // Heltall     
+#define U_FLYT          2     // Flyttall    
+#define U_ALFA          9     // Tekststreng 
+*/
+
+   /* GINFO i minne */
+typedef struct dLC_GINFO_BUFFER {
+   char *pszTx;         /* GINFO buffer */
+   unsigned long ulOfset[LC_MAX_GINFO]; /* Peker til starten av hver GINFO-linje */
+} LC_GINFO_BUFFER;
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Systemadministrasjon                                         !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_SYSTEMADM {
+   char   szBaseVer[LC_BASEVER_LEN];  // Versjon og dato for aktuell versjon av FYBA
+   char   szIdxVer[5];                // Indeksfil-versjon
+
+   short  sResPlass;  // Ant. tegn reserve plass bak ny gruppe
+   long   lMaxSkriv;  // Max antall skriv uten lagring til SOSI-filen
+   long   lAntSkriv;  // Antall skriv siden siste lagring til SOSI
+   short  sNGISmodus; // Behandlingsm�te for grupper med NGIS-oppdateringsflagg
+   short  sUtvidModus; // Handteringsm�te for utvidelse av SOSI-filer.
+   char   szIdxPath[_MAX_PATH]; //Katalognavn for ny indeks.
+   LB_LESEBUFFER BufAdm;         // Lesebuffer mot SOSI-fil-hode
+
+   LC_NAVNETABELL  SosiNavn;     // Navnetabell (brukes av HO-rutinene)
+
+   /* Div opplysninger om aktuell gruppe */
+   short sGrEndra;         // Er aktuell gruppe endra?
+   LC_BGR GrId;            // Gruppens identifikasjon
+   LC_GRTAB_LINJE *pGrInfo;  // Peker til gruppetabell-linje
+   
+   /* Aktuell gruppe i minne */
+   /* GINFO i minne */
+   LC_GINFO_BUFFER Hode;     // Hodebuffer
+   unsigned short usHoLen;   // Ant tegn i hodebuffer
+   LC_GINFO_BUFFER Ginfo;    // GINFO-buffer
+   double *pdAust;    // �st koordinat
+   double *pdNord;    // Nord koordinat
+   LB_INFO * pInfo;    // H�yde,KP og PINFO-peker
+   char *pszPinfo;    // PINFO buffer
+
+   /* S�kebuffer for PINFO */
+   long lPibufPnr;                 // Punktnummer for data i buffer
+   short sPibufAntPi;               // Antall elementer brukt i PIbuf
+   char cPibuf[LC_MAX_PIBUF_TEGN];  // Kopi av PINFO, (for raskere s�king)
+   short sPibufStatus;              // Status for bruken av cPibuf
+   /* Peker til startposisjoner i cPibuf for hver PINFO */
+   char *pcPibufNavn[LC_MAX_PIBUF_LIN];   // Peker til SOSI-navn
+   char *pcPibufVerdi[LC_MAX_PIBUF_LIN];  // Peker til verdi
+
+   unsigned short usMerkRefGr;  // Flagg for � vise om refererte grupper skal merkes ved utvalg
+
+   LC_BASEADM * pForsteBase;   // Peker til f�rste base-adm.
+   LC_BASEADM * pAktBase;      // Peker til aktuell base-adm.
+} LC_SYSTEMADM;
+
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fyho.c                       */
+/* ======================================================= */
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fylb.c                       */
+/* ======================================================= */
+void    LB_Save(LC_FILADM *pFil);
+void    LB_NyRp(void);
+short   LB_RGru(LC_FILADM *pFil,UT_INT64 start,UT_INT64 *slutt);
+void    LB_Swap(void);
+char   *LB_FormaterEnhet(char *streng,short sStrengMaxLen,char *SosiNavn,double enhet);
+void    LB_ClGr (void);
+short   LB_WGru (short strategi,long fra_punkt,long antall,
+                 LC_FILADM *pFil,UT_INT64 ffipos,UT_INT64 *lfipos);
+short   LB_Plass(LC_FILADM *pFil, UT_INT64 start, UT_INT64 *neste);
+short   LB_WriteLine (FILE *fil,short sTegnsett,char *tx);
+short   LB_GetSet(FILE *fil,LB_LESEBUFFER *plb,LC_NAVNETABELL * pNavn);
+
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fyli.c                       */
+/* ======================================================= */
+short   LI_TestIdx(char *szSosFil);
+short   LI_OpenInit(LC_FILADM *pFil);
+short   LI_OpenRead(LC_FILADM *pFil);
+void    LI_Close(LC_FILADM *pFil,short s_stat);
+void    LI_SaveAdm(LC_FILADM *pFil);
+
+LC_R_LEAF * LI_GetGeo(LC_FILADM *pFil,long linje);
+/*  void   LI_PutGeo(LC_FILADM *pFil,long linje,LC_GEOSOK_BOKS *geop); */
+
+long   LI_GetSnr(LC_FILADM *pFil,long lSnr);
+void   LI_PutSnr(LC_FILADM *pFil,long lSnr,long lGrNr);
+
+LC_GRTAB_LINJE * LI_GetGrt(LC_FILADM *pFil,long linje);
+LC_GRTAB_LINJE * LI_AppGrt(LC_FILADM *pFil,long linje);
+
+unsigned long   LI_GetBt(LC_FILADM *pFil,long linje);
+void   LI_PutBt(LC_FILADM *pFil,long linje,unsigned long bt_val);
+
+void    LI_SetBt(LC_FILADM *pFil,long lGrNr,short kolonne);
+void    LI_ClrBt(LC_FILADM *pFil,long lGrNr,short kolonne);
+short   LI_InqBt(LC_FILADM *pFil,long lGrNr,short kolonne);
+void    LI_EraseBt(short fra_kol,short til_kol);
+
+void LI_WriteRb(LC_FILADM *pFil, UT_INT64 n64FilPos,
+                char *pszGi, unsigned long ulGiLen,
+                double *pdAust, double *pdNord,
+                LB_INFO * pInfo, long lNko,
+                char *pszPi, unsigned long ulPiLen);
+void LI_ReadRb(LC_FILADM *pFil, UT_INT64 n64FilPos,
+               char *pszGi, unsigned long ulGiLen,
+               double *pdAust, double *pdNord,
+               LB_INFO * pInfo, long lNko,
+               char *pszPi, unsigned long ulPiLen);
+void LI_ReadCoordRb(LC_FILADM *pFil, UT_INT64 n64FilPos, unsigned long ulGiLen,
+               double *pdAust, double *pdNord,
+               LB_INFO * pInfo, long lNko,
+               char *pszPi, unsigned long ulPiLen);
+long LI_BerBufferLen(unsigned long ulGiLen,long lNko,unsigned long ulPiLen);
+
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fyln.c                       */
+/* ======================================================= */
+void  LN_InitTab(LC_NAVNETABELL *pLn);
+short LN_Enhet(LC_NAVNETABELL *pLn,char *ginfo_linje);
+short LN_EnhetHoyde(LC_NAVNETABELL *pLn,char *ginfo_linje);
+short LN_EnhetDybde(LC_NAVNETABELL *pLn,char *ginfo_linje);
+short LN_TestOy(char *ginfo_linje);
+short LN_PakkNavn(LC_NAVNETABELL *pLn,char *navn,short *navn_nr,
+                short *ant_par);
+short LN_FinnNavn(LC_NAVNETABELL *pLn,char *navn,short *navn_nr);
+char *LN_GetNavn(LC_NAVNETABELL *pLn,short navn);
+char *LN_VisNavn(LC_NAVNETABELL *pLn,short navn);
+void  LN_TolkKvalitet(char *pszParameter,short *psMetode,long *plNoyaktighet,
+                      short *psSynbarhet,short *psHoydeMetode,long *plHoydeNoyaktighet);
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fyls.c                       */
+/* ======================================================= */
+void    LS_Indx(void);
+void    LS_PutSn(LC_FILADM *pFil,long lGrNr,long lSnr);
+char *  LS_VisSn(LC_FILADM *pFil,long lin);
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fylr.c                       */
+/* ======================================================= */
+/* Indeksoppbygging */
+void  LR_Indx(void);
+void  LR_IndxFlate(void);
+short LR_PTstGruppe(LC_BGR * pBgr,double a,double n);
+void LR_R_Delete(LC_R_LEAF * pCL);
+LC_R_LEAF * LR_InsertGeo(LC_FILADM *pFil,long lNr,LC_BOKS * pB);
+void LR_R_FrigiGren(LC_R_NODE *pRN);
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fylo.c                       */
+/* ======================================================= */
+LC_FEILMELDING& err();
+void   LO_CloseSos(LC_BASEADM *pBase);
+void   LO_ReopenSos(LC_FILADM *pFil);
+void   LO_BeFt(LC_FILADM *pFil);
+void   LO_TestFilpeker(LC_FILADM *pFil,char *pszRutineNavn);
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fylx.c                       */
+/* ======================================================= */
+void   LX_PutSn(long snr);
+void   LX_CreGiPeker(LC_GINFO_BUFFER *pGinfo,short ngi);
+char  *LX_GetGi(short lin_nr);
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fylp.c                       */
+/* ======================================================= */
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fylh.c                       */
+/* ======================================================= */
+char* LH_GetNgisLag(void);
+
+/* ======================================================= */
+/*  Funksjonsdefinisjoner for fyho.c                       */
+/* ======================================================= */
+void  ho_New(FILE *fil,short koosys,double origo_a,double origo_n,
+             double enhet,double enhet_h,double enhet_d,
+             double nv_a,double nv_n,double oh_a,double oh_n);
+short ho_TestSOSI(FILE *fil,UT_INT64 *sluttpos);
+char *ho_GetVal(FILE *fil,char *sosi_navn,short *sett_nr);
+short ho_GetKvalitet(FILE *fil,short *psMetode,long *plNoyaktighet,
+                     short *psSynbarhet,short *psHoydeMetode,long *plHoydeNoyaktighet);
+short ho_GetTrans(FILE *fil,short *koosys,double *origo_a,
+                  double *origo_n,double *enhet,double *enhet_h,double *enhet_d);
+short ho_GetTransEx(FILE *pFil,unsigned short *pusMaske, LC_TRANSPAR * pTrans);
+short ho_GetOmr(FILE *fil,double *nv_a,double *nv_n,double *oh_a,double *oh_n);
+short ho_GetTegnsett(FILE *pfFil,short *psTegnsett);
+short ho_SjekkTegnsett(FILE *fil,short *psTegnsett);
+short ho_FinnHode(FILE *pFil, UT_INT64 *lHodepos);
+
diff --git a/FYBA/fyln.cpp b/FYBA/fyln.cpp
new file mode 100644
index 0000000..8d8c362
--- /dev/null
+++ b/FYBA/fyln.cpp
@@ -0,0 +1,870 @@
+/* == AR 910819 ========================================== */
+/*  STATENS KARTVERK  -  FYSAK-PC                          */
+/*  Fil: fyln.c                                            */
+/*  Innhold: Navnesystem for fysak-pc                      */
+/* ======================================================= */
+
+#include "stdafx.h"
+
+#include <fcntl.h>
+#include <ctype.h>
+#include <limits.h>
+
+
+/*
+AR-890616
+CH LN_InitTab                                           Klargj�r navnetabell
+CD ==========================================================================
+CD Form�l:
+CD Initierer navnetabellen med kjente navn.
+CD
+CD Parametre:
+CD Type             Navn I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_NAVNETABELL *  pLn   i   Peker til navnetabell
+CD
+CD Bruk:
+CD LN_InitTab(pLn);
+   ==========================================================================
+*/
+void LN_InitTab(LC_NAVNETABELL * pLn)
+{
+   UT_StrCopy(pLn->sosi[L_SLUTT].szNavn, ".SLUTT", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_SLUTT].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_SLUTT].cNivo = 1;
+   pLn->sosi[L_SLUTT].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_PUNKT].szNavn, ".PUNKT", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_PUNKT].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_PUNKT].cNivo = 1;
+   pLn->sosi[L_PUNKT].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_LINJE].szNavn, ".LINJE", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_LINJE].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_LINJE].cNivo = 1;
+   pLn->sosi[L_LINJE].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_KURVE].szNavn, ".KURVE", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_KURVE].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_KURVE].cNivo = 1;
+   pLn->sosi[L_KURVE].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_BUE].szNavn, ".BUE", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_BUE].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_BUE].cNivo = 1;
+   pLn->sosi[L_BUE].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_BUEP].szNavn, ".BUEP", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_BUEP].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_BUEP].cNivo = 1;
+   pLn->sosi[L_BUEP].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_SIRKEL].szNavn, ".SIRKEL", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_SIRKEL].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_SIRKEL].cNivo = 1;
+   pLn->sosi[L_SIRKEL].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_SIRKELP].szNavn, ".SIRKELP", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_SIRKELP].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_SIRKELP].cNivo = 1;
+   pLn->sosi[L_SIRKELP].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_KLOTOIDE].szNavn, ".KLOTOIDE", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_KLOTOIDE].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_KLOTOIDE].cNivo = 1;
+   pLn->sosi[L_KLOTOIDE].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_BEZIER].szNavn, ".BEZIER", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_BEZIER].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_BEZIER].cNivo = 1;
+   pLn->sosi[L_BEZIER].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_RASTER].szNavn, ".RASTER", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_RASTER].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_RASTER].cNivo = 1;
+   pLn->sosi[L_RASTER].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_TEKST].szNavn, ".TEKST", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_TEKST].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_TEKST].cNivo = 1;
+   pLn->sosi[L_TEKST].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_TRASE].szNavn, ".TRASE", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_TRASE].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_TRASE].cNivo = 1;
+   pLn->sosi[L_TRASE].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_FLATE].szNavn, ".FLATE", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_FLATE].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_FLATE].cNivo = 1;
+   pLn->sosi[L_FLATE].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_SVERM].szNavn, ".SVERM", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_SVERM].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_SVERM].cNivo = 1;
+   pLn->sosi[L_SVERM].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_DEF].szNavn, ".DEF", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_DEF].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_DEF].cNivo = 1;
+   pLn->sosi[L_DEF].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_OBJDEF].szNavn, ".OBJDEF", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_OBJDEF].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_OBJDEF].cNivo = 1;
+   pLn->sosi[L_OBJDEF].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_MLINJE].szNavn, ".MLINJE", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_MLINJE].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_MLINJE].cNivo = 1;
+   pLn->sosi[L_MLINJE].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_STRUKTUR].szNavn, ".STRUKTUR", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_STRUKTUR].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_STRUKTUR].cNivo = 1;
+   pLn->sosi[L_STRUKTUR].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_OBJEKT].szNavn, ".OBJEKT", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_OBJEKT].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_OBJEKT].cNivo = 1;
+   pLn->sosi[L_OBJEKT].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_SYMBOL].szNavn, ".SYMBOL", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_SYMBOL].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_SYMBOL].cNivo = 1;
+   pLn->sosi[L_SYMBOL].bBrukt = false;
+   
+   UT_StrCopy(pLn->sosi[L_HODE].szNavn, ".HODE", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_HODE].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_HODE].cNivo = 1;
+   pLn->sosi[L_HODE].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_NA].szNavn, "..N�", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_NA].ucAntPar = 2;
+   pLn->sosi[L_NA].cNivo = 2;
+   pLn->sosi[L_NA].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_NAH].szNavn, "..N�H", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_NAH].ucAntPar = 3;
+   pLn->sosi[L_NAH].cNivo = 2;
+   pLn->sosi[L_NAH].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_NAD].szNavn, "..N�D", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_NAD].ucAntPar = 3;
+   pLn->sosi[L_NAD].cNivo = 2;
+   pLn->sosi[L_NAD].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_REF1].szNavn, "..", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_REF1].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_REF1].cNivo = 2;
+   pLn->sosi[L_REF1].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_REF2].szNavn, "..REF", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_REF2].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_REF2].cNivo = 2;
+   pLn->sosi[L_REF2].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_RADIUS].szNavn, "..RADIUS", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_RADIUS].ucAntPar = 1;
+   pLn->sosi[L_RADIUS].cNivo = 2;
+   pLn->sosi[L_RADIUS].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_ENHET2].szNavn, "..ENHET", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_ENHET2].ucAntPar = 1;
+   pLn->sosi[L_ENHET2].cNivo = 2;
+   pLn->sosi[L_ENHET2].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_ENHET2H].szNavn, "..ENHET-H", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_ENHET2H].ucAntPar = 1;
+   pLn->sosi[L_ENHET2H].cNivo = 2;
+   pLn->sosi[L_ENHET2H].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_ENHET2D].szNavn, "..ENHET-D", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_ENHET2D].ucAntPar = 1;
+   pLn->sosi[L_ENHET2D].cNivo = 2;
+   pLn->sosi[L_ENHET2D].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_ENHET3].szNavn, "...ENHET", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_ENHET3].ucAntPar = 1;
+   pLn->sosi[L_ENHET3].cNivo = 3;
+   pLn->sosi[L_ENHET3].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_ENHET3H].szNavn, "...ENHET-H", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_ENHET3H].ucAntPar = 1;
+   pLn->sosi[L_ENHET3H].cNivo = 3;
+   pLn->sosi[L_ENHET3H].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_ENHET3D].szNavn, "...ENHET-D", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_ENHET3D].ucAntPar = 1;
+   pLn->sosi[L_ENHET3D].cNivo = 3;
+   pLn->sosi[L_ENHET3D].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_ORIGONO].szNavn, "...ORIGO-N�", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_ORIGONO].ucAntPar = 2;
+   pLn->sosi[L_ORIGONO].cNivo = 3;
+   pLn->sosi[L_ORIGONO].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_HOYDE].szNavn, "..H�YDE", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_HOYDE].ucAntPar = 1;
+   pLn->sosi[L_HOYDE].cNivo = 2;
+   pLn->sosi[L_HOYDE].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_DYBDE].szNavn, "..DYBDE", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_DYBDE].ucAntPar = 1;                                   
+   pLn->sosi[L_DYBDE].cNivo = 2;
+   pLn->sosi[L_DYBDE].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_NGISFLAGG].szNavn, "..NGIS-FLAGG", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_NGISFLAGG].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_NGISFLAGG].cNivo = 2;
+   pLn->sosi[L_NGISFLAGG].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_NGISLAG].szNavn, "..NGIS-LAG", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_NGISLAG].ucAntPar = LC_ANT_PAR_UKJENT;
+   pLn->sosi[L_NGISLAG].cNivo = 2;
+   pLn->sosi[L_NGISLAG].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_OBJTYPE].szNavn, "..OBJTYPE", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_OBJTYPE].ucAntPar = 1;
+   pLn->sosi[L_OBJTYPE].cNivo = 2;
+   pLn->sosi[L_OBJTYPE].bBrukt = false;
+
+   UT_StrCopy(pLn->sosi[L_KP].szNavn, "...KP", LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[L_KP].ucAntPar = 1;
+   pLn->sosi[L_KP].cNivo = 3;
+   pLn->sosi[L_KP].bBrukt = false;
+
+   pLn->sAntNavn = L_KP + 1;           /* Antall navn i navnetabellen */
+}
+
+
+/*
+AR-910919
+CH LN_Enhet                                          Sjekk om det er ..ENHET
+CD ==========================================================================
+CD Form�l:
+CD Sjekk om denne ginfo-linjen er ..ENHET.
+CD
+CD Parametre:
+CD Type             Navn        I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_NAVNETABELL *  pLn          i   Peker til navnetabell
+CD char            *ginfo_linje  i   F�rste pos i linjen
+CD short            ok           r   1=linjen er ..ENHET, 0=ikke ..ENHET
+CD
+CD Bruk:
+CD ok = LN_Enhet(pLn,ginfo_linje);
+  ===========================================================================
+*/
+short LN_Enhet(LC_NAVNETABELL * pLn,char *ginfo_linje)
+{
+   char ord[LC_MAX_SOSINAVN_LEN];
+
+   //JA�-20000313
+   //Leter etter "..ENHET " istedet for "..ENHET" for ikke � f� tilslag p� ..ENHET-H eller ..ENHET-D
+   UT_StrCopy(ord,pLn->sosi[L_ENHET2].szNavn,LC_MAX_SOSINAVN_LEN);
+   UT_StrCat(ord, " ", LC_MAX_SOSINAVN_LEN);
+
+   return(strstr(ginfo_linje,ord) != NULL);
+   //return(strstr(ginfo_linje,pLn->sosi[L_ENHET2].szNavn) != NULL);
+}
+
+
+/*
+AR-940704
+CH LN_EnhetHoyde                                   Sjekk om det er ..ENHET-H
+CD ==========================================================================
+CD Form�l:
+CD Sjekk om denne ginfo-linjen er ..ENHET-H.
+CD
+CD Parametre:
+CD Type             Navn        I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_NAVNETABELL *  pLn          i   Peker til navnetabell
+CD char            *ginfo_linje  i   F�rste pos i linjen
+CD short            ok           r   1=linjen er ..ENHET-H, 0=ikke ..ENHET-H
+CD
+CD Bruk:
+CD ok = LN_EnhetHoyde(pLn,ginfo_linje);
+  ===========================================================================
+*/
+short LN_EnhetHoyde(LC_NAVNETABELL * pLn,char *ginfo_linje)
+{
+   char ord[LC_MAX_SOSINAVN_LEN];
+
+   // Leter etter "..ENHET-H " istedet for "..ENHET-H" for ikke � f� tilslag p� andre navn
+   UT_StrCopy(ord,pLn->sosi[L_ENHET2H].szNavn,LC_MAX_SOSINAVN_LEN);
+   UT_StrCat(ord, " ", LC_MAX_SOSINAVN_LEN);
+                                         
+   //return(strstr(ginfo_linje,pLn->sosi[L_ENHET2H].szNavn) != NULL);
+   return(strstr(ginfo_linje,ord) != NULL);
+}
+
+
+/*
+AR-940704
+CH LN_EnhetDybde                                    Sjekk om det er ..ENHET-D
+CD ==========================================================================
+CD Form�l:
+CD Sjekk om denne ginfo-linjen er ..ENHET-D.
+CD
+CD Parametre:
+CD Type             Navn        I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_NAVNETABELL *  pLn          i   Peker til navnetabell
+CD char            *ginfo_linje  i   F�rste pos i linjen
+CD short            ok           r   1=linjen er ..ENHET-D, 0=ikke ..ENHET-D
+CD
+CD Bruk:
+CD ok = LN_EnhetDybde(pLn,ginfo_linje);
+  ===========================================================================
+*/
+short LN_EnhetDybde(LC_NAVNETABELL * pLn,char *ginfo_linje)
+{
+   char ord[LC_MAX_SOSINAVN_LEN];
+
+   // Leter etter "..ENHET-D " istedet for "..ENHET-D" for ikke � f� tilslag p� andre navn
+   UT_StrCopy(ord,pLn->sosi[L_ENHET2D].szNavn,LC_MAX_SOSINAVN_LEN);
+   UT_StrCat(ord, " ",LC_MAX_SOSINAVN_LEN);
+
+   //return(strstr(ginfo_linje,pLn->sosi[L_ENHET2D].szNavn) != NULL);
+   return(strstr(ginfo_linje,ord) != NULL);
+}
+
+
+/*
+AR-910315
+CH LN_TestOy                               Sjekk om referansen inneholder �y
+CD ==========================================================================
+CD Form�l:
+CD Sjekk om denne ginfo-linjen inneholder referanse med �Y.
+CD Forutsetter at aktuell linje inneholder referanser. 
+CD
+CD Parametre:
+CD Type     Navn        I/U  Forklaring
+CD -----------------------------------------------------------------------
+CD char    *ginfo_linje  i   F�rste pos i linjen
+CD short    ok           r   1=linjen har �y-flate, 0=ikke �y
+CD
+CD Bruk:
+CD ok = LN_TestOy(char *ginfo_linje);
+  ===========================================================================
+*/
+short LN_TestOy(char *ginfo_linje)
+{
+   if (strchr(ginfo_linje,'(') != NULL)  return 1;
+
+   return 0;
+}
+
+
+/*
+AR-910918
+CH LN_FinnNavn                          S�k etter et SOSI-navn i navnetabelen
+CD =============================================================================
+CD Form�l:
+CD S�ker etter navnet i navnetabellen.
+CD (Ukjent navn blir ikke lagt inn i navnetabellen.)
+CD
+CD Parametre:
+CD Type             Navn    I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_NAVNETABELL *  pLn      i    Peker til navnetabell
+CD char            *streng   i    Peker til SOSI-navn. Avslutta av '\0'.
+CD short           *navn_nr  u    Navnets linjenummer i navnetabellen
+CD short            nivo     r    Antall prikker (0=ukjent navn, 1=gruppenavn, osv.)
+CD
+CD Bruk:
+CD nivo = LN_FinnNavn(pLn,streng,&neste,&navn_nr);
+   =============================================================================
+*/
+short LN_FinnNavn(LC_NAVNETABELL * pLn,char *navn,short *navn_nr)
+{
+   short nr = 0;
+
+                                    /* Utf�r s�ket */
+   for (; nr < pLn->sAntNavn; nr++)
+   {
+      if (strncmp(navn,pLn->sosi[nr].szNavn,LC_MAX_SOSINAVN_LEN-1) == 0)
+      {
+         // Legger inn merke om at navnet er brukt
+         pLn->sosi[nr].bBrukt = true;
+
+         // Navnet er funnet, ==> returner
+         *navn_nr = nr;
+         return  (pLn->sosi[nr].cNivo);     /* Niv� */
+      }
+   }
+   
+   return 0;                         /* Ukjent navn */
+}
+
+
+/*
+AR-910710
+CH LN_PakkNavn                          S�k etter navn, legg inn ukjent navn
+CD ==========================================================================
+CD Form�l:
+CD Finner et SOSI-navn i navnetabellen.  (Max LC_MAX_SOSINAVN_LEN tegn.)
+CD Hvis navnet er ukjent, blir det lagt inn i tabellen.
+CD
+CD Parametre:
+CD Type            Navn    I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_NAVNETABELL *  pLn     i   Peker til navnetabell
+CD char            *navn    i  SOSI-navn.
+CD short           *ant_par u  Antall parametre til dette navnet.
+CD                             LC_ANT_PAR_UKJENT (-1) = Ant. param. er ukjent.
+CD short           *navn_nr u  Navnenummer.
+CD short            nivo    r  Antall prikker i navnet (1=gruppenavn, osv.)
+CD
+CD Bruk:
+CD type = LN_PakkNavn(pLn,navn,&navn_nr,&ant_par);
+   =============================================================================
+*/
+short LN_PakkNavn (LC_NAVNETABELL * pLn,char *navn,short *navn_nr,short *ant_par)
+{
+   char nivo,*cp;
+   short nr;
+                                    /* Utf�r s�ket */
+   for (nr=0; nr < pLn->sAntNavn; nr++) 
+   {
+      if (strncmp(navn,pLn->sosi[nr].szNavn,LC_MAX_SOSINAVN_LEN-1) == 0)
+      {
+         // Legger inn merke om at navnet er brukt
+         pLn->sosi[nr].bBrukt = true;
+
+         // Navnet er funnet, ==> returner
+         *ant_par = pLn->sosi[nr].ucAntPar;
+         *navn_nr = nr;
+         return  (pLn->sosi[nr].cNivo);     /* Niv� */
+      }
+   }
+
+   /* Er det plass i tabellen for et nytt navn? */
+   if (pLn->sAntNavn >= LC_MAX_NAVN) {
+      UT_FPRINTF(stderr,"Utskrift av navnetabellen:\n");
+      for (nr=0; nr < pLn->sAntNavn; nr++) {
+         UT_FPRINTF(stderr,"%s\n",LN_VisNavn(pLn,nr));
+      }
+      LC_Error(21,"(LN_PakkNavn)","");
+      exit (2);
+   }   
+
+   /* ----- Nytt navn */
+   UT_StrCopy(pLn->sosi[pLn->sAntNavn].szNavn,navn,LC_MAX_SOSINAVN_LEN);
+   pLn->sosi[pLn->sAntNavn].ucAntPar = (unsigned char) LC_ANT_PAR_UKJENT;
+   *ant_par = LC_ANT_PAR_UKJENT;
+   
+   /* Finn antall prikker */
+   nivo = 0;
+   cp = navn;
+   while (*cp == '.') {
+      nivo++;
+      cp++;
+   }
+   pLn->sosi[pLn->sAntNavn].cNivo = nivo;
+
+   // Legger inn merke om at navnet er brukt
+   pLn->sosi[pLn->sAntNavn].bBrukt = true;
+
+   *navn_nr = pLn->sAntNavn;
+
+   pLn->sAntNavn++;
+
+   /* Melding om ulovlig gruppestart */
+   if (nivo <= 1) {
+      LC_Error(22,"(LN_PakkNavn)",navn);
+   }
+
+   return (nivo);     /* Antall prikker */
+}
+
+
+/*
+AR-910819
+CH LN_GetNavn                               Hent en linje fra  navnetabellen
+CD ==========================================================================
+CD Form�l:
+CD Henter et navn fra navnetabellen.
+CD
+CD Parametre:
+CD Type             Navn  I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD LC_NAVNETABELL *  pLn    i    Peker til navnetabell
+CD long             navn   i    Linjenummer i navnetabellen
+CD char            *tx     r    Peker til SOSI-navn, NULL=ukjent linje
+CD
+CD Bruk:
+CD cp = LN_GetNavn(pLn,navn_nr);
+   =============================================================================
+*/
+char *LN_GetNavn(LC_NAVNETABELL * pLn,short navn)
+{
+   SOSINAVN *ip;
+
+   if (navn >= 0  &&  navn < pLn->sAntNavn){
+       ip = pLn->sosi + navn;
+       return ip->szNavn;
+   }
+
+   return NULL;
+}
+
+
+/*
+AR:2009-05-05
+CH LC_GetElementNavn                                        Hent elementnavn
+CD ==========================================================================
+CD Form�l:
+CD Hent et elementnavn fra den interne navnetabellen i FYBA.
+CD Denne tabellen inneholder b�de gruppenavn (.LINJE, .KURVE, ...) og
+CD egenskapsnavn (..OBJTYPE, ..LTEMA, ...)
+CD
+CD Tabellen har tre logiske deler:
+CD  - (Linje 0 - L_HODE): Forh�ndsdefinerte gruppenavn.
+CD  - (Linje L_HODE+1 - L_KP): Forh�ndsdefinerte egenskapsnavn.
+CD  - (Linje L_KP+1 - n): Andre elementnavn brukt i SOSI-filen etter
+CD                        indeksoppbygging.
+CD
+CD Selv om egenskapen blir fjernet fra SOSI-filen blir navnet fortsatt
+CD liggende i navnetabellen
+CD
+CD Parametre:
+CD Type        Navn    I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM  *pFil     i   Peker til FilAdm
+CD short       sNavnNr  i   Linjenummer i navnetabellen (0 - n)
+CD bool       *bBrukt       Viser om navnet har/er brukt i filen
+CD                          Hvis det har v�rt en gruppe som har brukt navnet blir
+CD                          denne st�ende "true" selv om gruppen er slettet.
+CD const char *pszNavn  r   Peker til elementnavn, 
+CD                          NULL = ukjent fil eller ulovlig linjenummer
+CD
+CD
+CD Bruk:
+CD // G�r gjennom alle navnene ut over de forh�ndsdefinerte navnene.
+CD short sNavnNr = L_KP+1; 
+CD while ((pszNavn = LC_GetElementNavn(pFil,sNavnNr)) != NULL)
+CD {
+CD    // Gj�r noe med navnet
+CD    ...
+CD    ++sNavnNr;
+CD }
+=============================================================================
+*/
+SK_EntPnt_FYBA const char *LC_GetElementNavn(LC_FILADM *pFil,short sNavnNr,bool *bBrukt)
+{
+   LO_TestFilpeker(pFil,"GetNavn");
+
+   LC_NAVNETABELL *pLn = &(pFil->SosiNavn);    //Peker til filens navnetabell
+
+   if (sNavnNr >= 0  &&  sNavnNr < pLn->sAntNavn)
+   {
+      SOSINAVN *ip = pLn->sosi + sNavnNr;
+
+      *bBrukt = ip->bBrukt;
+
+      return ip->szNavn;
+   }
+
+   return NULL;
+}
+
+
+/*
+AR-910819
+CH LN_VisNavn                                Hent en linje fra  navnetabellen
+CD =============================================================================
+CD Form�l:
+CD Henter en linje fra navnetabellen som formatert streng.
+CD
+CD Parametre:
+CD Type             Navn  I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_NAVNETABELL *  pLn    i    Peker til navnetabell
+CD long             navn   i    Linjenummer i navnetabellen som skall vises
+CD char            *tx     r    Peker til streng med formatert linje
+CD
+CD Bruk:
+CD for (navn=0,linje=10; navn<10; navn++,linje++){
+CD     SH_OutTx(linje,1,LN_VisNavn(pLn,navn));
+CD }
+   =============================================================================
+*/
+char *LN_VisNavn(LC_NAVNETABELL * pLn,short navn)
+{
+   SOSINAVN *ip;
+
+   if (navn < pLn->sAntNavn){
+       ip = pLn->sosi + navn;
+       UT_SNPRINTF(err().tx,LC_ERR_LEN,"%2d %16s", navn,ip->szNavn);
+   } else{
+       *err().tx = '\0';
+   }
+
+   return err().tx;
+}
+
+
+/*
+AR-940413
+CH LN_TolkKvalitet                                             Tolk KVALITET
+CD ==========================================================================
+CD Form�l:
+CD Tolk parameterstrengen for KVALITET.
+CD
+CD Parametre:
+CD Type    Navn         I/U   Forklaring
+CD -------------------------------------------------------------------------
+CD char   *pszParameter       i  Peker til '\0'-avslutta streng, eller
+CD                                 NULL hvis KVALITET mangler.
+CD short  *psMetode           u  Hvordan data er registrert.
+CD                                 KVAL_MET_UNDEF  metode er udefinert.
+CD                                 KVAL_MET_STD    standard metode fra niv� over.
+CD long   *plNoyaktighet      u  Registreringsn�yaktighet
+CD                                 KVAL_NOY_UKJENT n�yaktighet er ukjent.
+CD                                 KVAL_NOY_STD    standard n�yaktighet fra niv� over.
+CD short  *psSynbarhet        u  Synbarhet i bilde
+CD                                 KVAL_SYN_GOD    godt synlig.
+CD                                 KVAL_SYN_UNDEF  synbarhet er udefinert.
+CD                                 KVAL_SYN_STD    standard metode fra niv� over.
+CD short  *psHoydeMetode      u  Hvordan h�yden er registrert.
+CD                                 KVAL_MET_UNDEF  metode er udefinert.
+CD                                 KVAL_MET_STD    standard metode fra niv� over.
+CD long   *plHoydeNoyaktighet u  Registreringsn�yaktighet
+CD                                 KVAL_NOY_UKJENT n�yaktighet er ukjent.
+CD                                 KVAL_NOY_STD    standard n�yaktighet fra niv� over.
+CD
+CD Bruk:
+CD   ist = LN_TolkKvalitet(pszParameter,&sMetode,&lNoyaktighet,&sSynbarhet,
+CD                         &sHoydeMetode,&lHoydeNoyaktighet);
+CD =============================================================================
+*/
+void LN_TolkKvalitet(char *pszParameter,short *psMetode,long *plNoyaktighet,
+                     short *psSynbarhet,short *psHoydeMetode,long *plHoydeNoyaktighet)
+{
+   char ord[32];
+   short i;
+   char szMetode[6] = {"*"};
+   char szNoyaktighet[11] = {"*"};
+   char szSynbarhet[6] = {"0"};
+   char szHoydeMetode[6] = {" "};
+   char szHoydeNoyaktighet[11] = {" "};
+
+   /* Er det noen parameterstreng? */
+   if (pszParameter) {
+                              /* Hent strengene */
+      if (UT_StrToken(pszParameter,0,&i,32,ord)) {
+         UT_StrCopy(szMetode,ord,6);
+
+         if (UT_StrToken(pszParameter,i,&i,32,ord)) {
+            UT_StrCopy(szNoyaktighet,ord,10);
+
+            if (UT_StrToken(pszParameter,i,&i,32,ord)) {
+               UT_StrCopy(szSynbarhet,ord,6);
+
+               if (UT_StrToken(pszParameter,i,&i,32,ord)) {
+                  UT_StrCopy(szHoydeMetode,ord,6);
+
+                  if (UT_StrToken(pszParameter,i,&i,32,ord)) {
+                     UT_StrCopy(szHoydeNoyaktighet,ord,10);
+                  }
+               }
+            }
+         }
+      }
+   }
+
+   /* Tolk strengene til tallverdier */
+   if (*szMetode == '*') {
+      *psMetode = KVAL_MET_UNDEF;
+   } else if (*szMetode == '@') {
+      *psMetode = KVAL_MET_STD;
+   } else {
+      UT_StrShort(szMetode,0,&i,psMetode);
+   }
+
+   if (*szNoyaktighet == '*') {
+      *plNoyaktighet = KVAL_NOY_UKJENT;
+   } else if (*szNoyaktighet == '@') {
+      *plNoyaktighet = KVAL_NOY_STD;
+   } else {
+      UT_StrLong(szNoyaktighet,0,&i,plNoyaktighet);
+   }
+
+   if (*szSynbarhet == '*') {
+      *psSynbarhet = KVAL_SYN_UNDEF;
+   } else if (*szSynbarhet == '@') {
+      *psSynbarhet = KVAL_SYN_STD;
+   } else {
+      UT_StrShort(szSynbarhet,0,&i,psSynbarhet);
+   }
+
+   if (*szHoydeMetode == '*') {
+      *psHoydeMetode = KVAL_MET_UNDEF;
+   } else if (*szHoydeMetode == '@') {
+      *psHoydeMetode = KVAL_MET_STD;
+   } else if (*szHoydeMetode == ' ') {
+      *psHoydeMetode = *psMetode;
+   } else {
+      UT_StrShort(szHoydeMetode,0,&i,psHoydeMetode);
+   }
+
+   if (*szHoydeNoyaktighet == '*') {
+      *plHoydeNoyaktighet = KVAL_NOY_UKJENT;
+   } else if (*szHoydeNoyaktighet == '@') {
+      *plHoydeNoyaktighet = KVAL_NOY_STD;
+   } else if (*szHoydeNoyaktighet == ' ') {
+      *plHoydeNoyaktighet = *plNoyaktighet;
+   } else {
+      UT_StrLong(szHoydeNoyaktighet,0,&i,plHoydeNoyaktighet);
+   }
+
+   return;
+}
+
+
+/*
+AR-940413
+CH LC_FormatterKvalitet                                   Formatter KVALITET
+CD ==========================================================================
+CD Form�l:
+CD Formater parameterstrengen for KVALITET.
+CD Resultatet legges i en intern streng, og m� kopieres over til andre
+CD variabler f�r endring.
+CD
+CD Parametre:
+CD Type    Navn         I/U   Forklaring
+CD -------------------------------------------------------------------------
+CD short   sMetode           i Hvordan data er registrert.
+CD                               KVAL_MET_UNDEF  metode er udefinert.
+CD                               KVAL_MET_STD    standard metode fra niv� over.
+CD long    lNoyaktighet      i Registreringsn�yaktighet
+CD                               KVAL_NOY_UKJENT n�yaktighet er ukjent.
+CD                               KVAL_NOY_STD    standard n�yaktighet fra niv� over 
+CD short   sSynbarhet        i Synbarhet i bilde
+CD                               KVAL_SYN_GOD    godt synlig.
+CD                               KVAL_SYN_UNDEF  synbarhet er udefinert.
+CD                               KVAL_SYN_STD    standard metode fra niv� over.
+CD short   sHoydeMetode      i Hvordan data er registrert.
+CD                               KVAL_MET_UNDEF  metode er udefinert.
+CD                               KVAL_MET_STD    standard metode fra niv� over.
+CD long    lHoydeNoyaktighet i Registreringsn�yaktighet
+CD                               KVAL_NOY_UKJENT n�yaktighet er ukjent.
+CD                               KVAL_NOY_STD    standard n�yaktighet fra niv� over 
+CD char   *pszParameter      r Peker til '\0'-avslutta streng.
+CD
+CD Bruk:
+CD  pszParameter = LC_FormatterKvalitet(sMetode,lNoyaktighet,sSynbarhet,
+CD                                      sHoydeMetode,lHoydeNoyaktighet);
+CD =============================================================================
+*/
+SK_EntPnt_FYBA char *LC_FormatterKvalitet(short sMetode,long lNoyaktighet,short sSynbarhet,
+                           short sHoydeMetode,long lHoydeNoyaktighet)
+{
+   static char szParameter[60];
+   char szMetode[8] = {"*"};
+   char szNoyaktighet[13] = {" *"};
+   char szSynbarhet[8] = {" *"};
+   char szHoydeMetode[8] = {" *"};
+   char szHoydeNoyaktighet[13] = {" *"};
+
+
+   /* Metode */
+   if (sMetode == KVAL_MET_STD) {
+      *szMetode = '@';
+   } else if (sMetode != KVAL_MET_UNDEF) {
+      UT_SNPRINTF(szMetode,8,"%hd",sMetode);
+   }
+
+   /* N�yaktighet */
+   if (lNoyaktighet == KVAL_NOY_STD) {
+      szNoyaktighet[1] = '@';
+   } else if (lNoyaktighet != KVAL_NOY_UKJENT  && lNoyaktighet != KVAL_NOY_UNDEF) {
+      UT_SNPRINTF(szNoyaktighet,13," %ld",lNoyaktighet);
+   }
+
+   /* Synbarhet */
+   if (sSynbarhet == KVAL_SYN_STD) {
+      szSynbarhet[1] = '@';
+   } else if (sSynbarhet != KVAL_SYN_UNDEF) {
+      UT_SNPRINTF(szSynbarhet,8," %hd",sSynbarhet);
+   }
+
+   /* H�yde-metode */
+   if (sHoydeMetode == KVAL_MET_STD) {
+      szHoydeMetode[1] = '@';
+   } else if (sHoydeMetode != KVAL_MET_UNDEF) {
+      UT_SNPRINTF(szHoydeMetode,8," %hd",sHoydeMetode);
+   }
+
+   /* H�yde-n�yaktighet */
+   if (lHoydeNoyaktighet == KVAL_NOY_STD) {
+      szHoydeNoyaktighet[1] = '@';
+   } else if (lHoydeNoyaktighet != KVAL_NOY_UKJENT  &&  lHoydeNoyaktighet != KVAL_NOY_UNDEF) {
+      UT_SNPRINTF(szHoydeNoyaktighet,13," %ld",lHoydeNoyaktighet);
+   }
+
+   
+   /* Bygg opp parameterstrengen */
+
+   UT_StrCopy(szParameter,szMetode,60);
+
+   if (szNoyaktighet[1] != '*'         ||
+       sSynbarhet != KVAL_SYN_GOD      ||
+       sHoydeMetode != sMetode         ||
+       lHoydeNoyaktighet != lNoyaktighet) {
+
+      UT_StrCat(szParameter,szNoyaktighet,60);
+
+      if (sSynbarhet != KVAL_SYN_GOD      ||
+          sHoydeMetode != sMetode         ||
+          lHoydeNoyaktighet != lNoyaktighet) {
+
+         UT_StrCat(szParameter,szSynbarhet,60);
+
+         if (sHoydeMetode != sMetode         ||
+             lHoydeNoyaktighet != lNoyaktighet) {
+
+            UT_StrCat(szParameter,szHoydeMetode,60);
+
+            if (lHoydeNoyaktighet != lNoyaktighet) {
+               UT_StrCat(szParameter,szHoydeNoyaktighet,60);
+            }
+         }
+      }
+   }
+
+   return szParameter;
+}
+
+
+/*
+AR: 2000-01-19
+CH LC_FinnNivo                                     Beregn niv�
+CD ==============================================================
+CD Form�l:
+CD Teller antall prikker i starten p� egenskapsnavn.
+CD
+CD PARAMETERLISTE:
+CD Type     Navn      I/U   Merknad
+CD -------------------------------------------------------------
+CD char    *pszGinfo   i    Streng med egenskapsnavn i starten
+CD short    sNivo      r    Antall prikker 
+CD
+CD Bruk:
+CD sNivo = LC_FinnNivo(pszGinfo);
+  ================================================================
+*/
+SK_EntPnt_FYBA short LC_FinnNivo(const char * pszNavn)
+{
+   short sNivo = 0;
+
+   while (*pszNavn != '\0'  &&  *pszNavn == '.') {
+      ++pszNavn;
+      ++sNivo;
+   }
+
+   return sNivo;
+}
diff --git a/FYBA/make.sh b/FYBA/make.sh
new file mode 100755
index 0000000..a2bf4c2
--- /dev/null
+++ b/FYBA/make.sh
@@ -0,0 +1,5 @@
+gcc -Wall -g -D_FILE_OFFSET_BITS=64 -DUNIX -DLINUX -fPIC -DI18N_EN -Wno-write-strings -c -I. -I../include *.cpp &&
+ar rcs libfyba.a *.o &&
+gcc -g -D_FILE_OFFSET_BITS=64 -DUNIX -DLINUX -fPIC -DI18N_EN -Wno-write-strings -shared -I. -I../include *.cpp -o ../lib/libfyba.so
+cp fyba.h ../include/fyba.h
+
diff --git a/FYBA/stdafx.cpp b/FYBA/stdafx.cpp
new file mode 100644
index 0000000..cc5aa89
--- /dev/null
+++ b/FYBA/stdafx.cpp
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// FYBA.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/FYBA/stdafx.h b/FYBA/stdafx.h
new file mode 100644
index 0000000..0651b55
--- /dev/null
+++ b/FYBA/stdafx.h
@@ -0,0 +1,16 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <fyut.h>
+#include <fygm.h>
+
+#include "fyba.h"
+#include "fybax.h"
diff --git a/GM/GM.cpp b/GM/GM.cpp
new file mode 100644
index 0000000..fab9572
--- /dev/null
+++ b/GM/GM.cpp
@@ -0,0 +1,3245 @@
+/* ======= =============================================================== */
+/*  STATENS KARTVERK  -  FYSAK-PC                                         */
+/*  Fil: gm.c                                                             */
+/*  Ansvarlig: Andreas R�stad                                             */
+/*  Innhold: Geometrirutiner fysak-pc                                     */
+/* ====================================================================== */
+
+#include "stdafx.h"
+
+#include <math.h>
+#include <stdlib.h>
+#include <memory.h>
+
+#include <fyut.h>
+
+#include "fygm.h"
+
+/* --- Konstanter -- */
+#define ACCY  1.0E-6
+#define GM_ACCY  1.0E-8
+
+/* --- Makroer -- */
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+
+/*
+AR-890723
+CH GM_wtstBue                               Sjekk om en bue ber�rer et vindu
+CD ==========================================================================
+CD Form�l:
+CD Sjekker om en bue ber�rer et vindu.
+CD                                    wmax
+CD                       !--------------!
+CD                       !   ......     !
+CD                      .!...      .....!
+CD                  .... !              !...
+CD               ...     !              !   x (p2)
+CD        (p1)  x        !--------------!
+CD                     wmin
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   as       i    Koordinat i sentrumspunktet
+CD double   ns       i
+CD double   radius   i    Buens radius
+CD double   fi       i    "Retning" fra sentrum til buens startpunkt.
+CD double   dfi      i    Vinkel mellom fi og retning sentrum - sluttpkt.
+CD double   wmina    i    -!
+CD double   wminn    i     ! Vindu
+CD double   wmaxa    i     !
+CD double   wmaxn    i    -!
+CD short    kryss    r    0=ikke skj�ring, 1=skj�ring eller inni
+CD
+CD Bruk:
+CD kryss = GM_wtstBue(as,ns,radius,fi,dfi,wmina,wminn,wmaxa,wmaxn);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_wtstBue(double as,double ns,double radius,double fi,double dfi,
+                           double wmina,double wminn,double wmaxa,double wmaxn)
+{
+   double nva,nvn,oha,ohn,as1,ns1,as2,ns2;
+   double r = fabs(radius);
+
+                                    /* Omskrevet rektangel */
+   GM_buebox(as,ns,r,fi,dfi,&nva,&nvn,&oha,&ohn);
+
+                               /* Er  hele buen inni? */
+   if (wmaxn >= ohn  &&  wmaxa >= oha  &&  wminn <= nvn  &&  wmina <= nva){
+      return 1;
+   }
+
+               /* Overlapp mellom rektangel og vindu?, m� teste videre */
+   if (wmaxn >= nvn  &&  wmaxa >= nva  &&  wminn <= ohn  &&  wmina <= oha){
+                                             /* Min N */
+      if (GM_sLinBue(as,ns,r,fi,dfi,wmina,wminn,wmaxa,wminn,
+         &as1,&ns1,&as2,&ns2)){
+         return 1;
+      }
+                                             /* Min A */
+      if (GM_sLinBue(as,ns,r,fi,dfi,wmina,wminn,wmina,wmaxn,
+         &as1,&ns1,&as2,&ns2)){
+         return 1;
+      }
+                                          /* Max N */
+      if (GM_sLinBue(as,ns,r,fi,dfi,wmina,wmaxn,wmaxa,wmaxn,
+         &as1,&ns1,&as2,&ns2)){
+         return 1;
+      }
+                                          /* Max a */
+      if (GM_sLinBue(as,ns,r,fi,dfi,wmaxa,wminn,wmaxa,wmaxn,
+         &as1,&ns1,&as2,&ns2)){
+         return 1;
+      }
+   }
+
+   return 0;
+}
+
+
+/*
+AR-881018
+CH GM_wtst                                Sjekk om en linje ber�rer et vindu
+CD ==========================================================================
+CD Form�l:
+CD Sjekker om en linje ber�rer et vindu.
+CD                                    wmax
+CD                       !--------------!
+CD                       !      ........!.........
+CD                   ....!......        !        p2
+CD          .........    !              !
+CD        p1             !              !
+CD                       !--------------!
+CD                     wmin
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   p1a      i    Koordinat i f�rste punkt
+CD double   p1n      i
+CD double   p2a      i    Koordinat i andre punkt
+CD double   p2n      i
+CD double   wmina    i    -!
+CD double   wminn    i     ! Vindu
+CD double   wmaxa    i     !
+CD double   wmaxn    i    -!
+CD short    kryss    r    0=ikke skj�ring, 1=skj�ring eller inni
+CD
+CD Bruk:
+CD kryss = GM_wtst(pa1,p1n,p2a,p2n,wmina,wminn,wmaxa,wmaxn);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_wtst(double p1a, double p1n, double p2a, double p2n,
+                        double wmina, double wminn, double wmaxa, double wmaxn)
+{
+   unsigned int visa,visb,heltute,inni,kryss;
+   double sn,sa;
+
+   visa = 0;
+   if (p1a < wmina)  visa |= (unsigned int)0x1;
+   if (p1a > wmaxa)  visa |= (unsigned int)0x2;
+   if (p1n < wminn)  visa |= (unsigned int)0x4;
+   if (p1n > wmaxn)  visa |= (unsigned int)0x8;
+   inni = (unsigned int)(visa == 0);
+                               /* Tester videre n�r f�rste pkt. er utenfor */
+   if (! inni){
+       visb = 0;
+       if (p2a < wmina)  visb |= (unsigned int)0x1;
+       if (p2a > wmaxa)  visb |= (unsigned int)0x2;
+       if (p2n < wminn)  visb |= (unsigned int)0x4;
+       if (p2n > wmaxn)  visb |= (unsigned int)0x8;
+
+       inni = (unsigned int)(visb == 0);
+       if (! inni){
+                               /* N�r pkt B ogs� er utenfor */
+           heltute = visa & visb;
+           if (! heltute){
+                               /* N�r det er mulig skj�ring med vinduet */
+                                                   /* Min N */
+               kryss = (unsigned int)GM_shor(p1a,p1n,p2a,p2n,
+                               wmina,wminn,wmaxa,wminn,&sa,&sn);
+               if (! kryss){                       /* Min A */
+                   kryss = (unsigned int)GM_sver(p1a,p1n,p2a,p2n,
+                                   wmina,wminn,wmina,wmaxn,&sa,&sn);
+               }
+               if (! kryss){                       /* Max N */
+                   kryss = (unsigned int)GM_shor(p1a,p1n,p2a,p2n,
+                                   wmina,wmaxn,wmaxa,wmaxn,&sa,&sn);
+               }
+               if (! kryss){                      /* Max a */
+                   kryss = (unsigned int)GM_sver(p1a,p1n,p2a,p2n,
+                                   wmaxa,wminn,wmaxa,wmaxn,&sa,&sn);
+               }
+               if (kryss)  inni = 1;
+           }
+       }
+   }
+   return (short)inni;
+}
+
+/*
+PG-030815
+CH GM_wtstPunkt       Sjekker om et punkt ligger inni  - eller i kanten av - vindu
+CD ===============================================================================
+CD Form�l:
+CD Sjekker om et punkt ligger inni et vindu - gjerne rotert vindu.
+CD
+CD PARAMETERLISTE:
+CD Navn      Type  Array i/U Merknad
+CD -------------------------------------------------------------------------------
+CD PktA      double       i   �st-koordinat for sjekkpunkt
+CD PktN      double       i   Nord-koordinat for sjekkpunkt
+CD wa1       double       i   �st-koordinat for 1.pkt i vindu
+CD wn1       double       i   Nord-koordinat for 1.pkt i vindu
+CD wa2       double       i   �st-koordinat for 2.pkt i vindu
+CD wn2       double       i   Nord-koordinat for 2.pkt i vindu
+CD wa3       double       i   �st-koordinat for 3.pkt i vindu
+CD wn3       double       i   Nord-koordinat for 3.pkt i vindu
+CD wa4       double       i   �st-koordinat for 4.pkt i vindu
+CD wn4       double       i   Nord-koordinat for 4.pkt i vindu
+CD inni      short        r   Er punktet innenfor vinduet
+CD 
+CD Bruk:  inni = GM_wtstPunkt(PktA, PktN, wa1, wn1, wa2, wn2, wa3, wn3, wa4, wn4);
+   ===============================================================================
+*/
+SK_EntPnt_GM short GM_wtstPunkt(double PktA, double PktN, double wa1, double wn1, double wa2, double wn2, double wa3, double wn3,
+                                double wa4, double wn4)
+{
+   
+   double dPolyMaxA,dPolyMaxN,dPolyMinA,dPolyMinN;
+   double maxA = 99999999999.9;           // "Uendelig" �st
+   double as,ns;
+   short sAntSkjaer;
+   
+   // Sjekk 1: Ligger punktet utenfor omskrevet rektangel - s� ligger det utenfor vinduet
+   dPolyMaxA=max(wa1,wa2); dPolyMaxA=max(dPolyMaxA,wa3); dPolyMaxA=max(dPolyMaxA,wa4);
+   dPolyMaxN=max(wn1,wn2); dPolyMaxN=max(dPolyMaxN,wn3); dPolyMaxN=max(dPolyMaxN,wn4);
+   dPolyMinA=min(wa1,wa2); dPolyMinA=min(dPolyMinA,wa3); dPolyMinA=min(dPolyMinA,wa4);
+   dPolyMinN=min(wn1,wn2); dPolyMinN=min(dPolyMinN,wn3); dPolyMinN=min(dPolyMinN,wn4);
+   if((PktA>dPolyMaxA) || (PktA<dPolyMinA) || (PktN>dPolyMaxN) || (PktN<dPolyMinN))
+      return 0;
+
+   // Sjekk 2: // Ligger punktet innenfor vinduet? 
+
+   // Pluss p� et lite tillegg for � unng� treff p� node
+   PktN += 0.000001;
+
+   // Beregn skj�ring med alle sidene
+   sAntSkjaer = GM_shor(wa1,wn1,wa2,wn2,PktA,PktN,maxA,PktN,&as,&ns);
+   sAntSkjaer += GM_shor(wa2,wn2,wa3,wn3,PktA,PktN,maxA,PktN,&as,&ns);
+   sAntSkjaer += GM_shor(wa3,wn3,wa4,wn4,PktA,PktN,maxA,PktN,&as,&ns);
+   sAntSkjaer += GM_shor(wa4,wn4,wa1,wn1,PktA,PktN,maxA,PktN,&as,&ns);
+
+   // Sjekk om punktet er innenfor
+   return  ((sAntSkjaer % 2) == 1)?  1 : 0;
+}
+
+/*
+AR-881018
+CH GM_sver                            Skj�ring mellom vertikal- og skr�linje
+CD ==========================================================================
+CD Form�l:
+CD Beregner skj�ringspunkt mellom en vertikal linje (M-N) og en skr�linje (K-L)
+CD
+CD                               M*     *L
+CD                                !   /
+CD                                ! /
+CD                                *S
+CD                              / !
+CD                            /   !
+CD                         K*     *N
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   ka       i    Koordinat i K
+CD double   kn       i
+CD double   la       i    Koordinat i L
+CD double   ln       i
+CD double   na       i    Koordinat i N
+CD double   nn       i
+CD double   ma       i    Koordinat i M
+CD double   mn       i
+CD double  *sa       u    Koordinat i S
+CD double  *sn       u
+CD short    kryss    r    0=ikke skj�ring, 1=skj�ring
+CD
+CD Bruk:
+CD kryss = GM_sver(ka,kn,la,ln,na,nn,ma,mn,&sa,&sn);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_sver(double ka,double kn,double la,double ln,double na,double nn,
+                        double ma,double mn,double *sa,double *sn)
+{
+   unsigned int kryss = 0;
+   double mini,maxi;
+
+   mini = min(ka,la);
+   maxi = max(ka,la);
+
+   if (na >= mini  &&  ma <= maxi){        /* (ma er lik na) */
+       if (fabs(la-ka) > 0.0001){
+                                               /* Beregn skj�ringspunktet */
+           *sa = ma;
+           *sn = kn + ((*sa-ka)*(ln-kn))/(la-ka);
+           mini = min(mn,nn) - ACCY;
+           maxi = max(mn,nn) + ACCY;
+                                               /* Sjekk om det er skj�ring */
+           kryss = (unsigned int)(*sn >= mini  &&  *sn <= maxi);
+       }
+   }
+   return (short)kryss;
+}
+
+
+/*
+AR-881018
+CH GM_shor                          Skj�ring mellom horisontal- og skr�linje
+CD ==========================================================================
+CD Form�l:
+CD Beregner skj�ringspunkt mellom en horisontal linje (M-N)
+CD og en skr�linje (K-L)
+CD
+CD                                     *L
+CD                                   /
+CD                                 /
+CD                     M*--------*S--------*N
+CD                             /
+CD                           /
+CD                        K*
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   ka       i    Koordinat i K
+CD double   kn       i
+CD double   la       i    Koordinat i L
+CD double   ln       i
+CD double   na       i    Koordinat i N
+CD double   nn       i
+CD double   ma       i    Koordinat i M
+CD double   mn       i
+CD double  *sa       u    Koordinat i S
+CD double  *sn       u
+CD short    kryss    r    0=ikke skj�ring, 1=skj�ring
+CD
+CD Bruk:
+CD kryss = GM_shor(ka,kn,la,ln,na,nn,ma,mn,&sa,&sn);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_shor(double ka,double kn,double la,double ln,double na,double nn,
+                        double ma,double mn,double *sa,double *sn)
+{
+   unsigned int kryss = 0;
+   double mini,maxi;
+
+   mini = min(kn,ln);
+   maxi = max(kn,ln);
+
+   if (mn >= mini  &&  nn <= maxi){        /* (mn er lik nn) */
+       if (fabs(ln-kn) > 0.0001){
+                                               /* Beregn skj�ringspunktet */
+           *sn = mn;
+           *sa = ka + ((*sn-kn)*(la-ka))/(ln-kn);
+           mini = min(ma,na) - ACCY;
+           maxi = max(ma,na) + ACCY;
+                                               /* Sjekk om det er skj�ring */
+           kryss = (unsigned int)(*sa >= mini  &&  *sa <= maxi);
+       }
+   }
+   return (short)kryss;
+}
+
+
+/*
+AR-901209
+CH GM_sLinLin                                 Skj�ringspunkt mellom 2 linjer
+CD ==========================================================================
+CD Form�l:
+CD Beregner skj�ringspunkt mellom 2 linjer (M-N) og (K-L)
+CD
+CD                         M*           *L
+CD                            \       /
+CD                              \   /
+CD                               *S          
+CD                             /   \
+CD                           /       \
+CD                        K*           *N
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   ka       i    Koordinat i K
+CD double   kn       i
+CD double   la       i    Koordinat i L
+CD double   ln       i
+CD double   ma       i    Koordinat i M
+CD double   mn       i
+CD double   na       i    Koordinat i N
+CD double   nn       i
+CD double  *sa       u    Koordinat i S
+CD double  *sn       u
+CD short    kryss    r    0=ikke skj�ring, 1=skj�ring
+CD
+CD Bruk:
+CD kryss = GM_sLinLin(ka,kn,la,ln,ma,mn,na,nn,&sa,&sn);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_sLinLin(double ka,double kn,double la,double ln,double ma,double mn,
+                           double na,double nn,double *sa,double *sn)
+{
+   double det,detinv,s,t;
+
+   double alk = la - ka;
+   double nlk = ln - kn;
+   double anm = na - ma;
+   double nnm = nn - mn;
+   double amk = ma - ka;
+   double nmk = mn - kn;
+
+
+   /* Sorterer f�rst ut �penbare tilfeller der det ikke er skj�ring */ 
+   if (max(ka,la) < min(ma,na))  return 0;
+   if (min(ka,la) > max(ma,na))  return 0;
+   if (max(kn,ln) < min(mn,nn))  return 0;
+   if (min(kn,ln) > max(mn,nn))  return 0;
+
+   det = anm * nlk - nnm * alk;
+
+   /* Parallelle linjer */
+   if (fabs(det) < ACCY)   return 0;
+
+   detinv = 1.0 / det;
+   s = (anm*nmk - nnm*amk) * detinv;
+   t = (alk*nmk - nlk*amk) * detinv;
+
+   if (s < 0.0  ||  s > 1.0  ||  t < 0.0  || t > 1.0)  return 0;
+
+   *sa = ka + alk*s;
+   *sn = kn + nlk*s;
+
+   return 1;
+
+#ifdef UTGAAR
+
+   /*
+    * Beregner skj�ring mellom to uendelige vektorer.
+    *  Sjekker etterp� om skj�ringspunktet ligger p� linjebitene.
+    */
+   if (GM_sVektVekt(ka,kn,la,ln,ma,mn,na,nn,sa,sn)){
+      if (*sn <= max(kn,ln)+ACCY  &&  *sn >= min(kn,ln)-ACCY  &&
+          *sa <= max(ka,la)+ACCY  &&  *sa >= min(ka,la)-ACCY  &&
+          *sn <= max(mn,nn)+ACCY  &&  *sn >= min(mn,nn)-ACCY  &&
+          *sa <= max(ma,na)+ACCY  &&  *sa >= min(ma,na)-ACCY) {
+
+         return 1;     /* Skj�ring funnet ==> returnerer */
+      }
+   }
+
+   return 0;     /* Ingen skj�ring funnet ==> returnerer */
+#endif
+}
+
+
+
+/*
+AR-901209
+CH GM_Overlapp                                      Overlapp mellom 2 linjer
+CD ==========================================================================
+CD Form�l:
+CD Sjekker om to linjer overlapper hverandre helt eller delevis.
+CD
+CD                         M*     
+CD                           \  
+CD                            \  
+CD                             \ *K         
+CD                              \ \
+CD                               \ \
+CD                                *N\
+CD                                   \
+CD                                    \
+CD                                     *L
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   ka       i    Koordinat i K
+CD double   kn       i
+CD double   la       i    Koordinat i L
+CD double   ln       i
+CD double   ma       i    Koordinat i M
+CD double   mn       i
+CD double   na       i    Koordinat i N
+CD double   nn       i
+CD double  *sa       u    Koordinat i S
+CD double  *sn       u
+CD short    overlapp r    0=ikke overlapp
+CD                        1=tangerer (likt endepunkt)
+CD                        2=delevis overlapp
+CD                        3=linjene er like
+CD Bruk:
+CD kryss = GM_Overlapp(ka,kn,la,ln,ma,mn,na,nn);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_Overlapp(double ka,double kn,double la,double ln,double ma,double mn,double na,double nn)
+{
+   // Sorterer f�rst ut �penbare tilfeller der det ikke er skj�ring
+   if (max(ka,la) < min(ma,na))  return 0;
+   if (min(ka,la) > max(ma,na))  return 0;
+   if (max(kn,ln) < min(mn,nn))  return 0;
+   if (min(kn,ln) > max(mn,nn))  return 0;
+
+
+   // Linjene er like
+   if (fabs((min(ka,la) - min(ma,na))) < GM_ACCY &&
+       fabs((max(ka,la) - max(ma,na))) < GM_ACCY &&
+       fabs((min(kn,ln) - min(mn,nn))) < GM_ACCY &&
+       fabs((max(kn,ln) - max(mn,nn))) < GM_ACCY)
+   {
+      return 3;
+   }
+
+   // Linjene tangerer i enden
+   if ((fabs(ka-ma)<GM_ACCY && fabs(kn-mn)<GM_ACCY) ||
+       (fabs(la-ma)<GM_ACCY && fabs(ln-mn)<GM_ACCY) ||
+       (fabs(ka-na)<GM_ACCY && fabs(kn-nn)<GM_ACCY) ||
+       (fabs(la-na)<GM_ACCY && fabs(ln-nn)<GM_ACCY))
+   {
+      return 1;
+   }
+
+   double alk = la - ka;
+   double nlk = ln - kn;
+   double anm = na - ma;
+   double nnm = nn - mn;
+   //double amk = ma - ka;
+   //double nmk = mn - kn;
+   double det = anm * nlk - nnm * alk;
+
+   // Parallelle linjer
+   if (fabs(det) < ACCY)
+   {
+      double a,n;
+      if (GM_fotp(ka,kn,la,ln,ma,mn,&a,&n) == 2)
+      {
+         if (fabs(ma-a)<GM_ACCY && fabs(mn-n)<GM_ACCY)  return 2;
+      }
+
+      if (GM_fotp(ka,kn,la,ln,na,nn,&a,&n) == 2)
+      {
+         if (fabs(na-a)<GM_ACCY && fabs(nn-n)<GM_ACCY)  return 2;
+      }
+
+      if (GM_fotp(ma,mn,na,nn,ka,kn,&a,&n) == 2)
+      {
+         if (fabs(ka-a)<GM_ACCY && fabs(kn-n)<GM_ACCY)  return 2;
+      }
+      if (GM_fotp(ma,mn,na,nn,la,ln,&a,&n) == 2) {
+         if (fabs(la-a)<GM_ACCY && fabs(ln-n)<GM_ACCY)  return 2;
+      }
+   }
+   
+   // Ikke parallelle
+   return 0;
+}
+
+
+/*
+AR-901209
+CH GM_sVektVekt                     Skj�ringspunkt mellom 2 uendelige linjer
+CD ==========================================================================
+CD Form�l:
+CD Beregner skj�ringspunkt mellom uendelige 2 linjer (M-N) og (K-L)
+CD   
+CD                         M*           *L
+CD                            \       /
+CD                              \   /
+CD                               *S          
+CD                             /   \
+CD                           /       \
+CD                        K*           *N
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   ka       i    Koordinat i K
+CD double   kn       i
+CD double   la       i    Koordinat i L
+CD double   ln       i
+CD double   ma       i    Koordinat i M
+CD double   mn       i
+CD double   na       i    Koordinat i N
+CD double   nn       i
+CD double  *sa       u    Koordinat i S
+CD double  *sn       u
+CD short    kryss    r    0=ikke skj�ring, 1=skj�ring
+CD
+CD Bruk:
+CD kryss = GM_sVektVekt(ka,kn,la,ln,ma,mn,na,nn,&sa,&sn);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_sVektVekt(double ka,double kn,double la,double ln,double ma,double mn,
+                             double na,double nn,double *sa,double *sn)
+{
+   double det,detinv,s,t;
+
+   double alk = la - ka;
+   double nlk = ln - kn;
+   double anm = na - ma;
+   double nnm = nn - mn;
+   double amk = ma - ka;
+   double nmk = mn - kn;
+
+
+   /* Sorterer f�rst ut �penbare tilfeller der det ikke er skj�ring */ 
+   //if (max(ka,la) < min(ma,na))  return 0;
+   //if (min(ka,la) > max(ma,na))  return 0;
+   //if (max(kn,ln) < min(mn,nn))  return 0;
+   //if (min(kn,ln) > max(mn,nn))  return 0;
+
+   det = anm * nlk - nnm * alk;
+
+   /* Parallelle linjer */
+   if (fabs(det) < ACCY)   return 0;
+
+   detinv = 1.0 / det;
+   s = (anm*nmk - nnm*amk) * detinv;
+   t = (alk*nmk - nlk*amk) * detinv;
+
+   //if (s < 0.0  ||  s > 1.0  ||  t < 0.0  || t > 1.0)  return 0;
+
+   *sa = ka + alk*s;
+   *sn = kn + nlk*s;
+
+   return 1;
+
+
+
+#ifdef UTGAAR
+
+   double pa1,pb1,pc1,pa2,pb2,pc2;
+
+   /*
+    * Beregner skj�ring mellom to uendelige vektorer.
+    */
+   if (GM_bepa(ka,kn,la,ln,&pa1,&pb1,&pc1)) {
+      if (GM_bepa(ma,mn,na,nn,&pa2,&pb2,&pc2)) {
+         if (GM_cint(pa1,pb1,pc1,pa2,pb2,pc2,sa,sn)) {
+            return 1;     /* Skj�ring funnet ==> returnerer */
+         }
+      }  
+   }
+
+   return 0;     /* Ingen skj�ring funnet ==> returnerer */
+
+#endif
+}
+
+
+/*
+AR-890722
+CH GM_sLinBue                                   Skj�ring mellom linje og bue
+CD ==========================================================================
+CD Form�l:
+CD Beregner skj�ringspunkt mellom en linje (K-L) og en bue.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   sa       i    Koordinat i buens sentrum.
+CD double   sn       i
+CD double   radius   i    Buens radius.
+CD double   fi       i    Retning fra sentrum til buens startpunkt
+CD double   dfi      i    Vinkel mellom retning til buens startpunkt og sluttpunkt
+CD double   ka       i    Koordinat i K.
+CD double   kn       i
+CD double   la       i    Koordinat i L.
+CD double   ln       i
+CD double  *a1       u    Koordinat i skj�ringspunkt 1
+CD double  *n1       u
+CD double  *a2       u    Koordinat i skj�ringspunkt 2
+CD double  *n2       u
+CD short    kryss    r    Antall skj�ringspunkter (0, 1 eller 2)
+CD
+CD Bruk:
+CD kryss = GM_sLinBue(sa,sn,radius,fi,dfi,ka,kn,la,ln,&a1,&n1,&a2,&n2);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_sLinBue(double sa,double sn,double radius,double fi,double dfi,
+                           double ka,double kn,double la,double ln,
+                           double *a1,double *n1,double *a2,double *n2)
+{
+   short kryss;
+   double mina,minn,maxa,maxn;
+
+            /* Beregn f�rst skj�ring mellom uendelig vektor og hele sirkelen */
+   kryss = GM_sVektSirk(sa,sn,radius,ka,kn,la,ln,a1,n1,a2,n2);
+
+                        /* Sjekk om punktene ligger p� linjen */
+   if (kryss > 0){
+       minn = min(kn,ln) - ACCY;
+       mina = min(ka,la) - ACCY;
+       maxn = max(kn,ln) + ACCY;
+       maxa = max(ka,la) + ACCY;
+
+       if (kryss == 2){
+           if (! (*a2 <= maxa  &&  *a2 >= mina  &&
+                  *n2 <= maxn  &&  *n2 >= minn)){
+               kryss = 1;            /* Utenfor linjen */
+           }
+       }
+
+       if (! (*a1 <= maxa && *a1 >= mina  &&  *n1 <= maxn && *n1 >= minn)){
+                                 /* Utenfor linjen */
+           if (kryss == 2){      /* Flytt ned forrige skj�ringspunkt */
+               kryss = 1;
+               *a1 = *a2;
+               *n1 = *n2;
+           } else{
+               kryss = 0;        /* Ikke noe skj�ringspunkt */
+           }
+       }
+   }
+
+                        /* Sjekk om punktene ligger p� buen */
+   if (kryss > 0){
+      if (kryss == 2){
+         if ( ! GM_TestPktBue(sa,sn,fi,dfi,*a2,*n2)){
+            kryss = 1;            /* Utenfor buen */
+         }
+      }
+
+      if ( ! GM_TestPktBue(sa,sn,fi,dfi,*a1,*n1)){
+         if (kryss == 2){      /* Flytt ned forrige skj�ringspunkt */
+            kryss = 1;
+            *a1 = *a2;
+            *n1 = *n2;
+         } else{
+            kryss = 0;        /* Ikke noe skj�ringspunkt */
+         }
+      }
+   }
+
+   return kryss;
+}
+
+
+/*
+AR-901209
+CH GM_sVektSirk                     Skj�ring mellom uendelig linje og sirkel
+CD ==========================================================================
+CD Form�l:
+CD Beregner skj�ringspunkt mellom en uendelig linje (K-L) og en sirkel.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   sa       i    Koordinat i sirkelens sentrum.
+CD double   sn       i
+CD double   radius   i    Sirkelens radius.
+CD double   ka       i    Koordinat i K.
+CD double   kn       i
+CD double   la       i    Koordinat i L.
+CD double   ln       i
+CD double  *a1       u    Koordinat i skj�ringspunkt 1
+CD double  *n1       u
+CD double  *a2       u    Koordinat i skj�ringspunkt 2
+CD double  *n2       u
+CD short    kryss    r    Antall skj�ringspunkter (0, 1 eller 2)
+CD
+CD Bruk:
+CD kryss = GM_sVektSirk(sa,sn,radius,ka,kn,la,ln,&a1,&n1,&a2,&n2);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_sVektSirk(double sa,double sn,double radius,
+                             double ka,double kn,double la,double ln,
+                             double *a1,double *n1,double *a2,double *n2)
+{
+   short kryss = 0;
+   double f,g,root,fsq,gsq,fgsq,xj0,yj0,fygx,fxgy,t,fginv,t1,t2;
+
+            /* Beregn skj�ring mellom uendelig vektor og sirkelen */
+                                       /* Parametre for K-L */
+   f = la - ka;
+   g = ln - kn;
+                                             /* Beregn skj�ring */
+   fsq = f * f;
+   gsq = g * g;
+   fgsq = fsq + gsq;
+   if (fgsq > ACCY){                       /* Linjen er ok */
+       xj0 = sa - ka;
+       yj0 = sn - kn;
+       fygx = f*yj0 - g*xj0;
+       root = radius*radius*fgsq - fygx*fygx;
+       if (root > -ACCY){             /* Linjen ber�rer sirkelen */
+           fxgy = f*xj0 + g*yj0;
+           if (root < ACCY){             /* Linjen tangerer sirkelen */
+               kryss = 1;
+               t = fxgy / fgsq;
+               *a1 = ka + f*t;
+               *n1 = kn + g*t;
+
+           } else{                       /* Linjen skj�rer sirkelen */
+               kryss = 2;
+               root = sqrt(root);
+               fginv = 1.0 / fgsq;
+               t1 = (fxgy - root) * fginv;
+               t2 = (fxgy + root) * fginv;
+               *a1 = ka + f*t1;
+               *n1 = kn + g*t1;
+               *a2 = ka + f*t2;
+               *n2 = kn + g*t2;
+           }
+       }
+   }
+
+   return kryss;
+}
+
+
+/*
+AR-901209
+CH GM_sBueBue                                   Skj�ringspunkt mellom 2 buer
+CD ==========================================================================
+CD Form�l:
+CD Beregner skj�ringspunkt mellom 2 buer.
+CD NB! Retningen oppgis i radianer, med retning 0 i �st-aksen, og med positiv
+CD oml�psretning mot urviseren. Alle vinkler er i omr�det 0 - 2PI.
+CD Metode: Se Bowyer and Woodwark: AProgrammer's Geometry, side 27-28.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   sa1      i    Koordinat i buens sentrum.
+CD double   sn1      i
+CD double   radius1  i    Buens radius.
+CD double   fi1      i    Retning fra sentrum til buens startpunkt
+CD double   dfi1     i    Vinkel mellom retning til buens startpunkt og sluttpunkt
+CD double   sa2      i    Koordinat i buens sentrum.
+CD double   sn2      i
+CD double   radius2  i    Buens radius.
+CD double   fi2      i    Retning fra sentrum til buens startpunkt
+CD double   dfi2     i    Vinkel mellom retning til buens startpunkt og sluttpunkt
+CD double  *a1       u    Koordinat i skj�ringspunkt 1
+CD double  *n1       u
+CD double  *a2       u    Koordinat i skj�ringspunkt 2
+CD double  *n2       u
+CD short    kryss    r    Antall skj�ringspunkter (0, 1 eller 2)
+CD
+CD Bruk:
+CD kryss = GM_sBueBue(as1,ns1,fi1,dfi1,as2,ns2,fi2,dfi2,&a1,&n1,&a2,&n2);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_sBueBue(double as1,double ns1,double radius1,double fi1,double dfi1,
+                           double as2,double ns2,double radius2,double fi2,double dfi2,
+                           double *a1,double *n1,double *a2,double *n2)
+{
+   short kryss;
+
+   /*
+    * Beregner f�rst skj�ring mellom to sirkler.
+    * Sjekker etterp� om skj�ringspunktene ligger p� buene.
+    */
+
+   kryss = GM_sSirkSirk(as1,ns1,radius1,as2,ns2,radius2,a1,n1,a2,n2);
+
+   /* Sjekk om punktene ligger inne p� de aktuelle buene */
+   if (kryss > 0){
+      /* Sjekk om skj�ringspunkt 2 ligger p� bue 1 */
+      if (kryss == 2){
+         if ( ! GM_TestPktBue(as1,ns1,fi1,dfi1,*a2,*n2)){
+            kryss = 1;            /* Utenfor buen */
+         }
+
+         /* Sjekk om skj�ringspunkt 2 ogs� ligger p� bue 2 */
+         if (kryss == 2){
+            if ( ! GM_TestPktBue(as2,ns2,fi2,dfi2,*a2,*n2)){
+               kryss = 1;            /* Utenfor buen */
+            }
+         }
+      }
+
+      /* Sjekk om skj�ringspunkt 1 ligger p� bue 1 */
+      if ( ! GM_TestPktBue(as1,ns1,fi1,dfi1,*a1,*n1)){
+         if (kryss == 2){      /* Flytt ned forrige skj�ringspunkt */
+            kryss = 1;
+            *a1 = *a2;
+            *n1 = *n2;
+         } else {
+            kryss = 0;        /* Ikke noe skj�ringspunkt */
+         }
+      }
+
+      if (kryss > 0){
+      /* Sjekk om skj�ringspunkt 1 ogs� ligger p� bue 2 */
+         if ( ! GM_TestPktBue(as2,ns2,fi2,dfi2,*a1,*n1)){
+            if (kryss == 2){      /* Flytt ned forrige skj�ringspunkt */
+               kryss = 1;
+               *a1 = *a2;
+               *n1 = *n2;
+            } else{
+               kryss = 0;        /* Ikke noe skj�ringspunkt */
+            }
+         }
+      }
+   }
+
+   return kryss;
+}
+
+
+/*
+AR-901209
+CH GM_sSirkSirk                              Skj�ringspunkt mellom 2 sirkler
+CD ==========================================================================
+CD Form�l:
+CD Beregner skj�ringspunkt mellom 2 sirkler.
+CD Metode: Se Bowyer and Woodwark: AProgrammer's Geometry, side 27-28.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   sa1      i    Koordinat i sirklens sentrum.
+CD double   sn1      i
+CD double   radius1  i    Sirklens radius.
+CD double   sa2      i    Koordinat i sirklens sentrum.
+CD double   sn2      i
+CD double   radius2  i    Sirklens radius.
+CD double  *a1       u    Koordinat i skj�ringspunkt 1
+CD double  *n1       u
+CD double  *a2       u    Koordinat i skj�ringspunkt 2
+CD double  *n2       u
+CD short    kryss    r    Antall skj�ringspunkter (0, 1 eller 2)
+CD
+CD Bruk:
+CD kryss = GM_sSirkSirk(as1,ns1,as2,ns2,&a1,&n1,&a2,&n2);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_sSirkSirk(double as1,double ns1,double radius1,
+                             double as2,double ns2,double radius2,
+                             double *a1,double *n1,double *a2,double *n2)
+{
+   double r1sq,r2sq,a21,n21,distsq,dstinv,sumrsq,root,a,n,afac,nfac;
+   double scl,delrsq;
+   short kryss = 0;
+
+   /*
+    * Beregner skj�ring mellom to sirkler.
+    */
+
+   r1sq = radius1 * radius1;
+   r2sq = radius2 * radius2;
+   a21 = as2 - as1;
+   n21 = ns2 - ns1;
+
+                                       /* Beregn kvadrert lengden L-K */
+   distsq = a21*a21 + n21*n21;
+
+   if (distsq > ACCY){    /* Ikke sammenfallende punkt */
+      delrsq = r2sq - r1sq;
+      sumrsq = r1sq + r2sq;
+      root = 2.0*sumrsq*distsq - distsq*distsq - delrsq*delrsq;
+
+      if (root > -ACCY){              /* Sirklene skj�rer */
+         dstinv = 0.5 / distsq;
+         scl = 0.5 - delrsq*dstinv;
+         a = as1 + a21*scl;
+         n = ns1 + n21*scl;
+
+         if (root < ACCY){        /* 1 tangeringspunkt */
+            *a1 = a;
+            *n1 = n;
+            kryss = 1;
+
+         } else{        /* 2 skj�ringspunkter */
+            root = dstinv * sqrt(root);
+            afac = a21 * root;
+            nfac = n21 * root;
+
+            *a1 = a - nfac;
+            *n1 = n + afac;
+            *a2 = a + nfac;
+            *n2 = n - afac;
+            kryss = 2;
+         }
+      }
+   }
+
+   return kryss;
+}
+
+
+/*
+AR-890904
+JA�-1999-02-03
+CH GM_fotp                                       Fotpunkt p� linje fra punkt
+CD ==========================================================================
+CD Form�l:
+CD Beregner fotpunktet  p� linjen 1-2 fra punktet P.
+CD
+CD                               *P
+CD                               !
+CD                               !
+CD                     1*--------*---------*2
+CD                               F
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   a1       i    Koordinat i 1
+CD double   n1       i
+CD double   a2       i    Koordinat i 2
+CD double   n2       i
+CD double   ap       i    Koordinat i P
+CD double   np       i
+CD double  *af       u    Koordinat i fotpunktet
+CD double  *nf       u
+CD short    kryss    r    0=ikke beregnet (brukes ikke)
+CD                        1=beregnet, men punktet er utenfor linjen
+CD                        2=bregnet, ok
+CD
+CD Bruk:
+CD kryss = GM_fotp(a1,n1,a2,n2,ap,np,&af,&nf);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_fotp(double a1,double n1,double a2,double n2,double ap,double np,
+                        double *af,double *nf)
+{
+   //double pa1,pb1,pc1,pa2,pb2,pc2;
+   double ap1,np1,ap2,np2,retning,a1u,n1u,a2u,n2u;
+   short beregnet = 0;
+
+
+   if (fabs(a2-a1) < ACCY) {
+      /* Punkt 1 og 2 er sammenfallende */
+      if (fabs(n2-n1) < ACCY) {
+         *af = a1;
+         *nf = n1;
+
+      /* Vertikal linje */
+      } else { 
+         *af = a1;
+         *nf = np;
+      }
+
+      /* Sjekk at fotpunktet er p� linjen */
+      //if ( (*nf <= max(n1,n2)+ACCY)  &&  (*nf >= min(n1,n2)-ACCY) ) {
+      if ( (*nf <= max(n1,n2))  &&  (*nf >= min(n1,n2)) ) {
+         beregnet = 2;
+      } else {
+         beregnet = 1;
+      }
+
+   /* Horisontal linje */
+   } else if (fabs(n2-n1) < ACCY) {
+      *af = ap;
+      *nf = n1;
+
+      /* Sjekk at fotpunktet er p� linjen */
+      //if ( (*af <= max(a1,a2)+ACCY)  &&  (*af >= min(a1,a2)-ACCY) ) {
+      if ( (*af <= max(a1,a2))  &&  (*af >= min(a1,a2)) ) {
+         beregnet = 2;
+      } else {
+         beregnet = 1;
+      }
+   }
+
+   /* ---------- Skr� linje */
+   if ( ! beregnet) {
+      //JA�-20001205 Pr�ver ny metode � beregne fotpunkt, pga avrundingsproblemer ved sm� verdier.
+      retning = GM_RetnGon(a1,n1,a2,n2);
+      //Utvider linjene "uendelig" for � v�re sikker p� � f� kryssing
+      a1u = a1; a2u = a2; n1u = n1; n2u = n2;
+      GM_PolRettv(&a1u,&n1u,retning+200.0,100000000);
+      GM_PolRettv(&a2u,&n2u,retning,100000000);
+      ap1 = ap; ap2 = ap; np1 = np; np2 = np;
+      GM_PolRettv(&ap1,&np1,retning+100.0,100000000);
+      GM_PolRettv(&ap2,&np2,retning-100.0,100000000);
+      GM_sLinLin(a1u,n1u,a2u,n2u,ap1,np1,ap2,np2,af,nf); //Da gikk det bedre!
+
+      //JA�-20001205 Fjernet gammel m�te � beregne fotpunkt, pga avrundingsproblemer ved sm� verdier.
+      /*
+      // Parametre for 1-2
+      if (GM_bepa(a1,n1,a2,n2,&pa1,&pb1,&pc1)){
+         // Parametre for P-F 
+         pa2=pb1;
+         pb2=-pa1;
+         pc2=pa1*np-pb1*ap;
+         // Fotpunktet 
+         GM_cint(pa1,pb1,pc1,pa2,pb2,pc2,af,nf);
+      }
+     */
+
+      /* Sjekk at fotpunktet er p� linjen */
+      //if (*nf <= (max(n1,n2)+ACCY)  &&  *nf >= (min(n1,n2)-ACCY)  &&
+      //   *af <= (max(a1,a2)+ACCY)  &&  *af >= (min(a1,a2)-ACCY)){
+      if (*nf <= (max(n1,n2))  &&  *nf >= (min(n1,n2))  &&
+         *af <= (max(a1,a2))  &&  *af >= (min(a1,a2))){
+         beregnet = 2;                     /* P� linjen */
+      } else {
+         beregnet = 1;            /* Utenfor linjen */
+      }
+   }
+
+   return beregnet;                
+}
+
+/*
+IR-2011-05-05
+CH GM_fotp                                       Fotpunkt p� line fr� punkt
+CD ==========================================================================
+CD Form�l:
+CD Bereknar fotpunktet  p� lina 1-2 fr� punktet P (i 2D).
+CD (Ein kan bruke same metoden i 3D, ved � ta med z-koordinatane i tillegg.)
+CD Sj� http://paulbourke.net/geometry/sphereline  for dokumentasjon.
+CD
+CD                               *P
+CD                               !
+CD                               !
+CD                     1*--------*---------*2
+CD                               F
+CD
+CD Parametrar:
+CD Type     Namn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   a1       i    Koordinat i 1
+CD double   n1       i
+CD double   a2       i    Koordinat i 2
+CD double   n2       i
+CD double   ap       i    Koordinat i P
+CD double   np       i
+CD double  *af       u    Koordinat i fotpunktet
+CD double  *nf       u
+CD short    kryss    r    0=ikkje berekna (blir ikkje brukt)
+CD                        1=berekna, men punktet er utanfor lina
+CD                        2=berekna, ok
+CD
+CD Bruk:
+CD kryss = GM_fotp(a1,n1,a2,n2,ap,np,&af,&nf);
+   ==========================================================================
+*/
+// SK_EntPnt_GM short GM_fotp_ny(double a1,double n1,double a2,double n2,double ap,double np,
+//                         double *af,double *nf)
+
+
+
+SK_EntPnt_GM short GM_fotp_ny(double a1, double n1, double a2, double n2, double ap, double np,
+                        double *af, double *nf)
+{
+	double da12, dn12, da1p, dn1p, teljar, nemnar, u;
+	short godfot;
+	
+	da12 = a2 - a1;
+	dn12 = n2 - n1;
+	da1p = ap - a1;
+	dn1p = np - n1;
+	teljar = da1p * da12 + dn1p * dn12;
+	nemnar = da12 * da12 + dn12  * dn12;
+	
+	if (nemnar == 0) // lina 1-2 er nullvektor
+	{	 
+	  *af = a1;
+	  *nf = n1;
+	  godfot = 2;
+	}
+	else 
+	{
+	  u = teljar / nemnar;
+	  *af = a1 + u * da12;
+	  *nf = n1 + u * dn12;
+	  if ( (u >= 0) && (u <= 1)) 
+	  {
+		 godfot = 2;
+	  }
+	  else 
+	  {
+		 godfot = 1;
+	  }
+	}
+	
+	return godfot;
+}
+
+#ifdef TEST
+{
+   //double pa1,pb1,pc1,pa2,pb2,pc2;
+   double retning;
+
+   double ap1=ap;
+   double np1=np;
+   short beregnet = 0;
+   double dn=fabs(n2-n1);
+   double da=fabs(a2-a1);
+
+   if (da < ACCY) {
+      /* Punkt 1 og 2 er sammenfallende */
+      if (dn < ACCY) {
+         *af = a1;
+         *nf = n1;
+
+      /* Vertikal linje */
+      } else { 
+         *af = a1;
+         *nf = np;
+      }
+
+      /* Sjekk at fotpunktet er p� linjen */
+      if ( (*nf <= max(n1,n2)+ACCY)  &&  (*nf >= min(n1,n2)-ACCY) ) {
+         beregnet = 2;
+      } else {
+         beregnet = 1;
+      }
+
+   /* Horisontal linje */
+   } else if (dn < ACCY) {
+      *af = ap;
+      *nf = n1;
+
+      /* Sjekk at fotpunktet er p� linjen */
+      if ( (*af <= max(a1,a2)+ACCY)  &&  (*af >= min(a1,a2)-ACCY) ) {
+         beregnet = 2;
+      } else {
+         beregnet = 1;
+      }
+   }
+
+   /* ---------- Skr� linje */
+   if ( ! beregnet) {
+
+      // AR 2000-12-10
+      // Forslag til ny metode for fotpunktberegning. Endrer ikke de opprinnelige punktene,
+      // og det blir da mulig � gi korrekt tilbakemelding om punktet ligger inne p� den gitte linjen.
+      retning = GM_RetnGon(a1,n1,a2,n2);
+      GM_PolRettv(&ap1, &np1, retning+100.0, max(da,dn));
+      GM_sVektVekt(a1,n1,a2,n2,ap,np,ap1,np1,af,nf);
+      
+      /* Sjekk at fotpunktet er p� linjen */
+      if (*nf <= (max(n1,n2)+ACCY)  &&  *nf >= (min(n1,n2)-ACCY)  &&
+         *af <= (max(a1,a2)+ACCY)  &&  *af >= (min(a1,a2)-ACCY)){
+         beregnet = 2;                     /* P� linjen */
+      } else {
+         beregnet = 1;            /* Utenfor linjen */
+      }
+   }
+
+   return beregnet;                
+}
+#endif
+
+
+/*
+AR-991012
+CH GM_Parallell                                       Parallellforskyver linje
+CD ==========================================================================
+CD Form�l:
+CD  Parallellforskyver linjen K-L gitt avstand normalt til siden. 
+CD
+CD
+CD                     L1        L         L1
+CD                      *- - - - * - - - - *
+CD                               !
+CD                      !        !         !
+CD                               !
+CD                      !        !         !
+CD                               !
+CD                      !        !         !
+CD                               !
+CD                      *- - - - * - - - - *
+CD                     K1        K         K1
+CD
+CD
+CD               avstand < 0            avstand > 0
+CD
+CD
+CD
+CD Parametre:
+CD Type     Navn       I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   ka          i    Koordinat i K
+CD double   kn          i
+CD double   la          i    Koordinat i L
+CD double   ln          i
+CD double   avstand     i    Forskyving (>0 = til h�yre(K2-L2), <0 = til venstre(K1-L1))
+CD double  *ka1         u    Koordinat i K1
+CD double  *kn1         u
+CD double  *la1         u    Koordinat i L1
+CD double  *ln1         u
+CD bool     status s    r    UT_FALSE = ikke beregnet (K og L har like koordinater)
+CD                           UT_TRUE = bregnet, ok
+CD
+CD Bruk:
+CD status = GM_Parallell(ka,kn,la,ln,avstand,&ka1,&kn1,&la1,&ln1);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_Parallell(double ka,double kn,double la,double ln,double avstand,
+                               double *ka1,double *kn1,double *la1,double *ln1)
+{
+   double fi, da, dn;
+
+
+   /* Punkt 1 og 2 er sammenfallende, klarer ikke � beregne */
+   if (fabs(ka-la) < ACCY  &&  fabs(kn-ln) < ACCY) {
+      *ka1 = ka;
+      *kn1 = kn;
+      *la1 = la;
+      *ln1 = ln;
+      return UT_FALSE;
+   }
+
+   /* Ingen forskyving */
+   if (fabs(avstand) <= ACCY) {
+      *ka1 = ka;
+      *kn1 = kn;
+      *la1 = la;
+      *ln1 = ln;
+      return UT_TRUE;
+   }
+
+   /* Beregner retninger fra K til L */
+   fi = GM_retning(ka,kn,la,ln);
+
+   /* Forskyvingsretning */
+   if ( avstand < ACCY ) {   /* Forskyving til venstre */            
+      fi += PI/2;
+   } else {                     /* Forskyving til h�yre */
+      fi -= PI/2;
+   }
+
+   /* Beregner nye koordinater */
+   avstand = fabs (avstand);
+   da = avstand * cos(fi);
+   dn = avstand * sin(fi);
+   *ka1 = ka + da;
+   *kn1 = kn + dn;
+   *la1 = la + da;
+   *ln1 = ln + dn;
+
+   return UT_TRUE;                
+}
+
+ 
+/*
+AR-890723
+CH GM_KonvBue                             Omregning til intern bue-angivelse
+CD ==========================================================================
+CD Form�l:
+CD Omregning til intern bue-angivelse med sirkelsentrum, radius og retning
+CD til buens start samt delta for sluttpunktet.
+CD NB! Retningen oppgis i radianer, med retning 0 i �st-aksen, og med positiv
+CD oml�psretning mot urviseren. Alle vinkler er i omr�det 0 - 2PI.
+CD Metode: Se Bowyer and Woodwark: AProgrammer's Geometry,
+CD         side 27-28 og 35-36.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   a1       i    Koordinat i P1
+CD double   n1       i
+CD double   a2       i    Koordinat i P2
+CD double   n2       i
+CD double   radius   i    Buens radius (med fortegn)
+CD short    storbue  i    Storbue (1=storbue, 0=ikke storbue)
+CD double  *as       u    Koordinat i sentrumspunktet
+CD double  *ns       u
+CD double  *fi       u    "Retning" sentrum - punkt 1.
+CD double  *dfi      u    Vinkel mellom fi og retning  sentrum - punkt 2.
+CD short    beregnet r    0=kan ikke beregne,  1=bregnet ok.
+CD
+CD Bruk:
+CD ok = GM_KonvBue(a1,n1,a2,n2,radius,storbue,&as,&ns,&fi,&dfi);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_KonvBue(double a1,double n1,double a2,double n2,double radius,
+                           short storbue,double *as,double *ns,double *fi,double *dfi)
+{
+   double rsq,a21,n21,distsq,dstinv,sumrsq,root,a,n,afac,nfac,fi2,f1;
+   short beregnet = 0;
+
+   rsq = radius * radius;
+   a21 = a2 - a1;
+   n21 = n2 - n1;
+
+                                       /* Beregn kvadrert lengden L-K */
+   distsq = a21*a21 + n21*n21;
+
+   if (distsq > ACCY) {    /* Ikke sammenfallende punkt */
+      sumrsq = rsq + rsq;
+      root = 2.0*sumrsq*distsq - distsq*distsq;
+
+      if (root > -ACCY) {        /* Sirklene skj�rer eller tangerer */
+         beregnet = 1;
+         dstinv = 0.5 / distsq;
+         a = a21 * 0.5 + a1;
+         n = n21 * 0.5 + n1;
+
+         if (root > ACCY) {        /* 2 skj�ringspunkter */
+            root = dstinv * sqrt(root);
+            afac = a21 * root;
+            nfac = n21 * root;
+            if ((radius < 0.0  && storbue == 0) ||
+                (radius > 0.0  && storbue == 1) )
+            {
+               *as = a - nfac;             /* Bruker 1. skj�ringspunkt */
+               *ns = n + afac;
+            } else {
+               *as = a + nfac;             /* Bruker 2. skj�ringspunkt */
+               *ns = n - afac;
+            }
+
+         } else {        /* Tangering */
+            *as = a;
+            *ns = n;
+         }
+
+         /* Beregn retninger fra sentrum til start og sluttpunkt */
+         *fi = GM_retning(*as,*ns,a1,n1);    /* S - K */
+         f1 = *fi;
+         fi2 = GM_retning(*as,*ns,a2,n2);    /* S - L */
+
+                           /* Beregner retningsavvik */
+         if (radius < 0.0)
+         {
+            if (fi2 < f1)  fi2 += (PI*2.0);
+         } else {
+            if (f1 < fi2)  f1 += (PI*2.0);
+         }
+         *dfi = fi2 - f1;
+      }
+   }
+
+   return beregnet;
+}
+
+
+/*
+AR-890723
+CH GM_KonvBuep                            Omregning til intern bue-angivelse
+CD ==========================================================================
+CD Form�l:
+CD Omregning til intern bue-angivelse med sirkelsentrum, radius og retning
+CD til buens start samt delta for sluttpunktet.
+CD NB! Retningen oppgis i radianer, med retning 0 i �st-aksen, og med positiv
+CD oml�psretning mot urviseren. Alle vinkler er i omr�det 0 - 2PI.
+CD Metode: Se Bowyer and Woodwark: AProgrammer's Geometry,
+CD         side 27-28 og 35-36.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   a1       i    Koordinat i P1  (startpunkt)
+CD double   n1       i
+CD double   a2       i    Koordinat i P2  (punkt p� buen)
+CD double   n2       i
+CD double   a3       i    Koordinat i P3  (sluttpunkt)
+CD double   n3       i
+CD double  *as       u    Koordinat i sentrumspunktet
+CD double  *ns       u
+CD double  *radius   u    Buens radius
+CD double  *fi       u    "Retning" sentrum - punkt 1.
+CD double  *dfi      u    Vinkel mellom fi og retning  sentrum - punkt 3.
+CD short    beregnet r    0=kan ikke beregne,  1=bregnet ok.
+CD
+CD Bruk:
+CD ok = GM_KonvBuep(a1,n1,a2,n2,a3,n3,&as,&ns,&radius,&fi,&dfi);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_KonvBuep(double a1,double n1,double a2,double n2,double a3,double n3,
+                            double *as,double *ns,double *radius,double *fi,double *dfi)
+{
+   double ap,np,fi2,fi3,dfi2,dfi3;
+   double pa1,pb1,pc1,pa2,pb2,pc2,pa3,pb3,pc3;
+   short beregnet = 0;
+
+   /* Parametre for linjen 1 - 3 */
+   if(GM_bepa(a1,n1,a3,n3,&pa1,&pb1,&pc1)){
+      /* Midtpunktet mellom 1 og 3 */
+      ap = a1 +  (a3-a1) / 2.0;
+      np = n1 +  (n3-n1) / 2.0;
+
+      /* Parametre for midtlinjen mellom 1 og 3 */
+      pa3=pb1;
+      pb3=-pa1;
+      pc3=pa1*np-pb1*ap;
+
+      /* Parametre for linjen 1 - 2 */
+      if(GM_bepa(a1,n1,a2,n2,&pa1,&pb1,&pc1)){
+         /* Midtpunktet mellom 1 og 2 */
+         ap = a1  +  (a2-a1) / 2.0;
+         np = n1  +  (n2-n1) / 2.0;
+
+         /* Parametre for midtlinjen mellom 1 og 2 */
+         pa2=pb1;
+         pb2=-pa1;
+         pc2=pa1*np-pb1*ap;
+
+         /* Sentrum er skj�ringspunktet mellom de to linjene */
+         if (GM_cint(pa3,pb3,pc3,pa2,pb2,pc2,as,ns)){
+            *radius = sqrt((*as-a1)*(*as-a1) + (*ns-n1)*(*ns-n1));
+
+                  /* Beregn retninger fra sentrum til start og sluttpunkt */
+            *fi = GM_retning(*as,*ns,a1,n1);    /* S - P1 */
+            fi2 = GM_retning(*as,*ns,a2,n2);    /* S - P2 */
+            fi3 = GM_retning(*as,*ns,a3,n3);    /* S - P3 */
+
+                              /* Beregner retningsavvik */
+            dfi2 = fi2 - *fi;
+            dfi3 = fi3 - *fi;
+
+            /* Positiv delta ? */
+            if (dfi2 < 0.0)  dfi2 += (PI*2.0);
+            if (dfi3 < 0.0)  dfi3 += (PI*2.0);
+            if (dfi2 <= dfi3){
+               *dfi = dfi3;
+            } else{
+               /* Negativ delta */
+               if (dfi3 > 0.0)  dfi3 -= (PI*2.0);
+               *dfi = dfi3;
+            }
+
+            beregnet = 1;
+         }
+      }
+   }
+
+   return beregnet;
+}
+
+
+/*
+AR-911029
+CH GM_KonvSirkel                         Omregning til intern bue-angivelse
+CD ==========================================================================
+CD Form�l:
+CD Omregning til intern bue-angivelse med sirkelsentrum, radius og retning
+CD til buens start samt delta for sluttpunktet.
+CD NB! Retningen oppgis i radianer, med retning 0 i �st-aksen, og med positiv
+CD oml�psretning mot urviseren. Alle vinkler er i omr�det 0 - 2PI.
+CD Metode: Se Bowyer and Woodwark: AProgrammer's Geometry,
+CD         side 27-28 og 35-36.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double  *as       iu   Koordinat i sentrumspunktet
+CD double  *ns       iu
+CD double  *radius   iu   Buens radius
+CD double  *fi       u    "Startretning"  sentrum - punkt 1.
+CD double  *dfi      u    "�pningsvinkel" (2PI).
+CD short    ist      r    1 = OK, 0 = ikke beregnet.
+CD
+CD Bruk:
+CD ist = GM_KonvSirkel(&as,&ns,&radius,&fi,&dfi);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_KonvSirkel(double *fi,double *dfi)
+{
+
+   *fi = 0.0;
+   *dfi = 2.0 * PI;
+
+   return 1;
+}
+
+
+/*
+AR-911029
+CH GM_KonvSirkelp                         Omregning til intern bue-angivelse
+CD ==========================================================================
+CD Form�l:
+CD Omregning til intern bue-angivelse med sirkelsentrum, radius og retning
+CD til buens start samt delta for sluttpunktet.
+CD NB! Retningen oppgis i radianer, med retning 0 i �st-aksen, og med positiv
+CD oml�psretning mot urviseren. Alle vinkler er i omr�det 0 - 2PI.
+CD Metode: Se Bowyer and Woodwark: AProgrammer's Geometry,
+CD         side 27-28 og 35-36.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   a1       i    Koordinat i P1  (punkt p� buen)
+CD double   n1       i
+CD double   a2       i    Koordinat i P2  (punkt p� buen)
+CD double   n2       i
+CD double   a3       i    Koordinat i P3  (punkt p� buen)
+CD double   n3       i
+CD double  *as       u    Koordinat i sentrumspunktet
+CD double  *ns       u
+CD double  *radius   u    Buens radius
+CD double  *fi       u    "Retning" sentrum - start av buen (0)
+CD double  *dfi      u    �pningsvinkel (2*PI)
+CD short    beregnet r    1 = OK; 0 = kan ikke beregne.
+CD
+CD Bruk:
+CD ist = GM_KonvSirkelp(a1,n1,a2,n2,a3,n3,&as,&ns,&radius,&fi,&dfi);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_KonvSirkelp(double a1,double n1,double a2,double n2,double a3,double n3,
+                               double *as,double *ns,double *radius,double *fi,double *dfi)
+{
+   double ap,np;
+   double pa1,pb1,pc1,pa2,pb2,pc2,pa3,pb3,pc3;
+   short beregnet = 0;
+
+   /* Parametre for linjen 1 - 3 */
+   if(GM_bepa(a1,n1,a3,n3,&pa1,&pb1,&pc1)){
+      /* Midtpunktet mellom 1 og 3 */
+      ap = a1 + (a3-a1)/2.0;
+      np = n1 + (n3-n1)/2.0;
+
+      /* Parametre for midtlinjen mellom 1 og 3 */
+      pa3=pb1;
+      pb3=-pa1;
+      pc3=pa1*np-pb1*ap;
+
+      /* Parametre for linjen 1 - 2 */
+      if(GM_bepa(a1,n1,a2,n2,&pa1,&pb1,&pc1)){
+         /* Midtpunktet mellom 1 og 2 */
+         ap = a1 + (a2-a1)/2.0;
+         np = n1 + (n2-n1)/2.0;
+
+         /* Parametre for midtlinjen mellom 1 og 2 */
+         pa2=pb1;
+         pb2=-pa1;
+         pc2=pa1*np-pb1*ap;
+
+         /* Sentrum er skj�ringspunktet mellom de to linjene */
+         if (GM_cint(pa3,pb3,pc3,pa2,pb2,pc2,as,ns)){
+            *radius = sqrt((*as-a1)*(*as-a1) + (*ns-n1)*(*ns-n1));
+
+            /* Beregn retninger fra sentrum til start og sluttpunkt */
+            *fi = GM_retning(*as,*ns,a1,n1);
+            *dfi = 2.0 * PI;
+
+            beregnet = 1;
+         }
+      }
+   }
+
+   return beregnet;
+}
+
+
+/*
+AR-881018
+CH GM_bepa                                                    Linjeparametre
+CD ==========================================================================
+CD Form�l:
+CD Beregner parametrene for linjen gjennom 1 og 2.
+CD Ligningen for linjen er: (AX+BY+C=0).
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   a1       i    Koordinat i 1
+CD double   n1       i
+CD double   a2       i    Koordinat i 2
+CD double   n2       i
+CD double  *pa       u    Parametre for linjen
+CD double  *pb       u
+CD double  *pc       u
+CD short    ist      r    1=beregnet, 0=ikke beregnet (1 og 2 er samme punkt)
+CD
+CD Bruk:
+CD ist = GM_bepa(a1,n1,a2,n2,&pa,&pb,&pc);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_bepa(double a1, double n1, double a2, double n2,
+                        double *pa, double *pb, double *pc)
+{
+   double ndif,adif,rinv,atmp,ntmp,dmn,dmx,div;
+
+   adif = a2-a1;
+   atmp = fabs(adif);
+   ndif = n2-n1;
+   ntmp = fabs(ndif);
+
+
+   if(atmp > ACCY  ||  ntmp > ACCY) {
+   
+      dmx = max(atmp,ntmp);
+      dmn = min(atmp,ntmp);
+      div = dmn / dmx;
+
+      rinv = 1.0 / (dmx * sqrt(1.0+div*div));
+      *pa = -ndif*rinv;
+      *pb =  adif*rinv;
+      //*pc = (a1*n2 - a2*n1) * rinv;
+      {
+         double d1 = a1*n2;
+         double d2 = a2*n1;
+         double d3 = d1 - d2;
+         *pc = d3 * rinv;
+      }
+
+      // -56430.600006104
+
+      return (1);
+   } else {
+      *pa = *pb = *pc = 0.0;
+      return (0);
+   }
+}
+
+
+/*
+AR-940522
+CH GM_bepa3                                                3D-Linjeparametre
+CD ==========================================================================
+CD Form�l:
+CD Beregner 3D parametrene for linjen gjennom 1 og 2.
+CD Ligningen for linjen er: (AX+BY+C=0).
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   a1       i    Koordinat i 1
+CD double   n1       i
+CD double   h1       i
+CD double   a2       i    Koordinat i 2
+CD double   n2       i
+CD double   h2       i
+CD double  *pf       u    Parametre for linjen
+CD double  *pg       u
+CD double  *ph       u
+CD short    ist      r    1=beregnet, 0=ikke beregnet (1 og 2 er samme punkt)
+CD
+CD Bruk:
+CD ist = GM_bepa3(a1,n1,h1,a2,n2,h2,&pa,&pb,&pc);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_bepa3(double a1, double n1, double h1,
+                         double a2, double n2, double h2,
+                         double *pf, double *pg, double *ph)
+{
+   double ndif,adif,hdif,rsq,rinv;
+
+   ndif = n2-n1;
+   adif = a2-a1;
+   hdif = h2-h1;
+   rsq = ndif*ndif + adif*adif + hdif*hdif;
+   if(rsq > ACCY){
+       rinv = 1.0 / sqrt(rsq);
+       *pf = adif * rinv;
+       *pg = ndif * rinv;
+       *ph = hdif * rinv;
+       return (1);
+   } else{
+       *pf = *pg = *ph = 0.0;
+       return (0);
+   }
+}
+
+
+/*
+AR-890717
+CH GM_cint                                         Skj�ring mellom to linjer
+CD ==========================================================================
+CD Form�l:
+CD Beregner kryssingspunktet mellom to linjer.
+CD Linjene er gitt p� implisitt form.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   pa1      i    Parametre for linje 1
+CD double   pb1      i
+CD double   pc1      i
+CD double   pa2      i    Parametre for linje 2
+CD double   pb2      i
+CD double   pc2      i
+CD double  *as       u    Koordinat i skj�ringspunktet
+CD double  *ns       u
+CD short    kryss    r    1=beregnet, 0=ikke beregnet (pralelle linjer)
+CD
+CD Bruk:
+CD kryss = GM_cint(pa1,pb1,pc1,pa2,pb2,pc2,&as,&ns);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_cint(double pa1, double pb1, double pc1, double pa2, double pb2,
+                        double pc2, double *as, double *ns)
+{
+   double det,dinv;
+
+                /* Beregner skj�ringspunktet mellom linjene p� implicit form */
+   det = pa1*pb2 - pa2*pb1;
+   if (fabs(det) > ACCY){
+       dinv = 1.0/det;
+       *as = (pb1*pc2 - pb2*pc1) * dinv;
+       *ns = (pa2*pc1 - pa1*pc2) * dinv;
+       return(1);
+   } else{
+       *ns = *as = 0.0;
+       return(0);
+   }
+}
+
+
+
+/*
+JEK-920514
+CH GM_Vinkel                     Beregner vinkel mellom to retninger
+CD ==================================================================
+CD Form�l:
+CD Beregner positiv vinkel mellom to retninger fi1 og fi2.
+CD
+CD PARAMETERLISTE:
+CD Navn      Type  Array i/U Merknad
+CD ------------------------------------------------------------------
+CD fi1       double       i   Retningsvinkel 1
+CD fi2       double       i   retningsvinkel 2
+CD vinkel    double       r   Positiv vinkel i rad. mellom fi1 og fi2
+CD                            Alltid i omr�det 0 - 2PI.
+CD
+CD Bruk : vinkel = GM_Vinkel(fi1,fi2);
+   ==================================================================
+*/
+SK_EntPnt_GM double GM_Vinkel(double fi1, double fi2)
+{
+   return GM_RedVinkel(fi2 - fi1);
+}
+
+
+/*
+JEK-920514
+CH GM_RedVinkel                Beregner en retn.vinkel i omr. 0-2*PI
+CD ==================================================================
+CD Form�l:
+CD Redusere en retningsvinkel til � ligge i omr�det 0 - 2*PI.
+CD
+CD PARAMETERLISTE:
+CD Navn      Type  Array i/U Merknad
+CD ------------------------------------------------------------------
+CD fi       double       i   Retningsvinkel 
+CD vinkel   double       r   Redusert vinkel
+CD
+CD Bruk:  red_vinkel = GM_RedVinkel(fi);
+   ==================================================================
+*/
+SK_EntPnt_GM double GM_RedVinkel(double dFi)
+{
+   double topi = 2.0*PI;            
+   double vinkel = dFi;
+
+   while ( vinkel < 0.0  ||  vinkel > topi ) {
+      if ( vinkel < 0.0 ) {
+         vinkel += topi;
+      }
+      if ( vinkel > topi ) {
+         vinkel -= topi;
+      }
+   }
+
+   return vinkel;
+}
+
+
+/*
+AR-901021
+CH GM_retning                                        Retning mellom to punkt
+CD ==========================================================================
+CD Form�l:
+CD Beregner retning fra et punkt til et annet (K-L).
+CD (Rutinen er spesiellt beregnet for � beregne retningsvinkler for buer.)
+CD NB! Retningen oppgis i radianer, med retning 0 i �st-aksen, og med positiv
+CD oml�psretning mot urviseren.
+CD
+CD                             *L
+CD                           /
+CD                         /
+CD                       /
+CD                    K*
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   ak       i    Koordinat i K.
+CD double   nk       i
+CD double   al       i    Koordinat i L.
+CD double   nl       i
+CD double   retning  r    Retning K-L.
+CD
+CD Bruk:
+CD retning = GM_retning(ak,nk,al,nl);
+   ==========================================================================
+*/
+SK_EntPnt_GM double GM_retning(double ak,double nk,double al,double nl)
+{
+   double retning;
+   double da = al - ak;
+   double dn = nl - nk;
+   
+   // Beregner retning
+   if (fabs(da) < ACCY  &&  fabs(dn) < ACCY) {
+      retning = 0.0;
+   } else {
+      retning = atan2(dn,da);
+   }
+
+   // Juster til positiv retningen
+   if (retning < 0.0) {
+      retning += PI * 2.0; 
+   }
+
+   return retning;
+}
+
+
+/*
+GL-910709
+CH GM_RetnGon                       Beregner retningsvinkel mellom 2 punkt
+CD ==========================================================================
+CD Bruk   : r = GM_RetnGon(a1,n1,a2,n2)
+CD ==========================================================================
+*/
+SK_EntPnt_GM double GM_RetnGon(double a1 , double n1, double a2, double n2)
+{
+   double r;
+   double da = a2 - a1;
+   double dn = n2 - n1;
+
+                                       /* Beregner retning */
+   if (fabs(da) < ACCY  &&  fabs(dn) < ACCY) {
+      r = 0.0;
+   } else {
+      r = atan2(da,dn);
+   }
+
+   r = Rad2Gon(r);
+   if (r < 0.0)  r += 400.0;
+
+   return r;
+}
+
+
+/*
+GL-910709
+CH GM_RettvPol               Beregner polare koord.(retnvinkel og avstand)
+CD ==========================================================================
+CD Bruk   : GM_RettvPol(a1,n1,a2,n2,&gon,&avst)
+CD ==========================================================================
+*/
+SK_EntPnt_GM void GM_RettvPol(double a1 , double n1, double a2, double n2,
+                         double *gon, double *avst)
+{
+   *gon =GM_RetnGon(a1,n1,a2,n2);
+   *avst=sqrt((a2-a1)*(a2-a1)+(n2-n1)*(n2-n1));
+}
+
+
+/*
+CH GM_Areal                                      Beregner areal av polygon
+CD ==========================================================================
+CD Form�l:
+CD Beregner areal av polygon.
+CD Forutsetter at polygonet er lukket. (F�rste og siste punkt er like.)
+CD
+CD PARAMETERLISTE:
+CD Navn    Type    I/U Merknad
+CD --------------------------------------------------------------------------
+CD pA     *double   i   �st-koordinater
+CD pN     *double   i   Nord-koordinater
+CD sNko    short    i   Antall koordinater
+CD dAreal  double   r   Areal m^2
+CD
+CD Bruk:  areal = GM_Areal ( pA, pN, sAnt );
+   ==========================================================================
+*/
+SK_EntPnt_GM double GM_Areal(double *pA, double *pN, short sAnt)
+{
+   double dAreal = 0.0;
+   double a_forrige,n_forrige;
+   short s = 1;
+
+   if (sAnt > 2) {
+      a_forrige = *pA;
+      n_forrige = *pN;
+
+      for ( ; s<sAnt; ++s) {
+         dAreal += (a_forrige - pA[s]) * (n_forrige + pN[s]);
+         a_forrige = pA[s];
+         n_forrige = pN[s];
+      }
+   }
+
+   return fabs(dAreal / 2.0);
+}
+
+
+/*
+GL-910704
+CH GM_PolRettv            Beregner nye rettvinkla koordinater fra gon+avst
+CD ==========================================================================
+CD Bruk   : GM_PolRettv(&a,&n,gon,avst)
+CD ==========================================================================
+*/
+SK_EntPnt_GM void GM_PolRettv(double *a , double *n, double gon, double avst)
+{
+   *n = *n + avst * (double)cos(Gon2Rad(gon));
+   *a = *a + avst * (double)sin(Gon2Rad(gon));
+}
+
+
+/*
+AR-890919
+CH GM_buebox                                          Omskreven boks for bue
+CD ==========================================================================
+CD Form�l:
+CD Beregner omskrevet rektangel for bue.
+CD Buen g�r mot urviseren fra P1 til P2 rundt sirkelen.
+CD NB! Retningen oppgis i radianer, med retning 0 i �st-aksen, og med positiv
+CD oml�psretning mot urviseren.
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   as       i    Koordinat i sirkelsentrum.
+CD double   ns       i
+CD double   radius   i    Aavstand fra senterpunkt til P1 og P2.
+CD                        (Fortegn blir ignorert.)
+CD double   fi       i    Retning sentrum - P1
+CD double   dfi      i    Delta retning p1 og p2
+CD double   nva      u    Nedre venstre hj�rne  av omskrevet rektangel.
+CD double   nvn      u
+CD double   oha      u    �vre h�yre hj�rne  av omskrevet rektangel.
+CD double   ohn      u
+CD
+CD Bruk:
+CD GM_buebox(as,ns,radius,fi,dfi,&nva,&nvn,&oha,&ohn);
+   ==========================================================================
+*/
+SK_EntPnt_GM void GM_buebox(double as,double ns,double radius,double fi,double dfi,
+                         double *nva,double *nvn,double *oha,double *ohn)
+{
+   double r = fabs(radius);
+   double a1,n1,a2,n2;
+
+
+   // ----- Hel sirkel
+   if (fabs(dfi) > ((2.0*PI)-ACCY))
+   {
+      *nva = as - r;
+      *nvn = ns - r;
+      *oha = as + r;
+      *ohn = ns + r;
+
+      return;     // ==>
+   }
+
+   // ----- Andre buer
+
+   // Starter med omskrevet boks for endepunktene
+   a1 = as + r*cos(fi);
+   n1 = ns + r*sin(fi);
+   a2 = as + r*cos(fi+dfi);
+   n2 = ns + r*sin(fi+dfi);
+
+   *nva = min(a1,a2);
+   *nvn = min(n1,n2);
+   *oha = max(a1,a2);
+   *ohn = max(n1,n2);
+
+   // For hver akse (fra sentrumspunktet) som krysses utvides omskrevet boks
+   radius = fabs(radius);
+   if (GM_TestPktBue(as, ns, fi, dfi, as+radius, ns))  *oha = as+radius;
+   if (GM_TestPktBue(as, ns, fi, dfi, as-radius, ns))  *nva = as-radius;
+
+   if (GM_TestPktBue(as, ns, fi, dfi, as, ns+radius))  *ohn = ns+radius;
+   if (GM_TestPktBue(as, ns, fi, dfi, as, ns-radius))  *nvn = ns-radius;
+}
+
+
+
+/* Gammel versjon
+
+   double r2;
+   double r = fabs(radius);
+   double a1,n1,a2,n2;
+
+
+   // ----- Hel sirkel
+   if (fabs(dfi) > ((2.0*PI)-ACCY))
+   {
+      *nva = as - r;
+      *nvn = ns - r;
+      *oha = as + r;
+      *ohn = ns + r;
+
+      return;     // ==>
+   }
+
+   // ----- Andre buer
+
+   a1 = as + r*cos(fi);
+   n1 = ns + r*sin(fi);
+   a2 = as + r*cos(fi+dfi);
+   n2 = ns + r*sin(fi+dfi);
+
+   // Beregn sorterte retninger
+   if (dfi < 0.0){
+      r2 = fi;
+      fi += dfi;
+   } else{
+      r2 = fi + dfi;
+   }
+
+   // S�rg for at alle vinkler ligger i omr�det 0 - 2*PI
+   while (fi < 0.0){                       // fi
+      fi +=  (2.0*PI);
+   }
+   while (fi > (2.0*PI)){
+      fi -=  (2.0*PI);
+   }
+   while (r2 < 0.0){                       // r2
+      r2 +=  (2.0*PI);
+   }
+   while (r2 > (2.0*PI)){
+      r2 -=  (2.0*PI);
+   }
+
+   // Beregner omskreven firkant for buen
+                                           // Start i 1. kvadrant
+   if (fi >= 0.0 && fi < PI/2.0){
+                                              // Slutt i 1. kvadrant
+      if (r2 >= 0.0 && r2 < PI/2.0){
+         *nva = min(a1,a2);
+         *nvn = min(n1,n2);
+         *oha = max(a1,a2);
+         *ohn = max(n1,n2);
+                           // Slutt i 2. kvadrant
+      } else if (r2 >= PI/2.0L && r2 < PI){
+         *nva = min(a1,a2);
+         *nvn = min(n1,n2);
+         *oha = max(a1,a2);
+         *ohn = ns + r;
+                           // Slutt i 3. kvadrant
+      } else if (r2 >=PI && r2 < PI*3.0L/2.0L){
+         *nva = as - r;
+         *nvn = min(n1,n2);
+         *oha = max(a1,a2);
+         *ohn = ns + r;
+                           // Slutt i 4. kvadrant
+      } else{
+         *nva = as - r;
+         *nvn = ns - r;
+         *oha = max(a1,a2);
+         *ohn = ns + r;
+      }
+
+                           // Start i 2. kvadrant
+   } else if (fi >= PI/2.0L && fi < PI){
+                           // Slutt i 1. kvadrant
+      if (r2 >= 0.0 && r2 < PI/2.0){
+         *nva = as - r;
+         *nvn = ns - r;
+         *oha = as + r;
+         *ohn = max(n1,n2);
+                           // Slutt i 2. kvadrant
+      } else if (r2 >= PI/2.0L && r2 < PI){
+         *nva = min(a1,a2);
+         *nvn = min(n1,n2);
+         *oha = max(a1,a2);
+         *ohn = max(n1,n2);
+                           // Slutt i 3. kvadrant 
+      } else if (r2 >=PI && r2 < PI*3.0L/2.0L){
+         *nva = as - r;
+         *nvn = min(n1,n2);
+         *oha = max(a1,a2);
+         *ohn = max(n1,n2);
+                           // Slutt i 4. kvadrant 
+      } else{
+         *nva = as - r;
+         *nvn = ns - r;
+         *oha = max(a1,a2);
+         *ohn = max(n1,n2);
+      }
+
+                           // Start i 3. kvadrant 
+   } else if (fi >=PI && fi < PI*3.0L/2.0L){
+                           // Slutt i 1. kvadrant 
+      if (r2 >= 0.0 && r2 < PI/2.0){
+         *nva = min(a1,a2);
+         *nvn = ns - r;
+         *oha = as + r;
+         *ohn = max(n1,n2);
+                           // Slutt i 2. kvadrant 
+      } else if (r2 >= PI/2.0L && r2 < PI){
+         *nva = min(a1,a2);
+         *nvn = ns - r;
+         *oha = as + r;
+         *ohn = ns + r;
+                           // Slutt i 3. kvadrant 
+      } else if (r2 >=PI && r2 < PI*3.0L/2.0L){
+         *nva = min(a1,a2);
+         *nvn = min(n1,n2);
+         *oha = max(a1,a2);
+         *ohn = max(n1,n2);
+      } else{
+                           // Slutt i 4. kvadrant 
+         *nva = min(a1,a2);
+         *nvn = ns - r;
+         *oha = max(a1,a2);
+         *ohn = max(n1,n2);
+      }
+
+                           // Start i 4. kvadrant 
+   } else {
+                           // Slutt i 1. kvadrant 
+      if (r2 >= 0.0 && r2 < PI/2.0) {
+         *nva = min(a1,a2);
+         *nvn = min(n1,n2);
+         *oha = as + r;
+         *ohn = max(n1,n2);
+                           // Slutt i 2. kvadrant 
+      } else if (r2 >= PI/2.0L && r2 < PI) {
+         *nva = min(a1,a2);
+         *nvn = min(n1,n2);
+         *oha = as + r;
+         *ohn = ns + r;
+
+                           // Slutt i 3. kvadrant 
+      } else if (r2 >=PI && r2 < PI*3.0L/2.0L) {
+         *nva = as - r;
+         *nvn = min(n1,n2);
+         *oha = as + r;
+         *ohn = ns + r;
+                           // Slutt i 4. kvadrant 
+      } else {
+         *nva = min(a1,a2);
+         *nvn = min(n1,n2);
+         *oha = max(a1,a2);
+         *ohn = max(n1,n2);
+      }
+   }
+}
+*/
+
+
+// ++----------------------------------------------------------------------
+// FILE: Arc.cpp - Implementation for class QdiArc
+// ++----------------------------------------------------------------------
+
+// For � finne minste omsluttende rektangel til en bue m� en f�rst finne sentrum
+//til buen. Koden for � gj�re dette fantes allerede i geometryutility.dll, men for � 
+//unng� gjensidige avhengigheter mellom modellen og geometryutility.dll, kopierte jeg
+//og skrev om koden her. 
+//
+//Etter at sentrum er funnet, finner jeg hvor mange akser som buen skj�rer. For hver akse
+//buen skj�rer, hentes en ekstremalverdi fra minste omsluttende rektangel til en 
+//SIRKEL som har sentrum samme sted som buen.
+//
+//Buen kan skj�re 0, en, to, tre eller fire akser.
+
+//
+//                 |
+//	                |
+//               --|-
+//             /   |  \
+//           1     |   \
+//   ----------2---|-------
+//                 |    |
+//                 |   3/
+//                 |
+//
+//
+//P� eksempelfiguren ovenfor skj�res 2 akser (y-aksen en gang og x-aksen en gang.
+//Her vil minste omsluttende rektangel hente LLX fra 1, LLY fra 3, URX fra sirkel
+//og URY fra sirkel. (Med sirkel menes sirkelens senter +/- radius eller minste omsluttende
+//rektangel til en sirkel med samme senter og radius)
+//
+
+/*
+void QdiArc::computeBbox( QdiRectangle *pRectangle ) 
+{
+//Regner f�rst ut senter av sirkelen
+	bool bMajor = isMajor();
+
+	QdiPosition *pStart= dynamic_cast <QdiPosition*> (getStartPosition()->clone());
+	QdiPosition *pEnd= dynamic_cast <QdiPosition*> (getEndPosition()->clone());
+	double dRadius= getRadius();
+	double dMin= 0.0009;
+	
+	QdiPosition2D center1, center2, trueCenter;
+	double dH = 0;
+	double dRadi1= dRadius;
+	double dRadi2= dRadius;
+	
+	double dX= pEnd->getX()- pStart->getX();
+	double dY= pEnd->getY()- pStart->getY();
+	double dDist= sqrt((dX*dX) + (dY*dY));
+	
+	double dInterX1= (((dRadi1*dRadi1) - (dRadi2*dRadi2))/(dDist*2)) + (dDist/2);
+	double dInterX1Abs= fabs(dInterX1);
+	
+	if ( fabs(dInterX1Abs-fabs(dRadi1)) < dMin )
+		dH= 0.0; // Only one intersection point.
+	else 
+		dH= sqrt( fabs((dRadi1*dRadi1)- (dInterX1*dInterX1)) );
+	
+	double dAspectX= dX/dDist;
+	double dAspectY= dY/dDist;
+	
+	center1.setX(pStart->getX() + (dAspectX*dInterX1) + (dAspectY*dH));
+	center1.setY(pStart->getY() + (dAspectY*dInterX1) - (dAspectX*dH));
+	center2.setX(pStart->getX() + (dAspectX*dInterX1) - (dAspectY*dH));
+	center2.setY(pStart->getY() + (dAspectY*dInterX1) + (dAspectX*dH));
+	
+	
+	if (!bMajor) 
+	{
+		if ( dRadi1>= 0 ) 
+		{
+			trueCenter.setX(center1.getX());
+			trueCenter.setY(center1.getY());
+		}
+		else if ( dRadi1< 0) 
+		{
+			trueCenter.setX(center2.getX());
+			trueCenter.setY(center2.getY());
+		}
+	}
+	// Use the "big/major arc" center
+	else 
+	{
+		if ( dRadi1< 0 ) 
+		{
+			trueCenter.setX(center1.getX());
+			trueCenter.setY(center1.getY());
+		}
+		else if ( dRadi1>= 0) 
+		{
+			trueCenter.setX(center2.getX());
+			trueCenter.setY(center2.getY());
+		}
+	}
+// Regner ut hvor mange akser som krysses
+
+//	1 startPos
+//	2 trueCenter	
+//  3 endPos
+	
+	int nStartQuadrant = 0;
+	int nEndQuadrant = 0;
+
+	double dMostLeft;
+	double dMostRight;
+	double dHighest;
+	double dLowest;
+
+//	Finner ekstremalverdiene.
+
+	dMostLeft = pStart->getX();
+	if (dMostLeft > pEnd->getX())
+	{
+		dMostLeft = pEnd->getX();
+	}
+
+	dMostRight = pStart->getX();
+	if (dMostRight < pEnd->getX())
+	{
+		dMostRight = pEnd->getX();
+	}
+
+	dHighest = pStart->getY();
+	if (dHighest < pEnd->getY())
+	{
+		dHighest = pEnd->getY();
+	}
+
+	dLowest = pStart->getY();
+	if (dLowest > pEnd->getY())
+	{
+		dLowest = pEnd->getY();
+	}
+
+// Om radius er negativ, byttes start og sluttpunkt
+
+	if (dRadius < 0)
+	{
+		QdiPosition2D midlPos;
+		midlPos.setX(pStart->getX());
+		midlPos.setY(pStart->getY());
+
+		pStart->setX(pEnd->getX());
+		pStart->setY(pEnd->getY());
+
+		pEnd->setX(midlPos.getX());
+		pEnd->setY(midlPos.getY());
+	}
+
+
+
+// Finner hvor mange akser som krysses og hvilke kvadranter punktene ligger i
+
+	if (pStart->getX() > trueCenter.getX())
+	{
+		if (pStart->getY() > trueCenter.getY())
+		{
+			// Kvadrant 4
+			nStartQuadrant = 4;
+		}
+		else
+		{
+			// Kvadrant 1
+			nStartQuadrant = 1;
+		}
+	}
+	else
+	{
+		if (pStart->getY() > trueCenter.getY())
+		{
+			// Kvadrant 3
+			nStartQuadrant = 3;
+		}
+		else
+		{
+			// Kvadrant 2
+			nStartQuadrant = 2;
+		}
+	}
+
+
+	if (pEnd->getX() > trueCenter.getX())
+	{
+		if (pEnd->getY() > trueCenter.getY())
+		{
+			// Kvadrant 4
+			nEndQuadrant = 4;
+		}
+		else
+		{
+			// Kvadrant 1
+			nEndQuadrant = 1;
+		}
+	}
+	else
+	{
+		if (pEnd->getY() > trueCenter.getY())
+		{
+			// Kvadrant 3
+			nEndQuadrant = 3;
+		}
+		else
+		{
+			// Kvadrant 2
+			nEndQuadrant = 2;
+		}
+	}
+
+	int nQuadrants = 0;
+
+
+	if (nStartQuadrant > nEndQuadrant)
+	{
+		nQuadrants = 4 + (nEndQuadrant - nStartQuadrant);
+	}
+	else
+	{
+		nQuadrants = nEndQuadrant - nStartQuadrant;
+	}
+	
+
+	if (bMajor)
+	{
+		// Hvis bMajor er sant, s� g�r buen over 4 kvadranter om start og endepunkt er
+		// i samme kvadrant.
+		if (nQuadrants == 0)
+		{
+			nQuadrants = 4;
+		}
+	}
+
+	// Lager f�rst en bounding box av en sirkel.
+
+	QdiPosition2D* llPos = new QdiPosition2D;
+	QdiPosition2D* urPos = new QdiPosition2D;
+
+	llPos->setX(trueCenter.getX() - abs(dRadius));
+	llPos->setY(trueCenter.getY() - abs(dRadius));
+
+	urPos->setX(trueCenter.getX() + abs(dRadius));
+	urPos->setY(trueCenter.getY() + abs(dRadius));
+
+	if (nQuadrants == 4)
+	{
+
+	}
+	else if (nQuadrants == 3)
+	{
+		if (nStartQuadrant == 1)
+		{
+			urPos->setX(dMostRight);
+		}
+		else if (nStartQuadrant == 2)
+		{
+			llPos->setY(dLowest);
+		}
+		else if (nStartQuadrant == 3)
+		{
+			llPos->setX(dMostLeft);
+		}
+		else if (nStartQuadrant == 4)
+		{
+			urPos->setY(dHighest);
+		}
+	}
+	else if (nQuadrants == 2)
+	{
+		if (nStartQuadrant == 1)
+		{
+			urPos->setX(dMostRight);
+			urPos->setY(dHighest);
+		}
+		else if (nStartQuadrant == 2)
+		{
+			llPos->setY(dLowest);
+			urPos->setX(dMostRight);
+		}
+		else if (nStartQuadrant == 3)
+		{
+			llPos->setX(dMostLeft);
+			llPos->setY(dLowest);
+		}
+		else if (nStartQuadrant == 4)
+		{
+			llPos->setX(dMostLeft);
+			urPos->setY(dHighest);
+		}
+	}
+	else if (nQuadrants == 1)
+	{
+		if (nStartQuadrant == 1)
+		{
+			urPos->setX(dMostRight);
+			urPos->setY(dHighest);
+			llPos->setX(dMostLeft);
+		}
+		else if (nStartQuadrant == 2)
+		{
+			llPos->setY(dLowest);
+			urPos->setX(dMostRight);
+			urPos->setY(dHighest);
+		}
+		else if (nStartQuadrant == 3)
+		{
+			llPos->setX(dMostLeft);
+			llPos->setY(dLowest);
+			urPos->setX(dMostRight);
+		}
+		else if (nStartQuadrant == 4)
+		{
+			llPos->setX(dMostLeft);
+			urPos->setY(dHighest);
+			llPos->setY(dLowest);
+		}
+	}
+	else if (nQuadrants == 0)
+	{
+		urPos->setX(dMostRight);
+		urPos->setY(dHighest);
+		llPos->setX(dMostLeft);
+		llPos->setY(dLowest);
+	}
+
+	//pRectangle->setLowerLeft(llPos);
+	pRectangle->expand( llPos );
+	//pRectangle->setUpperRight(urPos);
+	pRectangle->expand( urPos );
+	
+	delete pStart;
+	delete pEnd;
+
+	return;
+}
+
+// Get implicitly defined startPosition
+//const QdiPosition* QdiArc::getStartPosition() const { return NULL; } // Dummy
+
+// Get implicitly defined endPosition
+//const QdiPosition* QdiArc::getEndPosition() const { return NULL; } // Dummy
+
+// -------------------------- End of file ---------------------------------
+
+*/
+
+
+
+
+
+
+
+/*
+AR-890903
+CH GM_NormVindu                                   Normaliser vindusangivelse
+CD ==========================================================================
+CD Form�l:
+CD Bytter om koordinatene slik at vindusangivelsen blir riktig.
+CD Sjekker ogs� at vinduet har lengde > 0.0001 i b�de �st og nord retning.
+CD
+CD Parametre:
+CD Type     Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double  *nva        iu   Avgrensing av vinduet
+CD double  *nvn        iu
+CD double  *oha        iu
+CD double  *ohn        iu
+CD short    ist        r    status: 1 = Vinduet er OK
+CD                                  0 = Vinduet er feil definert.
+CD                                      (Lengde 0.0 i en retning.)
+CD
+CD Bruk:
+CD ist = GM_NormVindu(&nva,&nvn,&oha,&ohn);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_NormVindu(double *nva,double *nvn,double *oha,double *ohn)
+{
+   double temp;
+
+   if (*nva > *oha){         /* Eventuell ombytting av hj�rnekoordinater */
+       temp = *nva;
+       *nva = *oha;
+       *oha = temp;
+   }
+   if (*nvn > *ohn){
+       temp = *nvn;
+       *nvn = *ohn;
+       *ohn = temp;
+   }
+                  /* Sjekk at lengden av vinduet er > 0.0 i begge retninger */
+   return (short)((*oha-*nva) > ACCY   &&  (*ohn - *nvn) > ACCY);
+}
+
+
+/*
+AR-890903
+CH GM_TestPktBue                  Sjekk om punkt ligger i sektor gitt av bue 
+CD ==========================================================================
+CD Form�l:
+CD Sjekk om punkt ligger i sektor gitt av bue. 
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   as       i    Koordinat i sirkelsenter
+CD double   ns       i
+CD double   fi       i    "Retning" sentrum - buens startpunkt.
+CD double   dfi      i    Vinkel mellom fi og retning buens sluttpunkt
+CD double   a        i    Koordinat som skal testes
+CD double   n        i
+CD short    ok       r    1=ligger i buens sektor, 0=ikke i buens sektor
+CD
+CD Bruk:
+CD ok = GM_TestPktBue(as,ns,fi,dfi,a,n);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_TestPktBue(double as,double ns,double fi,double dfi,
+                              double a,double n)
+{
+   double fi1,d;
+   short ok = 1;
+
+   // Sjekk om punktene ligger p� buen
+   fi1 = GM_retning(as,ns,a,n);
+   d = fi1 - fi;
+   if (dfi < 0.0){
+      if (d > 0.0)  d -= (PI * 2.0);
+      //if (d < dfi)  ok = 0;            /* Utenfor buen */
+      if ((d+GM_ACCY) < dfi)  ok = 0;            /* Utenfor buen */
+
+   } else{
+      if (d < 0.0)  d += (PI * 2.0);
+      //if (d > dfi)  ok = 0;            /* Utenfor buen */
+      if ((d-GM_ACCY) > dfi)  ok = 0;            /* Utenfor buen */
+   }
+
+   return ok;
+}
+
+
+/*
+AR-890903
+CH GM_PktBue                  Beregner vinkel til punkt i sektor gitt av bue 
+CD ==========================================================================
+CD Form�l:
+CD Beregner vinkel til punkt som ligger i sektor gitt av bue. 
+CD
+CD Parametre:
+CD Type     Navn    I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD double   as       i    Koordinat i sirkelsenter
+CD double   ns       i
+CD double   fi       i    "Retning" sentrum - buens startpunkt.
+CD double   dfi      i    Vinkel mellom fi og retning buens sluttpunkt
+CD double   a        i    Punkt som skal testes
+CD double   n        i
+CD double  *dfiPkt   u    Vinkel mellom fi og retning til testpunktet
+CD short    ok       r    1=ligger i buens sektor, 0=ikke i buens sektor
+CD
+CD Bruk:
+CD ok = GM_PktBue(as,ns,fi,dfi,a,n,&dfiPkt);
+   ==========================================================================
+*/
+SK_EntPnt_GM short GM_PktBue(double as,double ns,double fi,double dfi,
+                              double a,double n,double *dfiPkt)
+{
+   double fi1;
+   short ok = 1;
+
+//UT_FPRINTF(stderr,"\r\n I GM_PktBue: ns=%.12g, as=%.12g, fi=%.12g, dfi=%.12g",ns,as,fi,dfi);
+//UT_FPRINTF(stderr,"\n I GM_PktBue: n=%.12g, a=%.12g",n,a);
+
+
+   // Sjekk om punktene ligger p� buen
+   fi1 = GM_retning(as,ns,a,n);
+
+//UT_FPRINTF(stderr,"\n I GM_PktBue: fi1=%.12g",fi1);
+
+   *dfiPkt = fi1 - fi;
+
+   // Spesialtilfelle for � handtere problemer n�r vinkelen blir tiln�rmet 0.0
+   if (fabs(*dfiPkt) < GM_ACCY)
+   {
+      *dfiPkt = 0.0;
+      return 1;  // ==> 
+   }
+
+   if (dfi < 0.0){
+      if (*dfiPkt > 0.0)  *dfiPkt -= (PI * 2.0);
+      if ((*dfiPkt+GM_ACCY) < dfi)  ok = 0;            /* Utenfor buen */
+   }
+   else
+   {
+      if (*dfiPkt < 0.0)  *dfiPkt += (PI * 2.0);
+      if ((*dfiPkt-GM_ACCY) > dfi)  ok = 0;            /* Utenfor buen */
+   }
+
+   return ok;
+}
+
+
+/*
+JEK-920520
+CH GM_Avstand            Beregner avstand mellom to punkt
+CD ==================================================================
+CD Form�l:
+CD Beregner avstand mellom to punkt.
+CD
+CD PARAMETERLISTE:
+CD Navn      Type  Array i/U Merknad
+CD ------------------------------------------------------------------
+CD a1        double       i   �st-koordinat for startpunkt
+CD n1        double       i   Nord-koordinat for startpunkt
+CD a2        double       i   �st-koordinat for endepunkt
+CD n2        double       i   Nord-koordinat for endepunkt
+CD avstand   double       r   Avstand mellom punktene
+CD
+CD Bruk:  avstand = GM_Avstand ( a1, n1, a2, n2 );
+   ==================================================================
+*/
+SK_EntPnt_GM double GM_Avstand(double a1, double n1, double a2, double n2 )
+{
+      double a,n;
+
+      a = a2 - a1;
+      n = n2 - n1;
+      return  sqrt( a*a + n*n );
+}
+
+
+/*
+TOU/AR-080521
+CH GM_Avstand            Beregner kvadrert avstand mellom to punkt
+CD ==================================================================
+CD Form�l:
+CD Beregner kvadrert avstand mellom to punkt.
+CD
+CD PARAMETERLISTE:
+CD Navn      Type  Array i/U Merknad
+CD ------------------------------------------------------------------
+CD a1        double       i   �st-koordinat for startpunkt
+CD n1        double       i   Nord-koordinat for startpunkt
+CD a2        double       i   �st-koordinat for endepunkt
+CD n2        double       i   Nord-koordinat for endepunkt
+CD avstand2   double      r   Kvadrert avstand mellom punktene
+CD
+CD Bruk:  avstand2 = GM_Avstand2 ( a1, n1, a2, n2 );
+==================================================================
+*/
+SK_EntPnt_GM double GM_Avstand2(double a1, double n1, double a2, double n2 )
+{
+   double a,n;
+
+   a = a2 - a1;
+   n = n2 - n1;
+   return ( a*a + n*n );
+}
+
+
+/*
+JEK-920520
+CH GM_BueTangent       Retnv. for tangent til punkt p� bue
+CD ==================================================================
+CD Form�l:
+CD Beregner retningsvinkel til tangent til punkt p� en sirkelbue.
+CD
+CD PARAMETERLISTE:
+CD Navn     Type     I/U  Merknad
+CD -----------------------------------------------------------------
+CD as       double    i   �st-koordinat for sirkelsentrum
+CD an       double    i   Nord-koordinat for sirkelsentrum
+CD fi       double    i   Retningsvinkel til start bue
+CD dfi      double    i   Retn.endring i radianer.
+CD                          + = mot klokka, - =med klokka
+CD radius   double    i   radius med fortegn
+CD                          +  =  med klokka,  -  = mot klokka
+CD a        double    i   �st-koordinat for tangeringspunkt
+CD n        double    i   Nord-koordinat for tangeringspunkt
+CD *buetan  double    u   Retning i radianer(0-2PI) for buetangent
+CD ist      short     r   status:  1 = Beregning ok                 
+CD                                 0 = Punkt ikke p� buesegment     
+CD                                     NB! Tangent beregnes uansett!
+CD
+CD Bruk:  ist = GM_BueTangent(as,ns,fi,dfi,radius,a,s,&buetan);
+   ==================================================================
+*/
+SK_EntPnt_GM short GM_BueTangent ( double as, double ns, double fi, double dfi,
+                                double radius, double a, double n, double *buetan)
+{     
+      short ist;
+      
+      ist = 0;
+      if ( GM_TestPktBue ( as, ns, fi, dfi, a, n ) ) {
+         if ( (fabs(radius) - GM_Avstand (as,ns,a,n)) < 0.01 ) ist=1;
+      }
+
+      if ( dfi > 0.0 ){        /* Mot klokka */        
+         *buetan = GM_RedVinkel ( GM_retning(as,ns,a,n) + PI/2 );
+      } else {                 /* Med klokka */                         
+         *buetan = GM_RedVinkel ( GM_retning(as,ns,a,n) - PI/2 );
+      }
+      return ist;
+}
+
+
+/*
+LS-900607
+AR-921001
+CH GM_BueTilKorder                        Tiln�rm ein sirkelboge med korder
+CD =========================================================================
+CD Form�l:
+CD   Tiln�rm ein sirkelboge med korder.
+CD
+CD PARAMETERLISTE:
+CD Type    Navn   I/U  Merknad
+CD ------------------------------------------------------------------
+CD double  as      i  �st-koordinat for sirkelsentrum
+CD double  an      i  Nord-koordinat for sirkelsentrum
+CD double  r       i  Radius i sirkelen
+CD double  fi      i  Retningsvinkel til start bue
+CD double  dfi     i  Retn.endring i radianer.
+CD                      + = mot klokka, - =med klokka
+CD double  delta   i  Vinkeltoleranse (max vinkel mellom korder i radianer)
+CD short   mpu     i  Max tal p� punkt i a_arr og n_arr
+CD double *a_arr   u  Knekkpunkt f�r, mellom og etter kordene
+CD double *n_arr   u  
+CD short   npu     r  Tal p� punkt i a_arr og n_arr
+CD
+CD Bruk:
+CD npu = GM_BueTilKorder(as,ns,r,fi,dfi,delta,mpu,a_arr,n_arr);
+CD =========================================================================
+*/
+SK_EntPnt_GM short GM_BueTilKorder (double as,double ns,double r,double fi,double dfi,
+                                 double delta,short mpu,double *a_arr,double *n_arr)
+{
+   double intdel;
+   short nk,npu;
+
+   r = fabs(r);
+                              /* Bestem presisjon (tal p� korder) */
+   if (dfi < 0.0) delta = -delta;
+   modf (dfi/delta, &intdel);
+   nk = (short)(UT_RoundDS(intdel) + 1);
+   if (nk >= mpu) {            /* For mange korder - reduser kravet */
+      nk = (short)(mpu - 1);
+      delta = dfi/(double)nk;
+   }
+   npu = (short)(nk + 1);
+   
+   /* Startpunktet */
+    *a_arr = as + r*cos(fi);
+    *n_arr = ns + r*sin(fi);
+
+   /* Sluttpunkt */
+    *(a_arr+nk) = as + r*cos(fi+dfi);
+    *(n_arr+nk) = ns + r*sin(fi+dfi);
+
+                                /* Korde-l�kke */
+    for (nk--,a_arr++,n_arr++,fi+=delta; nk; nk--,a_arr++,n_arr++,fi+=delta) {
+      *a_arr = as + r*cos(fi);
+      *n_arr = ns + r*sin(fi);
+    }
+
+    return npu;
+}
+
+
+/*
+LS-900607
+AR-921001
+CH GM_PktTilOktagon                  Beregner en �ttekant rundt gitt punkt.
+CD =========================================================================
+CD Form�l:
+CD   Beregner en �ttekant med gitt areal rundt gitt punkt.
+CD
+CD PARAMETERLISTE:
+CD Type    Navn   I/U  Merknad
+CD ------------------------------------------------------------------
+CD double  dAs     i  �st-koordinat for sentrum
+CD double  dNns    i  Nord-koordinat for sentrum
+CD double  dAreal  i  �nsket areal
+CD double *a_arr   u  Hj�rnepunkt (M� ha plass til 8 punkt.)
+CD double *n_arr   u  
+CD
+CD Bruk:
+CD GM_PktTilOktagon(dAs,dNs,dAreal,a_arr,n_arr);
+CD =========================================================================
+*/
+SK_EntPnt_GM void GM_PktTilOktagon (double dAs,double dNs,double dAreal,double *a_arr,double *n_arr)
+{
+   double dS,dS2,dX;
+   double d2Rot = sqrt(2.0);
+
+   //            1            2
+   //            +------------+ - - - -   -
+   //          /                \      |
+   //        /                    \       dX
+   //      /                        \  |
+   //    /                            \   _
+   //  8+                              +3
+   //   |                              |
+   //   |                              |
+   //   |               +              |  dS
+   //   |                s             |
+   //   |                              |
+   //  7+                              +4 _
+   //    \                            /
+   //      \                        / 
+   //        \                    /  
+   //          \                /   
+   //            +------------+
+   //            6            5
+
+   // Beregner sidelengde mm.
+   dS = sqrt( dAreal / ( (2.0 * d2Rot) + 2.0));
+   dS2 = dS / 2.0;
+   dX = dS2 * d2Rot;
+
+   // Beregner koordineter
+   // 1
+   *a_arr++ = dAs - dS2;
+   *n_arr++ = dNs + dS2 + dX;
+   // 2
+   *a_arr++ = dAs + dS2;
+   *n_arr++ = dNs + dS2 + dX;
+   // 3
+   *a_arr++ = dAs + dS2 + dX;
+   *n_arr++ = dNs + dS2;
+   // 4
+   *a_arr++ = dAs + dS2 + dX;
+   *n_arr++ = dNs - dS2;
+   // 5
+   *a_arr++ = dAs + dS2;
+   *n_arr++ = dNs - dS2 - dX;
+   // 6
+   *a_arr++ = dAs - dS2;
+   *n_arr++ = dNs - dS2 - dX;
+   // 7
+   *a_arr++ = dAs - dS2 - dX;
+   *n_arr++ = dNs - dS2;
+   // 8
+   *a_arr = dAs - dS2 - dX;
+   *n_arr = dNs + dS2;
+}
+
+
+/*
+AR:2008-08-12
+CH GM_TynnDared
+CD ==========================================================================
+CD Form�l:
+CD Tynning med pilh�yde og maks avstand.
+CD Samme som SiTynnDared, men noe forenklet:
+CD - Koordinatene kommer inn i N� buffer.
+CD - Handterer ikke h�yde
+CD - Tar ikke hensyn til knutepunkt
+CD
+CD Parametre:
+CD Type     Navn        I/U  Forklaring
+CD --------------------------------------------------------------------------
+CD double   dMaxAvst     i   Max distanse mellom punkta
+CD double   dMaxPil      i   Max pilh�yde
+CD long    *nko         iu   Antall koordinater
+CD double  *pA          iu   �st-koordinater
+CD double  *pN          iu   Nord-koordinater
+CD bool     bBeregnet    r   Status.
+CD Bruk:
+CD bBeregnet = GM_TynnDared(dMaxAvst,dPilhoyde,&nko,pA,pN);
+==========================================================================
+*/
+SK_EntPnt_GM void GM_TynnDared(double dMaxAvst,double dMaxPil,long *nko, double *pA,double *pN)
+{
+   long lTeller,lStorPnr=0;
+   bool bNyttFastpunktFunnet;
+   double a,n,a1,n1,a2,n2,ap,np,da,dn,dAvst2;
+   double pa,pb,pc;
+   double dPil,dStorPil;
+   long lLagre  = 2;  // Peker for lagring av punkt (f�rste ledig)
+   long lForste = 1;  // Starten av aktuelt segment
+   long lSiste;       // Siste punkt i segmentet
+   double dMaxAvst2 = dMaxAvst * dMaxAvst;
+   double dPil2 = dMaxPil * dMaxPil;
+   bool bBeregnet = true;
+
+
+   // Ta kopi av opprinnelige koordinater
+   double *pdAust = (double*) malloc((sizeof(double))*(*nko));
+   UT_memcpy(pdAust, (sizeof(double))*(*nko), pA, (sizeof(double))*(*nko));
+
+   double *pdNord = (double*) malloc((sizeof(double))*(*nko));      
+   UT_memcpy(pdNord, (sizeof(double))*(*nko), pN, (sizeof(double))*(*nko));
+
+   // UT_FPRINTF(stderr,"\n\nTynner: %s",LC_GetGi(1));
+
+   while (lForste < *nko)
+   {
+      // Sjekk ett segment. Segmentet avsluttes n�r:
+      // - pilh�yden overskrider gitt verdi
+      //   (Det punktet som hadde st�rst pilh�yde blir neste fastpunkt)
+      // - lengden overskrider gitt verdi
+
+      //LC_GetTK(lForste,&a1,&n1);
+      a1 = *(pA+lForste-1);
+      n1 = *(pN+lForste-1);
+      // UT_FPRINTF(stderr,"\n%hd  a: %.1f n: %.1f",lForste,a1,n1);
+
+      bNyttFastpunktFunnet = false;
+      for (lSiste=lForste+1; !bNyttFastpunktFunnet && lSiste<=*nko; lSiste++)
+      {
+         // UT_FPRINTF(stderr,"\n\nSegment %hd - %hd",lForste,siste);
+
+         //LC_GetTK(lSiste,&a2,&n2);
+         a2 = *(pA+lSiste-1);
+         n2 = *(pN+lSiste-1);
+         // UT_FPRINTF(stderr,"\n%hd  a: %.1f n: %.1f",lSiste,a2,n2);
+
+         // Beregn st�rste pilh�yde
+         dStorPil = 0.0;
+         for (lTeller=lForste+1; lTeller<lSiste; lTeller++)
+         {
+            //LC_GetTK(lTeller,&ap,&np);
+            ap = *(pA+lTeller-1);
+            np = *(pN+lTeller-1);
+            dPil = 0.0;
+            // UT_FPRINTF(stderr,"\n%hd  a: %.1f n: %.1f h: %.1f",s,ap,np,hp);
+
+            if (GM_bepa(a1,n1,a2,n2,&pa,&pb,&pc))
+            {
+               // UT_FPRINTF(stderr,"\n%hd  pa: %.5f pb: %.5f pc: %.5f",s,pa,pb,pc);
+               dPil = fabs(pa*ap + pb*np + pc);
+               // UT_FPRINTF(stderr,"\n%hd  2D ph: %.4f",s,dPil);
+            }
+
+            // Husker st�rste pilh�yde
+            if (dPil > dStorPil) {
+               lStorPnr = lTeller;
+               dStorPil = dPil;
+            }
+         }
+
+         // Max pilh�yde er overskredet, nytt fastpunkt er funnet
+
+         // UT_FPRINTF(stderr,"\nMax pilh�yde %hd  : %.4f",sStorPnr,dStorPil);
+
+         if (dStorPil > dMaxPil)
+         {
+            //LC_GetTK(lStorPnr,&ap,&np);
+            ap = *(pA+lStorPnr-1);
+            np = *(pN+lStorPnr-1);
+            //LC_PutTK(lLagre,ap,np);
+            *(pA+lLagre-1) = ap;
+            *(pN+lLagre-1) = np;
+            // UT_FPRINTF(stderr,"\nLagres som punkt nr %hd",lagre);
+
+            lLagre++;
+            lForste = lStorPnr; 
+            bNyttFastpunktFunnet = true;
+         }
+
+         // Sjekk om max avstand er overskredet
+         if ( ! bNyttFastpunktFunnet)
+         {
+            da = a2 - a1;
+            dn = n2 - n1;
+            dAvst2 = da*da + dn*dn;
+            // UT_FPRINTF(stderr,"\nAvst %hd %hd : %.4f",forste,siste,sqrt(dAvst2));
+
+            if (dAvst2 > dMaxAvst2)
+            {
+               if (lSiste == lForste+1)
+               {
+                  //LC_PutTK(lLagre,a2,n2);
+                  *(pA+lLagre-1) = a2;
+                  *(pN+lLagre-1) = n2;
+
+                  // UT_FPRINTF(stderr,"\nMax avst. overskredet, lagres som punkt nr %hd",lagre);
+
+                  lLagre++;
+                  lForste = lSiste;
+                  bNyttFastpunktFunnet = true;
+               }
+
+               else
+               {
+                  //LC_GetTK(lSiste-1,&ap,&np);
+                  ap = *(pA+lSiste-1-1);
+                  np = *(pN+lSiste-1-1);
+                  //LC_PutTK(lLagre,ap,np);
+                  *(pA+lLagre-1) = ap;
+                  *(pN+lLagre-1) = np;
+
+                  // UT_FPRINTF(stderr,"\nMax avst. overskredet, lagres som punkt nr %hd",lagre);
+
+                  lLagre++;
+                  lForste = lSiste-1;
+                  bNyttFastpunktFunnet = true;
+               }
+            }
+
+            // Siste punkt i gruppen er alltid fastpunkt
+            if (lSiste == *nko)
+            {
+               // Sjekk at koordinatene er forskjellige fra forrige punkt
+               if (lLagre > 1) 
+               {
+                  //LC_GetTK((short)(lLagre-1),&a,&n);
+                  a = *(pA+lLagre-1-1);
+                  n = *(pN+lLagre-1-1);
+
+                  if (fabs(a2-a) < ACCY  &&  fabs(n2-n) < ACCY) 
+                  {
+                     // Samme koordinater som forrige punkt, kutt ut dette
+                     lLagre--;
+                  }
+               }
+
+               //LC_PutTK(lLagre,a2,n2);
+               *(pA+lLagre-1) = a2;
+               *(pN+lLagre-1) = n2;
+               // UT_FPRINTF(stderr,"\nSiste pkt., lagres som punkt nr %hd",lagre);
+
+               lLagre++;
+               lForste = lSiste;
+               bNyttFastpunktFunnet = true;
+            }
+         }
+      }
+   }
+
+   // ----- Sjekk at gruppen ikke har klappet sammen til en kort liten strek
+
+   if (lLagre <= 3)
+   {
+      // Har 2 koordinater etter tynning,
+      // legg tilbake opprinnelige koordinater
+      bBeregnet = false;
+      UT_memcpy(pA, (sizeof(double))*(*nko), pdAust, (sizeof(double))*(*nko));
+      UT_memcpy(pN, (sizeof(double))*(*nko), pdNord, (sizeof(double))*(*nko));
+   }
+
+   else if (lLagre == 4)
+   {  
+      // Har 3 koordinater etter tynning, og
+      // avstand fra f�rste til siste punkt er mindre enn pilh�yden
+      da = (*(pA+lLagre-2)) - (*(pA));
+      dn = (*(pN+lLagre-2)) - (*(pN));
+
+      if ((da*da + dn*dn) < dPil2)
+      {
+         // Gruppen har blitt feil, legg tilbake opprinnelige koordinater
+         bBeregnet = false;
+         UT_memcpy(pA, (sizeof(double))*(*nko), pdAust, (sizeof(double))*(*nko));
+         UT_memcpy(pN, (sizeof(double))*(*nko), pdNord, (sizeof(double))*(*nko));
+      }
+   }
+
+   free(pdAust);
+   free(pdNord);
+
+   // Legg ut antall koordinater i resultatet
+   if (bBeregnet)  *nko = lLagre-1;
+}
+
+
+/*
+CH GM_BeregnHjelpepunkt
+CD ==============================================================
+CD Form�l: 
+CD Beskriv funksjonaliteten her ...
+CD
+CD
+CD
+CD                        *3             *2
+CD                       /             /
+CD                           n1*     /
+CD                     /           /
+CD                               /
+CD                   /    n2*  /
+CD                           /   
+CD                 /   n3* /    
+CD                       /
+CD               /     /
+CD                   /       
+CD             /   /
+CD               /
+CD           / /  
+CD           *1    
+CD
+CD Parameterliste:
+CD Type    Navn         I/U   Merknad
+CD -------------------------------------------------------------
+CD double  dA1           i    Koordinater punkt 1
+CD double  dN1           i
+CD double  dA2           i    Koordinater punkt 2
+CD double  dN2           i
+CD double  dA3           i    Koordinater punkt 3
+CD double  dN3           i
+CD double  dEnhet        i    Enhet som styrer avrunding og beregning
+CD short   sMaxAntPkt    i    Max antall punkt i pdAustArr og pdNordArr
+CD double *pdAustArr     u    Peker til array som mottar beregnede koordinater(  n1 -nx
+CD double *pdNordArr     u    Peker til array som mottar beregnede koordinater
+CD short   sAntPkt       u    Antall punkt beregnet
+CD bool    bBeregnet     r    Status: true = beregnet OK
+CD                                    false = ikke beregnet. (ikke nok plass i resultat-array, og andre feil?)
+CD
+CD  Bruk:
+CD  bStatus = GM_BeregnHjelpepunkt(dA1,dN1,dA2,dN2,dA3,dN3,dEnhet,sMaxAntPkt,&dAustArr,&pdNordArr,&sAntPkt);
+CD  ==============================================================
+*/
+
+/*
+bool GM_BeregnHjelpepunkt(double dA1,double dN1,double dA2,double dN2,double dA3,double dN3,double dEnhet,
+                          short sMaxAntPkt,double *pdAustArr,double *pdNordArr,short *psAntPkt)
+{
+   // Beskriv algoritme som brukes her ...
+   // (Eventuelt med henvisning til bok med detaljbeskrivelse)
+
+
+   bool bStatus = true;
+
+   // Legg inn funksjonaliteten her ...
+
+   return bStatus;
+}
+*/
+
diff --git a/GM/LICENSE b/GM/LICENSE
new file mode 100644
index 0000000..642f5d5
--- /dev/null
+++ b/GM/LICENSE
@@ -0,0 +1,24 @@
+/******************************************************************************
+* STATENS KARTVERK  -  FYSAK
+*
+* Copyright (c) 1990-2011 Statens kartverk
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+* DEALINGS IN THE SOFTWARE.
+******************************************************************************/
+
diff --git a/GM/fygm.h b/GM/fygm.h
new file mode 100644
index 0000000..b60a422
--- /dev/null
+++ b/GM/fygm.h
@@ -0,0 +1,129 @@
+/******************************************************************************
+*
+* STATENS KARTVERK  -  FYSAK
+*
+* Filename: fygm.h
+* 
+* Content: Prototyper for generelle geometrirutiner.
+*
+* Copyright (c) 1990-2011 Statens kartverk
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+* DEALINGS IN THE SOFTWARE.
+******************************************************************************/
+
+#pragma once
+
+#ifdef WIN32
+#ifdef _DEBUG
+ #pragma comment (lib, "GmD.lib")
+#else
+ #pragma comment (lib, "Gm.lib")
+#endif
+#endif
+
+#ifndef SK_EntPnt_GM
+#  define SK_EntPnt_GM
+#endif
+
+
+/* --- Konstanter -- */
+//#define PI  3.14159265358979324
+#define PI  3.14159265358979323846
+#define PIHALV (PI/2.0)
+#define TOPI   (PI*2.0)
+
+/* --- Makroer -- */
+#define Rad2Deg(Rad) ((Rad/PI)*180)
+#define Rad2Gon(Rad) ((Rad/PI)*200)
+
+#define Deg2Rad(Deg) ((Deg/180)*PI)
+#define Gon2Rad(Gon) ((Gon/200)*PI)
+
+
+/* ---- Funksjonsdefinisjoner for fygm.c -- */
+SK_EntPnt_GM short GM_sver(double ka,double kn,double la,double ln,double na,double nn,
+                        double ma,double mn,double *sa,double *sn);
+SK_EntPnt_GM short GM_shor(double ka,double kn,double la,double ln,double na,double nn,
+                        double ma,double mn,double *sa,double *sn);
+SK_EntPnt_GM short GM_sLinLin(double ka,double kn,double la,double ln,double ma,double mn,
+                           double na,double nn,double *sa,double *sn);
+SK_EntPnt_GM short GM_Overlapp(double ka,double kn,double la,double ln,double ma,double mn,double na,double nn);
+SK_EntPnt_GM short GM_sVektVekt(double ka,double kn,double la,double ln,double ma,double mn,
+                             double na,double nn,double *sa,double *sn);
+SK_EntPnt_GM short GM_sLinBue(double sa,double sn,double radius,double fi,double dfi,
+                           double ka,double kn,double la,double ln,
+                           double *a1,double *n1,double *a2,double *n2);
+SK_EntPnt_GM short GM_sVektSirk(double sa,double sn,double radius,
+                             double ka,double kn,double la,double ln,
+                             double *a1,double *n1,double *a2,double *n2);
+SK_EntPnt_GM short GM_sBueBue(double as1,double ns1,double radius1,double fi1,double dfi1,
+                           double as2,double ns2,double radius2,double fi2,double dfi2,
+                           double *a1,double *n1,double *a2,double *n2);
+SK_EntPnt_GM short GM_sSirkSirk(double as1,double ns1,double radius1,
+                             double as2,double ns2,double radius2,
+                             double *a1,double *n1,double *a2,double *n2);
+SK_EntPnt_GM short GM_fotp(double a1,double n1,double a2,double n2,double ap,double np,
+                        double *af,double *nf);
+SK_EntPnt_GM short GM_fotp_ny(double a1, double n1, double a2, double n2, double ap, double np,
+								double *af, double *nf);
+SK_EntPnt_GM short GM_KonvBue(double a1,double n1,double a2,double n2,double radius,
+                           short storbue,double *as,double *ns,double *fi,double *dfi);
+SK_EntPnt_GM short GM_KonvBuep(double a1,double n1,double a2,double n2,double a3,double n3,
+                            double *as,double *ns,double *radius,double *fi,double *dfi);
+SK_EntPnt_GM short GM_KonvSirkel(double *fi,double *dfi);
+SK_EntPnt_GM short GM_KonvSirkelp(double a1,double n1,double a2,double n2,double a3,double n3,
+                               double *as,double *ns,double *radius,double *fi,double *dfi);
+SK_EntPnt_GM short GM_bepa(double a1,double n1,double a2,double n2,
+                        double *pa,double *pb,double *pc);
+SK_EntPnt_GM short GM_bepa3(double a1, double n1, double h1,
+                         double a2, double n2, double h2,
+                         double *pf, double *pg, double *ph);
+SK_EntPnt_GM short GM_cint(double pa1,double pb1,double pc1,double pa2,double pb2,
+                        double pc2,double *as,double *ns);
+SK_EntPnt_GM short GM_wtst(double p1a,double p1n,double p2a,double p2n,
+                        double wmina,double wminn,double wmaxa,double wmaxn);
+SK_EntPnt_GM short GM_wtstBue(double as,double ns,double radius,double fi,double dfi, 
+                           double wmina,double wminn,double wmaxa,double wmaxn);
+SK_EntPnt_GM short GM_wtstPunkt(double PktA, double PktN, double wa1, double wn1, double wa2, double wn2, double wa3, double wn3,
+                               double wa4, double wn4);
+SK_EntPnt_GM short GM_Parallell(double ka,double kn,double la,double ln,double avstand,
+                               double *ka1,double *kn1,double *la1,double *ln1);
+SK_EntPnt_GM double GM_Avstand(double as, double ns, double a, double n);
+SK_EntPnt_GM double GM_Avstand2(double a1, double n1, double a2, double n2);
+SK_EntPnt_GM double GM_Areal(double *pA, double *pN, short sNko);
+SK_EntPnt_GM double GM_retning(double ak,double nk,double al,double nl);
+SK_EntPnt_GM double GM_RetnGon(double a1, double n1, double a2, double n2);
+SK_EntPnt_GM double GM_Vinkel(double fi1, double fi2 );
+SK_EntPnt_GM double GM_RedVinkel(double fi );
+SK_EntPnt_GM void   GM_RettvPol(double a1 , double n1, double a2, double n2,
+                             double *gon, double *avst);
+SK_EntPnt_GM void  GM_PolRettv(double *a , double *n, double gon, double avst);
+SK_EntPnt_GM void  GM_buebox(double as,double ns,double radius,double fi,double dfi,
+                          double *nva,double *nvn,double *oha,double *ohn);
+SK_EntPnt_GM short GM_NormVindu(double *nva,double *nvn,double *oha,double *ohn);
+SK_EntPnt_GM short GM_PktBue(double as,double ns,double fi,double dfi,
+                             double a,double n,double *dfiPkt);
+SK_EntPnt_GM short GM_TestPktBue(double as,double ns,double fi,double dfi,
+                              double a,double n);
+SK_EntPnt_GM short  GM_BueTangent(double as, double ns, double fi, double dfi,
+                               double radius, double a, double n, double *buetan);
+SK_EntPnt_GM short GM_BueTilKorder (double as,double ns,double r,double fi,double dfi,
+                                 double delta,short mpu,double *a_arr,double *n_arr);
+SK_EntPnt_GM void GM_PktTilOktagon (double dAs,double dNs,double dAreal,double *a_arr,double *n_arr);
+SK_EntPnt_GM void GM_TynnDared(double dMaxAvst,double dMaxPil,long *nko, double *pA,double *pN);
diff --git a/GM/make.sh b/GM/make.sh
new file mode 100755
index 0000000..aee3aea
--- /dev/null
+++ b/GM/make.sh
@@ -0,0 +1,4 @@
+gcc -Wall -g -D_FILE_OFFSET_BITS=64 -DUNIX -DLINUX -fPIC -Wno-write-strings -c -I. -I../include *.cpp
+ar rcs libfygm.a *.o
+gcc -g -D_FILE_OFFSET_BITS=64 -DUNIX -DLINUX -fPIC -Wno-write-strings -shared -I. -I../include *.cpp -o ../lib/libfygm.so
+cp fygm.h ../include/fygm.h
diff --git a/GM/stdafx.cpp b/GM/stdafx.cpp
new file mode 100644
index 0000000..0455cd1
--- /dev/null
+++ b/GM/stdafx.cpp
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// GM.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/GM/stdafx.h b/GM/stdafx.h
new file mode 100644
index 0000000..f1ffb54
--- /dev/null
+++ b/GM/stdafx.h
@@ -0,0 +1,9 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+
+// TODO: reference additional headers your program requires here
diff --git a/UT/ANFORSEL.cpp b/UT/ANFORSEL.cpp
new file mode 100644
index 0000000..2fe1572
--- /dev/null
+++ b/UT/ANFORSEL.cpp
@@ -0,0 +1,189 @@
+/*
+CD AR-920127
+CH Anforsel                  Legger til eller fjerner anf�rseltegn
+CD ===============================================================
+CD
+CD Eier.......: STATENS KARTVERK / FYSAK-prosjektet
+CD Ansvarlig..: �ge Eliassen
+CD
+CD ===============================================================
+*/
+
+#include "stdafx.h"
+#include <string.h>
+
+#include "fyut.h"
+
+
+/*
+OJ-2003-12-03
+�E-950401
+CH UT_PutAnfTegn           Legg inn / fjern anf�rseltegn forran og bak streng
+CD ===========================================================================
+CD Form�l:
+CD Legger inn eller fjerner anf�rseltegn forran eller bak parameter-streng.
+CD Ved rydding av anf�rseltegn ryddes ogs� tegn inni strengen.
+CD Ved rydding m� parameterstrengen best� av mer enn ett tegn.
+CD
+CD PARAMETERLISTE:
+CD Type   Navn       I/U   Merknad
+CD --------------------------------------------------------------------------
+CD char  *pszTx       iu   Tekststreng som skal behandles
+CD char   cTegn       i    Styreparameter:
+CD                           "  = Omslutt pszTx med  ' " '
+CD                           '  = Omslutt pszTx med  " ' "
+CD                           F  = Fjern anf�rselstegn fra strengen
+CD short  sMaksLen    i    Makslimal lengde p� streng inklusiv null-termiantor
+CD short  sOk         r    Feilstatus. UT_OK hvis ok, UT_ERROR hvis strengen er
+CD                         for kort til � f�ye p� anf�rselstegn.
+CD
+CD Bruk:
+CD bOk = UT_PutAnfTegn(pszTx,cTegn, sMaksLen);
+CD =============================================================================
+*/
+SK_EntPnt_UT short UT_PutAnfTegn(char *pszTx, char cTegn, short sMaksLen)
+{
+   short i,ii,sTxtLen;
+   char t1,t2;
+   short sOk = UT_OK;
+
+   sTxtLen = (short)strlen(pszTx);
+   /* Hvis det skal legges p� " eller ' i para-strengens ender: */
+   if (cTegn=='\"' || cTegn=='\'') {
+
+      /* Hvis para-strengen allerede er innrammet av anf�rselstegn :*/
+      if ((sTxtLen>1 && pszTx[0]=='\"' && pszTx[sTxtLen]=='\"')
+         || (sTxtLen>1 && pszTx[0]=='\'' && pszTx[sTxtLen]=='\'')) {
+         if (sTxtLen <= sMaksLen - 1)
+         {
+            pszTx[0] = pszTx[sTxtLen] = cTegn;
+         }
+         else
+         {
+            sOk = UT_ERROR;
+         }
+      // Hvis tegnet finnes bare i starten av strengen.
+      } else if ((sTxtLen > 1 ) && (pszTx[0]=='\'' || pszTx[0]=='\"')){
+         if(sTxtLen < sMaksLen - 2)
+         {
+            pszTx[0] = pszTx[sTxtLen] = cTegn;
+            pszTx[sTxtLen + 1] = '\0';
+         }
+         else
+         {
+            sOk = UT_ERROR;
+         }
+      // Hvis tegnet finnes bare i slutten av strengen.
+      } else if ((sTxtLen > 1 ) && (pszTx[sTxtLen - 1]=='\'' || pszTx[sTxtLen - 1]=='\"')){
+          if(sTxtLen < sMaksLen - 2)
+          {
+            t1 = pszTx[0];
+            t2 = pszTx[1];
+            pszTx[0] = cTegn;
+            pszTx[1] = t1;
+
+            i = 2;
+            while (pszTx[i] != '\0') {
+               t1 = pszTx[i];
+               pszTx[i] = t2;
+               t2 = t1;
+               i++;
+            }
+            pszTx[i] = cTegn;
+            pszTx[i+1] = '\0';
+         }else{
+            sOk = UT_ERROR;
+          }
+      // Strengen best�r av bare et anf�rselstegn.
+      } else if ((sTxtLen == 1 ) && (pszTx[sTxtLen - 1]=='\'' || pszTx[sTxtLen - 1]=='\"')){
+          if (sTxtLen <= sMaksLen - 2)
+          {
+             pszTx[0] = pszTx[1] = cTegn;
+             pszTx[2] = '\0';
+          }
+          else
+          {
+            sOk = UT_ERROR;
+          }
+
+      /* Hvis para-strengen ikke er innrammet av ' eller " :*/
+      } else {
+          if (sTxtLen <= sMaksLen - 3)
+          {
+             if (pszTx[0] == '\0') {         /* ingen tegn, legger inn "" */
+                pszTx[0] = pszTx[1] = cTegn;
+                pszTx[2] = '\0';
+             } else if (pszTx[1] == '\0') {  /* ett tegn, legger inn "x" */
+                pszTx[1] = pszTx[0];
+                pszTx[0] = pszTx[2] = cTegn;
+                pszTx[3] = '\0';
+             } else {                      /* flere tegn, legger inn "xx yy" */
+                t1 = pszTx[0];
+                t2 = pszTx[1];
+                pszTx[0] = cTegn;
+                pszTx[1] = t1;
+
+                i = 2;
+                while (pszTx[i] != '\0') {
+                   t1 = pszTx[i];
+                   pszTx[i] = t2;
+                   t2 = t1;
+                   i++;
+                }
+                pszTx[i]   = t2;
+                pszTx[i+1] = cTegn;
+                pszTx[i+2] = '\0';
+             }
+          }
+          else
+          {
+             sOk = UT_ERROR;
+          }
+      }
+
+   /* Fjerner appostroffer: */
+   } else if (cTegn=='F') {
+       if (sTxtLen <= sMaksLen)
+       {
+          /* Para-strengen m� innholde mer enn ett tegn: */
+          if (sTxtLen > 1) {
+
+             /* " */
+             if ( pszTx[0]=='\"' || pszTx[sTxtLen-1]=='\"') {
+
+                /* Fjerner alle " i hele strengen. */
+                i = 0;
+                ii = 0;
+                do {
+                   if (pszTx[i] != '\"') {
+                      pszTx[ii] = pszTx[i];
+                      ii++;
+                   }
+                   i++;
+                } while (pszTx[i] != '\0');
+                pszTx[ii] = '\0';
+
+             /* ' */
+             } else if ( pszTx[0]=='\'' || pszTx[sTxtLen-1]=='\'') {
+
+                /* Fjerner alle ' i hele strengen. */
+                i = 0;
+                ii = 0;
+                do {
+                   if (pszTx[i] != '\'') {
+                      pszTx[ii] = pszTx[i];
+                      ii++;
+                   }
+                   i++;
+                } while (pszTx[i] != '\0');
+                pszTx[ii] = '\0';
+             }
+          }
+       }
+       else
+       {
+           sOk = UT_ERROR;
+       }
+   }
+   return sOk;
+}
diff --git a/UT/CREDIR.cpp b/UT/CREDIR.cpp
new file mode 100644
index 0000000..6b0430d
--- /dev/null
+++ b/UT/CREDIR.cpp
@@ -0,0 +1,81 @@
+/* ------------------------------ 
+ * Fil: CreDir.c
+ * ------------------------------ */
+
+#include "stdafx.h"
+
+#ifdef UNIX
+#  ifndef _INCLUDE_POSIX_SOURCE
+#     define _INCLUDE_POSIX_SOURCE
+#  endif
+
+#  ifndef _HPUX_SOURCE
+#     define _HPUX_SOURCE
+#  endif
+
+#  include<sys/types.h>
+#  include <sys/stat.h>
+#endif
+
+#ifdef OS232
+#  define INCL_DOSFILEMGR
+#  define INCL_DOSERRORS
+#  include <os2.h>
+#endif
+
+#ifdef OS216
+#  include <direct.h>
+#endif
+
+#ifdef WIN32
+#  include <direct.h>
+#endif
+
+#ifdef BORLAND
+#  include <dir.h>
+#endif
+
+//#include "StdAfx.h"
+#include "fyut.h"
+
+/*
+AR-921013
+CH UT_CreateDir                                Oppretter et directory
+CD ==================================================================
+CD Form�l:
+CD Sletter et directory.
+CD
+CD PARAMETERLISTE:
+CD Type      Navn     I/U  Merknad
+CD ------------------------------------------------------------------
+CD char     *pszPath   i   Directory-navn
+CD short     sStatus   r   Status; 0=OK, annen verdi er feil.
+CD
+CD Bruk:  sStatus = UT_CreateDir(szPath);
+	==================================================================
+*/
+SK_EntPnt_UT short UT_CreateDir(char *pszPath)
+{
+#ifdef UNIX
+	mode_t modus;
+	/*  Setter alle rettigheter for user ingen for andre*/
+	modus = (S_IRUSR  | S_IWUSR  | S_IXUSR);
+	return  (short)mkdir(pszPath,modus);
+#endif
+
+#ifdef OS232
+	return  (short)DosCreateDir(pszPath,NULL);
+#endif
+
+#ifdef OS216
+   return  (short)mkdir(pszPath);
+#endif
+
+#ifdef WIN32
+   return  (short)_mkdir(pszPath);
+#endif
+
+#ifdef BORLAND
+	return  (short)mkdir(pszPath);
+#endif
+}
diff --git a/UT/CopyFile.cpp b/UT/CopyFile.cpp
new file mode 100644
index 0000000..4e6d32c
--- /dev/null
+++ b/UT/CopyFile.cpp
@@ -0,0 +1,78 @@
+/* ------------------------------
+ * Fil: CopyFile.c
+ * ------------------------------ */
+
+#include "stdafx.h"
+
+#ifdef UNIX
+#  ifndef _INCLUDE_POSIX_SOURCE
+#    define _INCLUDE_POSIX_SOURCE
+#  endif
+#  ifndef _HPUX_SOURCE
+#    define _HPUX_SOURCE
+#  endif
+#endif
+
+#ifdef OS2
+#endif
+
+#ifdef WIN32
+#  include<windows.h>
+#endif
+
+#ifdef BORLAND
+#endif
+
+//#include "StdAfx.h"
+#include "fyut.h"
+
+/*
+AR-971118
+CH UT_CopyFile                                            Kopier fil
+CD ==================================================================
+CD Form�l:
+CD Kopierer en eksisterende fil til en ny fil.
+CD
+CD PARAMETERLISTE:
+CD Type   Navn               I/U Merknad
+CD ------------------------------------------------------------------
+CD char  *pszFraFilnavn       i  Kopier fra denne filen
+CD char  *pszTilFilnavn       i  Kopier til denne filen
+CD short  sFeilHvisEksisterer i  Hva skal skje hvis resultatfilen finnes fra f�r:
+CD                                  UT_TRUE = Avbryter
+CD                                  UT_FALSE = Overskriver  
+CD short  sStatus             r  Status:
+CD                                  UT_TRUE = OK
+CD                                  UT_FALSE = Feil.
+CD
+CD Bruk:  sStatus = UT_CopyFile(pszFraFilnavn,pszTilFilnavn,UT_TRUE);
+   ==================================================================
+*/
+SK_EntPnt_UT short UT_CopyFile(char *pszFraFilnavn,char *pszTilFilnavn,short sFeilHvisEksisterer)
+{
+#ifdef WIN32
+   if (CopyFile( pszFraFilnavn, pszTilFilnavn, sFeilHvisEksisterer)) {
+      return UT_TRUE;
+   } else {
+      return UT_FALSE;
+   }
+#endif
+
+
+#ifdef UNIX
+      return UT_FALSE;
+#endif
+
+#ifdef OS232
+      return UT_FALSE;
+#endif
+
+#ifdef OS216
+      return UT_FALSE;
+#endif
+
+#ifdef BORLAND
+      return UT_FALSE;
+#endif
+
+}
diff --git a/UT/DELDIR.cpp b/UT/DELDIR.cpp
new file mode 100644
index 0000000..e42846a
--- /dev/null
+++ b/UT/DELDIR.cpp
@@ -0,0 +1,78 @@
+/* ------------------------------
+ * Fil: DelDir.c
+ * ------------------------------ */
+
+#include "stdafx.h"
+
+#ifdef LINUX
+#  include <unistd.h>
+#endif
+
+#ifdef UNIX
+#  include <sys/types.h>
+#  include <sys/stat.h>
+#endif
+
+#ifdef OS232
+#  define INCL_DOSFILEMGR
+#  define INCL_DOSERRORS
+#  include <os2.h>
+#endif
+
+#ifdef OS216
+#  include <direct.h>
+#endif
+
+#ifdef WIN32
+#  include <direct.h>
+#endif
+
+#ifdef BORLAND
+#  include <dir.h>
+#endif
+
+//#include "StdAfx.h"
+#include "fyut.h"
+
+/*
+AR-921013
+CH UT_DeleteDir                                 Sletter et directory
+CD ==================================================================
+CD Form�l:
+CD Sletter et directory.
+CD
+CD PARAMETERLISTE:
+CD Type      Navn     I/U  Merknad
+CD ------------------------------------------------------------------
+CD char     *pszPath   i   Directory-navn
+CD short     sStatus   r   Status; 0=OK, annen verdi er feil.
+CD
+CD Bruk:  sStatus = UT_DeleteDir(szPath);
+   ==================================================================
+*/
+SK_EntPnt_UT short UT_DeleteDir(char *pszPath)
+{
+#ifdef LINUX
+	return  (short)rmdir(pszPath);
+#endif
+
+#ifdef UNIX
+	return  (short)rmdir(pszPath);
+#endif
+
+#ifdef OS232
+   return  (short)DosDeleteDir(pszPath);
+#endif
+
+#ifdef OS216
+   return  (short)rmdir(pszPath);
+#endif
+
+#ifdef WIN32
+   return  (short)_rmdir(pszPath);
+#endif
+
+#ifdef BORLAND
+	return  (short)rmdir(pszPath);
+#endif
+}
diff --git a/UT/DELFILE.cpp b/UT/DELFILE.cpp
new file mode 100644
index 0000000..6bc2489
--- /dev/null
+++ b/UT/DELFILE.cpp
@@ -0,0 +1,43 @@
+/* ------------------------------ 
+ * Fil: DelFile.c
+ * ------------------------------ */
+
+#include "stdafx.h"
+
+#ifdef LINUX
+#  include <unistd.h>
+#  define UT_access access
+#else
+#  include <io.h>
+#  define UT_access _access
+#endif
+
+#include "fyut.h"
+
+/*
+AR-921013
+CH  UT_DeleteFile                                      Sletter en fil
+CD  ==================================================================
+CD  Form�l:
+CD  Sletter en fil.
+CD
+CD  PARAMETERLISTE:
+CD  Type      Navn     I/U  Merknad
+CD  ------------------------------------------------------------------
+CD  char     *pszPath   i   Filnavn
+CD  short     sStatus   r   Status; 0=OK, annen verdi er feil.
+CD
+CD  Bruk:  sStatus = UT_DeleteFile(szPath);
+    ==================================================================
+*/
+
+SK_EntPnt_UT short UT_DeleteFile(char *pszPath)
+{
+   // Sjekk at filen finnes
+   if( (UT_access( pszPath, 0 )) == 0 ) {
+      /* Sletter eventuell gammel hjelpefil */
+      return remove(pszPath); 
+   }
+   
+   return  0;
+}
diff --git a/UT/DISKINFO.cpp b/UT/DISKINFO.cpp
new file mode 100644
index 0000000..d165832
--- /dev/null
+++ b/UT/DISKINFO.cpp
@@ -0,0 +1,199 @@
+/* ------------------------------
+ * Fil: DiskInfo.c
+ * ------------------------------ */
+#include "stdafx.h"
+#include <ctype.h>
+
+#ifdef UNIX
+#  ifndef _INCLUDE_POSIX_SOURCE
+#     define _INCLUDE_POSIX_SOURCE
+#  endif
+
+#  ifndef _HPUX_SOURCE
+#     define _HPUX_SOURCE
+#  endif
+
+#  ifdef SUNOS                  /* NB! DIKAS */
+#     include <sys/statvfs.h>
+#  else
+#     include <sys/stat.h>
+#     include <sys/vfs.h>
+#  endif
+
+#  include <sys/types.h>
+#  include <unistd.h>
+#  include <limits.h>
+#endif
+
+#ifdef OS2
+#  define INCL_DOSFILEMGR
+#  define INCL_DOSERRORS
+#  include <os2.h>
+#endif
+
+#ifdef WIN32
+#  include <windows.h>
+#  include <LIMITS.H>
+#endif
+
+#ifdef BORLAND
+#  include <windows.h>
+#endif
+
+#include "fyut.h"
+
+/*
+AR-930623
+CH UT_InqAvailSize                       Finn ledig plass p� disken
+CD ==================================================================
+CD Form�l:
+CD Finner hvor mye plass som er ledig for utvidelse av gitt fil.
+CD
+CD PARAMETERLISTE:
+CD Type          Navn     I/U  Merknad
+CD ------------------------------------------------------------------
+CD char           *pszPath        i   Filnavn inkl. full sti.
+CD unsigned long  *pulLedigPlass  u   Ledig plass p� disken
+CD short           sStatus        r   Status; 0=OK, annen verdi er feil.
+CD
+CD Bruk:  sStatus = UT_InqAvailSize(pszPath,&ulLedigPLass);
+   ==================================================================
+*/
+SK_EntPnt_UT short UT_InqAvailSize(char *pszPath,unsigned long *pulLedigPlass)
+{
+#ifdef UNIX
+   int rc;
+#  ifdef SUNOS
+      struct statvfs buf;
+#  else
+      struct statfs buf;
+#  endif
+   
+   /* Hent filopplysninger */
+   rc = statfs(pszPath,&buf);
+   if (rc == 0) {
+      *pulLedigPlass = buf.f_bavail * buf.f_bsize;
+   }
+
+   /* Hent filopplysninger */
+#  ifdef SUNOS
+      /* NB! statfs er p� vei ut av systemet ! , bruker statvfs i stedet*/
+      rc = statvfs(pszPath,&buf);
+      if (rc == 0) {
+         *pulLedigPlass = buf.f_bavail * buf.f_bsize;
+      }
+
+#  else
+      rc = statfs(pszPath,&buf);
+      if (rc == 0) {
+         *pulLedigPlass = buf.f_bavail * buf.f_bsize;
+      }
+#  endif
+
+   return (short)rc;
+#endif
+
+
+#ifdef OS232
+   unsigned long ulDisk;
+   char disk[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
+   APIRET rc;
+   FSALLOCATE drive;
+
+   /* Finn disknummer */
+   UT_splitpath(pszPath,disk,dir,fname,ext);
+   if (*disk != '\0') {
+      ulDisk = toupper(*disk) - '@';
+   } else {
+      ulDisk = 0L;
+   }
+
+   /* Hent filopplysninger */
+   rc = DosQueryFSInfo(ulDisk,FSIL_ALLOC,(PBYTE)&drive,sizeof drive);
+
+   if (rc == NO_ERROR) {
+      *pulLedigPlass = drive.cUnitAvail * drive.cSectorUnit * drive.cbSector;
+   }
+
+   return (short)rc;
+#endif
+
+
+#ifdef OS216
+   unsigned short usDisk;
+   char disk[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
+   int rc;
+   FSALLOCATE drive;
+
+   /* Finn disknummer */
+   UT_splitpath(pszPath,disk,dir,fname,ext);
+   if (*disk != '\0') {
+      usDisk = toupper(*disk) - '@';
+   } else {
+      usDisk = 0;
+   }
+
+   /* Hent filopplysninger */
+   rc = DosQFSInfo(usDisk,FSIL_ALLOC,(PBYTE)&drive,sizeof drive);
+
+   if (rc == NO_ERROR) {
+      *pulLedigPlass = drive.cUnitAvail * drive.cSectorUnit * drive.cbSector;
+   }
+
+   return (short)rc;
+#endif
+
+
+#ifdef WIN32
+         char disk[_MAX_DRIVE+1],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
+         DWORD  SectorsPerCluster;       // address of sectors per cluster
+         DWORD  BytesPerSector;     // address of bytes per sector
+         DWORD  FreeClusters;       // address of number of free clusters
+         DWORD  Clusters;                 // address of total number of clusters
+         
+         UINT64 ui64; 
+
+        // Finn disk
+        UT_splitpath(pszPath,disk,dir,fname,ext);
+        strcat_s(disk,"\\");
+        //Hent filopplysninger
+        if (GetDiskFreeSpace((LPCTSTR)disk,
+                              (LPDWORD)&SectorsPerCluster,
+                              (LPDWORD)&BytesPerSector,
+                              (LPDWORD)&FreeClusters,
+                              (LPDWORD)&Clusters  ) )
+        {
+           ui64 = (UINT64)FreeClusters * (UINT64)SectorsPerCluster * (UINT64)BytesPerSector;
+           if (ui64 < ULONG_MAX)   *pulLedigPlass = (unsigned long)ui64;
+           else                     *pulLedigPlass = ULONG_MAX;
+
+           return 0;
+        }
+   return 1;
+#endif
+
+#ifdef BORLAND
+         char disk[_MAX_DRIVE+1],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
+         DWORD  SectorsPerCluster;      /* address of sectors per cluster */
+         DWORD  BytesPerSector;     /* address of bytes per sector */
+         DWORD  FreeClusters;       /* address of number of free clusters */
+         DWORD  Clusters;               /* address of total number of clusters */
+
+        /* Finn disk */
+        UT_splitpath(pszPath,disk,dir,fname,ext);
+        UT_StrCat(disk,"\\",_MAX_DRIVE+1);
+
+        /* Hent filopplysninger */
+        if (GetDiskFreeSpace((LPCTSTR)disk,
+                                                (LPDWORD)&SectorsPerCluster,
+                                                (LPDWORD)&BytesPerSector,
+                                                (LPDWORD)&FreeClusters,
+                                                (LPDWORD)&Clusters  ) ) {
+
+                 *pulLedigPlass = FreeClusters * SectorsPerCluster * BytesPerSector;
+                 return 0;
+        }
+
+        return 1;
+#endif
+}
diff --git a/UT/FILNACMP.cpp b/UT/FILNACMP.cpp
new file mode 100644
index 0000000..b2a5ec2
--- /dev/null
+++ b/UT/FILNACMP.cpp
@@ -0,0 +1,54 @@
+/* ------------------------------ 
+ * Fil: FilnaCmp.c
+ * ------------------------------ */
+
+#include "stdafx.h"
+#include <string.h>
+#include "fyut.h"
+
+#ifdef BORLAND
+#  include <windows.h>
+#endif
+
+#ifdef WIN32
+#  include <windows.h>
+#endif
+
+/*
+AR-921013
+CH UT_FilnavnCmp                                   Sammenlignfilnavn
+CD ==================================================================
+CD Form�l:
+CD Sammenligner om 2 filnavn er like.
+CD Tar hensyn til om filsystemet handterer store og sm� bokstaver likt.
+CD
+CD PARAMETERLISTE:
+CD Type      Navn     I/U  Merknad
+CD ------------------------------------------------------------------
+CD char     *pszFil1   i   Filnavn 1
+CD char     *pszFil2   i   Filnavn 2
+CD short     sStatus   r   Status; 0=Navnene er like, annen verdi = ulik
+CD
+CD Bruk:  sStatus = UT_FilnavnCmp(pszFil1,pszFil2);
+   ==================================================================
+*/
+SK_EntPnt_UT short UT_FilnavnCmp(char *pszFil1,char *pszFil2)
+{
+   char fil1[_MAX_PATH];
+   char fil2[_MAX_PATH];
+
+#ifdef LINUX
+   strncpy(fil1,pszFil1,strlen(pszFil1));
+   strncpy(fil2,pszFil2,strlen(pszFil2));
+#else
+   strcpy_s(fil1,pszFil1);
+   strcpy_s(fil2,pszFil2);
+#endif
+
+#ifndef UNIX
+   UT_StrUpper(fil1);
+   UT_StrUpper(fil2);
+#endif
+
+   return  (short)strcmp(fil1,fil2);
+}
diff --git a/UT/FULLPATH.cpp b/UT/FULLPATH.cpp
new file mode 100644
index 0000000..5ad422f
--- /dev/null
+++ b/UT/FULLPATH.cpp
@@ -0,0 +1,309 @@
+/* ------------------------------
+ * Fil: FullPath.c
+ * ------------------------------ */
+
+#include "stdafx.h"
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef LINUX
+#  include <unistd.h>
+#endif
+
+#ifdef UNIX
+#  include <ctype.h>
+#endif
+
+#ifdef OS2
+#  define INCL_DOSFILEMGR
+#  define INCL_DOSERRORS
+#  include <os2.h>
+#endif
+
+#ifdef BORLAND
+#  include <windows.h>
+#endif
+
+#ifdef WIN32
+#  include <windows.h>
+#endif
+
+#include "fyut.h"
+
+
+#ifdef UNIX
+
+/*-----------------------------------------------------------------------* 
+ * filename - fullpath.c
+ *
+ * function(s)
+ *        isSlash   - check for directory separator character
+ *        _fullpath - make an absolute path name from a relative path name
+ *-----------------------------------------------------------------------*/
+
+/*
+ *      C/C++ Run Time Library - Version 5.0
+ *
+ *      Copyright (c) 1987, 1992 by Borland International
+ *      All Rights Reserved.
+ *
+ */
+
+
+/*---------------------------------------------------------------------*
+
+Name            isSlash - check for directory separator character
+
+Usage           int isSlash(int c);
+
+Prototype in    local
+
+Description     isSlash returns true if the character c is a valid
+                directory separator character (\ or / on DOS, / on UNIX).
+                It returns false otherwise.
+
+Return value    Describe above.
+
+*---------------------------------------------------------------------*/
+static int isSlash (int c)
+{
+    return (c == '\\' || c == '/');
+}
+
+/*---------------------------------------------------------------------*
+
+Name            _fullpath - makes new file name
+
+Usage           #include <dir.h>
+                char *_fullpath(char *buffer, const char * pathname,
+                                size_t maxlen);
+
+Prototype in    stdlib.h
+
+Description     _fullpath converts the relative path name name 'pathname'
+                to a fully qualified pathname, stored in 'buffer'.  The
+					 relative path can contain ".\" and "..".
+
+                The maximum size of the supplied buffer is 'maxlen'.
+                If the fully qualified path is longer than 'maxlen',
+                NULL is returned.  The buffer should be at least _MAX_PATH
+                bytes long (this constant is defined in stdlib.h).
+
+                If 'buffer' is NULL, a buffer to store the fully qualified
+                path is allocated and is returned.  The calling program
+                must free this buffer with GlobalFree(() when it is no longer needed.
+
+                If the pathname does not specify a disk drive, the current
+                drive is used.
+
+Return value    A pointer to the buffer containing the fully qualified
+                path is returned.  If there is an error, NULL is returned.
+
+Note            This function is a rewrite of the FExpand procedure
+                in the Turbo Pascal RTL, with modifications for MSC
+					 compatibility.
+
+*---------------------------------------------------------------------*/
+char * _fullpath(char *buffer,
+                 const char *pathname,
+                 size_t maxlen
+                 )
+{
+	 char *tempbuf;
+    char *dst, *src;
+    int c, driveletter;
+    size_t len;
+
+
+    /* Allocate a temporary buffer to hold the fully qualified path.
+	  */
+	 if ((tempbuf = (char*)UT_MALLOC(_MAX_PATH*2+1)) == NULL)
+		  return (NULL);
+    
+    
+     driveletter = 7;
+     src = (char *)pathname; 
+    
+    
+	 /* If supplied path is relative, append it to the drivename
+     * and its current directory.  Otherwise append it to the
+     * drivename only.
+     */
+    if (!isSlash(src[0])) {              /* path is relative? */
+        /* Get drivename and its current directory.
+         */
+		  if (getcwd(tempbuf,_MAX_PATH*2+1) == NULL) {
+				UT_FREE(tempbuf);
+				return (NULL);
+        }
+        dst = &tempbuf[strlen(tempbuf)];
+        if (!isSlash(*(dst-1)))         /* if directory doesn't end in slash */
+            *dst++ = UT_SLASH;              /* append one */
+
+    } else {
+        /* Path is absolute.  Store the drivename only.*/
+        dst = tempbuf;
+    }
+    strcpy(dst,src);                    /* concatenate supplied path */
+
+    /* Scan the path, squeezing out "../" and "./", and
+     * squeezing out the previous directory when "../" is found.
+	  */
+    src = dst = tempbuf;
+    
+    for (;;) {
+        /* If this the end of the path, or end of a directory,
+         * we must check for "." or ".."
+         */
+        if ((c = *src++) == '\0' || isSlash(c)) {
+            /* If last directory copied was "/.", back up over it.
+             * Skip test if we are still at the beginning of tempbuf.
+             */
+            if (src != (tempbuf+1)) {
+			  if (*(dst-1) == '.' && isSlash(*(dst-2))) {
+                dst -= 2;
+
+            /* If last directory copied was "/..", back up over it
+             * AND the previous directory.
+             */
+              } else if (*(dst-1) == '.' && *(dst-2) == '.' && isSlash(*(dst-3))) {
+                dst -= 3;                /* back up over "/.." */
+					 if (*(dst-1) == ':') {   /* can't back up over drivename */
+						  UT_FREE(tempbuf);
+						  return(NULL);
+					 }
+					 while (!isSlash(*--dst))
+                    ;                   /* back up to start of prev. dir. */
+			  }
+
+              if (c == '\0') {             /* end of path? */
+                if (isSlash(*(dst-1)))  /* if last char is slash */
+                    dst--;              /*  back up over it */
+                if (*(dst-1) == ':')    /* if path is just a drivename */
+                    *dst++ = '/';      /*  append a slash */
+                *dst = '\0';            /* append null terminator */
+                break;
+            
+              } else {
+					 *dst++ = c;             /* copy the slash */
+              }
+		    }
+
+        } else {
+            *dst++ = c;                 /* copy the character */
+        }
+    }
+
+	 /* Copy the temp buffer to the user's buffer, if present.
+     * Otherwise shrink the temp buffer and return a pointer to it.
+     */
+    len = strlen(tempbuf) + 1;                  /* length of path and null */
+    if (buffer != NULL) {
+		  if (len > maxlen) {                     /* user buffer too small? */
+				UT_FREE(tempbuf);
+				return (NULL);
+
+        } else {
+				strcpy(buffer,tempbuf);
+				UT_FREE(tempbuf);
+            return (buffer);
+        }
+
+    } else {
+        return (char*)(realloc(tempbuf,len));          /* shrink the buffer */
+	 }
+}
+#endif
+
+
+/*
+AR-930423
+CH UT_FullPath                              Finn fullstendig filnavn
+CD ==================================================================
+CD Form�l:
+CD Lag absolutt path navn fra relativt path navn.
+CD I tilleg tolker denne environment-variabler inn i filnavnet.
+CD Environment-varialen skrives i parantes.
+CD
+CD Eks:
+CD    SET FKB=D:\DATA\SOSI\FKB
+CD
+CD   Filnavnet   (FKB)\CV03851V.SOS
+CD   pakkes ut til  D:\DATA\SOSI\FKB\CV03851V.SOS
+CD
+CD PARAMETERLISTE:
+CD Type             Navn       I/U  Merknad
+CD ------------------------------------------------------------------
+CD char            *pszBuffer u   Komplett filnavn
+CD const char      *pszPath   i   Forkortet filnavn
+CD size_t           maxlen    i   Max lengde av pszBuffer
+CD short            sStatus   r   Status; 0=OK, annen verdi er feil.
+CD
+CD Bruk:  sStatus = UT_FullPath(szBuffer,szPath,maxlen);
+	==================================================================
+*/
+SK_EntPnt_UT short  UT_FullPath(char *pszBuffer, const char *pszPath, size_t maxlen)
+{
+	char szFilnavn[_MAX_PATH];
+	char *pszStart,*pszSlutt;
+	char *env;
+#ifdef BORLAND
+	char  *pszOrgPath;
+#endif
+
+	/* S�k start- og sluttparantes */
+	UT_StrCopy(szFilnavn,pszPath,_MAX_PATH);
+	pszStart = strchr(szFilnavn,'(');
+	pszSlutt = strchr(szFilnavn,')');
+
+	/* B�de start- og sluttparantes er funnet,
+      og starten er f�rst i strengen */
+   if (pszStart != NULL  &&  pszSlutt != NULL  &&  pszStart < pszSlutt) {
+      *pszStart++ = '\0';
+		*pszSlutt++ = '\0';
+#ifdef LINUX
+      env = getenv( UT_StrUpper(pszStart));
+#else      
+      size_t len;
+      _dupenv_s(&env, &len, UT_StrUpper(pszStart));
+#endif
+
+      /* Navnet er ikke funnet */
+      if (env == NULL) {
+         UT_StrCopy(szFilnavn,pszPath,_MAX_PATH);
+
+		} else {
+ 		  UT_StrCat(szFilnavn,env,_MAX_PATH);
+        UT_ClrTrailsp(szFilnavn);
+        UT_StrCat(szFilnavn,pszPath+(pszSlutt-szFilnavn),_MAX_PATH);
+		}
+	}
+
+	/* Hent filopplysninger */
+#ifdef UNIX
+   return  (short)(_fullpath(pszBuffer,szFilnavn,maxlen) != NULL)?  0 : 1;
+#endif
+
+#ifdef OS232
+	return  (short) DosQueryPathInfo(szFilnavn,FIL_QUERYFULLNAME,pszBuffer,maxlen);
+#endif
+
+#ifdef OS216
+	return  (short) DosQPathInfo(szFilnavn,FIL_QUERYFULLNAME,(PBYTE)pszBuffer,(USHORT)maxlen,0);
+#endif
+
+#ifdef WIN32
+   return  (short)(_fullpath(pszBuffer,szFilnavn,maxlen) != NULL)?  0 : 1;
+#endif
+
+#ifdef BORLAND
+	pszOrgPath = _fullpath(pszBuffer,szFilnavn,maxlen);
+
+	if (pszOrgPath != NULL)
+		return((short)0);
+	else
+		return ((short)1);
+#endif
+
+}
+
diff --git a/UT/INQSIZE.cpp b/UT/INQSIZE.cpp
new file mode 100644
index 0000000..023c2a0
--- /dev/null
+++ b/UT/INQSIZE.cpp
@@ -0,0 +1,173 @@
+/* ------------------------------
+ * Fil: InqSize.c
+ * ------------------------------ */
+
+#include "stdafx.h"
+
+#ifdef UNIX
+#  ifndef _INCLUDE_POSIX_SOURCE
+#    define _INCLUDE_POSIX_SOURCE
+#  endif
+
+#  ifndef _HPUX_SOURCE
+#    define _HPUX_SOURCE
+#  endif
+
+#  include<stdio.h>
+#  include<sys/time.h>
+#  include<sys/types.h>
+#  include<sys/vfs.h>
+#  include<fcntl.h>
+#  include<sys/stat.h>
+#  include<errno.h>
+#endif
+
+#ifdef OS2
+#  define INCL_DOSFILEMGR
+#  define INCL_DOSERRORS
+#  include <os2.h>
+#endif
+
+#ifdef WIN32
+#  include<sys/stat.h>
+#endif
+
+#ifdef BORLAND
+#  include<sys/stat.h>
+#endif
+
+#include "fyut.h"
+
+/*
+AR-921013
+CH UT_InqPathSize                                  Finn filst�rrelse
+CD ==================================================================
+CD Form�l:
+CD Henter filst�rrelsen for gitt fil.
+CD
+CD PARAMETERLISTE:
+CD Type      Navn     I/U  Merknad
+CD ------------------------------------------------------------------
+CD char     *pszPath   i   Filnavn
+CD long     *plSize    u   Filst�rrelse
+CD short     sStatus   r   Status; 0=OK, annen verdi er feil.
+CD
+CD Bruk:  sStatus = UT_InqPathSize(szPath,&lSize);
+   ==================================================================
+*/
+SK_EntPnt_UT short UT_InqPathSize(char *pszPath,long *plSize)
+{
+#ifdef UNIX
+   struct stat buf; 
+   int result;
+
+
+   /* Hent filopplysninger */
+   result = stat(pszPath,&buf);
+   if (result == 0) {
+      *plSize = (long)buf.st_size;
+   }
+
+   return (short)result;
+#endif
+
+#ifdef OS232
+      APIRET rc;
+		FILESTATUS3 PathInfoBuf;
+
+      /* Hent filopplysninger */
+      rc = DosQueryPathInfo(pszPath,FIL_STANDARD,&PathInfoBuf,sizeof(FILESTATUS3));
+
+      if (rc == NO_ERROR) {
+         *plSize = (long)PathInfoBuf.cbFile;
+      }
+
+      return (short)rc;
+#endif
+
+#ifdef OS216
+	int rc;
+	FILESTATUS PathInfoBuf;
+
+   /* Hent filopplysninger */
+   rc = DosQPathInfo(pszPath,FIL_STANDARD,(PBYTE)&PathInfoBuf,sizeof(FILESTATUS),0);
+
+   if (rc == NO_ERROR) {
+      *plSize = (long)PathInfoBuf.cbFile;
+   }
+
+	return (short)rc;
+#endif
+
+#ifdef WIN32
+    struct _stat buf;
+	 int result;
+
+
+	 /* Hent filopplysninger */
+    result = _stat(pszPath,&buf);
+	 if (result == 0) {
+		  *plSize = (long)buf.st_size;
+	 }
+
+	 return (short)result;
+#endif
+
+#ifdef BORLAND
+	 struct stat buf;
+	 int result;
+
+
+	 /* Hent filopplysninger */
+	 result = stat(pszPath,&buf);
+	 if (result == 0) {
+		  *plSize = (long)buf.st_size;
+	 }
+
+	 return (short)result;
+#endif
+
+}
+
+
+
+/*
+AR-921013
+CH UT_InqPathSize_i64                              Finn filst�rrelse
+CD ==================================================================
+CD Form�l:
+CD Henter filst�rrelsen for gitt fil.
+CD
+CD PARAMETERLISTE:
+CD Type      Navn     I/U  Merknad
+CD ------------------------------------------------------------------
+CD char     *pszPath   i   Filnavn
+CD UT_INT64 *n64Size   u   Filst�rrelse
+CD short     sStatus   r   Status; 0=OK, annen verdi er feil.
+CD
+CD Bruk:  sStatus = UT_InqPathSize_i64(szPath,&n64Size);
+   ==================================================================
+*/
+SK_EntPnt_UT short UT_InqPathSize_i64(char *pszPath,UT_INT64 *n64Size)
+{
+#ifdef LINUX
+	struct stat buf;
+#else
+    struct _stat32i64 buf;
+#endif
+	 int result;
+
+
+	 // Hent filopplysninger
+    //result = _stat(pszPath,&buf);
+#ifdef LINUX
+    result = stat(pszPath,&buf);
+#else
+    result = _stat32i64(pszPath,&buf);
+#endif
+	 if (result == 0) {
+		  *n64Size = buf.st_size;
+	 }
+
+	 return (short)result;
+}
diff --git a/UT/INQTID.cpp b/UT/INQTID.cpp
new file mode 100644
index 0000000..c98df02
--- /dev/null
+++ b/UT/INQTID.cpp
@@ -0,0 +1,209 @@
+/* ------------------------------ 
+ * Fil: InqTid.c
+ * ------------------------------ */
+#include "stdafx.h"
+
+#ifdef UNIX
+#  ifndef _INCLUDE_POSIX_SOURCE
+#    define _INCLUDE_POSIX_SOURCE
+#  endif
+
+#  ifndef _HPUX_SOURCE
+#    define _HPUX_SOURCE
+#  endif
+
+#  include<stdio.h>
+#  include<sys/time.h>
+#  include<sys/types.h>
+#  include<sys/vfs.h>
+#  include<fcntl.h>
+#  include<sys/stat.h>
+#  include<errno.h>
+#endif
+
+#ifdef OS2
+#  define INCL_DOSFILEMGR
+#  define INCL_DOSERRORS
+#  include <os2.h>
+#endif
+
+#ifdef WIN32
+#  include<windows.h>
+#  include<sys/types.h>
+#  include<sys/stat.h>
+#  include<time.h>
+#endif
+
+#ifdef BORLAND
+#  include<sys/stat.h>
+#  include<time.h>
+#endif
+
+#ifdef LINUX
+#   include <time.h>
+#endif
+
+#include "fyut.h"
+
+/*
+AR-921013
+CH UT_InqPathTid                                Finn oppdateringstid
+CD ==================================================================
+CD Form�l:
+CD Henter oppdateringstidspunktet for gitt fil.
+CD
+CD PARAMETERLISTE:
+CD Type      Navn     I/U  Merknad
+CD ------------------------------------------------------------------
+CD char     *pszPath   i   Filnavn
+CD PFTID     pFilTid   u   Oppdateringstid
+CD short     sStatus   r   Status; 0=OK, annen verdi er feil.
+CD
+CD Bruk:  sStatus = UT_InqPathTid(szPath,&FilTid);
+   ==================================================================
+*/
+SK_EntPnt_UT short UT_InqPathTid(char *pszPath,PFTID pFilTid)
+{
+#ifdef LINUX
+    struct stat buf; 
+    struct tm *ntime;
+    int sStatus;
+    time_t temp;
+
+    /* Hent filopplysninger */
+    sStatus = stat(pszPath,&buf);
+  
+    temp = buf.st_mtime;
+     
+    ntime = localtime(&temp);
+   
+    if (sStatus == 0) {
+        pFilTid->usAar  = (unsigned short)ntime->tm_year;
+        pFilTid->usMnd  = (unsigned short)ntime->tm_mon; 
+        pFilTid->usDag  = (unsigned short)ntime->tm_mday;
+        pFilTid->usTime = (unsigned short)ntime->tm_hour;
+        pFilTid->usMin  = (unsigned short)ntime->tm_min;
+        pFilTid->usSek  = (unsigned short)ntime->tm_sec;
+    }
+
+    return (short)sStatus;
+#else
+#ifdef UNIX
+    struct stat buf; 
+    struct tm ntime;
+    int sStatus;
+    time_t temp;
+
+    /* Hent filopplysninger */
+    sStatus = stat(pszPath,&buf);
+  
+    temp = buf.st_mtime;
+     
+    localtime(&ntime,&temp);
+   
+    if (sStatus == 0) {
+        pFilTid->usAar  = (unsigned short)ntime.tm_year;
+        pFilTid->usMnd  = (unsigned short)ntime.tm_mon; 
+        pFilTid->usDag  = (unsigned short)ntime.tm_mday;
+        pFilTid->usTime = (unsigned short)ntime.tm_hour;
+        pFilTid->usMin  = (unsigned short)ntime.tm_min;
+        pFilTid->usSek  = (unsigned short)ntime.tm_sec;
+    }
+
+    return (short)sStatus;
+#endif
+#endif /*not LINUX*/
+
+#ifdef OS232
+   APIRET rc;
+   FILESTATUS3 PathInfoBuf;
+
+   /* Hent filopplysninger */
+   rc = DosQueryPathInfo(pszPath,FIL_STANDARD,&PathInfoBuf,sizeof(FILESTATUS3));
+
+   if (rc == NO_ERROR) {
+      pFilTid->usAar  = PathInfoBuf.fdateLastWrite.year;
+      pFilTid->usMnd  = PathInfoBuf.fdateLastWrite.month;
+      pFilTid->usDag  = PathInfoBuf.fdateLastWrite.day;
+      pFilTid->usTime = PathInfoBuf.ftimeLastWrite.hours;
+      pFilTid->usMin  = PathInfoBuf.ftimeLastWrite.minutes;
+      pFilTid->usSek  = PathInfoBuf.ftimeLastWrite.twosecs;
+   }
+
+   return (short)rc;
+#endif
+
+#ifdef OS216
+   int rc;
+   FILESTATUS2 PathInfoBuf;
+
+   /* Hent filopplysninger */
+   rc = DosQPathInfo(pszPath,FIL_STANDARD,(PBYTE)&PathInfoBuf,sizeof(FILESTATUS2),0);
+
+   if (rc == NO_ERROR) {
+      pFilTid->usAar  = PathInfoBuf.fdateLastWrite.year;
+      pFilTid->usMnd  = PathInfoBuf.fdateLastWrite.month;
+      pFilTid->usDag  = PathInfoBuf.fdateLastWrite.day;
+      pFilTid->usTime = PathInfoBuf.ftimeLastWrite.hours;
+      pFilTid->usMin  = PathInfoBuf.ftimeLastWrite.minutes;
+      pFilTid->usSek  = PathInfoBuf.ftimeLastWrite.twosecs;
+   }
+
+   return (short)rc;
+#endif
+ 
+
+#ifdef WIN32
+    struct _stat32i64 buf;
+	 struct tm ntime;
+	 int sStatus;
+	 time_t temp;
+
+	 /* Hent filopplysninger */
+	 sStatus = _stat32i64(pszPath,&buf);
+
+    /* Endringstidspunktet */
+	 temp = buf.st_mtime;                 
+    /* Hvis filen ikke er endret brukes opprettelsestidspunktet */
+    if (temp == -1)  temp = buf.st_ctime;
+
+	 localtime_s(&ntime,&temp);
+
+	 if (sStatus == 0) {
+        pFilTid->usAar  = (unsigned short)ntime.tm_year;
+		  pFilTid->usMnd  = (unsigned short)ntime.tm_mon;
+		  pFilTid->usDag  = (unsigned short)ntime.tm_mday;
+		  pFilTid->usTime = (unsigned short)ntime.tm_hour;
+		  pFilTid->usMin  = (unsigned short)ntime.tm_min;
+		  pFilTid->usSek  = (unsigned short)ntime.tm_sec;
+	 }
+
+	 return (short)sStatus;
+#endif
+
+#ifdef BORLAND
+	 struct stat buf;
+	 struct tm ntime;
+	 int sStatus;
+	 time_t temp;
+
+	 /* Hent filopplysninger */
+	 sStatus = stat(pszPath,&buf);
+
+	 temp = buf.st_mtime;
+
+	 localtime(&ntime,&temp);
+
+	 if (sStatus == 0) {
+        pFilTid->usAar  = (unsigned short)ntime.tm_year;
+		  pFilTid->usMnd  = (unsigned short)ntime.tm_mon;
+		  pFilTid->usDag  = (unsigned short)ntime.tm_mday;
+		  pFilTid->usTime = (unsigned short)ntime.tm_hour;
+		  pFilTid->usMin  = (unsigned short)ntime.tm_min;
+		  pFilTid->usSek  = (unsigned short)ntime.tm_sec;
+	 }
+
+	 return (short)sStatus;
+#endif
+
+}
diff --git a/UT/LICENSE b/UT/LICENSE
new file mode 100644
index 0000000..642f5d5
--- /dev/null
+++ b/UT/LICENSE
@@ -0,0 +1,24 @@
+/******************************************************************************
+* STATENS KARTVERK  -  FYSAK
+*
+* Copyright (c) 1990-2011 Statens kartverk
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+* DEALINGS IN THE SOFTWARE.
+******************************************************************************/
+
diff --git a/UT/MAKEPATH.cpp b/UT/MAKEPATH.cpp
new file mode 100644
index 0000000..7fb9628
--- /dev/null
+++ b/UT/MAKEPATH.cpp
@@ -0,0 +1,140 @@
+/*-----------------------------------------------------------------------*
+ * Fil - makepath.c
+ *
+ * funksjon 
+ *        UT_makepath - bygg opp filnavn
+ *-----------------------------------------------------------------------*/
+
+#include "stdafx.h"
+#include "fyut.h"
+
+#ifdef BORLAND
+#	include <windows.h>
+#endif
+#ifdef WIN32
+#	include <windows.h>
+#endif
+
+static char *_stpcpy(char *til, const char *fra);
+
+
+/*---------------------------------------------------------------------*
+
+Name            UT_makepath - bygg opp filnavn
+
+Bruk            #include <fyut.h>
+                void UT_makepath(char *path, const char * drive, const char * dir,
+                                 const char * name, const char * ext);
+
+Prototype i     fyut.h
+
+Beskrivelse     UT_makepath bygger opp et fullstendig filnavn ut fra dets deler.
+                Det nye filnavnet blir
+
+                        X:\DIR\SUBDIR\NAME.EXT
+
+                hvor
+
+                        X er drive
+                        \DIR\SUBDIR\ er gitt av dir
+                        NAME.EXT er gitt av name og ext
+
+                If the drive, dir, name, or ext parameters are null or empty,
+                they are not inserted in the path string.  Otherwise, if
+                the drive doesn't end a colon, one is inserted in the path.
+                If the dir doesn't end in a slash, one is inserted in the
+                path.  If the ext doesn't start with a dot, one is inserted
+                in the path.
+
+                The maximum sizes for the path string is given by the
+                constant _MAX_PATH (defined in stdlib.h), which includes space
+                for the null-terminator.
+
+                UT_splitpath and UT_makepath are invertible; if you split a given
+                path with UT_splitpath, then merge the resultant components
+                with UT_makepath, you end up with path.
+
+Return value    None
+
+*---------------------------------------------------------------------*/
+
+
+/*
+AR-930423
+CH UT_makepath                                    Sl� sammen filnavn
+CD ==================================================================
+CD Form�l:
+CD UT_makepath bygger opp et fullstendig filnavn ut fra dets deler.
+CD Det nye filnavnet blir:  X:\DIR\SUBDIR\NAME.EXT
+CD hvor:                    X er drive
+CD                          \DIR\SUBDIR\ er gitt av dir
+CD                          NAME.EXT er gitt av name og ext
+CD
+CD PARAMETERLISTE:
+CD Type         Navn       I/U  Merknad
+CD --------------------------------------------------------------
+CD char        *pszPath   u   Komplett filnavn
+CD const char  *pszDrive  i   Disk
+CD const char  *pszDir    i   Katalog
+CD const char  *pszNavn   i   Navn
+CD const char  *pszExt    i   Extension
+CD
+CD Bruk:  UT_makepath(szPath,szDrive,szDir,szNavn,szExt);
+   ==================================================================
+*/
+SK_EntPnt_UT void  UT_makepath(char *pathP, const char *driveP, const char *dirP,
+                  const char *nameP, const char *extP)
+{
+#ifdef UNIX
+   if (dirP && *dirP) {
+      if(*(dirP)!=UT_SLASH) {
+         *pathP++=UT_SLASH;
+      }
+      pathP = _stpcpy(pathP,dirP);
+      if (*(pathP-1) != '\\' && *(pathP-1) != '/')  *pathP++ = UT_SLASH;
+   }
+
+   if (nameP)  pathP = _stpcpy(pathP,nameP);
+
+   if (extP && *extP) {
+      if (*extP != '.')  *pathP++ = '.';
+      pathP = _stpcpy(pathP,extP);
+   }
+
+   *pathP = '\0';
+
+#else
+
+   if (driveP && *driveP) {
+      *pathP++ = *driveP;
+      *pathP++ = ':';
+   }
+
+   if (dirP && *dirP) {
+      pathP = _stpcpy(pathP,dirP);
+      if (*(pathP-1) != '\\' && *(pathP-1) != '/')  *pathP++ = UT_SLASH;
+   }
+
+   if (nameP)  pathP = _stpcpy(pathP,nameP);
+
+   if (extP && *extP) {
+      if (*extP != '.')  *pathP++ = '.';
+      pathP = _stpcpy(pathP,extP);
+   }
+
+   *pathP = '\0';
+#endif
+}
+
+
+//====================================================
+static char *_stpcpy(char *til, const char *fra)
+{
+   while (*fra) {
+      *til = *fra;
+      til++;
+      fra++;
+   } /* endwhile */
+
+   return til;
+}
diff --git a/UT/SETSIZE.cpp b/UT/SETSIZE.cpp
new file mode 100644
index 0000000..b65638e
--- /dev/null
+++ b/UT/SETSIZE.cpp
@@ -0,0 +1,210 @@
+/* ------------------------------
+ * Fil: SetSize.c
+ * ------------------------------ */
+
+#include "stdafx.h"
+
+#ifdef LINUX
+#  include <unistd.h>
+#endif
+
+#ifdef OS232
+#  define INCL_DOSFILEMGR
+#  define INCL_DOSERRORS
+#  include <os2.h>
+#endif
+
+#ifdef OS216
+#  define INCL_DOSFILEMGR
+#  define INCL_DOSERRORS
+#  include <os2.h>
+#  include <io.h>
+#endif
+
+#ifdef WIN32
+#	include <windows.h>
+#  include <io.h>
+#  include <Share.h>
+#  include <fcntl.h>
+#  include <sys/types.h>
+#  include <sys/stat.h>
+#  include <stdlib.h>
+#endif
+
+#ifdef BORLAND
+#  include <fcntl.h>
+#  include <sys/stat.h>
+#endif
+
+#include "fyut.h"
+
+/*
+AR-921013
+CH UT_SetPathSize                                  Sett filst�rrelse
+CD ==================================================================
+CD Form�l:
+CD Setter filst�rrelsen for gitt fil.
+CD
+CD PARAMETERLISTE:
+CD Type      Navn     I/U  Merknad
+CD ------------------------------------------------------------------
+CD char     *pszPath   i   Filnavn
+CD long      lSize     i   �nsket filst�rrelse
+CD short     sStatus   r   Status; 0=OK, annen verdi er feil.
+CD
+CD Bruk:  sStatus = UT_SetPathSize(szPath,lSize);
+   ==================================================================
+*/
+
+SK_EntPnt_UT short UT_SetPathSize(char *pszPath,long lSize)
+{
+#ifdef UNIX
+   size_t filesize;
+
+   filesize  = (size_t)lSize;
+   return  (short) truncate(pszPath,filesize);
+#endif
+
+#ifdef OS232
+   APIRET rc;
+   HFILE   FileHandle;
+   ULONG   Action;
+
+   /* UT_FPRINTF(stderr,"SetPathSize: %s: %ld\n",pszPath,lSize); */
+
+   rc = DosOpen(pszPath,                    /* File path name */
+                &FileHandle,                /* File handle */
+                &Action,                    /* Action taken */
+                0,                          /* File primary allocation */
+                FILE_NORMAL,                /* File attribute */
+                OPEN_ACTION_FAIL_IF_NEW |    /* Open function type */
+                OPEN_ACTION_OPEN_IF_EXISTS,
+                OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_READWRITE, /* Open mode of the file */
+                NULL);                      /* No extended attributes */
+
+   if (rc == NO_ERROR) {
+      rc = DosSetFileSize(FileHandle,(ULONG)lSize);
+      DosClose(FileHandle);
+	}
+
+	return (short)rc;
+#endif
+
+#ifdef OS216
+   int rc;
+   HFILE   FileHandle;
+   USHORT   Action;
+
+   rc = DosOpen(pszPath,                    /* File path name */
+                &FileHandle,                /* File handle */
+                &Action,                    /* Action taken */
+                0,                          /* File primary allocation */
+                FILE_NORMAL,                /* File attribute */
+                OPEN_ACTION_FAIL_IF_NEW |   /* Open function type */
+                OPEN_ACTION_OPEN_IF_EXISTS,
+                OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_READWRITE, /* Open mode of the file */
+                0L);                      /* No extended attributes */
+
+   if (rc == NO_ERROR) {
+      rc = chsize(FileHandle,lSize);
+		DosClose(FileHandle);
+   }
+
+	return (short)rc;
+#endif
+
+
+#ifdef WIN32
+   int fh,rc;
+
+	//fh = _open( pszPath, _O_RDWR | _O_BINARY | _O_RANDOM );
+   _sopen_s(&fh, pszPath, _O_RDWR | _O_BINARY | _O_RANDOM, _SH_DENYRW, _S_IREAD | _S_IWRITE);
+
+	 if (fh != -1) {
+		  rc = _chsize(fh,lSize);
+		  _close(fh);
+
+	 }  else {
+		rc = fh;
+	}
+
+	 return (short)rc;
+#endif
+
+#ifdef BORLAND
+	 int fh,rc;
+
+
+	 fh = open( pszPath, O_RDWR | O_BINARY);
+
+	 if (fh != -1) {
+		  rc = chsize(fh,lSize);
+		  close(fh);
+
+	 }  else {
+		rc = fh;
+	}
+
+	 return (short)rc;
+#endif
+}
+
+
+#ifdef WIN32
+/*
+AR-921013
+CH UT_SetPathSize_i64                              Sett filst�rrelse
+CD ==================================================================
+CD Form�l:
+CD Setter filst�rrelsen for gitt fil.
+CD
+CD PARAMETERLISTE:
+CD Type      Navn     I/U  Merknad
+CD ------------------------------------------------------------------
+CD char     *pszPath   i   Filnavn
+CD UT_INT64  n64Size   i   �nsket filst�rrelse
+CD short     sStatus   r   Status; 0=OK, annen verdi er feil.
+CD
+CD Bruk:  sStatus = UT_SetPathSize_i64(szPath,lSize);
+   ==================================================================
+*/
+SK_EntPnt_UT short UT_SetPathSize_i64(char *pszPath, UT_INT64 n64Size)
+{
+   int fh,rc;
+
+   //fh = _open( pszPath, _O_RDWR | _O_BINARY | _O_RANDOM );
+   _sopen_s(&fh, pszPath, _O_RDWR | _O_BINARY | _O_RANDOM, _SH_DENYRW, _S_IREAD | _S_IWRITE);
+  
+   // �pnet OK
+   if (fh != -1)
+   {
+      rc = _chsize_s(fh,n64Size);
+
+      // _chsize_s returns the value 0 if the file size is successfully changed.
+      if (rc != 0)
+      {
+         char szError[256];
+         UT_strerror(szError,256,errno);
+         UT_FPRINTF(stderr,"(UT_SetPathSize_i64)Feil ved endring av filst�rrelse (_chsize_s). (%s, Posisjon:%ld, Feil:%s)\n",pszPath,n64Size,szError);
+      }
+
+      _close(fh);
+   } 
+
+   // Feil ved fil�pning
+   else
+   {
+      char szError[256];
+      UT_strerror(szError,256,errno);
+      UT_FPRINTF(stderr,"(UT_SetPathSize_i64)Feil ved fil�pning. (%s, Feil:%s)\n",pszPath,szError);
+      rc = fh;
+   }
+
+   return (short)rc;
+}
+#else
+SK_EntPnt_UT short UT_SetPathSize_i64(char *pszPath, UT_INT64 n64Size)
+{
+	return UT_SetPathSize(pszPath, n64Size);
+}
+#endif
diff --git a/UT/SPLITPTH.cpp b/UT/SPLITPTH.cpp
new file mode 100644
index 0000000..eb0a38e
--- /dev/null
+++ b/UT/SPLITPTH.cpp
@@ -0,0 +1,226 @@
+/*------------------------------------------------------------------------
+ * filename - spltpath.c
+ *
+ * function(s)
+ *        DotFound - checks for special directory names
+ *        UT_splitpath - split a full path name (MSC compatible)
+ *-----------------------------------------------------------------------*/
+
+/*
+ *      C/C++ Run Time Library - Version 5.0
+ *
+ *      Copyright (c) 1987, 1992 by Borland International
+ *      All Rights Reserved.
+ *
+ */
+
+#include "stdafx.h"
+#include <string.h>
+
+#ifdef BORLAND
+#include <windows.h>
+#endif
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+
+#include "fyut.h"
+
+
+/*---------------------------------------------------------------------*
+
+Name            DotFound - checks for special dir name cases
+
+Usage           int DotFound(char *pB);
+
+Prototype in    local to this module
+
+Description     checks for special directory names
+
+*---------------------------------------------------------------------*/
+static size_t DotFound(char *pB)
+{
+        if (*(pB-1) == '.')
+                pB--;
+        switch (*--pB) {
+           case ':'  :
+              if (*(pB-2) != '\0') {
+                 break;
+              } else {
+                 return UT_TRUE;
+              }
+           case '/'  :
+           case '\\' :
+           case '\0' :
+              return UT_TRUE;
+        }
+        return UT_FALSE;
+}
+
+/*---------------------------------------------------------------------*
+
+Name            UT_splitpath - splits a full path name into its components
+
+Usage           #include <fyut.h>
+                void UT_splitpath(const char *path, char * drive, char * dir,
+                             char * name, char * ext);
+
+Related
+functions usage void UT_makepath(char *path, const char *drive, const char *dir,
+                            const char *name, const char *ext);
+
+Prototype in    fyut.h
+
+Description     UT_splitpath takes a file's full path name (path) as a string
+                in the form
+
+                        X:\DIR\SUBDIR\NAME.EXT
+
+                and splits path into its four components. It then stores
+                those components in the strings pointed to by drive, dir,
+                name and ext. (Each component is required but can be a
+                NULL, which means the corresponding component will be
+                parsed but not stored.)
+
+                The maximum sizes for these strings are given by the
+                constants _MAX_DRIVE, _MAX_DIR, _MAX_PATH, _MAX_NAME and _MAX_EXT,
+                (defined in fyut.h) and each size includes space for the
+                null-terminator.
+
+                UT_splitpath assumes that there is enough space to store each
+                non-NULL component. fnmerge assumes that there is enough
+                space for the constructed path name. The maximum constructed
+                length is _MAX_PATH.
+
+                When UT_splitpath splits path, it treats the punctuation as
+                follows:
+
+                * drive keeps the colon attached (C:, A:, etc.)
+
+                * dir keeps the leading and trailing backslashes
+                  (\turboc\include\,\source\, etc.)
+
+                * ext keeps the dot preceding the extension (.c, .exe, etc.)
+
+                UT_splitpath and _makepath are invertible; if you
+                split a given path with UT_splitpath, then
+                merge the resultant components with UT_makepath, you end up
+                with path.
+
+Return value    UT_splitpath does not return a value.
+
+*---------------------------------------------------------------------*/
+
+
+/*
+AR-930423
+CH UT_splitpath                                       Splitt filnavn
+CD ==================================================================
+CD Form�l:
+CD UT_splitpath splitter et fullstendig filnavn i enkelte komponenter.
+CD Filnavnet:  X:\DIR\SUBDIR\NAME.EXT
+CD blir til:      X er drive
+CD                \DIR\SUBDIR\ er gitt av dir
+CD                NAME.EXT er gitt av name og ext
+CD
+CD PARAMETERLISTE:
+CD Type         Navn       I/U  Merknad
+CD --------------------------------------------------------------
+CD char        *pszPath   i   Komplett filnavn
+CD const char  *pszDrive  u   Disk
+CD const char  *pszDir    u   Katalog
+CD const char  *pszNavn   u   Navn
+CD const char  *pszExt    u   Extension
+CD
+CD Bruk:  UT_splitpath(szPath,szDrive,szDir,szNavn,szExt);
+   ==================================================================
+*/
+SK_EntPnt_UT void UT_splitpath(const char *pathP, char *driveP, char *dirP,
+                  char *nameP, char *extP)
+{
+        char   *pB;
+        size_t Wrk;
+        int    ExtFunnet;
+
+        char buf[ _MAX_PATH+2 ];
+
+        /*
+         * Set all string to default value zero
+         */
+        ExtFunnet = UT_FALSE;
+        if (driveP)
+                *driveP = 0;
+        if (dirP)
+                *dirP = 0;
+        if (nameP)
+                *nameP = 0;
+        if (extP)
+                *extP = 0;
+
+        /*
+         * Copy filename into template up to _MAX_PATH characters
+         */
+        pB = buf;
+        while (*pathP == ' ')
+                pathP++;
+
+        if ((Wrk = strlen(pathP)) >= _MAX_PATH)
+                Wrk = _MAX_PATH - 1;
+        *pB++ = 0;
+        UT_StrCopy(pB, pathP, Wrk+1);
+
+        *(pB += Wrk) = 0;
+
+        /*
+         * Split the filename and fill corresponding nonzero pointers
+         */
+        Wrk = 0;
+        for (; ; ) {
+                switch (*--pB) {
+                case '.'  :
+                        if (!Wrk && (*(pB+1) == '\0'))
+                                Wrk = DotFound(pB);
+                        if ((!Wrk) && (!ExtFunnet)) {
+                                ExtFunnet = UT_TRUE;
+                                UT_StrCopy(extP, pB, _MAX_EXT);
+                                *pB = 0;
+                        }
+                        continue;
+                case ':'  :
+                        if (pB != &buf[2])
+                                continue;
+                case '\0' :
+                        if (Wrk) {
+                                pB++;
+                                UT_StrCopy(dirP, pB, _MAX_DIR);
+                                *pB-- = 0;
+                                break;
+                        }
+                case '/'  :
+                case '\\' :
+                        if (!Wrk) {
+                                Wrk++;
+                                pB++;
+                                UT_StrCopy(nameP, pB, _MAX_FNAME);
+                                *pB-- = 0;
+                                if (*pB == 0 || (*pB == ':' && pB == &buf[2]))
+                                        break;
+                        }
+                        continue;
+
+                case '*'  :
+                case '?'  :
+                        continue;
+
+                default :
+                        continue;
+                }
+                break;
+        }
+
+        if (*pB == ':') {
+                UT_StrCopy(driveP, &buf[1], _MAX_DRIVE);
+        }
+}
diff --git a/UT/StrtPros.cpp b/UT/StrtPros.cpp
new file mode 100644
index 0000000..e348918
--- /dev/null
+++ b/UT/StrtPros.cpp
@@ -0,0 +1,122 @@
+/* ------------------------------
+ * Fil: StrtPros.c
+ * ------------------------------ */
+
+#include "stdafx.h"
+
+#ifdef UNIX
+#  ifndef _INCLUDE_POSIX_SOURCE
+#    define _INCLUDE_POSIX_SOURCE
+#  endif
+#  ifndef _HPUX_SOURCE
+#    define _HPUX_SOURCE
+#  endif
+#endif
+
+#ifdef OS2
+#endif
+
+#ifdef WIN32
+#  include<windows.h>
+#endif
+
+#ifdef BORLAND
+#endif
+
+#include "fyut.h"
+
+
+/*
+AR-961118
+CH  UT_StartProsess      
+CD  ==============================================================
+CD  Form�l:
+CD  Starter en ny prosess.
+CD
+CD  PARAMETERLISTE:
+CD  Type   Navn           I/U Merknad
+CD  ------------------------------------------------------------- 
+CD  char  *pszCommandLine  i  Kommandolinje
+CD  short  sVent           i  UT_VENT = Vent til prosessen avsluttes
+CD                            UT_FORTSETT = Ikke vent
+CD short  sStatus          r  Status:
+CD                              UT_TRUE = OK
+CD                              UT_FALSE = Feil.
+CD
+CD
+CD  Bruk:
+CD  sStatus = UT_StartProsess(szKommandolinje,UT_VENT);
+CD
+CD  ==============================================================
+*/
+SK_EntPnt_UT short UT_StartProsess(char *pszCommandLine,short sVent)
+{
+
+#ifdef WIN32
+   PROCESS_INFORMATION ProcessInfo;
+   STARTUPINFO StartupInfo;
+   DWORD ExitCode = 0;
+   //char szCurrentDir[_MAX_PATH];
+   //char szShortPath[100];
+
+
+   // Setter opp oppstartinformasjon
+   StartupInfo.cb = sizeof(STARTUPINFO); 
+   StartupInfo.lpDesktop = NULL; 
+   StartupInfo.lpTitle = NULL; 
+   StartupInfo.cbReserved2 = 0;
+   StartupInfo.lpReserved = NULL; 
+   StartupInfo.lpReserved2 = NULL;
+   StartupInfo.dwFlags = 0;
+   //   STARTF_USESTDHANDLES	If this value is specified, sets the standard input of the process, standard output,
+   //                        and standard error handles to the handles specified in the hStdInput, hStdOutput, 
+   //                        and hStdError members of the STARTUPINFO structure. The CreateProcess function's fInheritHandles
+   //                        parameter must be set to TRUE for this to work properly.
+	//                        If this value is not specified, the hStdInput, hStdOutput, and hStdError members of the STARTUPINFO
+   //                        structure are ignored.
+
+   //StartupInfo.dwX; 
+   //StartupInfo.dwY; 
+   //StartupInfo.dwXSize; 
+   //StartupInfo.dwYSize; 
+   //StartupInfo.dwXCountChars; 
+   //StartupInfo.dwYCountChars; 
+   //StartupInfo.dwFillAttribute; 
+   //StartupInfo.wShowWindow; 
+   //StartupInfo.hStdInput; 
+   //StartupInfo.hStdOutput; 
+   //StartupInfo.hStdError; 
+
+
+   //GetCurrentDirectory(_MAX_PATH,szCurrentDir);
+   //GetShortPathName(szCurrentDir,szShortPath,100);
+
+   // Utf�rer system-kommando
+   if ( ! CreateProcess(NULL, pszCommandLine, NULL, NULL, FALSE,
+                        NORMAL_PRIORITY_CLASS , 
+                                  //CREATE_NEW_CONSOLE	
+                                  //CREATE_NEW_PROCESS_GROUP	
+                                  //CREATE_SEPARATE_WOW_VDM	
+                                  //CREATE_SHARED_WOW_VDM	
+                        NULL, NULL, &StartupInfo, &ProcessInfo)) {
+      return UT_FALSE;
+   }   
+
+   // Vent til prosessen er ferdig
+   if (sVent == UT_VENT) {
+      WaitForSingleObject( ProcessInfo.hProcess, INFINITE);
+
+      //Retrieves the termination status of the specified process.
+      GetExitCodeProcess(ProcessInfo.hProcess, &ExitCode);
+   }
+
+   CloseHandle(ProcessInfo.hProcess);
+   CloseHandle(ProcessInfo.hThread);
+   
+   return (ExitCode == 0)? UT_TRUE:UT_FALSE;
+
+#else
+
+   return UT_FALSE;
+#endif
+}
diff --git a/UT/UT1.cpp b/UT/UT1.cpp
new file mode 100644
index 0000000..ccd17a4
--- /dev/null
+++ b/UT/UT1.cpp
@@ -0,0 +1,817 @@
+/***************************************************************************
+*                                                                           *
+*       Hjelpebiblioteket   U T  (Utilities)                                *
+*       Georg Langerak, Statens Kartverk / FYSAK-prosjektet, januar 1989    *
+*       Fil: UT1.C : Filhandtering                                          *
+*                                                                           *
+****************************************************************************/
+
+/*
+CH  UT1                                                 Leser-p�-Disk
+CD  ==================================================================
+CD  Rutiner for � �pne, posisjonere og lese/skrive p� filer �pnet
+CD  for bin�r les/skriv som stream.
+CD  ==================================================================
+CD
+CH  INSTALLERINGS- OG BRUKS-OPPLYSNINGER:
+CD
+CD  Bibliotek..: UTLE.LIB
+CD  Kildefiler.: UT1.C + fyut.h
+CD  Versjon....: E00
+CD  Eier.......: STATENS KARTVERK / FYSAK-prosjektet
+CD  Ansvarlig..: Georg Langerak / Andreas R�stad
+CD
+CD  #include...: fyut.h
+CD  ==================================================================
+*/ 
+
+#include "stdafx.h"
+
+#ifdef OS2
+#   define INCL_DOSFILEMGR
+#   define INCL_DOSERRORS
+#   include <os2.h>
+#endif
+
+#ifdef UNIX
+#  ifndef _INCLUDE_POSIX_SOURCE
+#     define _INCLUDE_POSIX_SOURCE
+#  endif
+#  ifndef _HPUX_SOURCE
+#     define _HPUX_SOURCE
+#  endif
+#  include<sys/stat.h>
+#endif
+
+#ifdef LINUX /*This is just a quick fix. The two parameter versions of these are just not portable.*/
+#   define strcpy_s strcpy
+#   define strcat_s strcat 
+#endif
+
+#ifdef WIN32
+#  include <sys/stat.h>
+#endif
+
+#ifdef BORLAND
+#  include <sys/stat.h>
+#endif
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+#ifndef LINUX
+  #include <share.h>
+#endif
+
+#include "fyut.h"
+
+/*******************************************************************************
+*                                                                              *
+*       RUTINER FOR VERSJONSKONTROLL                                         *
+*                                                                              *
+*******************************************************************************/
+
+/*
+GL-890215
+AR-911006
+CH UT_OpenFile                                          �pner og sjekker fil
+CD ==========================================================================
+CD Bruk:
+CD  fp = UT_OpenFile("TULLFILA","DAT",READ,OLD,&ierr);
+CD
+CD Parametre:
+CD Type        Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD const char *fnam       i    Filnavn inkl. type (Max 46 tegn inkl. '\0')
+CD const char *ftyp       i    Filtype (extention) (Max 4 tegn inkl. '\0')
+CD short   facc        i    Aksess (0=UT_READ,1=UT_WRITE,2=UT_UPDATE)
+CD short   exist       i    �pningstatus (0=UT_UNKNOWN,1=UT_OLD,2=UT_NEW)
+CD short   &ierr       u    (UT_OK,UT_ERROR eller skriv printf(strerror(ierr));
+CD FILE    filpeker    r    filpeker.
+CD
+CD Form�l:
+CD     �pner en fil med angitt aksess og �pningstatus.
+CD     returnerer status som kan benyttes videre eller utskrives
+	==========================================================================
+*/
+SK_EntPnt_UT FILE *UT_OpenFile(const char *filnavn,const char *ftyp,short facc,short exist,short *ierr)
+{
+	FILE *fp;
+	char mode[4];
+	char drive[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
+	char path[_MAX_PATH];
+	int filslutt = 0;
+
+#  ifdef OS232
+		FILESTATUS3 PathInfoBuf;
+		APIRET rc;
+#  endif
+
+#  ifdef OS216
+		FILESTATUS PathInfoBuf;
+		int rc;
+#  endif
+
+#  ifdef UNIX
+		struct stat buf;
+		int status;
+#  endif
+
+#ifdef WIN32
+		//struct _stat buf;
+        struct _stat32i64 buf32i64;
+		int status;
+#endif
+
+#ifdef BORLAND
+		struct stat buf;
+		int status;
+#endif
+
+   /* Lag fullstendig filnavn */
+	UT_FullPath(path,filnavn,_MAX_PATH);
+
+	/* Splitt filnavnet */
+	UT_splitpath(path,drive,dir,fname,ext);
+
+	/* Ikke gitt filtype */
+	if (*ext == '\0') {
+		if (ftyp != NULL) {
+			if (*ftyp != '\0') {
+				strcpy_s(ext,".");
+				strcat_s(ext,ftyp);
+			}
+		}
+	}
+
+	/* Bygg opp filnavnet igjen */
+	UT_makepath(path,drive,dir,fname,ext);
+
+	mode[0] = '\0';
+
+	/* UT_FPRINTF(stderr,"\nFilnavn \"%s\"\n",path); */
+
+	/* Hent filopplysninger */
+#  ifdef OS232
+		rc = DosQueryPathInfo(path,FIL_STANDARD,&PathInfoBuf,sizeof(FILESTATUS3));
+		/* UT_FPRINTF(stderr,"Fra DosQeryPathInfo rc = %d\n",rc); */
+#  endif
+#  ifdef OS216
+		rc = DosQPathInfo(path,FIL_STANDARD,(PBYTE)&PathInfoBuf,sizeof(FILESTATUS),0);
+#  endif
+#  ifdef UNIX
+		status =  stat(path,&buf);
+#  endif
+#  ifdef WIN32
+		//status = _stat(path,&buf);
+      status = _stat32i64(path,&buf32i64);
+      /*
+      if (status == -1){
+         char szError[256];
+         UT_strerror(szError,256,errno);
+         szError[255] = '\0';
+      }
+      */
+
+#  endif
+
+#  ifdef BORLAND
+		status =  stat(path,&buf);
+#  endif
+
+
+	/* Setter sammen flagg for �pningsmodus */
+	if (facc == UT_READ && exist == UT_UNKNOWN) {
+		/* Hvis filen IKKE eksisterer */
+#     ifdef OS2
+		if (rc == ERROR_FILE_NOT_FOUND) {
+#     endif
+#     ifdef UNIX
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+#     ifdef WIN32
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+#     ifdef BORLAND
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+			strcpy_s(mode,"wb+");
+		} else {      /* Filen finnes fra f�r */
+			strcpy_s(mode,"rb");
+		}
+	} else if (facc == UT_READ  && exist == UT_OLD) {
+		/* Filen finnes ikke */
+
+#     ifdef OS2
+		if (rc == ERROR_FILE_NOT_FOUND) {
+#     endif
+#     ifdef UNIX
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+#     ifdef WIN32
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+#     ifdef BORLAND
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+			*ierr = ENOENT;
+			return (NULL);     /* ===> RETUR */
+		}
+
+		strcpy_s(mode,"rb");
+
+	} else if (facc == UT_READ  && exist == UT_NEW) {
+		/* Sjekk at filen IKKE eksisterer */
+#     ifdef OS2
+		if (rc == ERROR_FILE_NOT_FOUND) {
+#     endif
+#     ifdef UNIX
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+#     ifdef WIN32
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+#     ifdef BORLAND
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+			strcpy_s(mode,"wb+");
+		} else {
+			*ierr = EEXIST;
+			return (NULL);     /* ===> RETUR */
+		}
+
+	} else if (facc == UT_WRITE && exist == UT_UNKNOWN) {
+		strcpy_s(mode,"wb+");
+
+	} else if (facc == UT_WRITE && exist == UT_OLD) {
+		/* Filen finnes ikke */
+#     ifdef OS2
+		if (rc == ERROR_FILE_NOT_FOUND) {
+#     endif
+#     ifdef UNIX
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+#     ifdef WIN32
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+#     ifdef BORLAND
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+			*ierr = ENOENT;
+			return (NULL);     /* ===> RETUR */
+		}
+
+		/* Hvis filen er OK */
+#     ifdef OS2
+		if (rc == NO_ERROR) {
+#     endif
+#     ifdef UNIX
+		if (status == 0) {
+#     endif
+#     ifdef WIN32
+		if (status == 0) {
+#     endif
+#     ifdef BORLAND
+		if (status == 0) {
+#     endif
+			strcpy_s(mode,"wb+");
+		}
+
+	} else if (facc == UT_WRITE && exist == UT_NEW) {
+		/* Sjekk at filen IKKE eksisterer */
+#     ifdef OS2
+		if (rc == ERROR_FILE_NOT_FOUND) {
+#     endif
+#     ifdef UNIX
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+#     ifdef WIN32
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+#     ifdef BORLAND
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+			strcpy_s(mode,"wb+");
+		}
+
+	} else if (facc == UT_UPDATE && exist == UT_UNKNOWN) {
+		/* Hvis filen IKKE eksisterer */
+#     ifdef OS2
+			if (rc == ERROR_FILE_NOT_FOUND) {
+#     endif
+#     ifdef UNIX
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+#     ifdef WIN32
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+#     ifdef BORLAND
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+			strcpy_s(mode,"wb+");
+
+		} else {      /* Filen finnes fra f�r */
+			strcpy_s(mode,"rb+");
+			filslutt=1;
+		}
+
+	} else if (facc == UT_UPDATE  &&  exist == UT_OLD) {
+		/* Filen finnes ikke */
+#     ifdef OS2
+		if (rc == ERROR_FILE_NOT_FOUND) {
+#     endif
+#     ifdef UNIX
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+#     ifdef WIN32
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+#     ifdef BORLAND
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+			*ierr = ENOENT;
+			return (NULL);     /* ===> RETUR */
+		}
+
+		strcpy_s(mode,"rb+");
+		filslutt=1;
+
+	} else if (facc == UT_UPDATE  &&  exist == UT_NEW) {
+		/* Sjekk at filen IKKE eksisterer */
+#     ifdef OS2
+		if (rc == ERROR_FILE_NOT_FOUND) {
+#     endif
+#     ifdef UNIX
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+#     ifdef WIN32
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+#     ifdef BORLAND
+		if (status == -1  &&  errno == ENOENT) {
+#     endif
+			strcpy_s(mode,"wb+");
+		}
+
+	} else {                                    /* Ugyldig kombinasjon */
+		*ierr=UT_ERROR;
+		return(NULL);
+	}
+
+/*
+_SH_COMPAT : Sets compatibility mode
+_SH_DENYRW : Denies read and write access to file
+_SH_DENYWR : Denies write access to file
+_SH_DENYRD : Denies read access to file
+_SH_DENYNO : Permits read and write access
+_SH_SECURE : Sets secure mode (shared read, exclusive write access).
+*/
+
+																
+   // ----- Selve fil�pningen
+	if (mode[0] != '\0') {
+#ifdef UNIX
+         fp = fopen(path,mode); 
+#else
+      if (mode[0] == 'w' || mode[2] == '+')
+      {
+         fp = _fsopen(path,mode,_SH_DENYWR);   // Sperrer mot at andre �pner filen for skriving, godtar lesing
+      }           
+      else
+      {
+         fp = _fsopen(path,mode,_SH_DENYNO);
+      }
+#endif
+
+
+      if (fp  == NULL)
+      {
+			*ierr = errno;
+		}
+
+      else
+      {
+			*ierr =UT_OK;
+			if (filslutt)
+         {
+				// Posisjoner p� slutten av filen
+#           ifdef OS2
+					UT_SetPos(fp,(long)PathInfoBuf.cbFile);
+#           endif
+#           ifdef UNIX
+					UT_SetPos(fp,(long)buf.st_size);
+#           endif
+#           ifdef WIN32
+					UT_SetPos_i64(fp,buf32i64.st_size);
+#           endif
+#           ifdef BORLAND
+					UT_SetPos(fp,(long)buf.st_size);
+#           endif
+			}
+		}
+
+		/* UT_FPRINTF(stderr,"Ierr: %d\n",*ierr); */
+		/* UT_FPRINTF(stderr,strerror(*ierr)); */
+	}
+
+   else 
+   {
+		*ierr = UT_ERROR;
+		return (NULL);
+	}
+
+	if (*ierr != UT_OK)  fp=NULL;
+	
+   return fp;
+}
+
+
+/*
+GL-890105
+CH UT_ReadLineCrlf                     Leser en linje inkl cl/lf
+CD ==================================================================
+CD Form�l......:  Leser en linje inkl. Crlf fra current posisjon.
+CD
+CD Aktivisering:  ist = UT_ReadLineCrlf(fil,llin,clin);
+CD
+CD Retur-verdier: short  UT_OK  - Lesing er ok
+CD                short  UT_EOF - Du har lest End Of File
+CD                short  UT_ERROR - Du har f�tt feil ved lesingen
+CD
+CD PARAMETERLISTE:
+CD Navn      Type    i/U Merknad
+CD --------------------------------------------------------------
+CD pfil      FILE     i   Peker til filstruktur (def i stdio.h)
+CD llin      short    i   Max lengde p� clin inkl (\r\n\0)
+CD clin      *char    u   Streng les. M� v�re 3 st�rre enn behov.
+	==================================================================
+*/
+SK_EntPnt_UT short UT_ReadLineCrlf(FILE *pfil,short llin, char *clin)
+{
+#ifdef UTGAAR
+   short ierr = UT_OK;
+
+   if (fgets(clin,llin,pfil) == NULL) {
+	   if      (feof(pfil))   ierr = UT_EOF;
+	   else if (ferror(pfil)) ierr = UT_ERROR;
+   }
+   if ((int)*clin == 26) ierr = UT_EOF;      /* LS-890928 */
+   return (ierr);
+#endif
+
+
+   char *cp = clin;
+   char *siste = clin + llin - 1;
+   short ierr = UT_OK;
+   int c;
+
+   while (cp < siste) {
+      c = getc(pfil);
+      if (c == EOF) {
+	      if (feof(pfil)) {
+            if (cp == clin)  ierr = UT_EOF;
+         } else if (ferror(pfil)) {
+            ierr = UT_ERROR;
+         }
+         break;
+
+      } else if (c == '\n') {
+         *cp = c;
+         cp++;
+         break;
+
+      } else if (c == '\0') {
+         *cp = ' ';
+
+      } else {
+         *cp = c;
+      }
+
+      cp++;
+   }
+
+   *cp = '\0';
+
+   if ((int)*clin == 26) ierr = UT_EOF;      /* LS-890928 */
+
+
+   return (ierr);
+}
+
+
+/*
+GL-890105
+CH UT_ReadLine                        Leser en linje og fjerner crlf
+CD ==================================================================
+CD Aktivisering:  ist = UT_ReadLine(fil,llin,clin);
+CD
+CD Retur-verdier: short  UT_OK  - Lesing er ok
+CD                short  UT_EOF - Du har lest End Of File
+CD                short  UT_ERROR - Du har f�tt feil ved lesingen
+CD
+CD PARAMETERLISTE:
+CD Navn    Type   i/U Merknad
+CD -----------------------------------------------------------
+CD pfil    FILE    i   Peker til filstruktur (def i stdio.h)
+CD llin    short   i   Max lengde p� clin inkl '\0'
+CD clin    *char   u   Streng lest. M� v�re 3 st�rre enn faktisk.
+	==================================================================
+*/
+SK_EntPnt_UT short UT_ReadLine(FILE *pfil,short llin, char *clin)
+{
+#ifdef UTGAAR
+	short ierr = UT_OK;
+	size_t len;
+									  /* Leser en linje */
+	if   (fgets(clin,llin,pfil) == NULL) {
+	   if (feof(pfil))  ierr = UT_EOF;
+	   else             ierr = UT_ERROR;
+	}
+	if ((int)*clin == 26) ierr = UT_EOF;      /* LS-890928 */
+									  /* Fjerner Crlf */
+	len = strlen(clin);
+	if  (len > 1) {
+	   if      (clin[len-2] == '\r') clin[len-2]=clin[len-1]='\0'; /* crlf */
+	   else if (clin[len-1] == '\n') clin[len-1]='\0';             /* lf */
+	}
+	return (ierr);
+#endif
+
+
+   char *cp = clin;
+   char *siste = clin + llin - 1;
+   short ierr = UT_OK;
+   int c;
+
+   while (cp < siste) {
+      c = getc(pfil);
+      if (c == EOF) {
+	      if (feof(pfil)) {
+            if (cp == clin)  ierr = UT_EOF;
+         } else if (ferror(pfil)) {
+            ierr = UT_ERROR;
+         }
+         break;
+      
+      } else if (c == '\n') {
+         *cp = c;
+         cp++;
+         break;
+
+      } else if (c == '\0') {
+         *cp = ' ';
+
+      } else {
+         *cp = c;
+      }
+
+      cp++;
+   }
+
+   *cp = '\0';
+
+   if ((int)*clin == 26) ierr = UT_EOF;      /* LS-890928 */
+
+
+   /* Fjerner Crlf */
+   if (cp-clin > 1) {
+	   if (*(cp-2) == '\r') {
+         *(cp-2) = *(cp-1) = '\0'; /* crlf */
+      } else if (*(cp-1) == '\n') {
+         *(cp-1) = '\0';             /* lf */
+      }
+	}
+
+   return (ierr);
+}
+
+
+/*
+GL-890308
+CH UT_ReadLineNoComm             Leser linjer og fjerner kommentarer
+CD ==================================================================
+CD Aktivisering :  ist = UT_ReadLineNoComm(fil,llin,clin);
+CD
+CD Retur-verdier: short  UT_OK  - Lesing er ok
+CD                short  UT_EOF - Du har lest End Of File
+CD                short  UT_ERROR - Du har f�tt feil ved lesingen
+CD
+CD PARAMETERLISTE:
+CD Type     Navn    i/U Merknad
+CD ------------------------------------------------------------------
+CD FILE     fi       i   Peker til filstruktur (def i stdio.h)
+CD short    llin     i   Max lengde p� clin inkl \r\n\0.(cr+lf)
+CD char    *clin     u   Streng lest. (Uten \r\n. (cr+lf))
+CD
+CD Form�l:
+CD Leser en linje fra filen, og fjerner CrLf. Hvis linjen er blank
+CD eller f�rste "ikke-blanke-tegn" er utropstegn leses p�f�lgende linje(r).
+	==================================================================
+*/
+SK_EntPnt_UT short UT_ReadLineNoComm(FILE *pfil,short llin, char *clin)
+{
+	short ierr;
+	register char *cp=NULL;
+
+	do{
+		 ierr = UT_ReadLine(pfil,llin,clin);
+		 if (ierr == UT_OK){
+			  for (cp=clin;  UT_IsSpace(*cp) && *cp;  cp++){
+					;
+			  }
+		 }
+	} while (ierr == UT_OK && (!*cp || *cp=='!'));
+
+	/* Fjern blanke p� slutten */
+	if (ierr == UT_OK) {
+		UT_ClrTrailsp(clin);
+	}
+
+	return (ierr);
+}
+
+
+/*
+GL-890107
+CH UT_WriteLineCrlf                      Skriver en linje incl crlf
+CD ==================================================================
+CD Form�l......:  Skriver en linje som alt HAR Crlf p� slutten .
+CD
+CD Aktivisering:  ist = UT_WriteLineCrlf(fil,clin);
+CD
+CD Retur-verdier: short  UT_OK  - Lesing er ok
+CD                short  UT_ERROR - Du har f�tt feil ved lesingen
+CD
+CD PARAMETERLISTE:
+CD Navn      Type    i/U Merknad
+CD --------------------------------------------
+CD pfil      FILE     i   Peker til filstruktur (def i stdio.h)
+CD clin      char[]   i   Streng som skal skrives (m� ha \r\n\0 )
+   ==================================================================
+*/
+SK_EntPnt_UT short UT_WriteLineCrlf(FILE *pfil,char clin[])
+{
+      fputs(clin,pfil);
+      if (ferror(pfil))  return UT_ERROR;
+      return UT_OK;
+}
+
+
+/*
+GL-890107
+CH UT_WriteLine                           Skriver en linje uten crlf
+CD ==================================================================
+CD Form�l......:  Skriver en linje og legger p� Crlf etterp� .
+CD
+CD Aktivisering:  ist = UT_WriteLine(fil,clin);
+CD
+CD Retur-verdier: short  UT_OK  - Lesing er ok
+CD                short  UT_ERROR - Du har f�tt feil ved lesingen
+CD
+CD PARAMETERLISTE:
+CD Navn      Type    i/U Merknad
+CD --------------------------------------------
+CD pfil      FILE     i   Peker til filstruktur (def i stdio.h)
+CD clin      char[]   i   Streng som skal skrives.
+   ==================================================================
+*/
+SK_EntPnt_UT short UT_WriteLine(FILE *pfil,char clin[])
+{
+      fputs(clin,pfil);
+		fputs("\r\n",pfil);
+      if (ferror(pfil)) return(UT_ERROR);
+      return(UT_OK);
+}
+
+
+/*
+GL-880809
+CH UT_Save                             Berger diskbuffer ut p� disk.
+CD ==================================================================
+CD Form�l......:  Sikre at at operativsystemets filbuffer
+CD                blir disklagret. (Sikre mot str�mstans etc.)
+CD
+CD Aktivisering:  UT_Save(fil);
+CD
+CD Retur-verdier: short  UT_OK  - Lesing er ok
+CD                short  UT_ERROR - Du har f�tt feil ved flushingen
+CD
+CD PARAMETERLISTE:
+CD Navn      Type  Array i/U Merknad
+CD ------------------------------------------------------------------
+CD pfil      FILE         i   Peker til filstruktur (def i stdio.h)
+   ==================================================================
+*/
+SK_EntPnt_UT short UT_Save (FILE *pfil)
+{
+   if (fflush(pfil) == EOF)  return (UT_ERROR);
+ 
+   return(UT_OK);
+}
+
+
+/*
+GL-871127
+CH UT_SetPos                               Sette current filposisjon
+CD ==================================================================
+CD Form�l......:  Setter filposisjon hvor det skal begynnes � lese fra
+CD
+CD Aktivisering:  ist = UT_SetPos(fil,lpos);
+CD
+CD Retur-verdier: short  UT_OK  - Lesing er ok
+CD                short  UT_ERROR - Du har f�tt feil.
+CD
+CD PARAMETERLISTE:
+CD Navn      Type  Array i/U Merknad
+CD ------------------------------------------------------------------
+CD pfil      FILE         i   Peker til filstruktur (def i stdio.h)
+CD lpos      long         i   Fil-posisjon
+   ==================================================================
+*/
+SK_EntPnt_UT short UT_SetPos  (FILE *fi,long lpos)
+{
+      if (fseek(fi,lpos,SEEK_SET)) return (UT_ERROR);
+      return(UT_OK);
+}
+
+
+/*
+CH UT_SetPos_i64                             Sette current filposisjon
+CD ==================================================================
+CD Form�l......:  Setter filposisjon hvor det skal begynnes � lese fra
+CD
+CD Aktivisering:  ist = UT_SetPos_i64(fil,pos);
+CD
+CD Retur-verdier: short  UT_OK  - Utf�rt OK.
+CD                short  UT_ERROR - Du har f�tt feil.
+CD
+CD PARAMETERLISTE:
+CD Type      Navn      i/U  Merknad
+CD ------------------------------------------------------------------
+CD FILE      pfil       i   Peker til filstruktur (def i stdio.h)
+CD UT_INT64  n64FilPos  i   Fil-posisjon
+   ==================================================================
+*/
+SK_EntPnt_UT short UT_SetPos_i64 (FILE *fi,UT_INT64 n64FilPos)
+{
+      if (_fseeki64(fi,n64FilPos,SEEK_SET)) return (UT_ERROR);
+      return(UT_OK);
+}
+
+
+/*
+GL-871127
+CH UT_GetPos                                Finner neste filposisjon
+CD ==================================================================
+CD Form�l......:  Finner NESTE posisjon p� filen.
+CD                Dette vil bli neste linje etter UT_Readxxx og,
+CD                UT_Writexxxx.
+CD
+CD Aktivisering:  ist = UT_GetPos(fil,&lpos);
+CD
+CD Retur-verdier: short  UT_OK  - Lesing er ok
+CD                short  UT_ERROR - Du har f�tt feil.
+CD
+CD PARAMETERLISTE:
+CD Navn      Type  Array i/U Merknad
+CD ------------------------------------------------
+CD pfil      FILE         i   Peker til filstruktur (def i stdio.h)
+CD lpos      long         u   Peker til filposisjon
+   ==================================================================
+*/
+SK_EntPnt_UT short UT_GetPos(FILE *fi,long *lpos)
+{
+      *lpos = ftell(fi);
+      if (*lpos == -1L ) return (UT_ERROR);
+      return(UT_OK);
+}
+
+
+/*
+CH UT_GetPos_i64                            Finner neste filposisjon
+CD ==================================================================
+CD Form�l......:  Finner NESTE posisjon p� filen.
+CD                Dette vil bli neste linje etter UT_Readxxx og,
+CD                UT_Writexxxx.
+CD
+CD Aktivisering:  ist = UT_GetPos_i64(fil,&n64FilPos);
+CD
+CD Retur-verdier: short  UT_OK  - Utf�rt OK
+CD                short  UT_ERROR - Du har f�tt feil.
+CD
+CD PARAMETERLISTE:
+CD Type  Navn        i/U Merknad
+CD ------------------------------------------------
+CD FILE  pfil              i   Peker til filstruktur (def i stdio.h)
+CD long  n64FilPos         u   Peker til filposisjon
+   ==================================================================
+*/
+SK_EntPnt_UT short UT_GetPos_i64(FILE *fi,UT_INT64 *n64FilPos)
+{
+      *n64FilPos = _ftelli64(fi);
+      if (*n64FilPos == -1L ) return (UT_ERROR);
+      return(UT_OK);
+}
+
+
diff --git a/UT/UT2.cpp b/UT/UT2.cpp
new file mode 100644
index 0000000..1eafd3f
--- /dev/null
+++ b/UT/UT2.cpp
@@ -0,0 +1,1550 @@
+/******************************************************************^$date;
+*                                                                           *
+*       Hjelpebiblioteket   U T  (Utilities)                                *
+*       Lars Staurset, Statens Kartverk / FYSAK-prosjektet, januar 1990     *
+*       Fil: UT2.C versjon C22: Streng- og teikn-operasjonar                *
+*                                                                           *
+****************************************************************************/
+
+#include "stdafx.h"
+
+#include	<math.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+
+#include "fyut.h"
+
+#ifdef WIN32
+#  include <windows.h>
+#  include <memory.h>
+#  include <stdlib.h>
+#endif
+
+/* Interne prototyper */
+static short VT_JustStr (char ztr[], short mstr, char str[]);
+static char  VT_StrWord (char str[], short ii, short *iu, char *sep, short mw,
+								 char word[]);
+
+/*******************************************************************************
+*                                                                              *
+*       FRAMHENTING AV TOKEN M.M.                                              *
+*                                                                              *
+*******************************************************************************/
+
+/*LS-890927*********************************************************************
+*       Get Token                                                              *
+*******************************************************************************/
+
+SK_EntPnt_UT char *UT_GetToken (char *str, short *tl)
+{
+	 char *ptr;
+                                /* Hopp fram til f�rste ikkje-blanke */
+	 while (UT_IsSpace(*str)) ++str;
+                /* Hopp evt. forbi eitt komma el. punktum og blanke etter det */
+    if (*str == ',' || *str == '.') {
+        ++str;
+        while (UT_IsSpace(*str)) ++str;
+    }
+                                /* Sjekk om strengen er ferdigbehandla */
+    if (*str == '\0') {
+      *tl=0;
+      return NULL;
+    }
+                                /* Token avgrensa av hermeteikn */
+    if (*str == '"') {
+		  ptr = str + 1;
+        while (*ptr != '"' && *ptr != '\0' && *ptr != '\n') ptr++;
+        *tl = (short)(ptr - str + 1);
+        return str;
+    }
+                                /* Tekststreng fram til skilleteikn */
+	 else {
+		  ptr = str;
+        while (!UT_IsSpace(*ptr)  &&  *ptr != ',' &&  *ptr != '\0')  ptr++;
+		  *tl = (short)(ptr - str);
+        return str;
+    }
+}
+
+/*LS-890927****AR-920317********************************************************
+*       Get Token From String                                                  *
+*******************************************************************************/
+
+SK_EntPnt_UT char UT_StrToken (char str[], short ii, short *iu, short mt, char token[])
+{
+    char ch;
+    register short it;
+
+    
+    /* Korrigerer max strenglengde (AR) */
+    mt--;
+
+    
+    /* Hopp fram til f�rste ikkje-blanke */
+    while (UT_IsSpace(str[ii])) ii++;
+	
+    /* Hopp evt. forbi eitt komma eller semikolon og blanke etter det */
+	 if (str[ii] == ','  ||  str[ii] == ';') {
+        ii++;
+		  while (UT_IsSpace(str[ii])) ii++;
+    }
+    
+    /* Sjekk om strengen er ferdigbehandla */
+    if (str[ii] == '\0') {
+        token[0] = '\0';
+        ch = '\0';
+
+    /* Token avgrensa av doble hermeteikn */
+    } else if (str[ii] == '"') {
+        for (ii++, it = 0; !strchr ("\"",str[ii]); ii++) {
+            if (it < mt) token[it++] = str[ii];
+        }
+        token[it] = '\0';
+		  ch = '"';
+        if (str[ii]) ii++;
+    
+    /* Token avgrensa av enkle hermeteikn */
+    } else if (str[ii] == '\'') {
+        for (ii++, it = 0; !strchr ("'",str[ii]); ii++) {
+            if (it < mt) token[it++] = str[ii];
+        }
+        token[it] = '\0';
+		  ch = '\'';
+        if (str[ii]) ii++;
+    
+
+    /* Token g�r fram til ',' , ';' , 'Space' el '\0' */
+    } else {
+        for (it = 0; (!UT_IsSpace(str[ii]) && str[ii] != ',' && str[ii] != ';' && str[ii] != '\0'); ii++) {
+				if (it < mt) token[it++] = str[ii];
+		  }
+        token[it] = '\0';
+										  /* Returkode avh. av slutt-teikn */
+        if (str[ii] == '\0' || UT_IsSpace(str[ii]))
+            ch = ' ';
+        else
+            ch = str[ii++];
+    }
+    *iu = ii;
+
+    return ch;
+}
+
+/*LS-880929*****AR-890713*******************************************************
+*       Get Word From String                                                   *
+*******************************************************************************/
+
+SK_EntPnt_UT char UT_StrWord (char *str, short ii, short *iu, short mw, char *word)
+{
+    return VT_StrWord (str,ii,iu," ,\x9\xA\xB\xC\xD",mw,word);
+}
+
+/*LS-881005******AR-890713******************************************************
+*       Get Integer From String                                                *
+*******************************************************************************/
+
+SK_EntPnt_UT short UT_StrInt (char str[], short ii, short *iu, int *_int)
+{
+    short ok;
+    long l;
+
+    ok = UT_StrLong (str,ii,iu,&l);
+    *_int = (int)l;
+    return ok;
+}
+
+/*LS-881005****AR-890713********************************************************
+*       Get Short Integer From String                                          *
+*******************************************************************************/
+
+SK_EntPnt_UT short UT_StrShort (char *str, short ii, short *iu, short *s)
+{
+   char tal[7];
+
+	if (VT_StrWord (str,ii,iu," ,\x9\xA\xB\xC\xD",7,tal)) {
+		*s = (short)atol(tal);
+      return UT_TRUE;
+	}
+
+   *s = (short)0;
+   return UT_FALSE;
+}
+
+
+/*LS-880929*****AR-890713*******************************************************
+*       Get Long Integer From String                                           *
+*******************************************************************************/
+
+SK_EntPnt_UT short UT_StrLong (char str[], short ii, short *iu, long *_long)
+{
+   char tal[12];
+
+   if (VT_StrWord (str,ii,iu," ,\x9\xA\xB\xC\xD",12,tal)) {
+      *_long = atol(tal);
+      return UT_TRUE;
+   }
+      
+	*_long = 0;
+	return UT_FALSE;
+}
+
+
+/*LS-880929*****AR:2007-08-09***************************************************
+*       Get Integer64 From String                                              *
+*******************************************************************************/
+
+SK_EntPnt_UT short UT_StrInt64 (char str[], short ii, short *iu, UT_INT64 *i64)
+{
+   char tal[20];
+
+   if (VT_StrWord (str,ii,iu," ,\x9\xA\xB\xC\xD",20,tal)) {
+#ifdef LINUX
+      *i64 = atoll(tal);
+#else
+      *i64 = _atoi64(tal);
+#endif
+      return UT_TRUE;
+   }
+      
+	*i64 = 0;
+	return UT_FALSE;
+}
+
+
+/*LS-880929*****AR-890713*******************************************************
+*       Get Unsigned Long Integer From String                                  *
+*******************************************************************************/
+
+SK_EntPnt_UT short UT_StrUlong (char str[], short ii, short *iu, unsigned long *_ulong)
+{
+   char tal[12],*endptr;
+
+   if (VT_StrWord (str,ii,iu," ,\x9\xA\xB\xC\xD",12,tal)) {
+
+      *_ulong = strtoul( tal, &endptr, 10 );
+
+		return UT_TRUE;
+   }
+      
+   *_ulong = 0;
+   return UT_FALSE;
+}
+
+/*LS-890909*********************************************************************
+*       Get Double From String                                                 *
+*******************************************************************************/
+
+SK_EntPnt_UT short UT_StrDbl (char str[], short ii, short *iu, char decpt,
+    double *dbl)
+{
+    char tal[31], *sep;
+    static char sep1[] = " ,\x9\xA\xB\xC\xD", sep2[] = " \x9\xA\xB\xC\xD";
+
+    sep = (decpt == ',') ? sep2 : sep1;
+    if (VT_StrWord (str,ii,iu,sep,31,tal)) {
+        UT_AtoD (tal,decpt,dbl);
+        return UT_TRUE;
+    }
+
+    *dbl = 0.0;
+    return UT_FALSE;
+}
+
+/*LS-890927****AR-890713********************************************************
+*       Get Word From String                                                   *
+*******************************************************************************/
+
+static char VT_StrWord (char *str, short ii, short *iu, char *sep, short mw,
+    char word[])
+{
+    char ch;
+    int iw;
+
+
+                            /* Korrigerer max strenglengde (AR) */
+    mw--;
+                            /* Hopp fram til f�rste ikkje-blanke */
+    while (UT_IsSpace(str[ii]))  ii++;
+                            /* Hopp evt. forbi eitt komma og blanke etter det */
+    if (strchr (sep,',')) {
+		  if (str[ii] == ',')  ii++;
+        while (UT_IsSpace(str[ii]))  ii++;
+    }
+
+                            /* Sjekk om strengen er ferdigbehandla */
+    if (str[ii] == '\0') {
+		  word[0] = '\0';
+		  ch = '\0';
+
+									 /* Ordet g�r fram til separator-teikn */
+    } else {
+        for (iw = 0; !strchr (sep,str[ii]); ii++) {
+            if (iw < mw) word[iw++] = str[ii];
+        }
+        word[iw] = '\0';
+                            /* Returkode avh. av slutt-teikn */
+        if (str[ii] == '\0' || UT_IsSpace(str[ii]))
+            ch = ' ';
+        else
+            ch = str[ii++];
+    }
+    *iu = ii;
+	 return ch;
+}
+
+
+/*
+AR:2011-08-04
+CH UT_memcpy                                      Kopiere buffer
+CD ==============================================================
+CD For beskrivelse, se dokumentasjonen av memcpy_s.
+CD
+CD PARAMETERLISTE:
+CD Type    Navn             I/U  Merknad
+CD -------------------------------------------------------------
+CD void   *dest              iu  Buffer det skal kopieres til.
+CD size_t  numberOfElements  i   Size of the destination buffer.
+CD void   *src               i   Buffer det kopieres fra.
+CD size_t  count             i   Number of characters to copy.
+CD int     status            r   Zero if successful; an error code on failure.
+CD  ==============================================================
+*/
+SK_EntPnt_UT int UT_memcpy(void *dest,size_t numberOfElements,const void *src,size_t count)
+{
+#ifdef WIN32
+   return memcpy_s(dest,numberOfElements,src,count);
+#else
+   if (memcpy(dest,src,count)==NULL) return 1;
+   return 0;
+#endif
+}
+
+
+/*
+AR:2011-08-08
+CH UT_strerror                          Henter systemfeilmelding
+CD ==============================================================
+CD For beskrivelse, se dokumentasjonen av strerror_s.
+CD
+CD PARAMETERLISTE:
+CD Type    Navn             I/U  Merknad
+CD -------------------------------------------------------------
+CD char   *buffer            iu  Buffer to hold error string.
+CD size_t  numberOfElements  i   Size of buffer.
+CD int     errnum            i   Error number.
+CD int     status            r   Zero if successful; an error code on failure.
+CD  ==============================================================
+*/
+SK_EntPnt_UT int UT_strerror(char *buffer,size_t numberOfElements,int errnum)
+{
+#ifdef WIN32
+   return strerror_s(buffer,numberOfElements,errnum);
+#else
+   UT_StrCopy(buffer,strerror(errnum),numberOfElements);
+   return 0;
+#endif
+}
+
+
+/*
+AR:2011-08-08
+CH UT_strtok                                        Henter token
+CD ==============================================================
+CD Overbygning over strtok i standardbiblioteket.
+CD For beskrivelse, se dokumentasjonen av strtok_s.
+CD
+CD PARAMETERLISTE:
+CD Type    Navn             I/U  Merknad
+CD -------------------------------------------------------------
+CD char       *strToken      iu  String containing token or tokens.
+CD const char *strDelimit    i   Set of delimiter characters.
+CD char      **context       iu  Used to store position information between calls to UT_strtok
+CD char       *token         r   Returns a pointer to the next token found in strToken. 
+CD                               They return NULL when no more tokens are found. 
+CD
+CD  ==============================================================
+*/
+SK_EntPnt_UT char *UT_strtok(char *strToken,const char *strDelimit,char **context)
+{
+#ifdef WIN32
+   return strtok_s(strToken,strDelimit,context);
+#else
+   return strtok(strToken,strDelimit);
+#endif
+}
+
+
+/*
+GL.06.03.89
+CH  UT_StrCopy                    Kopiere streng med overflyttest
+CD  ==============================================================
+CD  Kopierer en streng med max ant tegn. Legger p� \0 p� slutten.
+CD
+CD  PARAMETERLISTE:
+CD  Navn     Type       I/U  Merknad
+CD  -------------------------------------------------------------
+CD  dst     *char       u   streng det skal kopieres til.
+CD  src     const *char i   streng det skal kopieres fra.
+CD  maxlen  int         i   max antall tegn som skal kopieres
+CD                          (Inkludert null-terminator.)
+CD  ==============================================================
+*/
+SK_EntPnt_UT void UT_StrCopy (char *dst, const char *src, int maxlen)
+{
+#ifdef WIN32
+   strncpy_s(dst,maxlen,src,_TRUNCATE);
+#else
+   strncpy(dst,src,maxlen);
+#endif
+}
+
+
+/*
+T.H.10.08.96
+CH  UT_StrCat                               Konkatinerer streng
+CD  ==============================================================
+CD  Koncatinerer en streng med max ant tegn. Legger p� \0 p� slutten.
+CD
+CD  PARAMETERLISTE:
+CD  Navn     Type    I/U  Merknad
+CD  -------------------------------------------------------------
+CD  dst     *char     u   streng det skal kopieres til.
+CD  src     *char     i   streng det skal kopieres fra.
+CD  maxlen   int      i   Max lengde av dst, inkl. null-terminator.
+CD  retur    short    r   1 = OK, 0 = feil.
+CD  ==============================================================
+*/
+SK_EntPnt_UT short UT_StrCat (char *dst,const char *src, const int maxlen)
+{
+   //return (strcat_s(dst,maxlen,src))?  0 : 1; 
+#ifdef WIN32
+   int err = strncat_s(dst,maxlen,src,_TRUNCATE);  //Returns 0 if successful, an error code on failure.
+   return (err == 0)?  1 : 0; 
+#else
+   strncat(dst,src,maxlen); 
+   return 1;
+#endif
+
+
+/*
+#ifndef BORLAND
+   short    sStatus = 1;
+   short sLen = (short)strlen(dst);
+
+   if (dst) {
+      //UT_StrCopy (dst+sLen-1, src, (short)(maxlen-sLen));
+      UT_StrCopy (dst+sLen, src, (short)(maxlen-sLen));  // AR:2000-10-26
+   }
+
+   return sStatus;
+
+#else
+
+   HANDLE   hStringDest;
+   HANDLE   hStringSource;
+   LPSTR    Dest;
+   LPCSTR   Source;
+   short    sStatus = 1;;
+
+   hStringDest    = LocalAlloc(LHND, maxlen + 1);
+   hStringSource  = LocalAlloc(LHND, maxlen + 1);
+
+   if ((hStringDest != NULL) && (hStringSource != NULL)) {
+	   Dest   = LocalLock(hStringDest);
+	   Source = LocalLock(hStringSource);
+	   Dest   = dst; // Setter Dest lik adressen til dst
+	   Source = src; // Setter Src lik adressen til src
+
+	   if (Dest) {
+		   maxlen--;  // Tar hensyn til null-terminator
+		   if ((short)lstrlen(Source) <= maxlen) {
+			   src+= maxlen;
+			   *src = '\0';
+         }
+         lstrcat(Dest, Source);
+      }
+	   LocalUnlock(hStringDest);
+	   LocalUnlock(hStringSource);
+
+	   if ((LocalFree(hStringDest))!= NULL)
+		   sStatus = 0;
+
+	   if ((LocalFree(hStringSource))!= NULL)
+		   sStatus = 0;
+
+   }
+   
+   return sStatus;
+   
+#endif
+*/
+}
+
+
+
+/* (AR) */
+/*GL-880907*LS-880829***********************************************************
+*       Get Substring                                                          *
+*******************************************************************************/
+SK_EntPnt_UT void UT_GetSubstr (char ctx[],short fra,short til,char sub[],short maxlen)
+{
+	short i;
+	short j = 0;
+	short txlen = (short)strlen(ctx);
+
+
+	sub[0] = '\0';
+
+	if (fra >= txlen)  return;  /* Starter etter slutten av strengen ==> retur */
+
+   if (til > txlen) til=txlen;
+
+   if (fra == -1) {
+		fra++;
+      while (UT_IsSpace(ctx[fra])  &&  fra < txlen) {
+         fra++;
+      }
+   }
+
+   if (til == -1) {
+      til=txlen;
+      while (UT_IsSpace(ctx[til])  &&  til > 0) {
+         til--;
+      }
+   }
+
+   for (i=fra; i<= til && ctx[i] != '\0' && maxlen>1 ; i++, maxlen--) {
+      sub[j++]=ctx[i];
+   }
+
+   sub[j]='\0';
+}
+
+
+/* (AR) */
+/*LS-880929*********************************************************************
+*       Search String for Substring (INDEX)                                    *
+*******************************************************************************/
+
+SK_EntPnt_UT short UT_Index (char str[], char substr[])
+{                              /* Wortman & Sidebottom, p. 101 */
+    short i;
+    short j,k;
+
+    for (i = 0; str[i] != '\0'; i++) {
+        for (j=i, k=0;  substr[k] != '\0' && substr[k] == str[j];  j++, k++) {
+           ;
+        }
+        if (substr[k] == '\0') return (i);
+    }
+    return (-1);
+}
+
+/*******************************************************************************
+*                                                                              *
+*       ANDRE STRENG- OG TEIKN-RUTINER                                         *
+*                                                                              *
+*******************************************************************************/
+
+/*LS-880929**AR-890713**********************************************************
+*       Clear After CR/LF                                                      *
+*******************************************************************************/
+
+SK_EntPnt_UT char *UT_ClrCrlf (char *str)
+{
+   char *cp;
+
+   if ((cp = strpbrk(str,"\r\n")) != NULL)   *cp = '\0';
+   
+   return str;
+}
+
+/*AR-900111********************************************************************
+*       Clear Trailing Space                                                     *
+*******************************************************************************/
+SK_EntPnt_UT char *UT_ClrTrailsp(char *str)
+{
+   char *cp;
+
+   if (*str != '\0')
+   {
+      // Fjern blanke p� slutten
+      cp = strchr(str,'\0');
+      --cp;
+      while ( cp >= str && UT_IsSpace(*cp) )
+      {
+         --cp;
+      }
+      *(cp+1) = '\0';
+   }
+
+   return str;
+}
+
+
+/*AR-900111********************************************************************
+*    Clear leading and trailing Space, and compress multiple space to one.    *
+*******************************************************************************/
+SK_EntPnt_UT char *UT_ClrExtrasp(char *str)
+{
+   char *cp,*tp;
+   short sSp = UT_TRUE;
+
+   /* Fjern blanke p� slutten */
+   UT_ClrTrailsp(str);
+
+   /* Fjern ledende blanke og overfl�dige blanke inni strengen */
+   cp = tp = str;
+
+   while (*cp != '\0') {
+      if (! UT_IsSpace(*cp)) {
+         *tp++ = *cp;
+         sSp = UT_FALSE;
+      } else {
+         if (sSp == UT_FALSE)  *tp++ = ' ';
+         sSp = UT_TRUE;
+      }
+      cp++;
+   }
+   *tp = '\0';
+
+   return str;
+}
+
+
+/*
+AR-890312
+CH UT_IsSpace                                           Test om mellomromstegn
+CD =============================================================================
+CD Form�l:
+CD Sjekker om et tegn er mellomromstegn (ascii 0x09-0x0d eller 0x20)
+CD
+CD Parametre:
+CD Type   Navn   I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD char   c       i    Tegn som skall testes.
+CD int    ist     r    1=mellomromstegn, 0=ikke mellomromstegn.
+CD
+CD Bruk:
+CD ist = UT_IsSpace(*cp);
+   =============================================================================
+*/
+SK_EntPnt_UT int UT_IsSpace(char c)
+{
+#ifdef WIN32
+   static unsigned char atab[256] =
+   { 0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
+
+   return atab[(unsigned char)c];
+
+#else
+   switch (c){
+      case 0x20:
+      case 0x09:
+      case 0x0A:
+      case 0x0B:
+      case 0x0C:
+      case 0x0D:
+         return 1;
+			break;
+      default:
+         return 0;
+			break;
+   }
+#endif
+}
+
+/*LS-890430*********************************************************************
+*       Check for Printable Character                                          *
+*******************************************************************************/
+
+SK_EntPnt_UT int UT_IsPrint (int ch)
+{
+    if (isprint (ch))              return UT_TRUE;
+    else if (ch == 0)              return UT_FALSE;
+    else if (strchr ("������",ch)) return UT_TRUE;
+    else                           return UT_FALSE;
+}
+
+/*LS-890517*********************************************************************
+*       Check for Lower-Case Character                                         *
+*******************************************************************************/
+
+SK_EntPnt_UT int UT_IsLower (int ch)
+{
+    if (islower (ch))           return UT_TRUE;
+    else if (ch == 0)           return UT_FALSE;
+    else if (strchr ("���������",ch)) return UT_TRUE;
+    else                        return UT_FALSE;
+}
+
+/*LS-890913*********************************************************************
+*       Convert Character to Lower-Case                                        *
+*******************************************************************************/
+
+SK_EntPnt_UT int UT_ToLower (int ch)
+{
+    if (ch >= 'A'  &&  ch <= 'Z') {
+       ch += 0x20;
+
+    } else {
+        switch (ch) {
+            case '�' : ch = '�'; break;
+            case '�' : ch = '�'; break;
+            case '�' : ch = '�'; break;
+
+            case '�' : ch = '�'; break; // � - SK-fonter + standardfonter
+            case '�' : ch = '�'; break; // � - SK-fonter + standardfonter
+            case '�' : ch = '�'; break; // Samisk c - SK-fonter og � - standardfonter
+            case '�' : ch = '�'; break; // � - SK-fonter + standardfonter
+            case '�' : ch = '�'; break; // Samisk n(aksent) - SK-fonter og � - standardfonter
+            case '�' : ch = '�'; break; // � - SK-fonter + standardfonter
+
+            case 0x010C : ch = 0x010D; break; // Samisk c - utvidede standardfonter
+            case 0x0110 : ch = 0x0111; break; // Samisk d - utvidede standardfonter
+            case 0x014A : ch = 0x014B; break; // Samisk n(lav) - utvidede standardfonter
+            case 0x0143 : ch = 0x0144; break; // Samisk n(aksent) - utvidede standardfonter
+            case 0x0160 : ch = 0x0161; break; // Samisk s - utvidede standardfonter
+            case 0x0166 : ch = 0x0167; break; // Samisk t - utvidede standardfonter
+            case 0x017D : ch = 0x017E; break; // Samisk z - utvidede standardfonter
+        }
+    } /* endif */
+
+    return ch;
+}
+
+/*AR-881020*LS-890517***********************************************************
+*       Convert String to Lower-Case                                           *
+*******************************************************************************/
+
+SK_EntPnt_UT char *UT_StrLower (char *ti)
+{
+   char *t = ti;
+
+   while ((*t = (char)UT_ToLower(*t)) != '\0')
+       t++;
+   return (ti);
+}
+
+/*LS-890517*********************************************************************
+*       Check for Upper-Case Character                                         *
+*******************************************************************************/
+
+SK_EntPnt_UT int UT_IsUpper (int ch)
+{
+    if (isupper (ch))           return UT_TRUE;
+    else if (ch == 0)           return UT_FALSE;
+    else if (strchr ("���������",ch)) return UT_TRUE;
+    else                        return UT_FALSE;
+}
+
+/*LS-890913*********************************************************************
+*       Convert Character to Upper-Case                                        *
+*******************************************************************************/
+
+SK_EntPnt_UT int UT_ToUpper (int ch)
+{
+    if (ch >= 'a'  &&  ch <= 'z') {
+       ch -= 0x20;
+
+    } else {
+        switch (ch) {
+            case '�' : ch = '�'; break;
+            case '�' : ch = '�'; break;
+            case '�' : ch = '�'; break;
+         
+            case '�' : ch = '�'; break; // � - SK-fonter + standardfonter
+            case '�' : ch = '�'; break; // � - SK-fonter + standardfonter
+            case '�' : ch = '�'; break; // Samisk c - SK-fonter og � - standardfonter
+            case '�' : ch = '�'; break; // � - SK-fonter + standardfonter
+            case '�' : ch = '�'; break; // Samisk n(aksent) - SK-fonter og � - standardfonter
+            case '�' : ch = '�'; break; // � - SK-fonter + standardfonter
+
+            case 0x010D : ch = 0x010C; break; // Samisk c - utvidede standardfonter
+            case 0x0111 : ch = 0x0110; break; // Samisk d - utvidede standardfonter
+            case 0x014B : ch = 0x014A; break; // Samisk n(lav) - utvidede standardfonter
+            case 0x0144 : ch = 0x0143; break; // Samisk n(aksent) - utvidede standardfonter
+            case 0x0161 : ch = 0x0160; break; // Samisk s - utvidede standardfonter
+            case 0x0167 : ch = 0x0166; break; // Samisk t - utvidede standardfonter
+            case 0x017E : ch = 0x017D; break; // Samisk z - utvidede standardfonter
+        }
+    }
+
+    return ch;
+}
+
+/*LS-890517*********************************************************************
+*       Convert String to Upper-Case                                           *
+*******************************************************************************/
+
+SK_EntPnt_UT char *UT_StrUpper (char *ti)
+{
+   char *t = ti;
+
+   while ((*t = (char)UT_ToUpper(*t)) != '\0')
+       t++;
+   return (ti);
+}
+
+/*******************************************************************************
+*                                                                              *
+*       KONVERTERINGSRUTINER                                                   *
+*                                                                              *
+*******************************************************************************/
+
+#ifdef OS216
+
+/*LS-880928*********************************************************************
+*       Convert String to Integer If Possible                                  *
+*******************************************************************************/
+
+SK_EntPnt_UT int UT_AtoI (char *str, int *_int)
+{
+    short s,ok;
+
+    ok = UT_AtoS (str,&s);
+    *_int = (int)s;
+    return ok;
+}
+
+/*LS-880929*********************************************************************
+*       Convert String to Short Integer If Possible                            *
+*******************************************************************************/
+
+SK_EntPnt_UT short UT_AtoS (char str[], short *s)
+{
+    short ok,slen;
+    short len,sif;
+
+    ok = UT_FALSE;
+                                    /* Finn f�rste siffer != 0 */
+    /*; for (sif=0; str[sif]<'1' || str[sif]>'9'; sif++); */ 
+    /* Rettet AR-940623 for � handtere streng uten siffer 1-9 */
+    for (sif=0; (str[sif]<'1' || str[sif]>'9') && str[sif]!='\0' ; sif++);
+                                    /* Lengde p� sifferstrengen */
+    slen = (short)strlen(str);
+    len = slen - sif;
+                                    /* Viss <5 siffer: ok */
+    if (len < 5) ok = UT_TRUE;
+                                    /* Viss 5 siffer: u.s. dei 4 f�rste */
+    else if (len == 5) {
+        sif = (short)str[--slen];
+        str[slen] = '\0';
+        *s = (short)abs(atoi(str));
+        if (*s < 3276) ok = UT_TRUE;
+                                    /* P� grensa for lovleg verdi, sjekk det 5. */
+        else if (*s == 3276) {
+            if (sif <= '7') ok = UT_TRUE;
+            else if (sif == '8') {
+                                    /* Neg. tal kan ha 1 st�rre abs.verdi */
+                if (atoi(str) < 0) ok = UT_TRUE;
+            }
+        }
+                                    /* Sett tilbake det l�nte sifferet */
+        str[slen++] = (char)sif;
+    }
+    if (ok) *s = (short)atoi(str);
+    else *s = 0;
+    return ok;
+}
+
+/*LS-880929*********************************************************************
+*       Convert String to Long Integer If Possible                             *
+*******************************************************************************/
+
+SK_EntPnt_UT short UT_AtoL (char str[], long *_long)
+{
+    short ok,slen;
+    register short len,sif;
+
+    ok = UT_FALSE;
+                                    /* Finn f�rste siffer != 0 */
+    /*; for (sif=0; str[sif]<'1' || str[sif]>'9'; sif++); */ 
+    /* Rettet AR-940623 for � handtere streng uten siffer 1-9 */
+    for (sif=0; (str[sif]<'1' || str[sif]>'9') && str[sif]!='\0' ; sif++);
+
+                                    /* Lengde p� sifferstrengen */
+    slen = (short)strlen(str);
+    len = slen - sif;
+                                    /* Viss <10 siffer: ok */
+    if (len < 10) ok = UT_TRUE;
+                                    /* Viss 10 siffer: u.s. dei 9 f�rste */
+    else if (len == 10) {
+        sif = (short)str[--slen];
+        str[slen] = '\0';
+        *_long = labs (atol (str));
+        if (*_long < 214748364) ok = UT_TRUE;
+                                    /* P� grensa for lovleg verdi, sjekk det 10. */
+        else if (*_long == 214748364) {
+            if (sif <= '7') ok = UT_TRUE;
+            else if (sif == '8') {
+                                    /* Neg. tal kan ha 1 st�rre abs.verdi */
+                if (atol(str) < 0) ok = UT_TRUE;
+            }
+        }
+                                    /* Sett tilbake det l�nte sifferet */
+        str[slen++] = (char)sif;
+    }
+    if (ok) *_long = atol (str);
+    else *_long = 0L;
+    return ok;
+}
+
+#endif
+
+
+/*LS-890519*********************************************************************
+*       Convert String to Double                                               *
+*******************************************************************************/
+
+SK_EntPnt_UT short UT_AtoD (char *str, char decpt, double *dbl)
+{
+    char *kompos;
+                                    /* Pass p� desimalkomma */
+    if (decpt == ',') {
+        kompos = strchr (str,',');
+        if (kompos) *kompos = '.';
+    }
+    else
+        kompos = NULL;
+    *dbl = atof (str);
+    if (kompos) *kompos = ',';
+    return UT_TRUE;
+}
+
+/*LS-889297*********************************************************************
+*       Convert Integer to String                                              *
+*******************************************************************************/
+
+SK_EntPnt_UT short UT_ItoA (int _int, short mstr, char *str)
+{
+   char ztr[12];
+   
+   UT_SNPRINTF(ztr,12,"%d",_int);
+   return VT_JustStr (ztr,mstr,str);
+}
+
+/*LS-880928*********************************************************************
+*       Convert Short Integer to String                                        *
+*******************************************************************************/
+
+SK_EntPnt_UT short UT_StoA (short s, short mstr, char *str)
+{
+   char ztr[7];
+
+   UT_SNPRINTF(ztr,7,"%hd",s);
+   return VT_JustStr (ztr,mstr,str);
+}
+
+/*LS-880929*********************************************************************
+*       Convert Long Integer to String                                         *
+*******************************************************************************/
+
+SK_EntPnt_UT short UT_LtoA (long _long, short mstr, char *str)
+{
+   char ztr[12];
+
+   UT_SNPRINTF(ztr,12,"%ld",_long);
+   return VT_JustStr (ztr,mstr,str);
+}
+
+/*LS-890912*********************************************************************
+*       Convert Double To String                                               *
+*******************************************************************************/
+
+SK_EntPnt_UT short UT_DtoA (double dbl, short dec, char decpt, short mstr, char *str)
+{  
+   /* size_t len; */
+   char *cp,ztr[41];
+   
+   /* Sjekk mot for lang streng  */ 
+   if (dbl!=0.0   &&  (log10(fabs(dbl)) + dec  > 36.0)) {
+      memset( ztr, '*', 40);
+      ztr[40] = '\0';
+
+   } else {
+
+      /* Konverter til streng */
+      UT_SNPRINTF(ztr,41,"%.*f",dec,dbl);
+
+      /* Skift til rett desimaltegn */
+      if ((cp = strchr(ztr,'.')) != NULL) {
+         *cp = decpt;
+      }
+
+      /* Kontroller strenglengda */
+      /*if ((len = strlen (ztr)) > 40) {                  */
+      /*   UT_FPRINTF (stderr,"\nFeil i UT_DtoA: %d",len);   */
+      /*   exit (1);                                      */
+      /*}                                                 */
+   }
+
+   /* Juster etter behov */
+   return VT_JustStr(ztr,mstr,str);
+}
+
+/*LS-890912*********************************************************************
+*       Check and Justify String                                               *
+*******************************************************************************/
+
+static short VT_JustStr (char ztr[], short mstr, char str[])
+{
+    short ok,i,lstr;
+
+    lstr = (short)strlen (ztr);
+    mstr--;
+                                        /* For kort streng? */
+    if (mstr > 0 && mstr < lstr) {
+        for (i=0; i<mstr; i++) str[i] = ztr[i+lstr-mstr];
+        str[mstr] = '\0';
+        ok = UT_FALSE;
+    }
+                                        /* Lang nok streng */
+    else {
+        //strcpy_s (str,mstr,ztr);
+#ifdef LINUX
+        strncpy (str,ztr,mstr+1);
+#else
+        strcpy_s (str,mstr+1,ztr); // M� bruke mstr+1 fordi det er trukket fra en i den verdien som kommer inn
+#endif
+        ok = UT_TRUE;
+    }
+                                        /* For lang streng? */
+    if (mstr > lstr) UT_JustStr ('>',' ',(short)(mstr+1),str);
+                                        /* Avslutt */
+    return ok;
+}
+
+/*LS-891011*********************************************************************
+*       Justify and Fill String                                                *
+*******************************************************************************/
+
+SK_EntPnt_UT void UT_JustStr (char justmode, char fill, short lstr, char *str)
+{
+   char *pc1, *pc2, *pc, *qc;
+
+   if (lstr > 0) {
+                                           /* Terminer strengen */
+      lstr--;
+      *(str+lstr) = '\0';
+                                           /* Finn endane av strengen */
+      pc1 = str;
+      while (UT_IsSpace(*pc1) || *pc1 == fill) {
+         pc1++;
+      }
+
+      pc2 = strchr(pc1,'\0')-1;
+      while (UT_IsSpace(*pc2) || *pc2 == fill) {
+         pc2--;
+      }
+
+      switch (justmode) {
+         case '>' :                      /* H�grepakking */
+            for (pc = pc2, qc = str+lstr-1; pc >= pc1; pc--) {
+               if (!UT_IsSpace(*pc) && *pc != fill) {
+                  *qc-- = *pc;
+               }
+            }
+            while (qc >= str) *qc-- = fill;
+            break;
+         case '/' :                      /* H�grejustering */
+            for (pc = pc2, qc = str+lstr-1; pc >= pc1; pc--)
+               *qc-- = *pc;
+            while (qc >= str) *qc-- = fill;
+            break;
+         case '<' :                      /* Venstrepakking */
+            for (pc = pc1, qc = str; pc <= pc2; pc++) {
+               if (!UT_IsSpace(*pc) && *pc != fill) *qc++ = *pc;
+            }
+            while (qc < str+lstr) *qc++ = fill;
+            break;
+         case '`' :                      /* Venstrejustering */
+            for (pc = pc1, qc = str; pc <= pc2; pc++)
+               *qc++ = *pc;
+            while (qc < str+lstr) *qc++ = fill;
+            break;
+      }
+   }
+}
+
+
+/*
+AR-890113 LS-890915
+CH UT_Ascii7to8                                          Konverter til PC-ASCII
+CD =============================================================================
+CD Form�l:
+CD Konverterer en streng fra ND-7-bits norsk ASCII til PC-8-bits norsk ASCII.
+CD
+CD Parametre:
+CD  Type    Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD  char   *tx        i    Peker til streng som skal konverteres
+CD                         (avsluttet med '\0').
+CD  char   *tp        r    Peker til konvertert streng.
+CD
+CD Bruk:
+CD tp = UT_Ascii7to8(tx);
+   =============================================================================
+*/
+SK_EntPnt_UT unsigned char *UT_Ascii7to8(unsigned char *tx)
+{
+   static unsigned char atab[256] =
+   {   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+      20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+      40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+      60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+      80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,146,157,143, 94, 95, 96, 97, 98, 99,
+     100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,
+     120,121,122,145,155,134,126,127,128,129,130,131,132,133,134,135,136,137,138,139,
+     140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
+     160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
+     180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,
+     200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,
+     220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
+     240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255};
+
+   unsigned char *tp = tx;
+
+   for ( ; ((*tp = atab[*tp]) != '\0'); tp++){
+       ;
+   }
+
+   return (tx);
+}
+
+
+/*
+AR-890113 LS-890915
+CH UT_Ascii8to7                                          Konverter til ND-ASCII
+CD =============================================================================
+CD Form�l:
+CD Konverterer en streng fra PC-8-bits norsk ASCII til ND-7-bits norsk ASCII.
+CD
+CD Parametre:
+CD  Type    Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD  char   *tx        i    Peker til streng som skal konverteres
+CD                         (avsluttet med '\0').
+CD  char   *tp        r    Peker til konvertert streng.
+CD
+CD Bruk:
+CD tp = UT_Ascii8to7(tx)
+   =============================================================================
+*/
+SK_EntPnt_UT unsigned char *UT_Ascii8to7(unsigned char *tx)
+{
+   static unsigned char atab[256] =
+   {   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+      20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+      40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+      60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+      80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+     100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,
+     120,121,122,123,124,125,126,127,128,129,130,131,132,133,125,135,136,137,138,139,
+     140,141,142, 93,144,123, 91,147,148,149,150,151,152,153,154,124,156, 92,158,159,
+     160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
+     180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,
+     200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,
+     220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
+     240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255};
+
+   unsigned char *tp = tx;
+
+   for ( ; (*tp = atab[*tp]) != '\0'; tp++){
+       ;
+   }
+
+   return (tx);
+}
+
+
+/*
+AR-920929
+CH UT_Ascii8toISO8859                                 Konverter til ISO8859-10
+CD =============================================================================
+CD Form�l:
+CD Konverterer en streng fra PC-8-bits norsk ASCII til ISO8859-10.
+CD
+CD Parametre:
+CD  Type    Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD  char   *tx        i    Peker til streng som skal konverteres
+CD                         (avsluttet med '\0').
+CD  char   *tp        r    Peker til konvertert streng.
+CD
+CD Bruk:
+CD tp = UT_Ascii8toISO8859(tx)
+   =============================================================================
+*/
+SK_EntPnt_UT unsigned char *UT_Ascii8toISO8859(unsigned char *tx)
+{
+   static unsigned char atab[256] =
+   {   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+      20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+      40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+      60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+      80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+     100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,
+     120,121,122,123,124,125,126,127,128,129,130,131,132,133,229,135,136,137,138,139,
+     140,141,142,197,144,230,198,147,148,149,150,151,152,153,154,248,156,216,158,159,
+     160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
+     180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,
+     200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,
+     220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
+     240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255};
+
+
+
+   unsigned char *tp = tx;
+
+   for ( ; (*tp = atab[*tp]) != '\0'; tp++){
+       ;
+   }
+
+   return (tx);
+}
+
+
+/*
+AR-920929
+CH UT_ISO8859toAscii8                                    Konverter til PC-ASCII
+CD =============================================================================
+CD Form�l:
+CD Konverterer en streng fra ISO8859-10 til PC-8-bits norsk ASCII.
+CD
+CD Parametre:
+CD  Type    Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD  char   *tx        i    Peker til streng som skal konverteres
+CD                         (avsluttet med '\0').
+CD  char   *tp        r    Peker til konvertert streng.
+CD
+CD Bruk:
+CD tp = UT_ISO8859toAscii8(tx);
+   =============================================================================
+*/
+SK_EntPnt_UT unsigned char *UT_ISO8859toAscii8(unsigned char *tx)
+{
+   static unsigned char atab[256] =
+   {   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+      20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+      40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+      60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+      80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+     100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,
+     120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,
+     140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
+     160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
+     180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,143,146,199,
+     200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,157,217,218,219,
+     220,221,222,223,224,225,226,227,228,134,145,231,232,233,234,235,236,237,238,239,
+     240,241,242,243,244,245,246,247,155,249,250,251,252,253,254,255};
+
+
+
+   unsigned char *tp = tx;
+
+   for ( ; ((*tp = atab[*tp]) != '\0'); tp++){
+       ;
+   }
+
+   return (tx);
+}
+
+
+/*
+AR-920929
+CH UT_Ascii7toISO8859                                 Konverter til ISO8859-10
+CD =============================================================================
+CD Form�l:
+CD Konverterer en streng fra norsk 7-bits ASCII til ISO8859-10.
+CD
+CD Parametre:
+CD  Type    Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD  char   *tx        i    Peker til streng som skal konverteres
+CD                         (avsluttet med '\0').
+CD  char   *tp        r    Peker til konvertert streng.
+CD
+CD Bruk:
+CD tp = UT_Ascii7toISO8859(tx)
+   =============================================================================
+*/
+SK_EntPnt_UT unsigned char *UT_Ascii7toISO8859(unsigned char *tx)
+{
+
+   static unsigned char atab[256] =
+   {   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+      20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+      40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+      60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+      80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,198,216,197, 94, 95, 96, 97, 98, 99,
+     100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,
+     120,121,122,230,248,229,126,127,128,129,130,131,132,133,134,135,136,137,138,139,
+     140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
+     160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
+     180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,
+     200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,
+     220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
+     240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255};
+
+   unsigned char *tp = tx;
+
+   for ( ; (*tp = atab[*tp]) != '\0'; tp++){
+       ;
+   }
+
+   return (tx);
+}
+
+
+/*
+AR-920929
+CH UT_ISO8859toAscii7                                    Konverter til ND-ASCII
+CD =============================================================================
+CD Form�l:
+CD Konverterer en streng fra ISO8859-10 til norsk 7-bits ASCII.
+CD
+CD Parametre:
+CD  Type    Navn     I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD  char   *tx        i    Peker til streng som skal konverteres
+CD                         (avsluttet med '\0').
+CD  char   *tp        r    Peker til konvertert streng.
+CD
+CD Bruk:
+CD tp = UT_ISO8859toAscii7(tx);
+   =============================================================================
+*/
+SK_EntPnt_UT unsigned char *UT_ISO8859toAscii7(unsigned char *tx)
+{
+
+   static unsigned char atab[256] =
+   {   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+      20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+      40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+      60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+      80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+     100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,
+     120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,
+     140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
+     160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
+     180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196, 93, 91,199,
+     200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215, 92,217,218,219,
+     220,221,222,223,224,225,226,227,228,125,123,231,232,233,234,235,236,237,238,239,
+     240,241,242,243,244,245,246,247,124,249,250,251,252,253,254,255};
+
+
+   unsigned char *tp = tx;
+
+   for ( ; ((*tp = atab[*tp]) != '\0'); tp++){
+       ;
+   }
+
+   return (tx);
+}
+
+
+/*
+AR-890113
+CH UT_KonverterTegnsett                                   Konverter tegnsett
+CD ==========================================================================
+CD Form�l:
+CD Konverterer en streng fra et tegnsett til et annet.
+CD
+CD Parametre:
+CD  Type    Navn         I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD  short   sFraTegnsett  i    Fra tegnsett
+CD                                TS_UKJENT  = Ukjent tegnsett
+CD                                TS_DOSN8   = DOS norsk 8-bits
+CD                                TS_ND7     = Norsk Data 7-bits
+CD                                TS_DECM8   = DEC multinasjonal 8-bits
+CD                                TS_DECN7   = DEC norsk 7-bits
+CD                                TS_ISO8859 = ISO8859-10
+CD  short   sTilTegnsett  i    Til tegnsett 
+CD                                TS_UKJENT  = Ukjent tegnsett
+CD                                TS_DOSN8   = DOS norsk 8-bits
+CD                                TS_ND7     = Norsk Data 7-bits
+CD                                TS_DECM8   = DEC multinasjonal 8-bits
+CD                                TS_DECN7   = DEC norsk 7-bits
+CD                                TS_ISO8859 = ISO8859-10
+CD  char   *pszTx         iu   Peker til streng som skal konverteres
+CD                             (avsluttet med '\0').
+CD  char   *pszTx         r    Peker til konvertert streng.
+CD
+CD Bruk:
+CD pszTx = UT_KonverterTegnsett(sFraTegnsett,sTilTegnsett,pszTx);
+   =============================================================================
+*/
+SK_EntPnt_UT unsigned char *UT_KonverterTegnsett(short sFraTegnsett,short sTilTegnsett,
+                                    unsigned char *pszTx)
+{
+   if (sFraTegnsett != sTilTegnsett) {
+      switch (sFraTegnsett) {
+         /* Fra DOS 8-bits */
+         case TS_DOSN8:
+            switch (sTilTegnsett) {
+               /* Til norsk 7-bits */
+               case TS_ND7:
+               case TS_DECN7:
+                  return  UT_Ascii8to7(pszTx);
+
+               /* Til ISO8859 */
+               case TS_ISO8859:
+               case TS_DECM8:
+                  return  UT_Ascii8toISO8859(pszTx);
+            }
+            break;
+
+         /* Fra norsk 7-bits */
+         case TS_ND7:
+         case TS_DECN7:
+            switch (sTilTegnsett) {
+               /* Til DOS 8-bits */
+               case TS_DOSN8:
+                  return  UT_Ascii7to8(pszTx);
+
+               /* Til ISO8859 */
+               case TS_ISO8859:
+               case TS_DECM8:
+                  return  UT_Ascii7toISO8859(pszTx);
+            }
+            break;
+
+         /* Fra Dec-multinasjonal 8-bits */
+         case TS_ISO8859:
+         case TS_DECM8:
+            switch (sTilTegnsett) {
+               /* Til DOS 8-bits */
+               case TS_DOSN8:
+                  return  UT_ISO8859toAscii8(pszTx);
+               
+               /* Til norsk 7-bits */
+               case TS_ND7:
+               case TS_DECN7:
+                  return  UT_ISO8859toAscii7(pszTx);
+            }
+            break;
+      }
+   }
+
+   return  pszTx;
+}
+
+
+
+/*
+AR:2003-10-13
+CH UT_StrCmpi                                            Sammenlign strenger
+CD ==========================================================================
+CD Form�l:
+CD Sammenligner to strenger uavhengig av store og sm� bokstaver.
+CD For sammenligning der det bare sjekkes p� likhet fungerer den for norske bokstaver.
+CD (Sammenligner bare karakterverdier.)
+CD For sortering m� UT_StrColli brukes for � handtere norske bokstaver rett. 
+CD UT_StrCmpi er mye raskere enn UT_StrColli.
+CD
+CD Parametre:
+CD  Type    Navn         I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD  char   *pszTx1        i    Peker til f�rste streng (avsluttet med '\0').
+CD  char   *pszTx2        i    Peker til andre streng (avsluttet med '\0').
+CD  int     iStatus       r    Status, samme som strcmpi
+CD
+CD Bruk:
+CD iStatus = UT_StrCmpi(szTx1,szTx2);
+   =============================================================================
+*/
+SK_EntPnt_UT int UT_StrCmpi(const char *pszTx1, const char *pszTx2)
+{
+   char *ps1,*ps2;
+   int iStatus;
+
+
+   ps1 = (char*)malloc(strlen(pszTx1)+1);
+#ifdef LINUX
+   strncpy(ps1, pszTx1, strlen(pszTx1)+1);
+#else
+   strcpy_s(ps1, strlen(pszTx1)+1, pszTx1);
+#endif
+   UT_StrUpper(ps1);
+
+   ps2 = (char*)malloc(strlen(pszTx2)+1);
+#ifdef LINUX
+   strncpy(ps2, pszTx2, strlen(pszTx2)+1);
+#else
+   strcpy_s(ps2, strlen(pszTx2)+1, pszTx2);
+#endif
+   UT_StrUpper(ps2);
+
+   iStatus = strcmp(ps1,ps2);
+
+   free(ps1);
+   free(ps2);
+
+   return iStatus;
+}
+
+/*
+PG:2010-10-21
+CH UT_StrColli                                            Sammenlign strenger
+CD ==========================================================================
+CD Form�l:
+CD Sammenligner to strenger uavhengig av store og sm� bokstaver.
+CD Fungerer for norske bokstaver. Justerer for landskode (LC_COLLATE)
+CD Hvis det er bare er likhet det sjekkes p�, b�r heller den raskere UT_StrCmpi brukes.
+CD
+CD Parametre:
+CD  Type    Navn         I/U   Forklaring
+CD -----------------------------------------------------------------------------
+CD  char   *pszTx1        i    Peker til f�rste streng (avsluttet med '\0').
+CD  char   *pszTx2        i    Peker til andre streng (avsluttet med '\0').
+CD  int     iStatus       r    Status, samme som strcmpi
+CD
+CD Bruk:
+CD iStatus = UT_StrColli(szTx1,szTx2);
+   =============================================================================
+*/
+SK_EntPnt_UT int UT_StrColli(const char *pszTx1, const char *pszTx2)
+{
+   char *ps1,*ps2;
+   int iStatus;
+
+   ps1 = (char*)malloc(strlen(pszTx1)+1);
+#ifdef LINUX
+   strncpy(ps1, pszTx1, strlen(pszTx1)+1);
+#else
+   strcpy_s(ps1, strlen(pszTx1)+1, pszTx1);
+#endif
+   UT_StrUpper(ps1);
+
+   ps2 = (char*)malloc(strlen(pszTx2)+1);
+#ifdef LINUX
+   strncpy (ps2, pszTx2, strlen(pszTx2)+1);
+#else
+   strcpy_s(ps2, strlen(pszTx2)+1, pszTx2);
+#endif
+   UT_StrUpper(ps2);
+
+   iStatus = strcoll(ps1,ps2);
+
+   free(ps1);
+   free(ps2);
+
+   return iStatus;
+}
diff --git a/UT/UT3.cpp b/UT/UT3.cpp
new file mode 100644
index 0000000..4824168
--- /dev/null
+++ b/UT/UT3.cpp
@@ -0,0 +1,575 @@
+ /******************************************************************^$date;
+*                                                                           *
+*       Hjelpebiblioteket   U T  (Utilities)                                *
+*       Lars Staurset, Statens Kartverk / FYSAK-prosjektet, januar 1990     *
+*       Fil: UT3.C versjon C22: Diverse rutiner                             *
+*                                                                           *
+****************************************************************************/
+
+#include "stdafx.h"
+
+#include <time.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#ifdef OS2
+  #define INCL_DOSMEMMGR
+  #include <os2.h>
+#endif
+
+#ifdef WIN32
+#	include <windows.h>
+#endif
+
+#include "fyut.h"
+
+/*******************************************************************************
+*                                                                              *
+*       RUTINER FOR � STYRE MASKINUTSTYR                                       *
+*                                                                              *
+*******************************************************************************/
+
+/*LS-880928*********************************************************************
+*       Sound Bell                                                             *
+*******************************************************************************/
+SK_EntPnt_UT void UT_Bell (void)
+{
+   UT_Sound(900,40);
+}
+
+
+/*AR-900110*********************************************************************
+*       Sound Speaker for OS/2                                                 *
+*******************************************************************************/
+SK_EntPnt_UT void UT_Sound (short freq, short dur)
+{
+#ifdef OS232
+   DosBeep((ULONG)freq,((ULONG)dur)*10);
+#endif
+
+#ifdef OS216
+   DosBeep((USHORT)freq,((USHORT)dur)*10);
+#endif
+
+#ifdef WIN32
+	Beep((DWORD)freq,((DWORD)dur)*10);
+#endif
+}
+
+/*LS-890706*********************************************************************
+*       Pause                                                                  *
+*******************************************************************************/
+SK_EntPnt_UT void UT_Pause (short dur)
+{
+#ifdef OS216
+   short t1,t2,t,tid[4];
+
+   UT_InqTime (tid);
+   t1 = 100*tid[2] + tid[3];
+   t2 = t1 + min (dur,6000);
+   do {
+      UT_InqTime (tid);
+      t = 100*tid[2] + tid[3];
+      if (t < t1) t += 6000;
+   } while (t < t2);
+#else
+#ifdef OS2
+   DosSleep(((ULONG)dur)*10);
+#endif
+#endif
+
+#ifdef WIN32
+	Sleep(((DWORD)dur)*10);
+#endif
+}
+
+/*******************************************************************************
+*                                                                              *
+*       MATEMATISKE FUNKSJONAR                                                 *
+*                                                                              *
+*******************************************************************************/
+
+/*AR*LS-890611******************************************************************
+*       Round Double to Double                                                 *
+*******************************************************************************/
+
+SK_EntPnt_UT double UT_RoundDD (double d)
+{
+   double dint;
+
+   modf((d + ((d < 0.0) ? -0.5 : 0.5)  ), &dint) ;
+
+   return dint;
+}
+
+/*AR*TOU*IR:2010-01-25**********************************************************
+*       Round Double to Double                                                 *
+*       Spesiell avrunding som runder av halve verdier oppover                 *
+*       Eks:  -1.1  ->  -1.0                                                   *
+*             -1.5  ->  -1.0                                                   *
+*              1.1  ->   1.0                                                   *
+*              1.5  ->   2.0                                                   *
+*******************************************************************************/
+
+SK_EntPnt_UT double UT_RoundHalfUpDD (double d)
+{
+   return floor(d + 0.5);
+}
+
+
+/*LS-890915*********************************************************************
+*       Round Double to Integer                                                *
+*******************************************************************************/
+
+SK_EntPnt_UT int UT_RoundDI (double d)
+{
+   if (d > INT_MAX  ||  d < INT_MIN)
+   {
+      UT_FPRINTF(stderr,"Kan ikke avrunde %.3f til int!(Fil:%s, Linje:%d)\n", d, __FILE__, __LINE__);
+#ifndef LINUX
+      RaiseException( EXCEPTION_INT_OVERFLOW, EXCEPTION_NONCONTINUABLE, 0, NULL);
+#endif
+      return  (d > INT_MAX)?  INT_MAX : INT_MIN;
+   }
+
+   //(d > 0.0)?  (d+=0.5) : (d-=0.5);
+   //return (int)d;
+   return (int)( d + ( (d < 0.0)? -0.5 : 0.5) );
+}
+
+
+/*LS-890915*********************************************************************
+*       Round Double to Unsigned Integer                                                *
+*******************************************************************************/
+
+SK_EntPnt_UT unsigned int UT_RoundDUI (double d)
+{
+   if (d > UINT_MAX  ||  d < 0)
+   {
+      UT_FPRINTF(stderr,"Kan ikke avrunde %.3f til unsigned int!(Fil:%s, Linje:%d)\n", d, __FILE__, __LINE__);
+#ifndef LINUX
+      RaiseException( EXCEPTION_INT_OVERFLOW, EXCEPTION_NONCONTINUABLE, 0, NULL);
+#endif
+      return  (d > UINT_MAX)?  UINT_MAX : 0;
+   }
+
+   return (unsigned int)( d + 0.5 );
+}
+
+
+/*LS-890915*********************************************************************
+*       Round Double to Long Integer                                           *
+*******************************************************************************/
+
+SK_EntPnt_UT long UT_RoundDL (double d)
+{
+   if (d > LONG_MAX  ||  d < LONG_MIN)
+   {
+      UT_FPRINTF(stderr,"Kan ikke avrunde %.3f til long!(Fil:%s, Linje:%d)\n", d, __FILE__, __LINE__);
+#ifndef LINUX
+      RaiseException( EXCEPTION_INT_OVERFLOW, EXCEPTION_NONCONTINUABLE, 0, NULL);
+#endif
+      return  (d > LONG_MAX)?  LONG_MAX : LONG_MIN;
+   }
+
+   //(d > 0.0)?  (d+=0.5) : (d-=0.5);
+   //return (long)d;
+   return (long)( d + ( (d < 0.0)? -0.5 : 0.5) );
+}
+
+/*PG-071219*********************************************************************
+*       Round Double to Long Long Integer                                      *
+*******************************************************************************/
+
+SK_EntPnt_UT long long UT_RoundDLL (double d)
+{
+   if (d > LLONG_MAX  ||  d < LLONG_MIN)
+   {
+      UT_FPRINTF(stderr,"Kan ikke avrunde %.3f til long long!(Fil:%s, Linje:%d)\n", d, __FILE__, __LINE__);
+#ifndef LINUX
+      RaiseException( EXCEPTION_INT_OVERFLOW, EXCEPTION_NONCONTINUABLE, 0, NULL);
+#endif
+      return  (d > LLONG_MAX)?  LLONG_MAX : LLONG_MIN;
+   }
+
+   //(d > 0.0)?  (d+=0.5) : (d-=0.5);
+   //return (long)d;
+   return (long long)( d + ( (d < 0.0)? -0.5 : 0.5) );
+}
+
+/*LS-890915*********************************************************************
+*       Round Double to Short Integer                                          *
+*******************************************************************************/
+
+SK_EntPnt_UT short UT_RoundDS (double d)
+{
+   if (d > SHRT_MAX  ||  d < SHRT_MIN)
+   {
+      UT_FPRINTF(stderr,"Kan ikke avrunde %.3f til short!(Fil:%s, Linje:%d)\n", d, __FILE__, __LINE__);
+#ifndef LINUX
+      RaiseException( EXCEPTION_INT_OVERFLOW, EXCEPTION_NONCONTINUABLE, 0, NULL);
+#endif
+      return  (d > SHRT_MAX)?  SHRT_MAX : SHRT_MIN;
+   }
+
+   //(d > 0.0)?  (d+=0.5) : (d-=0.5);
+   //return (short)d;
+   return (short)( d + ( (d < 0.0)? -0.5 : 0.5) );
+}
+
+/*******************************************************************************
+*                                                                              *
+*       DIVERSE - DIVERSE                                                      *
+*                                                                              *
+*******************************************************************************/
+
+/*LS-890926*********************************************************************
+*       Get Environment Variable                                               *
+*******************************************************************************/
+
+SK_EntPnt_UT char *UT_GetEnv (char *var, short mstr, char *str)
+{
+    char *env;
+#ifdef LINUX
+    env = getenv (UT_StrUpper(var));
+    if (env == NULL) {
+        UT_StrCopy(str,"C:\\",mstr);
+        UT_StrCat(str,var,(mstr-3));
+    }
+    else {
+        UT_StrCopy(str,env,mstr);
+        *(str+mstr-1) = '\0';
+        UT_ClrTrailsp(str);
+    }
+    return str;
+#else
+    size_t len;
+    _dupenv_s(&env, &len, UT_StrUpper(var));
+    //env = getenv (UT_StrUpper(var));
+    if (env == NULL) {
+        UT_StrCopy(str,"C:\\",mstr);
+        UT_StrCat(str,var,(mstr-3));
+    }
+    else {
+        UT_StrCopy(str,env,mstr);
+        *(str+mstr-1) = '\0';
+        UT_ClrTrailsp(str);
+    }
+    return str;
+#endif   
+}
+
+
+#ifdef WIN32
+
+/*LS-890926*********************************************************************
+*       Lag filnavn med path til FYSAK                                               *
+*******************************************************************************/
+SK_EntPnt_UT char *UT_MakeFysakPath ( char *str, short mstr, char *path, char *filename )
+{
+	size_t len;
+
+	/* Standardverdi */
+	if (path == NULL  ||  *path == '\0') {
+		GetCurrentDirectory(mstr,str);
+	} else {
+		UT_StrCopy(str,path,mstr);
+	}
+
+	UT_ClrTrailsp(str);
+	UT_FullPath(str,str,mstr);
+
+	/* Heng p� '\' */
+	len = strlen(str);
+	if (*(str+len-1) != '\\'  &&  *(str+len-1) != ':'){
+		UT_StrCat(str, "\\", mstr);
+	}
+
+	/* Heng p� filnavn */
+	len = strlen(str);
+	UT_StrCat(str, filename, mstr);
+
+   return str;
+}
+
+#endif
+
+
+#ifdef OS216
+
+/*LS-890926*********************************************************************
+*       Lag filnavn med path til FYSAK                                               *
+*******************************************************************************/
+SK_EntPnt_UT char *UT_MakeFysak ( char *str, short mstr, char *filename )
+{
+   char *cp,finn_env[_MAX_EXT+10];
+   size_t len;
+   char *env = NULL;
+
+   /* S�k etter filtype, og hent environment-variabel */
+   if ((cp = strchr(filename,'.')) != NULL) {
+      cp++;
+      strcpy(finn_env,"FYSAK_");
+      strcat(finn_env,cp);
+      size_t len;
+      errno_t err = _dupenv_s(&env, &len, UT_StrUpper(finn_env));
+		//env = getenv( UT_StrUpper(finn_env));
+   }
+
+   /* Spesialtype er ikke funnet, bruk FYSAK-standard */
+   if (env == NULL) {
+      size_t len;
+      errno_t err = _dupenv_s(&env, &len, "FYSAK");
+      //env = getenv ("FYSAK");
+   }
+ 
+   /* Standardverdi */
+   if (env == NULL) {
+      strncpy(str,"C:\\FYSAK\\",(size_t)(mstr-1));
+      *(str+mstr-1) = '\0';
+
+   } else {
+      strncpy (str,env,(size_t)(mstr-1));
+		*(str+mstr-1) = '\0';
+      UT_ClrTrailsp(str);
+   }
+
+   /* Heng p� '\' */
+   len = strlen(str);
+   if (*(str+len-1) != '\\'  &&  *(str+len-1) != ':'){
+      strncat (str,"\\",mstr-len-1);
+      *(str+mstr-1) = '\0';
+   }
+
+   /* Heng p� filnavn */
+   len = strlen(str);
+	strncat (str,filename,mstr-len-1);
+   *(str+mstr-1) = '\0';
+
+    return str;
+}
+
+#endif
+
+
+/*LS-880929*********************************************************************
+*       Function : Inquire System Date                                         *
+*******************************************************************************/
+
+SK_EntPnt_UT void UT_InqDate (short *date)
+{
+#ifdef LINUX
+   struct tm *ntime;
+   time_t ltime=NULL;
+
+   time(&ltime);
+
+   ntime = localtime(&ltime);
+
+    *date++ = (short)ntime->tm_year;
+    *date++ = (short)ntime->tm_mon;
+    *date++ = (short)ntime->tm_mday;
+    *date   = (short)((ntime->tm_wday) ? ntime->tm_wday - 1 : 6);
+#else
+   time_t ltime=NULL;
+   struct tm ntime;
+
+   time(&ltime);
+
+   localtime_s(&ntime,&ltime);
+
+    *date++ = (short)ntime.tm_year;
+    *date++ = (short)ntime.tm_mon;
+    *date++ = (short)ntime.tm_mday;
+    *date   = (short)((ntime.tm_wday) ? ntime.tm_wday - 1 : 6);
+#endif
+}
+
+
+//*****************************************************************
+// Henter og formatterer dagens dato som en 8-sifret streng
+//*****************************************************************
+SK_EntPnt_UT char *UT_InqDateString(void)
+{ 
+#ifdef LINUX
+   struct tm *ntime;
+   time_t aclock;
+   static char szDato[9];
+
+
+   time(&aclock);
+   ntime = localtime(&aclock);
+   UT_SNPRINTF(szDato,9,"%4d%02d%02d",
+           1900+ntime->tm_year,
+           ntime->tm_mon+1,
+           ntime->tm_mday);
+
+   return szDato;
+#else
+   struct tm ntime;
+   time_t aclock;
+   static char szDato[9];
+
+
+   time(&aclock);
+   localtime_s(&ntime,&aclock);
+   UT_SNPRINTF(szDato,9,"%4d%02d%02d",
+           1900+ntime.tm_year,
+           ntime.tm_mon+1,
+           ntime.tm_mday);
+
+   return szDato;
+#endif
+}
+
+
+//*****************************************************************
+// Henter og formatterer dagens dato og tid som en 14-sifret 
+// streng p� formen ����mmddttmmss.
+//*****************************************************************
+SK_EntPnt_UT char *UT_InqDatetimeString(void)
+{ 
+#ifdef LINUX
+   struct tm *ntime;
+   time_t aclock;
+   static char szDatotid[15];
+
+   time(&aclock);
+   ntime = localtime(&aclock);
+   UT_SNPRINTF(szDatotid,15,"%4d%02d%02d%02d%02d%02d",
+           1900+ntime->tm_year,
+           ntime->tm_mon+1,
+           ntime->tm_mday,
+           ntime->tm_hour,
+           ntime->tm_min,
+           ntime->tm_sec);
+
+   return szDatotid;
+#else
+   struct tm ntime;
+   time_t aclock;
+   static char szDatotid[15];
+
+   time(&aclock);
+   localtime_s(&ntime,&aclock);
+   UT_SNPRINTF(szDatotid,15,"%4d%02d%02d%02d%02d%02d",
+           1900+ntime.tm_year,
+           ntime.tm_mon+1,
+           ntime.tm_mday,
+           ntime.tm_hour,
+           ntime.tm_min,
+           ntime.tm_sec);
+
+   return szDatotid;
+#endif
+}
+
+
+/*LS-880929*********************************************************************
+*        Inquire System Time                                                   *
+*******************************************************************************/
+
+SK_EntPnt_UT void UT_InqTime (short *tid)
+{
+#ifdef LINUX
+   struct tm *ntime;
+   time_t ltime;
+
+   time(&ltime);
+   ntime = localtime(&ltime);
+   *tid++ = (short)ntime->tm_hour;
+   *tid++ = (short)ntime->tm_min;
+   *tid++ = (short)ntime->tm_sec;
+#else 
+   time_t ltime;
+   struct tm ntime;
+
+   time(&ltime);
+   localtime_s(&ntime,&ltime);
+   *tid++ = (short)ntime.tm_hour;
+	*tid++ = (short)ntime.tm_min;
+   *tid++ = (short)ntime.tm_sec;
+#endif
+}
+
+
+/*LS-890913********************************************************************/
+/*      Inquire Free Memory  i OS2                                            */
+/******************************************************************************/
+SK_EntPnt_UT extern unsigned long UT_InqFreemem (void)
+{
+#ifdef OS216
+   ULONG size;
+   DosMemAvail(&size);
+	return size;
+
+#else
+   return 0L;
+#endif
+}
+
+
+/*
+JEK-920604
+CH UT_SortD                                         Sorteringsrutine
+CD ==================================================================
+CD Form�l:
+CD Sorterer verdier i en double-tabell i stigende rekkef�lge.
+CD Teorien bak sorteringsalgoritmen(CombSort11) er beskrevet i
+CD Byte April-91 s315-320.
+CD
+CD NB! Rutina flytter de enkelte elementer i tabellen!!
+CD
+CD PARAMETERLISTE:
+CD Navn      Type  Array I/U  Merknad
+CD ------------------------------------------------------------------
+CD *db_arr   double       i/u Tabell som skal sorteres
+CD size      short        i   Ant elementer i tabell
+CD
+CD Bruk:  UT_SortD(db_arr, size)
+	==================================================================
+*/
+SK_EntPnt_UT void UT_SortD ( double *db_arr, short size)
+{
+	#define SHRINKFACTOR 1.3          /* Empirisk verdi */
+
+	int  switches;
+	int  i, j;
+   int  top, gap;
+   double dtmp;
+
+   gap = size;                       /* Initier gap til tabellst�rrelse */
+
+   /* ----- Start l�kke */
+   do {
+      gap = (int)((float)gap/SHRINKFACTOR);
+
+      switch (gap) {
+         case 0:                     /* Minste gap --> boblesortering */
+            gap = 1;
+            break;
+         case 9:                     /* Spesielt for CombSort11 */
+         case 10:
+            gap = 11;
+            break;
+         default:
+            break;
+      }
+
+      switches = 0;
+      top = size - gap;
+   
+      for (i=0;i<top;++i) {
+         j = i + gap;
+         if (db_arr[i] > db_arr[j]) {
+            dtmp = db_arr[i];
+            db_arr[i] = db_arr[j];
+            db_arr[j] = dtmp;
+            ++switches;
+         }
+      }
+
+   } while (switches || (gap > 1));
+}
diff --git a/UT/UT4.cpp b/UT/UT4.cpp
new file mode 100644
index 0000000..0c626ac
--- /dev/null
+++ b/UT/UT4.cpp
@@ -0,0 +1,149 @@
+/******************************************************************^$date;
+*                                                                           *
+*       Hjelpebiblioteket   U T  (Utilities)                                *
+*       Lars Staurset, Statens Kartverk / FYSAK-prosjektet, januar 1990     *
+*       Fil: UT4.C: Handtering av flag-tabell                               *
+*                                                                           *
+****************************************************************************/
+
+#include "stdafx.h"
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "fyut.h"
+
+
+/**************************************************************************
+*                                                                         *
+*       RUTINER FOR � HANDTERE FLAG-TABELL                                *
+*                                                                         *
+***************************************************************************/
+
+/*
+OJ-920309
+CH UT_InitFlag
+CD ==========================================================================
+CD Form�l:
+CD Opprette og nullstille flag-tabell.
+CD
+CD Parametre:
+CD Type        Navn        I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD short       sNlin        i    Antall linjer.
+CD long[]      *plFlag      r    Peker til minneblokk for flagging.
+CD
+CD Bruk:
+CD plFlag = UT_InitFlag(sNgi,&sAktLines);
+   ==========================================================================
+*/
+SK_EntPnt_UT unsigned long *UT_InitFlag(short sNlin)
+{
+   unsigned long *plFlag;
+
+   unsigned long ulAntUL = UT_RoundDL(ceil((double)(sNlin + 1) / (double)(sizeof(unsigned long) * 8)));
+	plFlag = (unsigned long *)UT_MALLOC((size_t)((ulAntUL+1) * (sizeof(unsigned long))));
+   memset(plFlag,0,(size_t)((ulAntUL+1) * (sizeof(unsigned long))));
+
+   *plFlag = (unsigned long)sNlin;
+
+   return plFlag;
+}
+
+/*
+OJ-920309
+CH UT_CloseFlag
+CD ==========================================================================
+CD Form�l:
+CD Frigj�re minne brukt til flagging av brukte linjer.
+CD
+CD Parametre:
+CD Type        Navn      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD long        *plFlag    I    Peker til minneblokk for flagging.
+CD
+CD Bruk:
+CD UT_CloseFlag(plFlag);
+   ==========================================================================
+*/
+SK_EntPnt_UT void UT_CloseFlag(unsigned long *plFlag)
+{
+	UT_FREE((void *)(plFlag));
+	plFlag = NULL;
+}
+
+/*
+OJ-920309
+CH UT_SetFlag                                 Flagger brukt linje.
+CD ==========================================================================
+CD Form�l:
+CD Legg inn merke i linje tabell.
+CD
+CD Parametre:
+CD Navn              Type        I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD bStatus          bool        r     Returstatus, UT_TRUE=OK, UT_FALSE=flagging feilet
+CD unsigned long   *plFlag      i     Peker til minneblokk for flagging.
+CD short            sLine       i     Linje som skal flagges som brukt.
+CD
+CD Bruk:
+CD bStatus = UT_SetFlag(plFlag,sLine)
+   ==========================================================================
+*/
+// SK_EntPnt_UT void UT_SetFlag(unsigned long *plFlag,short sLine)
+SK_EntPnt_UT bool UT_SetFlag(unsigned long *plFlag,short sLine)
+{
+
+   // char szErrMsg[80];
+
+        /* Maksimalt: antall long * 32 - 1 for bit 0 i f�rste */
+   /*
+   if (sLine >= (short)*plFlag){
+      UT_SNPRINTF(szErrMsg,80,"For mange -linjer %hd, maksimalt: %hd",sLine,(short)*plFlag-1);
+   }
+   *(plFlag + (sLine / (sizeof(unsigned long) * 8)) + 1) |=
+                     (0x00000001L << (sLine % (sizeof(unsigned long) * 8)));
+   */
+
+   // JEK 20090428 Gjort om til boolsk funksjon
+   if (sLine < (short)*plFlag){
+      *(plFlag + (sLine / (sizeof(unsigned long) * 8)) + 1) |=
+         (0x00000001L << (sLine % (sizeof(unsigned long) * 8)));
+      return UT_TRUE;
+   }else{
+      // UT_SNPRINTF(szErrMsg,80,"For mange -linjer %hd, maksimalt: %hd",sLine,(short)*plFlag-1);
+      return UT_FALSE;
+   }
+}
+
+
+/*
+OJ-920309
+CH UT_GetFlag                                 Flagger brukt -linje.
+CD ==========================================================================
+CD Form�l:
+CD Teste merke i linje tabell.
+CD
+CD Parametre:
+CD Navn        Type      I/U   Forklaring
+CD --------------------------------------------------------------------------
+CD unsigned long       *plFlag    i    Peker til minneblokk for flagging.
+CD short       sLine      i    Linje som skal hentes.
+CD
+CD Bruk:
+CD UT_GetFlag(plFlag,sNlines,sLine)
+   ==========================================================================
+*/
+SK_EntPnt_UT short UT_GetFlag(unsigned long *plFlag,short sLine)
+{
+   char szErrMsg[80];
+
+        /* Maksimalt: antall long * 32 - 1 for bit 0 i f�rste */
+   if (sLine >= (short)*plFlag){
+      UT_SNPRINTF(szErrMsg,80,"For mange -linjer %hd, maksimalt: %hd",sLine,(short)*plFlag-1);
+   }
+   return ((*(plFlag + (sLine / (sizeof(unsigned long) * 8)) + 1)  &
+            (0x00000001L << (sLine % (sizeof(unsigned long) * 8)))) == 0)?
+                                                           UT_FALSE : UT_TRUE;
+}
diff --git a/UT/fyut.h b/UT/fyut.h
new file mode 100644
index 0000000..e7f7f77
--- /dev/null
+++ b/UT/fyut.h
@@ -0,0 +1,279 @@
+/******************************************************************************
+*
+* STATENS KARTVERK  -  FYSAK
+*
+* Filename: fyut.h
+*
+* Content: Prototyper for generelle hjelperutiner og operativsystemavhengige rutiner.
+*
+* Copyright (c) 1990-2011 Statens kartverk
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+* DEALINGS IN THE SOFTWARE.
+******************************************************************************/
+
+#pragma once
+
+
+
+#include <stdio.h>
+
+#ifndef SK_EntPnt_UT
+#  define SK_EntPnt_UT
+#endif
+
+
+/* ----------------------------------------- Konstanter */
+/* Div. manifeste konstantar */
+
+#ifdef WIN32
+#ifdef _DEBUG
+ #pragma comment (lib, "UtD.lib")
+#else
+ #pragma comment (lib, "Ut.lib")
+#endif
+/* For DOS/OS2/Windows */
+#   define UT_SLASH  '\\'
+#   define UT_STR_SLASH  "\\"
+#   define UT_INT64  __int64
+#   define UT_SNPRINTF _snprintf_s
+#   define UT_FPRINTF fprintf_s
+#   define UT_GETPID   _getpid
+
+#else
+          /* For UNIX */
+#  ifdef LINUX /* specifically the LINUX */
+#    include <stdint.h>
+#    include <inttypes.h>
+#    define UT_INT64 int64_t 
+#  endif
+
+#   define UT_SNPRINTF snprintf
+#   define UT_FPRINTF fprintf
+#   define UT_GETPID   getpid
+
+#   define UT_SLASH  '/'
+#   define UT_STR_SLASH  "/"
+#   define cdecl
+#   define EZERO 0
+
+#  ifdef  _FILE_OFFSET_BITS
+#    undef _FILE_OFFSET_BITS
+#  endif
+#  define _FILE_OFFSET_BITS 64
+#  include <limits.h>
+#  include <sys/types.h>
+#  include <unistd.h>
+#  include <stdio.h>
+
+#  define _TRUNCATE 0
+#  define _fseeki64 fseek
+#  define _ftelli64 ftell
+#  define _strcmpi  strcasecmp
+
+#endif
+
+#define UT_FALSE 0
+#define UT_TRUE  1
+#define UT_OVRFLW 2
+
+#define UT_NULL 0L
+
+#define UT_OK  0
+#define UT_EOF 1
+#define UT_ERROR -1
+#define UT_READ   0
+#define UT_WRITE  1
+#define UT_UPDATE  2
+#define UT_UNKNOWN 0
+#define UT_OLD     1
+#define UT_NEW     2
+
+/* Konstanter for UT_KonverterTegnsett */
+#define TS_UKJENT   0  /* Ukjent tegnsett */
+#define TS_DOSN8    1  /* DOS norsk 8-bits (standardverdi) */
+#define TS_ND7      2  /* Norsk Data 7-bits */
+#define TS_DECM8    4  /* DEC multinasjonal 8-bits */
+#define TS_DECN7    8  /* DEC norsk 7-bits */
+#define TS_ISO8859  16 /* ISO8859-10 (Samisk og norsk mm. ) */
+
+/* Div lengder for filnavn; jfr. stdlib.h */
+#define _MAX_PATH   260  /* max. length of full pathname */
+#define _MAX_DRIVE    3  /* max. length of drive component */
+#define _MAX_DIR    256  /* max. length of path component */
+#define _MAX_FNAME  256  /* max. length of file name component */
+#define _MAX_EXT    256  /* max. length of extension component */
+
+
+/* ----------------------------------------- Makroer */
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Oppdateringstid for fil                                      !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dFTID {
+   unsigned short usAar;
+   unsigned short usMnd;
+   unsigned short usDag;
+   unsigned short usTime;
+   unsigned short usMin;
+   unsigned short usSek;
+} FTID;
+
+typedef FTID *PFTID;
+
+
+/* ----------------------------------------- Prototyper */
+
+SK_EntPnt_UT void  UT_makepath(char *pathP,const char *driveP,const char *dirP,const char *nameP,const char *extP);
+SK_EntPnt_UT void  UT_splitpath(const char *pathP,char *driveP,char *dirP,char *nameP,char *extP);
+SK_EntPnt_UT short UT_InqPathSize(char *pszPath,long *plSize);
+SK_EntPnt_UT short UT_InqPathSize_i64(char *pszPath,UT_INT64 *n64Size);
+SK_EntPnt_UT short UT_SetPathSize(char *pszPath,long lSize);
+SK_EntPnt_UT short UT_SetPathSize_i64(char *pszPath, UT_INT64 n64Size);
+SK_EntPnt_UT short UT_InqPathTid(char *pszPath,PFTID pFilTid);
+SK_EntPnt_UT short UT_InqAvailSize(char *pszPath,unsigned long *pulLedigPlass);
+SK_EntPnt_UT short UT_FullPath(char *pszBuffer, const char *pszPath, size_t maxlen);
+SK_EntPnt_UT short UT_DeleteFile(char *pszPath);
+SK_EntPnt_UT short UT_DeleteDir(char *pszPath);
+SK_EntPnt_UT short UT_CreateDir(char *pszPath);
+SK_EntPnt_UT short UT_FilnavnCmp(char *pszFil1,char *pszFil2);
+SK_EntPnt_UT short UT_CopyFile(char *pszFraFilnavn,char *pszTilFilnavn,short sFeilHvisEksisterer);
+
+
+/* Framhenting fr� streng */
+SK_EntPnt_UT char *UT_GetToken (char *str, short *l_tok);
+SK_EntPnt_UT char  UT_StrToken (char *str, short ii, short *iu, short mt, char *token);
+SK_EntPnt_UT char  UT_StrWord (char *str, short ii, short *iu, short mw, char *word);
+SK_EntPnt_UT short UT_StrInt (char *str, short ii, short *iu, int *_int);
+SK_EntPnt_UT short UT_StrInt64 (char str[], short ii, short *iu, UT_INT64 *i64);
+SK_EntPnt_UT short UT_StrShort (char *str, short ii, short *iu, short *s);
+SK_EntPnt_UT short UT_StrLong (char *str, short ii, short *iu, long *_long);
+SK_EntPnt_UT short UT_StrUlong (char str[], short ii, short *iu, unsigned long *_ulong);
+SK_EntPnt_UT short UT_StrDbl (char *str, short ii, short *iu, char decpt,double *dbl);
+SK_EntPnt_UT void  UT_StrCopy (char *tx_to, const char *tx_from, int tx_len);
+SK_EntPnt_UT short UT_StrCat (char *dst,const char *src, const int maxlen);
+SK_EntPnt_UT int UT_memcpy(void *dest,size_t numberOfElements,const void *src,size_t count);
+SK_EntPnt_UT int UT_strerror(char *buffer,size_t numberOfElements,int errnum);
+SK_EntPnt_UT char *UT_strtok(char *strToken,const char *strDelimit,char **context);
+
+
+/* Konvertering */
+#ifdef OS216
+SK_EntPnt_UT    short UT_AtoI (char *str, int *_int);
+SK_EntPnt_UT    short UT_AtoS (char str[], short *s);
+SK_EntPnt_UT    short UT_AtoL (char str[], long *_long);
+#endif
+SK_EntPnt_UT short UT_AtoD (char *str, char decpt, double *d);
+SK_EntPnt_UT short UT_ItoA (int i, short sl, char *str);
+SK_EntPnt_UT short UT_StoA (short s, short mstr, char *str);
+SK_EntPnt_UT short UT_LtoA (long l, short sl, char *str);
+SK_EntPnt_UT short UT_DtoA (double d, short dec, char decpt, short sl, char *str);
+
+/* Strengmanipulering ellers */
+SK_EntPnt_UT char *UT_ClrCrlf (char *str);
+SK_EntPnt_UT char *UT_ClrTrailsp(char *str);
+SK_EntPnt_UT char *UT_ClrExtrasp(char *str);
+SK_EntPnt_UT void  UT_JustStr (char justmode, char fill, short lstr, char *str);
+SK_EntPnt_UT short UT_Index (char *str, char *substr);
+SK_EntPnt_UT void  UT_GetSubstr (char ctx[],short fra,short til,char sub[],short maxlen);
+SK_EntPnt_UT char *UT_StrLower (char *tx);
+SK_EntPnt_UT char *UT_StrUpper (char *tx);
+SK_EntPnt_UT int   UT_StrCmpi(const char *pszTx1, const char *pszTx2);
+SK_EntPnt_UT int   UT_StrColli(const char *pszTx1, const char *pszTx2);
+SK_EntPnt_UT unsigned char *UT_Ascii7to8 (unsigned char *tx);
+SK_EntPnt_UT unsigned char *UT_Ascii8to7 (unsigned char *tx);
+SK_EntPnt_UT unsigned char *UT_ISO8859toAscii8(unsigned char *tx);
+SK_EntPnt_UT unsigned char *UT_Ascii8toISO8859(unsigned char *tx);
+SK_EntPnt_UT unsigned char *UT_ISO8859toAscii7(unsigned char *tx);
+SK_EntPnt_UT unsigned char *UT_Ascii7toISO8859(unsigned char *tx);
+SK_EntPnt_UT unsigned char *UT_KonverterTegnsett(short sFraTegnsett,short sTilTegnsett,
+                                    unsigned char *pszTx);
+
+
+/* Andre teiknhandterings rutiner */
+SK_EntPnt_UT int UT_IsSpace (char c);
+SK_EntPnt_UT int UT_IsPrint (int ch);
+SK_EntPnt_UT int UT_IsLower (int ch);
+SK_EntPnt_UT int UT_IsUpper (int ch);
+SK_EntPnt_UT int UT_ToUpper (int ch);
+SK_EntPnt_UT int UT_ToLower (int ch);
+
+/* Matematiske funksjonar */
+SK_EntPnt_UT double UT_RoundDD (double d);
+SK_EntPnt_UT double UT_RoundHalfUpDD (double d);
+SK_EntPnt_UT int    UT_RoundDI (double d);
+SK_EntPnt_UT unsigned int UT_RoundDUI (double d);
+SK_EntPnt_UT long   UT_RoundDL (double d);
+SK_EntPnt_UT long long UT_RoundDLL (double d);
+SK_EntPnt_UT short  UT_RoundDS (double d);
+
+/* Kalender/klokke-rutiner */
+SK_EntPnt_UT void UT_InqDate (short *date);
+SK_EntPnt_UT char *UT_InqDateString(void);
+SK_EntPnt_UT char *UT_InqDatetimeString(void);
+SK_EntPnt_UT void UT_InqTime (short *time);
+
+/* H�gniv� */
+SK_EntPnt_UT FILE *UT_OpenFile     (const char *filnavn,const char *ftyp,
+                                    short facc,short exist,short *ierr);
+SK_EntPnt_UT short UT_ReadLine     (FILE *pfil,short llin, char clin[]);
+SK_EntPnt_UT short UT_ReadLineCrlf (FILE *pfil,short llin, char clin[]);
+SK_EntPnt_UT short UT_ReadLineNoComm(FILE *pfil,short llin, char *clin);
+SK_EntPnt_UT short UT_WriteLine    (FILE *pfil,char clin[]);
+SK_EntPnt_UT short UT_WriteLineCrlf(FILE *pfil,char clin[]);
+SK_EntPnt_UT short UT_SetPos       (FILE *fi,long lpos);
+SK_EntPnt_UT short UT_SetPos_i64   (FILE *fi,UT_INT64 n64FilPos);
+SK_EntPnt_UT short UT_GetPos       (FILE *fi,long *lpos);
+SK_EntPnt_UT short UT_GetPos_i64(FILE *fi,UT_INT64 *n64FilPos);
+SK_EntPnt_UT short UT_Save         (FILE *pfil);
+
+/* Div. rutiner */
+SK_EntPnt_UT void UT_Bell (void);
+SK_EntPnt_UT void UT_Sound (short freq, short dur);
+SK_EntPnt_UT void UT_Pause (short dur);
+SK_EntPnt_UT unsigned long UT_InqFreemem (void);
+SK_EntPnt_UT char *UT_GetEnv (char *var, short mstr, char *str);
+SK_EntPnt_UT char *UT_MakeFysak ( char *str, short mstr, char *filename );
+SK_EntPnt_UT char *UT_MakeFysakPath ( char *str, short mstr, char *path, char *filename );
+SK_EntPnt_UT void UT_SortD(double *db_arr, short size);
+
+SK_EntPnt_UT unsigned long *UT_InitFlag(short sNlin);
+SK_EntPnt_UT void UT_CloseFlag(unsigned long *plFlag);
+SK_EntPnt_UT bool UT_SetFlag(unsigned long *plFlag,short sLine);
+SK_EntPnt_UT short UT_GetFlag(unsigned long *plFlag,short sLine);
+
+SK_EntPnt_UT short UT_StartProsess(char *pszCommandLine,short sVent);
+
+SK_EntPnt_UT short UT_PutAnfTegn(char *pszTx, char cTegn, short sMaksLen);
+
+
+/* --- Makroer -- */
+#define UT_MALLOC  malloc
+#define UT_FREE  free
+
+#define UT_VENT 1
+#define UT_FORTSETT 2
+
+
+
diff --git a/UT/make.sh b/UT/make.sh
new file mode 100755
index 0000000..a06309b
--- /dev/null
+++ b/UT/make.sh
@@ -0,0 +1,4 @@
+gcc -Wall -g -D_FILE_OFFSET_BITS=64 -DUNIX -DLINUX -fPIC -Wno-write-strings -c -I. *.cpp
+ar rcs libfyut.a *.o
+gcc -g -D_FILE_OFFSET_BITS=64 -DUNIX -DLINUX -fPIC -Wno-write-strings -shared -I. *.cpp -o ../lib/libfyut.so
+cp fyut.h ../include/fyut.h
diff --git a/UT/stdafx.cpp b/UT/stdafx.cpp
new file mode 100644
index 0000000..f506d58
--- /dev/null
+++ b/UT/stdafx.cpp
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// UT.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/UT/stdafx.h b/UT/stdafx.h
new file mode 100644
index 0000000..f1ffb54
--- /dev/null
+++ b/UT/stdafx.h
@@ -0,0 +1,9 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+
+// TODO: reference additional headers your program requires here

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/fyba.git



More information about the Pkg-grass-devel mailing list