Universität Ulm,
SAI,
Übungen zu
Systemnahe Software I
Lösungsbeispiel zu Blatt 9 (Aufgabe 13): names
Verwaltung von Listen von Dateinamen für SAM.
/*
* names.h - Headerfile for SAM filename handling.
*
* Martin Hasch, University of Ulm, January 1997
*/
#ifndef NAMES_H
#define NAMES_H
#include "sam.h"
typedef struct names_l {
char *nl_filename;
sam_Name nl_name;
struct names_l *nl_prev, *nl_next;
} *names_List;
/*
* Add given filename and corresponding archive member name to list
* or replace entry with same archive member name.
* Return modified list.
*/
names_List names_add(names_List list, char *filename);
/*
* Search list for given archive member name. If it is there,
* return a pointer to the entry, otherwise return NULL.
*/
names_List names_get(names_List list, sam_Name name);
/*
* Delete an entry from list. Return modified list.
*/
names_List names_delete(names_List list, names_List entry);
/*
* Print for each entry of list an error message indicating that
* the entry was not found.
*/
void names_notfound(names_List list);
#endif /* NAMES_H */
/*
* names.c - SAM filename handling.
*
* Martin Hasch, University of Ulm, January 1997
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sam.h"
#include "names.h"
#define PATHSEP '/'
/*
* typedef struct names_l {
* char *nl_filename;
* sam_Name nl_name;
* struct names_l *nl_prev, *nl_next;
* } *names_List;
*/
/*
* Get archive member name from given filename and copy it to name.
*/
static void make_name(sam_Name name, char *filename)
{
size_t len = 0;
char * base = filename + strlen(filename);
while ( base > filename && base[-1] == PATHSEP )
--base;
while ( base > filename && base[-1] != PATHSEP )
++len, --base;
if ( !len )
len = 1;
else if ( len > SAM_NAMELEN )
len = SAM_NAMELEN;
(void) strncpy(name, base, len);
name[len] = '\0';
}
/*
* Add given filename and corresponding archive member name to list
* or replace entry with same archive member name.
* Return modified list.
*/
names_List names_add(names_List list, char *filename)
{
names_List this, prev;
sam_Name name;
make_name(name, filename);
prev = NULL;
this = list;
while ( this != NULL ) {
if ( !strcmp(this->nl_name, name) ) {
this->nl_filename = filename;
return list;
}
prev = this;
this = this->nl_next;
}
this = (names_List) malloc( sizeof(struct names_l) );
if ( this == NULL ) {
perror("storage allocation");
exit(ECODE_PROBLEM);
}
this->nl_filename = filename;
(void) strncpy(this->nl_name, name, sizeof this->nl_name);
this->nl_next = NULL;
this->nl_prev = prev;
if ( prev == NULL )
list = this;
else
prev->nl_next = this;
return list;
}
/*
* Search list for given archive member name. If it is there,
* return a pointer to the entry, otherwise return NULL.
*/
names_List names_get(names_List list, sam_Name name)
{
while ( list != NULL ) {
if ( !strcmp(list->nl_name, name) )
return list;
list = list->nl_next;
}
return list;
}
/*
* Delete an entry from list. Return modified list.
*/
names_List names_delete(names_List list, names_List entry)
{
if ( entry->nl_next != NULL )
entry->nl_next->nl_prev = entry->nl_prev;
if ( entry->nl_prev != NULL )
entry->nl_prev->nl_next = entry->nl_next;
else
list = entry->nl_next;
free(entry);
return list;
}
/*
* Print for each entry of list an error message indicating that
* the entry was not found.
*/
void names_notfound(names_List list)
{
while ( list != NULL ) {
(void) fprintf(stderr, "%s: not found in archive\n",
list->nl_name);
list = list->nl_next;
}
}
<- Alle Module
Martin Hasch, Februar 1997