home *** CD-ROM | disk | FTP | other *** search
- /*---------------------- SCORE.LIB Library to read and write SCORE files -----*/
- #include <stdio.h>
- #include <string.h>
- #include <math.h>
- #include <malloc.h>
- #include "sctypes.h"
- #include "sclib.h"
-
- /*----------------------------------------------------------------------------*/
- /* get_fnames Dieser Funktion wird ein String-Feld übergeben. Der Eintrag */
- /* 0 wird auf Vorhandensein geprüft und dann maximal count */
- /* weitere lexikographische Einträge gesucht und damit die */
- /* weiteren Felder gefüllt. */
- /* */
- /* Rückgabe: > 0: Entprechend viele Dateien gefunden */
- /* = 0: Datei konnte nicht gefunden werden */
- /* < 0: Ungültiger Dateiname übergeben. */
- /* */
- /*----------------------------------------------------------------------------*/
- /* get_fnames This Funktion receives a stringarray. The first entry */
- /* (fname[0]) must contain a filename. The function searches */
- /* 'count' more filenames in alphabetical order and fills the */
- /* stringarray with filenames */
- /* */
- /* Return: > 0: number of files found */
- /* = 0: no files found */
- /* < 0: illegal filename */
- /* */
- /*----------------------------------------------------------------------------*/
- Int get_fnames(Char fname[][FNAME_LEN], Int count, Int name_max)
- {
- Int i,erg1,erg2,pos;
- Char *s1, c;
-
- s1 = strpbrk(fname[0],".");
- if (s1 == NULL) return(-1);
- pos =(Int) (s1 - fname[0] - 1);
-
- if (count > name_max) count = name_max;
-
- for (i = 0; i < count; i++) {
- erg1 = exists(fname[i]);
- if ((erg1 == 0) && (i == 0)) return(0);
- if ((erg1 != 0) && (pos < 1)) return(i);
- if (erg1 == 0) {
- c = fname[i][pos];
- if ((c > 47) && (c < 59))
- fname[i][pos] = 48;
- else
- fname[i][pos] = 65;
- fname[i][pos-1] += 1;
- erg2 = exists(fname[i]);
- if ((erg2 == 0) && (pos < 2)) return(i);
- if (erg2 == 0) {
- c = fname[i][pos-1];
- if ((c > 47) && (c < 59))
- fname[i][pos-1] = 48;
- else
- fname[i][pos-1] = 65;
- fname[i][pos-2] += 1;
- if (exists(fname[i]) == 0) return(i);
- }
- }
- strcpy(fname[i+1],fname[i]);
- fname[i+1][pos] += 1;
- }
- return(i);
-
- }
-
- /*----------------------------------------------------------------------------*/
- /* exists Diese Funktion überprüft, ob der übergebene Dateiname */
- /* vorhanden ist. */
- /* Rückgabewert 0: Datei wurde nicht gefunden */
- /* 1: Datei wurde gefunden */
- /*----------------------------------------------------------------------------*/
- /* exists This function checks whether the filenam exists */
- /* */
- /* Return: 0: file found */
- /* 1: file not found */
- /*----------------------------------------------------------------------------*/
- Int exists(Char *filename)
- {
- FILE *f_handler;
-
- f_handler = fopen(filename, "rb");
- if (f_handler == NULL) return(0);
-
- fclose(f_handler);
- return(1);
- }
-
- /*----------------------------------------------------------------------------*/
- /* get_parms Diese Funktion liest eine SCORE-Datei in eine verkettete */
- /* Listenstruktur ein (siehe SCORE.H). Dazu wird ein Listen- */
- /* kopf übergeben der Zeiger auf das erste und letzte Listen- */
- /* element enthält, die aber noch uninitialisiert sind. Ausser- */
- /* dem enthält der Listenkopf noch Informationen über die */
- /* Gesamtzahl der Parameter und Objekte und die fünf letzten */
- /* Parameter die keinem Objekt zugeordnet sind und nach meiner */
- /* Erfahrung immer 0.0, 3.0, 1.0, 4.0, -9999.0 enthalten. */
- /* Bei der Datenstruktur handelt es sich um eine zweifach */
- /* verkettete Liste mit einem Datenfeld für 19 Fließkommazahlen */
- /* und einem Zeiger auf Text der nur bei Objekten vom Typ */
- /* Text (16) und EPS (15) verwendet wird. Der erste Eintrag */
- /* im Zahlenfeld (cd[0]) enthält die Anzahl der gültigen */
- /* Parameter also maximal 18. Ausnahmen stellen Objekte vom */
- /* Typ 15 und 16 dar. Hier sind genau 13 Parameter gültig. */
- /* */
- /* Rückgabe: OK SCORE-Datei erfolgreich eingelesen */
- /* CONSIST_ERR Konsistenzfehler in der internen Datenstruktur */
- /* FORMAT_ERR Formatfehler in der SCORE-Datei */
- /* MEMORY_ERR Fehler bei der Speicherreservierung */
- /* FILE_ERR Fehler beim Öffnen der Datei */
- /* */
- /*----------------------------------------------------------------------------*/
- /* get_parms This function reads a SCORE file in a double linked list */
- /* (see SCORE.H) The function needs a listhead which contains */
- /* uninitialized pointers to the first and last listitem. */
- /* Additionaly the listhead contains information about the total */
- /* number of parameters and items and the 5 last parameters */
- /* which are not assigned to a specific item and always contain */
- /* 0.0, 3.0, 1.0, 4.0, -9999.0. The objects of the double-linked- */
- /* list contain the data of the SCORE-items in an array of */
- /* 19 floatnumbers and a pointer to char which is only used for */
- /* code 16 (Text) and code-15 (EPS) items. */
- /* The first entry in the float-array cd[0] contains the number */
- /* of valid entries. */
- /* */
- /* ATTENTION !!! If you modify a score item do not forget to */
- /* update cd[0] if the number of valid parameters has changed. */
- /* */
- /* Return: OK SCORE-file sucessfully processed */
- /* CONSIST_ERR Consistency error in the internal datastructure */
- /* FORMAT_ERR Format error in the SCORE file */
- /* MEMORY_ERR Error while allocating memory */
- /* FILE_ERR Error hen trying to open a file */
- /* */
- /*----------------------------------------------------------------------------*/
- Int get_parms(Char *fname, list_ptr sl)
- {
- FILE *handle;
- Int count, tmp_cnt, parm_cnt;
- Int rd_stat, i, fsize, item_type;
- Float fl_num;
- item_ptr cur_pos, temp;
-
- count = 0;
- parm_cnt = 0;
-
- handle = fopen(fname, "rb"); /* Datei öffnen */
- if (handle == NULL) return(FILE_ERR);
-
- rd_stat = fread(&fsize, 2, 1, handle); /* Parameter Anzahl */
- if (rd_stat != 1) {fclose(handle); return(FORMAT_ERR);}
-
-
- while (count < fsize - 7) { /* Parameter einlesen */
-
- if (count == 0) {
- temp = (item_ptr) malloc(sizeof(item));
- if (temp == NULL) { fclose(handle); return(MEMORY_ERR);}
-
- sl -> first = temp;
- sl -> last = temp;
- cur_pos = temp;
-
- cur_pos -> text = NULL;
- cur_pos -> tied = NULL;
- cur_pos -> next = NULL;
- cur_pos -> prev = NULL;
- }
- else {
- temp = (item_ptr) malloc(sizeof(item));
- if (temp == NULL) { fclose(handle); return(MEMORY_ERR);}
-
- cur_pos -> next = temp;
- sl -> last = temp;
-
- temp -> text = NULL;
- temp -> tied = NULL;
- temp -> next = NULL;
- temp -> prev = cur_pos;
- cur_pos = temp;
- } /* cur_pos zeigt nun auf neues Item */
-
-
- rd_stat = fread(&fl_num, 4, 1, handle); /* Länge des Item */
- if (rd_stat != 1) {fclose(handle);return(FORMAT_ERR);}
- if (fl_num < 2.0F) {fclose(handle);return(FORMAT_ERR);}
- count += 1;
- cur_pos -> cd[0] = fl_num;
- parm_cnt = (Int) fl_num;
- if (fabs(fl_num - (Float) parm_cnt) > FLOAT_EPS) {
- fclose(handle);return(FORMAT_ERR);
- }
-
- rd_stat = fread(&fl_num, 4, 1, handle); /* Objekttyp */
- if (rd_stat != 1) {fclose(handle);return(FORMAT_ERR);}
- count += 1;
- cur_pos -> cd[1] = fl_num;
- item_type = (Int) fl_num;
-
- if ((item_type == 15) || (item_type == 16)) { /* EPS oder Text */
- if (parm_cnt < 14) {fclose(handle);return(FORMAT_ERR);}
-
- for (i = 2; i <= 13; i++) {
- rd_stat = fread(&fl_num, 4, 1, handle); /* Param. rest */
- if (rd_stat != 1) {fclose(handle);return(FORMAT_ERR);}
- count += 1;
- cur_pos -> cd[i] = fl_num;
- }
- tmp_cnt = parm_cnt - 13; /* Größe des Text div 4 */
- cur_pos -> text = (string) malloc(4 * tmp_cnt);
- if (cur_pos -> text == NULL) {fclose(handle); return(MEMORY_ERR);}
-
- rd_stat = fread(cur_pos -> text, 4, tmp_cnt, handle);
- if (rd_stat != tmp_cnt) {fclose(handle);return(FORMAT_ERR);}
- count += tmp_cnt;
- }
- else {
- for (i = 2; i <= parm_cnt; i++) {
- rd_stat = fread(&fl_num, 4, 1, handle); /* Param. rest */
- if (rd_stat != 1) {fclose(handle);return(FORMAT_ERR);}
- count += 1;
- cur_pos -> cd[i] = fl_num;
- }
- for (i = parm_cnt+1; i < MAX_CD; i++) cur_pos->cd[i] = 0.0F;
- } /* alle Parameter eines Item wurden eingetragen */
- } /* end while (count < fsize-5) */
-
- parm_cnt = fsize - count;
- rd_stat = fread(sl->cd, 4, parm_cnt, handle);
- if ((rd_stat != parm_cnt) || (sl->cd[parm_cnt-1] != -9999.0F)) {
- fclose(handle);
- return(FORMAT_ERR);
- }
-
- fclose(handle);
- sl->trail_len = parm_cnt;
- if (set_info(sl) != OK) return(CONSIST_ERR);
- return(OK);
- }
-
- /*----------------------------------------------------------------------------*/
- /* put_parms Diese Funktion schreibt die Datenstruktur nach */
- /* SCORE-Konventionen in eine Datei. */
- /* */
- /* Rückgabe: OK Datei wurde erfolgreich geschrieben */
- /* FILE_ERR Datei nicht gefunden oder Diskette voll */
- /* CONSIST_ERR Fehler in Listenstruktur */
- /*----------------------------------------------------------------------------*/
- /* put_parms This Function writes the SCORE-list according to the */
- /* SCORE-binary format in a file. */
- /* */
- /* Return: OK File sucessfully saved */
- /* FILE_ERR No more space available on disk */
- /* CONSIST_ERR error in the liststructure */
- /*----------------------------------------------------------------------------*/
- Int put_parms(Char *fname, list_ptr sl)
- {
- FILE *handle;
- Int parm_cnt, fsize, wr_stat, tmp_cnt;
- item_ptr cur_pos;
-
- handle = fopen(fname, "wb");
- if (handle == NULL) return(FILE_ERR);
- if (set_info(sl) != OK) return(CONSIST_ERR);
-
- fsize = sl -> parameters + sl -> trail_len;
- wr_stat = fwrite(&fsize, 2, 1, handle);
- if (wr_stat != 1) {fclose(handle); return(FILE_ERR);}
-
- cur_pos = sl -> first;
- while (cur_pos != NULL) {
-
- parm_cnt = (Int) cur_pos -> cd[0];
-
- if ((cur_pos->cd[1] == 15.0F)||(cur_pos->cd[1] == 16.0F)) {
-
- wr_stat = fwrite(cur_pos->cd, 4, 14, handle);
- if (wr_stat != 14) {fclose(handle); return(FILE_ERR);}
-
- tmp_cnt = parm_cnt - 13;
- if (tmp_cnt < 1) {fclose(handle); return(FORMAT_ERR);}
-
- wr_stat = fwrite(cur_pos->text, 4, tmp_cnt, handle);
- if (wr_stat != tmp_cnt) {fclose(handle); return(FILE_ERR);}
- }
- else {
- wr_stat = fwrite(cur_pos->cd, 4, parm_cnt+1, handle);
- if (wr_stat != parm_cnt+1) {fclose(handle); return(FILE_ERR);}
- }
-
- cur_pos = cur_pos -> next;
- } /* end of while (cur_pos) != 0 */
-
- wr_stat = fwrite(sl->cd, 4, sl->trail_len, handle);
- if (wr_stat != sl->trail_len) {fclose(handle); return(FILE_ERR);}
-
- fclose(handle);
- return(OK);
- }
-
- /*----------------------------------------------------------------------------*/
- /* set_free Diese Hilfsfunktion gibt mit Hilfe der free()-Funktion */
- /* den gsamten allozierten Speicher der Datenstruktur wieder */
- /* frei. Alle Daten gehen verloren */
- /* Die Datenstruktur score_item enthält auch einen Zeiger auf */
- /* ein Textfeld der normalerweise auf NULL zeigt. Wenn dieser */
- /* Zeiger auf einen Textbereich zeigt wird dieser Speicher */
- /* nicht freigegeben. */
- /*----------------------------------------------------------------------------*/
- /* set_free This function uses the free()-function to release the */
- /* allocated memeory used by the SCORE-itemlist. All data will */
- /* be lost. */
- /* Allocated memory used for Textdata in code 15 and code 16 - */
- /* items is not released in this version of the software. */
- /*----------------------------------------------------------------------------*/
- void set_free(list_ptr sl)
- {
- item_ptr cur_pos, temp;
-
-
- cur_pos = sl -> last;
-
- while (cur_pos != NULL) {
- temp = cur_pos -> prev;
- free(cur_pos);
- cur_pos = temp;
- }
-
- }
-
- /*----------------------------------------------------------------------------*/
- /* set_info Diese Hilfsfunktion ermittelt folgende Werte: */
- /* sl -> items = Anzahl vorhandener Objekte */
- /* sl -> parameters = Anzahl aller Parameter */
- /* Ausserdem wird die Konsistenz der Liste überprüft */
- /* Rückgabe: OK */
- /* CONSIST_ERR */
- /*----------------------------------------------------------------------------*/
- /* set_info This Function calculates the following figures: */
- /* sl -> items = number of items */
- /* sl -> parameters = total number of parameters */
- /* additionally the list-consistency will be checked */
- /* Return: OK */
- /* CONSIST_ERR */
- /*----------------------------------------------------------------------------*/
- Int set_info(list_ptr sl)
- {
- Int item_cnt, parm_cnt;
- item_ptr cur_pos, temp;
-
- item_cnt = 0;
- parm_cnt = 0;
-
- cur_pos = sl -> first;
- if (cur_pos == NULL) return(CONSIST_ERR);
- if (cur_pos -> prev != NULL) return(CONSIST_ERR);
-
- while (cur_pos -> next != NULL) {
- temp = cur_pos -> next;
- if (temp -> prev != cur_pos) return(CONSIST_ERR);
- item_cnt += 1;
- parm_cnt += (Int) cur_pos -> cd[0] + 1;
- cur_pos = temp;
- }
-
- if (cur_pos != sl -> last) return(CONSIST_ERR);
- item_cnt += 1;
- parm_cnt += (Int) cur_pos -> cd[0] + 1;
-
- sl -> items = item_cnt;
- sl -> parameters = parm_cnt;
- return(OK);
- }
-
- /*----------------------------------------------------------------------------*/
- /* Diese Funktion sortiert alle Objekte nach ihrem X-Wert (cd[3]) */
- /* Die Sortiermethode berücksichtigt, daß eine SCORE-Datei normalerweise */
- /* bereits aus sortierten Teilstücken besteht und stellt für diesen */
- /* Fall die schnellste Implementation dar. */
- /* */
- /* Rückgabewert: OK */
- /* CONSIST_ERR (Listenstruktur beschädigt) */
- /* */
- /*----------------------------------------------------------------------------*/
- /* This function sorts all items according to the x-value (cd[3]). */
- /* The sorting method takes into account that normaly a SCORE-file */
- /* contains already sorted strings of items and is therefore an */
- /* performance optimized implementation. */
- /* */
- /* Return: OK */
- /* CONSIST_ERR (liststructure damaged) */
- /* */
- /*----------------------------------------------------------------------------*/
- Int sort_items_x(list_ptr head)
- {
- struct score_item cliplow, cliphigh;
- struct score_item *z1, *z2;
- Bool z1_ge_z2, z1_le_z2next;
-
- /*------------------- Initializing ------------------------------*/
-
- cliplow.next = &cliphigh;
- cliplow.prev = NULL;
-
- cliphigh.next = NULL;
- cliphigh.prev = &cliplow;
-
- cliplow.cd[3] = -1E38;
- cliphigh.cd[3] = 1E38 ;
-
- z1 = head->first;
- z2 = &cliplow;
-
- /*---------------------------------------------------------------*/
- /* Sortierung: Die Liste wird nun Stück für Stück zwischen */
- /* cliplow und cliphigh einsortiert */
- /*---------------------------------------------------------------*/
- /* Sort: The items will be inserted in sorted order */
- /* between cliplow and cliphigh. */
- /*---------------------------------------------------------------*/
- while (head->first != NULL) {
-
- if (z1->cd[3] >= z2->cd[3]) z1_ge_z2 = TRUE;
- else z1_ge_z2 = FALSE;
-
- if (z1->cd[3] < z2->next->cd[3]) z1_le_z2next = TRUE;
- else z1_le_z2next = FALSE;
-
- if (z1_ge_z2 && z1_le_z2next) {
-
- head->first = z1->next;
-
- z1->next = z2->next;
- z2->next->prev = z1;
- z2->next = z1;
- z1->prev = z2;
-
- z2 = z1;
- z1 = head->first;
- }
- else {
- if (z1_ge_z2) {
- z2 = z2->next;
- }
- else {
- z2 = &cliplow;
- }
- }
- }
-
- /*---------------------------------------------------------------*/
- /* Nachlauf: die sortierte Liste wird nun an head angehängt */
- /* */
- /*---------------------------------------------------------------*/
- /* Finish: the sorted list is now moved back to head */
- /* */
- /*---------------------------------------------------------------*/
- head->first = cliplow.next;
- head->last = cliphigh.prev;
-
- head->first->prev = NULL;
- head->last->next = NULL;
-
- return(set_info(head)); /* Konsistenzprüfung */
- }
-
- /*----------------------------------------------------------------------------*/
- /* sort_items_xy Diese Sortierfunktion entspricht dem OS-Befehl in SCORE */
- /* */
- /* Die Sortiermethode berücksichtigt, daß eine SCORE-Datei normalerweise */
- /* bereits aus sortierten Teilstücken besteht und stellt für diesen */
- /* Fall die schnellste Implementation dar. */
- /* */
- /* Rückgabe: OK */
- /* CONSIST_ERR */
- /*----------------------------------------------------------------------------*/
- /* sort_items_xy This Function is realizes the OS Command in SCORE */
- /* */
- /* The sorting method takes into account that normaly a SCORE-file */
- /* contains already sorted strings of items and is therefore an */
- /* performance optimized implementation. */
- /* */
- /* Return: OK */
- /* CONSIST_ERR */
- /*----------------------------------------------------------------------------*/
- Int sort_items_xy(list_ptr head)
- {
- struct score_item cliplow, cliphigh;
- struct score_item *z1, *z2;
- Bool z1_ge_z2, z1_le_z2next;
-
- /*------------------- Initializing ------------------------------*/
-
- cliplow.next = &cliphigh;
- cliplow.prev = NULL;
- cliphigh.next = NULL;
- cliphigh.prev = &cliplow;
-
- cliplow.cd[3] = -1E38;
- cliplow.cd[2] = -32768.0F;
- cliphigh.cd[3] = 1E38 ;
- cliphigh.cd[2] = 32767.0F;
-
- z1 = head->first;
- z2 = &cliplow;
-
- /*------------------- Sort --------------------------------------*/
-
- while (head->first != NULL) {
-
- if ( (Int) z1->cd[2] > (Int) z2->cd[2])
- z1_ge_z2 = TRUE;
- else if (( (Int) z1->cd[2] == (Int) z2->cd[2])
- && (z1->cd[3] >= z2->cd[3]))
- z1_ge_z2 = TRUE;
- else
- z1_ge_z2 = FALSE;
-
- if ( (Int) z1->cd[2] < (Int) z2->next->cd[2])
- z1_le_z2next = TRUE;
- else if (( (Int) z1->cd[2] == (Int) z2->next->cd[2])
- && (z1->cd[3] < z2->next->cd[3]))
- z1_le_z2next = TRUE;
- else
- z1_le_z2next = FALSE;
-
-
- if (z1_ge_z2 && z1_le_z2next) {
-
- head->first = z1->next;
-
- z1->next = z2->next;
- z2->next->prev = z1;
- z2->next = z1;
- z1->prev = z2;
-
- z2 = z1;
- z1 = head->first;
- }
- else {
- if (z1_ge_z2) {
- z2 = z2->next;
- }
- else {
- z2 = &cliplow;
- }
- }
- }
-
- /*------------------- Finish ------------------------------------*/
-
- head->first = cliplow.next;
- head->last = cliphigh.prev;
-
- head->first->prev = NULL;
- head->last->next = NULL;
-
- return(set_info(head)); /* Konsistenzprüfung */
- }
-
-