[WikiDyd] [TitleIndex] [WordIndex

Projekt dirdu: moduł kontenera

[wiki:Jimp1/ProgramowanieProceduralne strona projektu]

W miarę ostateczna wersja kodu

Plik do pobrania: attachment:container.tgz

Teksty programów:

container.h

   1 #ifndef _CONTAINER_H_
   2 #define _CONTAINER_H_
   3                                                                                                     
   4 /* container.h
   5    version 0.2, 18-10-2005
   6    jstar@iem.pw.edu.pl
   7 */
   8 
   9 #include <stdio.h>
  10                                                                                                     
  11 typedef enum
  12 { CONTAINER_OK, CONTAINER_NO_MEMORY } container_err_type;
  13                                                                                                     
  14 typedef enum
  15 { AS_FILE, AS_DIRECTORY } entry_type;
  16                                                                                                     
  17 typedef struct path_elem
  18 {                               /* informacja o sciezce - lista podrzedna */
  19   char *path;
  20   entry_type type;
  21   struct path_elem *nextp;
  22 } path_elem_t;
  23                                                                                                     
  24 typedef struct name_elem
  25 {                               /* informacja o nazwie - lista nadrzędna */
  26   char *name;
  27   path_elem_t *paths;
  28   struct name_elem *nextn;
  29 } name_elem_t;
  30                                                                                                     
  31 typedef struct
  32 {                               /* typ danych dla interfejsu */
  33   char *name;
  34   int no_paths;
  35   char **paths;
  36 } group_t;
  37                                                                                                     
  38 void add (char *name, char *path, entry_type type);     /* dodaje element do kontenera, inicjuje iterator po grupach */
  39                                                                                                     
  40 void init_group_iterator (void);        /* inicjuje iterator po grupach */
  41                                                                                                     
  42 group_t *next_group (void);     /* zwraca następną grupę, lub NULL, jeśli nie ma więcej */
  43                                                                                                     
  44 void print_all( FILE *out ); /* wypisuje cala liste */
  45                                                                                                     
  46 #endif
  47 

container.c

   1 /* container.c
   2    version 0.2, 18-10-2005
   3    jstar@iem.pw.edu.pl
   4 */
   5                                                                                                     
   6 #include "container.h"
   7 #include <stdlib.h>
   8 #include <string.h>
   9 #include <stdio.h>
  10                                                                                                     
  11 #include "utils.h"
  12                                                                                                     
  13 container_err_type container_err = CONTAINER_OK;
  14                                                                                                     
  15 static name_elem_t *head = NULL;  /* kontener */
  16                                                                                                     
  17 static name_elem_t *iterator = NULL;
  18                                                                                                     
  19 static group_t g = { NULL, 0, NULL }; /* zmienna robocza, uzywana w next_group */
  20                                                                                                     
  21 path_elem_t *
  22 new_path_element (char *path, entry_type type, path_elem_t * next)
  23 {
  24   path_elem_t *n = malloc (sizeof *n);
  25   if (n == NULL || (n->path = malloc (strlen (path) + 1)) == NULL) {
  26     container_err = CONTAINER_NO_MEMORY;
  27     if (n != NULL)
  28       free (n);
  29     return next;
  30   }
  31   else {
  32     strcpy (n->path, path);
  33     n->type = type;
  34     n->nextp = next;
  35     return n;
  36   }
  37 }
  38                                                                                                     
  39 path_elem_t *
  40 addpath (path_elem_t * list, char *path, entry_type type)
  41 /* dodaje nowy element do listy sciezek
  42    funkcja rekurencyjna, tworzaca liste posortowana wg nazw */
  43 {
  44   if( list == NULL || list->path > path )
  45     return new_path_element (path, type, list);
  46   else {
  47     list->nextp= addpath( list->nextp, path, type );
  48     return list;
  49   }
  50 }
  51 
  52 name_elem_t *
  53 new_name_element (char *name, char *path, entry_type type, name_elem_t * next)
  54 /* dodaje nowy element główny */
  55 {
  56   name_elem_t *e;
  57                                                                                                     
  58   if ((e = malloc (sizeof *e)) == NULL) {
  59     container_err = CONTAINER_NO_MEMORY;
  60     return next;
  61   }
  62   if ((e->name = malloc (strlen (name) + 1)) == NULL) {
  63     container_err = CONTAINER_NO_MEMORY;
  64     return next;
  65   }
  66   strcpy (e->name, name);
  67   e->paths = addpath (NULL, path, type);  /* uwaga! po tym powinno się sprawdzic container_err ! */
  68   e->nextn = next;
  69   return e;
  70 }
  71                                                                                                     
  72 void
  73 add (char *name, char *path, entry_type type)
  74 /* dodaje element do kontenera, inicjuje iterator po grupach */
  75 {
  76   name_elem_t *e;
  77                                                                                                     
  78   if (head == NULL || strcmp (head->name, name) > 0) {
  79     e = new_name_element (name, path, type, head);
  80     if (container_err == CONTAINER_OK) {
  81       head = e;
  82     }
  83   }
  84   else if (strcmp (head->name, name) == 0) {
  85     head->paths = addpath (head->paths, path, type);
  86   }
  87   else {
  88     e = head;
  89     while (e->nextn != NULL && strcmp (name, e->nextn->name) > 0)
  90       e = e->nextn;
  91     if (e->nextn == NULL || strcmp (name, e->nextn->name) < 0)
  92       /* trzeba wstawic nowy element za e */
  93       e->nextn = new_name_element (name, path, type, e->nextn);
  94     else
  95       /* e->nextn->name == name   => tylko dodajemy path */
  96       e->nextn->paths = addpath (e->nextn->paths, path, type);
  97   }
  98   iterator = head;
  99 }
 100 
 101 void
 102 init_group_iterator (void)
 103 /* inicjuje iterator po grupach */
 104 {
 105   iterator = head;
 106 }
 107                                                                                                     
 108 group_t *
 109 next_group (void)
 110 /* zwraca następną grupę, lub NULL, jeśli nie ma więcej */
 111 {
 112   path_elem_t *pit;
 113   int all_paths_length = 0; /* total length of the table containing all paths */
 114   int i;
 115                                                                                                     
 116 #ifdef DEBUG_CONTAINER
 117   dbg_messg ("Entering next_group, head= %p, iterator= %p\n", head, iterator);
 118 #endif
 119   if (iterator == NULL)
 120     return NULL;
 121                                                                                                     
 122   if (g.name != NULL)
 123     free (g.name);
 124   if (g.paths != NULL) {
 125     free (g.paths[0]);
 126     free (g.paths);
 127   }
 128                                                                                                     
 129 #ifdef DEBUG_CONTAINER
 130   dbg_messg ("Creating group for name %s\n", iterator->name);
 131 #endif
 132   if ((g.name = malloc (strlen (iterator->name) + 1)) == NULL) {
 133     container_err= CONTAINER_NO_MEMORY;
 134     return NULL;
 135   }
 136   else {
 137     strcpy (g.name, iterator->name);
 138   }
 139                                                                                                     
 140   /* calculate how much memory needs to be allocated for all paths (+descriptions) */
 141   pit = iterator->paths;
 142   i = 0;
 143   while (pit != NULL) {
 144 #ifdef DEBUG_CONTAINER
 145     dbg_messg ("path: %s", pit->path);
 146 #endif
 147     all_paths_length += strlen (pit->path) + 4 + 1; /* 4 for " (d)" or " (f)", 1 for '\0' */
 148 #ifdef DEBUG_CONTAINER
 149     dbg_messg (" + %i bytes\n", strlen (pit->path) + 4 + 1);
 150 #endif
 151     pit = pit->nextp;
 152     i++;
 153   }
 154 
 155 #ifdef DEBUG_CONTAINER
 156   dbg_messg ("found %i paths\n", i);
 157 #endif
 158   if ((g.paths = malloc (i * sizeof *g.paths)) == NULL) {
 159     container_err = CONTAINER_NO_MEMORY;
 160     free (g.name);
 161     g.name= NULL;
 162     return NULL;
 163   }
 164   g.no_paths = i;
 165                                                                                                     
 166 #ifdef DEBUG_CONTAINER
 167   dbg_messg ("Need to allocate %i bytes for paths\n", all_paths_length);
 168 #endif
 169                                                                                                     
 170   if ((g.paths[0] = malloc (all_paths_length)) == NULL) {
 171     container_err = CONTAINER_NO_MEMORY;
 172     free (g.paths);
 173     g.paths= NULL;
 174     free (g.name);
 175     g.name= NULL;
 176     return NULL;
 177   }
 178   /* now copy paths to allocated memory */
 179 #ifdef DEBUG_CONTAINER
 180   dbg_messg ("Starting to collect paths\n");
 181 #endif
 182   pit = iterator->paths;
 183   i = 0;
 184   while (pit != NULL) {
 185     int this_length = sprintf (g.paths[i], "%s %s", pit->path,
 186              (pit->type == AS_FILE ? "(f)" : "(d)"));
 187 #ifdef DEBUG_CONTAINER
 188     dbg_messg ("prepared %s\n", g.paths[i]);
 189 #endif
 190     i++;
 191     pit = pit->nextp;
 192     if (pit != NULL)
 193       g.paths[i] = g.paths[i - 1] + this_length + 1;
 194   }
 195                                                                                                     
 196   iterator = iterator->nextn;
 197   return &g;
 198 }
 199 
 200 void
 201 print_all (FILE * out)
 202 /* do testowania - wypisuje cala liste */
 203 {
 204   name_elem_t *e = head;
 205   while (e != NULL) {
 206     path_elem_t *p = e->paths;
 207     fprintf (out, "NAME: %s\n", e->name);
 208     while (p != NULL) {
 209       fprintf (out, "\tAS %s IN PATH: %s\n",
 210          (p->type == AS_FILE ? "file     " : "directory"), p->path);
 211       p = p->nextp;
 212     }
 213     e = e->nextn;
 214   }
 215 }

2015-09-23 06:43