ftp.nice.ch/pub/next/database/plz/NXplz.1.1.NI.s.tar.gz#/NXplz-1.1/convert.c

This is convert.c in view mode; [Download] [Up]

/* $Id: convert.c,v 3.3 1993/06/28 12:16:59 klute Exp klute $ */

/* 
 * Copyright 1993 Rainer Klute <klute@irb.informatik.uni-dortmund.de>
 *
 * Permission to use, copy, modify, distribute, and sell this software and
 * its documentation for any purpose is hereby granted without fee, provided
 * that the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation. The author makes no representations about the suitability
 * of this software for any purpose. It is provided "as is" without express
 * or implied warranty.
 *
 */

#ifdef __NeXT__
#include <stdlib.h>
#include <ctype.h>
#else
#include <malloc.h>
#endif
#include <string.h>

#include "xplz.h"
#include "convert.h"
#include "message.h"
#include "ortarda.h"
#include "pofada.h"
#include "strada.h"
#include "umsda.h"
#include "utils.h"

#if defined (HANDLE_BROKEN_DATAFILES)
#define IbmToIso IbmAndBrokenToIso
#endif

static char **msgTexts = (char **) 0;




char *ConversionStatusString (PlzConversionState pcs)
{
    int i;

    if (msgTexts == (char **) 0)
    {
	msgTexts = (char **) calloc (PlzLetzterZustand, sizeof (char *));
	if (msgTexts == (char **) 0)
	{
	    OutOfMemory ("ConversionStatusString");
	    return "";
	}
	for (i = 0; i < PlzLetzterZustand; i++)
	    msgTexts[i] = "";
	msgTexts[PlzOrtNichtGefunden] = "Ort nicht gefunden.";
	msgTexts[PlzOrtMehrdeutig] = "Bitte alte Postleitzahl eingeben!";
	msgTexts[PlzPlzAltGeaendert] = "Bitte überprüfen!";
	msgTexts[PlzPostanstaltBenoetigt] = "Bitte Zustellbezirk, Straße oder Postfach eingeben!";
	msgTexts[PlzStrassePostfachBenoetigt] = "Bitte Straße oder Postfach eingeben!";
	msgTexts[PlzStrasseNichtGefunden] = "Straße nicht gefunden.";
	msgTexts[PlzStrasseMehrfachInOrt] = "Bitte Zustellbezirk oder Ortsteil eingeben!";
	msgTexts[PlzStrasseMehrfachInPostanstalt] = "Bitte Ortsteil eingeben!";
	msgTexts[PlzStrasseMehrfachInOrtsteil] = "Bitte Zustellbezirk eingeben!";
	msgTexts[PlzHausnummerBenoetigt] = "Bitte Hausnummer eingeben!";
	msgTexts[PlzHausnummerNichtGefunden] = "Hausnummer nicht gefunden.";
	msgTexts[PlzPostfachNichtGefunden] = "Postfach nicht gefunden.";
	msgTexts[PlzPostfachMehrfachInOrt] = "Bitte Postanstalt oder alte Postleitzahl eingeben!";
	msgTexts[PlzPostfachMehrfachInPostanstalt] = "Bitte alte Postleitzahl eingeben!";
	msgTexts[PlzPostfachMehrfachInPlz] = "Bitte Postanstalt eingeben!";
    }
    return msgTexts[pcs];
}




/*
 * FreePofadaSet
 */

static void FreePofadaSet (PofadaSet **p)
{
    if (*p != (PofadaSet *) 0)
    {
	if ((*p)->list != (Pofada *) 0)
	    free ((*p)->list);
	free (*p);
	*p = (PofadaSet *) 0;
    }
}




/*
 * FreeStradaSet
 */

static void FreeStradaSet (StradaSet **s)
{
    if (*s != (StradaSet *) 0)
    {
	if ((*s)->list != (Strada *) 0)
	    free ((*s)->list);
	free (*s);
	*s = (StradaSet *) 0;
    }
}




/*
 * FreeUmsdaSet
 */

static void FreeUmsdaSet (UmsdaSet **u)
{
    if (*u != (UmsdaSet *) 0)
    {
	if ((*u)->list != (Umsda *) 0)
	    free ((*u)->list);
	free (*u);
	*u = (UmsdaSet *) 0;
    }
}




/*
 * FreeOrtardaSet
 */

static void FreeOrtardaSet (OrtardaSet **u)
{
    if (*u != (OrtardaSet *) 0)
    {
	if ((*u)->list != (Ortarda *) 0)
	    free ((*u)->list);
	free (*u);
	*u = (OrtardaSet *) 0;
    }
}




static Boolean UpdateIsoStringFromFixed (char **old, char *new, int length)
{
    char *s = malloc (length + 1);
    char *iso;
    Boolean r;

    if (s == (char *) 0)
    {
	OutOfMemory ("UpdateIsoStringFromFixed");
	return False;
    }
    strncpy (s, new, length);
    s[length] = '\0';
    StripBlanks (s);
    iso = IbmToIso (s);
    if (iso == (char *) 0)
    {
	free (s);
	return False;
    }
    r = UpdateString (old, iso);
    free (iso);
    free (s);
    return r;
}




/*
 * UpdateState
 */

static void UpdateState (PlzConversionState *pcs, PlzConversionState newState)
{
    if (*pcs > newState)
	*pcs = newState;
}




/*
 * UpdatePlzAlt
 */

static Boolean UpdatePlzAlt (char **old, char *new, char verkehrsgebiet)
{
    char msg[300];
    Boolean changed = False;
    char oldPlz[6];
    char newPlz[6];

    strcpy (oldPlz, OldPlz (*old, verkehrsgebiet));
    strcpy (newPlz, OldPlz (new, verkehrsgebiet));
    if (**old && strcmp (oldPlz, newPlz) != 0)
    {
	strcpy (msg, "Alte Postleitzahl ");
	strcat (msg, oldPlz);
	strcat (msg, " geändert in ");
	strcat (msg, newPlz);
	strcat (msg, ". ");
	Message (msg);
	changed = True;
    }
    UpdateIsoStringFromFixed (old, newPlz, 5);
    return changed;
}




/*
 * OrtEindeutig
 */

static Boolean OrtEindeutig (UmsdaSet *orte, OrtardaSet *archivOrte)
{
    char orteAlort[sizeof (((Umsda *) 0)->alort) + 1];
    char archivOrteAlort[sizeof (((Ortarda *) 0)->alort) + 1];

    strcpy (orteAlort, UmsdaSetOrtEindeutig (orte));
    strcpy (archivOrteAlort, OrtardaSetOrtEindeutig (archivOrte));
    if (!*orteAlort && orte->entries >= 1)
	return False;
    if (!*archivOrteAlort && archivOrte->entries >= 1)
	return False;
    if (*orteAlort && *archivOrteAlort
    && strcmp (orteAlort, archivOrteAlort) != 0)
	return False;
    else
	return True;
}




/*
 * ConvertPlz
 */

void ConvertPlz (PlzConversion *pc, char *strasse, char *hausnummer, 
		 char *postfach, char *plzalt, char *ort, char *postanstalt,
		 char *ortsteil)
{
    PlzConversionState previousState;
    char plz_neu[6];
    Boolean changed=False;

    NoteClear ();

    /*
     * Prüfen, ob irgendein Parameter vom vorigen Wert abweicht. In diesem Fall
     * muß der Zustand entsprechend geändert werden.
     */

    if (UpdateString (&pc->hausnummer, hausnummer))
	UpdateState (&pc->status, PlzHausnummerBenoetigt);

    if (UpdateString (&pc->strasse, strasse))
	UpdateState (&pc->status, PlzSucheStrasse);

    if (UpdateString (&pc->postfach, postfach))
	UpdateState (&pc->status, PlzSuchePostfach);

    if (pc->status == PlzSucheStrasse && *pc->postfach)
	pc->status = PlzSuchePostfach;
    if (pc->status == PlzSuchePostfach && *pc->strasse)
	pc->status = PlzSucheStrasse;

    if (UpdateString (&pc->postanstalt, postanstalt))
	UpdateState (&pc->status, PlzSucheOrt);
    if (UpdateString (&pc->ortsteil, ortsteil))
	UpdateState (&pc->status, PlzSucheOrt);

    if (UpdateString (&pc->plz_alt, plzalt))
	UpdateState (&pc->status, PlzSucheOrt);
    if (UpdateString (&pc->ort, ort))
	UpdateState (&pc->status, PlzSucheOrt);

    if (pc->status == PlzFehler || pc->status == PlzPlzAltGeaendert)
	pc->status = PlzSucheOrt;

    do
    {
	previousState = pc->status;
	switch (pc->status)
	{


	    case PlzSucheOrt:
	    {
		if (!*pc->ort)
		    {pc->status = PlzOrtNichtGefunden; break;}
		FreeUmsdaSet (&pc->orte);
		pc->orte = UmsdaSucheOrt (pc->ort);
		FreeOrtardaSet (&pc->archivOrte);
		pc->archivOrte = OrtardaSucheOrt (pc->ort);
		if (pc->orte == (UmsdaSet *) 0
		|| pc->archivOrte == (OrtardaSet *) 0)
		    {pc->status = PlzFehler; break;}
		if (pc->orte->entries <= 0 && pc->archivOrte->entries <= 0)
		    {pc->status = PlzOrtNichtGefunden; break;}
		pc->status = PlzOrtGefunden;
		break;
	    }


	    case PlzOrtGefunden:
	    {
		if (pc->orte->entries >= 1 || pc->archivOrte->entries >= 1)
		{
		    if (OrtEindeutig (pc->orte, pc->archivOrte))
		    {
			pc->status = PlzOrtEindeutig;
			if (pc->orte->entries > 0)
			    UpdateIsoStringFromFixed (&pc->ort,
				pc->orte->list[0].ortname_a,
				sizeof (((Umsda *) 0)->ortname_a));
			else
			{
			    UpdateIsoStringFromFixed (&pc->ort,
				pc->archivOrte->list[0].ortname_n,
				sizeof (((Ortarda *) 0)->ortname_n));
			    UpdateIsoStringFromFixed (&pc->ortsteil,
				pc->archivOrte->list[0].ortname_a,
				sizeof (((Ortarda *) 0)->ortname_a));
			}
		    }
		    else
			pc->status = PlzOrtMehrdeutig;
		}
		else
		    pc->status = PlzOrtNichtGefunden;
		break;
	    }


	    case PlzOrtMehrdeutig:
	    {
		UmsdaSet *orteNeu;
		OrtardaSet *archivOrteNeu;

		/* Grund für Mehrdeutigkeiten können die Sortierfehler in den
		 * Dateien "umsda" oder "ortarda" sein. Daher müssen die
		 * Ortsnamen erneut überprüft werden, diesmal in voller Länge.
		 * Diese Überprüfung entfällt, wenn der Ortsname als Wildcard
		 * angegeben wurde.
		 */
		if (!ispunct (pc->ort[strlen (pc->ort) - 1]))
		{
		    orteNeu = UmsdaSetSucheOrt (pc->orte, pc->ort);
		    archivOrteNeu = OrtardaSetSucheOrt (pc->archivOrte,
							pc->ort);
		    if (orteNeu == (UmsdaSet *) 0
		    || archivOrteNeu == (OrtardaSet *) 0)
		    {
		        pc->status = PlzFehler;
		        break;
		    }
		    if (orteNeu->entries + archivOrteNeu->entries > 0)
		    {
			FreeUmsdaSet (&pc->orte);
			FreeOrtardaSet (&pc->archivOrte);
			pc->orte = orteNeu;
			pc->archivOrte = archivOrteNeu;
		    }
		}

		if (!OrtEindeutig (pc->orte, pc->archivOrte) && *pc->plz_alt)
		{
		    orteNeu = UmsdaSetSuchePlzAlt (pc->orte, pc->plz_alt,
						   pc->verkehrsgebiet);
		    archivOrteNeu =
		    OrtardaSetSuchePlzAlt (pc->archivOrte, pc->plz_alt,
					   pc->verkehrsgebiet);
		    if (orteNeu == (UmsdaSet *) 0
		    || archivOrteNeu == (OrtardaSet *) 0)
		    {
		        pc->status = PlzFehler;
		        break;
		    }
		    if (orteNeu->entries + archivOrteNeu->entries > 0)
		    {
			FreeUmsdaSet (&pc->orte);
			FreeOrtardaSet (&pc->archivOrte);
			pc->orte = orteNeu;
			pc->archivOrte = archivOrteNeu;
		    }
		}

		if (OrtEindeutig (pc->orte, pc->archivOrte))
		    pc->status = PlzOrtGefunden;

		break;
	    }

	    case PlzOrtEindeutig:
	    {
		if (pc->orte->entries > 0)
		{
		    if (strcmp (UmsdaSetPlzAltEindeutig (pc->orte), "") != 0)
			changed =
			UpdatePlzAlt (&pc->plz_alt, pc->orte->list[0].plz_w_o,
				      pc->verkehrsgebiet);
		    if (pc->orte->list[0].nplzo_z[0] == '1'
		    && pc->orte->list[0].nplzo_p[0] == '1'
		    && strncmp (pc->orte->list[0].plz_z,
		    pc->orte->list[0].plz_p, sizeof (pc->orte->list[0].plz_z))
		    == 0)
		    {
		        strncpy (plz_neu, pc->orte->list[0].plz_z, 5);
		        plz_neu[5] = '\0';
		        UpdateString (&pc->plz_neu, plz_neu);
		        pc->status = PlzPlzNeuGefunden;
		    }
		    else
		        pc->status = PlzPostanstaltBenoetigt;
		}
		if (pc->archivOrte->entries > 0)
		{
		    if (strcmp (OrtardaSetPlzAltEindeutig (pc->archivOrte), "")
		    != 0)
			changed =
			UpdatePlzAlt (&pc->plz_alt,
				      pc->archivOrte->list[0].plz_w_o,
				      pc->verkehrsgebiet);
		    if (pc->archivOrte->entries == 1
		    && pc->archivOrte->list[0].nplz_z[0] == '1'
		    && pc->archivOrte->list[0].nplz_p[0] == '1'
		    && strncmp (pc->archivOrte->list[0].plz_z,
		    pc->archivOrte->list[0].plz_p,
		    sizeof (pc->archivOrte->list[0].plz_z)) == 0)
		    {
		        strncpy (plz_neu, pc->archivOrte->list[0].plz_z, 5);
		        plz_neu[5] = '\0';
		        UpdateString (&pc->plz_neu, plz_neu);
		        pc->status = PlzPlzNeuGefunden;
		    }
		    else
		        pc->status = PlzPostanstaltBenoetigt;
		}
		if (changed)
		    pc->status = PlzPlzAltGeaendert;
		break;
	    }


	    case PlzPostanstaltBenoetigt:
	    {
		if (*(pc->postanstalt))
		{
		    UmsdaSet *orteNeu;
		    OrtardaSet *archivOrteNeu;
		    orteNeu =
		    UmsdaSetSuchePostanstalt (pc->orte, pc->postanstalt);
		    if (orteNeu != (UmsdaSet *) 0 && orteNeu->entries == 1)
		    {
			FreeUmsdaSet (&pc->orte);
			pc->orte = orteNeu;
			if (pc->orte->list[0].nplz_z[0] == '1'
			&& pc->orte->list[0].nplz_p[0] == '1'
			&& strncmp (pc->orte->list[0].plz_z,
			pc->orte->list[0].plz_p,
			sizeof (pc->orte->list[0].plz_z)) == 0)
			{
			    strncpy (plz_neu, pc->orte->list[0].plz_z, 5);
			    plz_neu[5] = '\0';
			    UpdateString (&pc->plz_neu, plz_neu);
			    pc->status = PlzPlzNeuGefunden;
			}
			else
			    pc->status = PlzStrassePostfachBenoetigt;
		     }
		     else
			pc->status = PlzStrassePostfachBenoetigt;
		    archivOrteNeu =
		    OrtardaSetSuchePostanstalt (pc->archivOrte,
						pc->postanstalt);
		    if (archivOrteNeu != (OrtardaSet *) 0
		    && archivOrteNeu->entries == 1)
		    {
			FreeOrtardaSet (&pc->archivOrte);
			pc->archivOrte = archivOrteNeu;
			if (pc->archivOrte->list[0].nplz_z[0] == '1'
			&& pc->archivOrte->list[0].nplz_p[0] == '1'
			&& strncmp (pc->archivOrte->list[0].plz_z,
			pc->archivOrte->list[0].plz_p,
			sizeof (pc->archivOrte->list[0].plz_z)) == 0)
			{
			    strncpy (plz_neu, pc->archivOrte->list[0].plz_z, 5);
			    plz_neu[5] = '\0';
			    UpdateString (&pc->plz_neu, plz_neu);
			    pc->status = PlzPlzNeuGefunden;
			}
			else
			    pc->status = PlzStrassePostfachBenoetigt;
		     }
		     else
			pc->status = PlzStrassePostfachBenoetigt;
		}
		else
		    pc->status = PlzStrassePostfachBenoetigt;
		break;
	    }


	    case PlzStrassePostfachBenoetigt:
	    {
		if (*(pc->strasse) && *(pc->postfach))
		    pc->status = PlzUnzulaessigerZustand;
		else if (*(pc->strasse))
		    pc->status = PlzSucheStrasse;
		else if (*(pc->postfach))
		    pc->status = PlzSuchePostfach;
		break;
	    }


	    case PlzSucheStrasse:
	    {
		FreeStradaSet (&pc->strassen);
		if (pc->orte->entries > 0)
		{
		    if (*(pc->orte->list[0].nplz_z) == '1')
		    {
		        strncpy (plz_neu, pc->orte->list[0].plz_z, 5);
		        plz_neu[5] = '\0';
		        UpdateString (&pc->plz_neu, plz_neu);
		        pc->status = PlzPlzNeuGefunden;
		        break;
		    }
		    pc->strassen = SucheStrasse (pc->orte->list[0].alort,
						 pc->strasse);
		}
		else if (pc->archivOrte->entries > 0)
		{
		    if (*(pc->archivOrte->list[0].nplz_z) == '1')
		    {
		        strncpy (plz_neu, pc->archivOrte->list[0].plz_z, 5);
		        plz_neu[5] = '\0';
		        UpdateString (&pc->plz_neu, plz_neu);
		        pc->status = PlzPlzNeuGefunden;
		        break;
		    }
		    pc->strassen = SucheStrasse (pc->archivOrte->list[0].alort,
						 pc->strasse);
		}
		if (pc->strassen == (StradaSet *) 0)
		    {pc->status = PlzFehler; break; }
		if (pc->strassen->entries == 0)
		    {pc->status = PlzStrasseNichtGefunden; break;}
		pc->status = PlzStrasseGefunden;
		break;
	    }


	    case PlzStrasseGefunden:
	    {
		UpdateIsoStringFromFixed (&pc->strasse,
					  pc->strassen->list[0].sname,
					  sizeof (((Strada *) 0)->sname));
		if (pc->strassen->entries >= 1)
		{
		    if (UniqueStreet (pc->strassen))
			pc->status = PlzStrasseEindeutig;
		    else
			pc->status = PlzStrasseMehrfachInOrt;
		}
		else
		    pc->status = PlzStrasseNichtGefunden;
		break;
	    }


	    case PlzStrasseEindeutig:
	    {
		UpdateIsoStringFromFixed (&pc->plz_alt,
					  pc->strassen->list[0].plz_w_o,
					  sizeof (((Strada *) 0)->plz_w_o) +
					  sizeof (((Strada *) 0)->plzalt));
		if (IsStrassePlzEindeutig (pc->strassen))
		{
		    UpdateIsoStringFromFixed (&pc->postanstalt,
					      pc->strassen->list[0].npanst,
					      sizeof (((Strada *) 0)->npanst));
		    UpdateIsoStringFromFixed (&pc->ortsteil,
					      pc->strassen->list[0].ortsteil,
					      sizeof (((Strada *)
					      0)->ortsteil));
		    strncpy (plz_neu, pc->strassen->list[0].plz_z, 5);
		    plz_neu[5] = '\0';
		    UpdateString (&pc->plz_neu, plz_neu);
		    pc->status = PlzPlzNeuGefunden;
		}
		else
		    pc->status = PlzHausnummerBenoetigt;
		break;
	    }


	    case PlzStrasseMehrfachInOrt:
	    {
		StradaSet *new;
		if (*pc->postanstalt)
		{
		    new = StrassenAndPostanstalt (pc->strassen,
						  pc->postanstalt);
		    if (new != (StradaSet *) 0)
		    {
			if (new->entries > 0)
			{
			    FreeStradaSet (&pc->strassen);
			    pc->strassen = new;
			    if (UniqueStreet (pc->strassen))
				pc->status = PlzStrasseEindeutig;
			    else
				pc->status = PlzStrasseMehrfachInPostanstalt;
			}
			else
			{
			    FreeStradaSet (&new);
			    UpdateString (&pc->postanstalt, "");
			    pc->status = PlzStrasseGefunden;
			}
		    }
		    else
			pc->status = PlzFehler;
		}
		if (*pc->ortsteil)
		{
		    new = StrassenAndOrtsteil (pc->strassen, pc->ortsteil);
		    if (new != (StradaSet *) 0)
		    {
			if (new->entries > 0)
			{
			    FreeStradaSet (&pc->strassen);
			    pc->strassen = new;
			    if (UniqueStreet (pc->strassen))
				pc->status = PlzStrasseEindeutig;
			    else
				pc->status = PlzStrasseMehrfachInOrtsteil;
			}
			else
			{
			    FreeStradaSet (&new);
			    UpdateString (&pc->ortsteil, "");
			    pc->status = PlzStrasseGefunden;
			}
		    }
		    else
			pc->status = PlzFehler;
		}
		break;
	    }


	    case PlzHausnummerBenoetigt:
	    {
		if (*pc->hausnummer)
		{
		    if (!UniqueStreet (pc->strassen))
		    {
			pc->status = PlzSucheStrasse;
			break;
		    }
		    strcpy (plz_neu,
			    SearchForHouseNumber (pc->strassen,
						  pc->hausnummer));
		    if (!*(plz_neu))
			pc->status = PlzHausnummerNichtGefunden;
		    else
		    {
			UpdateIsoStringFromFixed (&pc->postanstalt,
			    pc->strassen->list[0].npanst,
			    sizeof (((Strada *) 0)->npanst));
			UpdateIsoStringFromFixed (&pc->ortsteil,
			    pc->strassen->list[0].ortsteil,
			    sizeof (((Strada *) 0)->ortsteil));
			UpdateString (&pc->plz_neu, plz_neu);
			pc->status = PlzPlzNeuGefunden;
		    }
		}
		break;
	    }


	    case PlzSuchePostfach:
	    {
		FreePofadaSet (&pc->postfaecher);
		if (pc->orte->entries > 0)
		{
		    if (*(pc->orte->list[0].nplz_p) == '1')
		    {
		        strncpy (plz_neu, pc->orte->list[0].plz_p, 5);
		        plz_neu[5] = '\0';
		        UpdateString (&pc->plz_neu, plz_neu);
		        pc->status = PlzPlzNeuGefunden;
		        break;
		    }
		    pc->postfaecher =
		    SuchePostfach (pc->orte->list[0].alort, pc->postfach);
		}
		else if (pc->archivOrte->entries > 0)
		{
		    if (*(pc->archivOrte->list[0].nplz_p) == '1')
		    {
		        strncpy (plz_neu, pc->archivOrte->list[0].plz_p, 5);
		        plz_neu[5] = '\0';
		        UpdateString (&pc->plz_neu, plz_neu);
		        pc->status = PlzPlzNeuGefunden;
		        break;
		    }
		    pc->postfaecher =
		    SuchePostfach (pc->archivOrte->list[0].alort, pc->postfach);
		}
		if (pc->postfaecher == (PofadaSet *) 0)
		    {pc->status = PlzFehler; break;}
		if (pc->postfaecher->entries == 0)
		    {pc->status = PlzPostfachNichtGefunden; break;}
		pc->status = PlzPostfachGefunden;
		break;
	    }


	    case PlzPostfachGefunden:
	    {
		if (pc->postfaecher->entries == 1)
		{
		    UpdateIsoStringFromFixed (&pc->plz_alt,
					      pc->postfaecher->list[0].plz_w_o,
					      sizeof (((Pofada *) 0)->plz_w_o) +
					      sizeof (((Pofada *) 0)->plzalt));
		    UpdateIsoStringFromFixed (&pc->postanstalt,
					      pc->postfaecher->list[0].npanst,
					      sizeof (((Pofada *) 0)->npanst));
		    UpdateString (&pc->ortsteil, "");
		    strncpy (plz_neu, pc->postfaecher->list[0].plzneu_p, 5);
		    plz_neu[5] = '\0';
		    UpdateString (&pc->plz_neu, plz_neu);
		    pc->status = PlzPlzNeuGefunden;
		}
		else
		    pc->status = PlzPostfachMehrfachInOrt;
		break;
	    }


	    case PlzPostfachMehrfachInOrt:
	    {
		PofadaSet *new;
		if (*pc->postanstalt)
		{
		    new = PostfaecherAndPostanstalt (pc->postfaecher,
						     pc->postanstalt);
		    if (new != (PofadaSet *) 0)
		    {
			FreePofadaSet (&pc->postfaecher);
			pc->postfaecher = new;
			if (UniquePostbox (pc->postfaecher))
			    pc->status = PlzPostfachGefunden;
			else
			    pc->status = PlzPostfachMehrfachInPostanstalt;
		    }
		    else
			pc->status = PlzFehler;
		}
		if (*pc->plz_alt)
		{
		    new = PostfaecherAndPlz (pc->postfaecher, pc->plz_alt);
		    if (new != (PofadaSet *) 0)
		    {
			FreePofadaSet (&pc->postfaecher);
			pc->postfaecher = new;
			if (UniquePostbox (pc->postfaecher))
			    pc->status = PlzPostfachGefunden;
			else
			    pc->status = PlzPostfachMehrfachInPlz;
		    }
		    else
			pc->status = PlzFehler;
		}
		break;
	    }


	    case PlzOrtNichtGefunden:
	    case PlzPlzAltGeaendert:
	    case PlzStrasseNichtGefunden:
	    case PlzStrasseMehrfachInPostanstalt:
	    case PlzStrasseMehrfachInOrtsteil:
    	    case PlzHausnummerNichtGefunden:
	    case PlzPostfachNichtGefunden:
	    case PlzPostfachMehrfachInPostanstalt:
	    case PlzPostfachMehrfachInPlz:
	    case PlzPlzNeuGefunden:
	    case PlzFehler:
		break;


	    default:
	    {
		pc->status = PlzUnzulaessigerZustand;
		Message ("Interner Fehler. Bitte senden Sie die Adresse\n");
		Message ("per E-Mail an klute@informatik.uni-dortmund.de!\n");
		break;
	    }
	}
    }
    while (previousState != pc->status);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.