Main Page | Class List | Directories | File List | Class Members | File Members

2Dlist.c

Go to the documentation of this file.
00001 /* cfengine for GNU
00002  
00003         Copyright (C) 1995/6
00004         Free Software Foundation, Inc.
00005  
00006    This file is part of GNU cfengine - written and maintained 
00007    by Mark Burgess, Dept of Computing and Engineering, Oslo College,
00008    Dept. of Theoretical physics, University of Oslo
00009  
00010    This program is free software; you can redistribute it and/or modify it
00011    under the terms of the GNU General Public License as published by the
00012    Free Software Foundation; either version 2, or (at your option) any
00013    later version.
00014  
00015    This program is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018    GNU General Public License for more details.
00019  
00020   You should have received a copy of the GNU General Public License
00021   along with this program; if not, write to the Free Software
00022   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
00023 
00024 */
00025 
00026 
00027 /*********************************************************************/
00028 /*                                                                   */
00029 /*  TOOLKIT: the "2Dlist" object library for cfengine                */
00030 /*           uses (inherits) item.c                                  */
00031 /*                                                                   */
00032 /*********************************************************************/
00033 
00034 #include "cf.defs.h"
00035 #include "cf.extern.h"
00036 
00037 /* private */
00038 
00039 #define TD_wrapped   1
00040 #define TD_nowrap    2
00041 
00042 /*********************************************************************/
00043 /* TOOLKIT : 2D list                                                 */
00044 /*********************************************************************/
00045 
00046 void Set2DList(list)
00047 
00048 struct TwoDimList *list;
00049 
00050 { struct TwoDimList *tp;
00051 
00052 Debug1("Set2DLIst()\n");
00053 
00054 for (tp = list; tp != NULL; tp=tp->next)
00055    {
00056    tp->current = tp->ilist;
00057    }
00058 }
00059 
00060 /*********************************************************************/
00061 
00062 char *Get2DListEnt(list)
00063 
00064    /* return a path string in static data, like getent in NIS */
00065 
00066 struct TwoDimList *list;
00067 
00068 { static char entry[bufsize];
00069   struct TwoDimList *tp;
00070   char seps[2];
00071 
00072 Debug1("Get2DListEnt()\n");
00073 
00074 if (EndOfTwoDimList(list))
00075    {
00076    return NULL;
00077    }
00078 
00079 bzero(entry,bufsize);
00080 
00081 for (tp = list; tp != NULL; tp=tp->next)
00082    {
00083    sprintf(seps,"%c",tp->sep);
00084 
00085    if (tp->current != NULL)
00086       {
00087       strcat(entry,(tp->current)->name);
00088       }
00089    }
00090 
00091 
00092 Debug1("Get2DLIstEnt returns %s\n",entry);
00093 
00094 IncrementTwoDimList(list,list);
00095 
00096 return entry;
00097 }
00098 
00099 /*********************************************************************/
00100 
00101 void Build2DListFromVarstring(TwoDimlist,varstring,sep)
00102 
00103  /* Build a database list with all expansions of a 2D list a */
00104  /* sep is a separator which is used to split a many-variable */
00105  /* string into many strings with only one variable           */
00106 
00107 struct TwoDimList **TwoDimlist;
00108 char *varstring, sep;
00109 /* GLOBAL LISTSEPARATOR */
00110 
00111 { char format[6], *sp;
00112   char node[bufsize];
00113   int i;
00114 
00115 Debug1("Build2DListFromVarstring(%s,sep=%c)\n",varstring,sep);
00116 
00117 if ((strlen(varstring) == 1) && (varstring[0] == sep))
00118    {
00119    AppendTwoDimItem(TwoDimlist,SplitVarstring("",'$'),sep);
00120    return;
00121    }
00122 
00123 snprintf(format,6,"%%[^%c]",sep);   /* set format string to search */
00124 
00125 for (sp = varstring; *sp != '\0'; sp++)
00126    {
00127    bzero(node,maxlinksize);
00128 
00129    *node = *sp;;
00130       
00131    for (i = 1; (*(sp+i) != '$') && (*(sp+i) != '\0'); i++)
00132       {
00133       *(node+i) = *(sp+i);
00134       }
00135 
00136       *(node+i) = '\0';
00137       sp += i-1;
00138    
00139    if (strlen(node) == 0)
00140       {
00141       continue;
00142       }
00143 
00144    AppendTwoDimItem(TwoDimlist,SplitVarstring(node,LISTSEPARATOR),sep);
00145 
00146    if (*sp == '\0')
00147       {
00148       break;
00149       }
00150    }
00151 }
00152 
00153 /*********************************************************************/
00154 
00155 int IncrementTwoDimList (from,list)
00156 
00157 struct TwoDimList *from, *list;
00158 
00159 { struct TwoDimList *tp;
00160 
00161 Debug1("IncrementTwoDimList()\n");
00162 
00163 for (tp = from; tp != NULL; tp=tp->next)
00164    {
00165    if (tp->is2d)
00166       {
00167       break;
00168       }
00169    }
00170 
00171 if (tp == NULL)
00172    {
00173    return TD_wrapped;
00174    }
00175 
00176 if (IncrementTwoDimList(tp->next,list) == TD_wrapped)
00177    {
00178    tp->current = (tp->current)->next;
00179 
00180    if (tp->current == NULL)
00181       {
00182       tp->current = tp->ilist;
00183       tp->rounds++;             /* count iterations to ident eolist*/
00184       return TD_wrapped;
00185       }
00186    else
00187       {
00188       return TD_nowrap;
00189       }
00190    }
00191 
00192 return TD_nowrap; /* Shouldn't get here */
00193 }
00194 
00195 /*********************************************************************/
00196 
00197 int EndOfTwoDimList(list)       /* bool */
00198 
00199 struct TwoDimList *list;
00200 
00201    /* returns true if the leftmost list variable has cycled */
00202    /* i.e. rounds is > 0 for the first is-2d list item      */
00203 
00204 { struct TwoDimList *tp;
00205 
00206 for (tp = list; tp != NULL; tp=tp->next)
00207    {
00208    if (tp->is2d)
00209        {
00210        break;
00211        }
00212    }
00213 
00214 if (list == NULL)
00215    {
00216    return true;
00217    }
00218 
00219 if (tp == NULL)             /* Need a case when there are no lists! */
00220    {
00221    if (list->rounds == 0)
00222       {
00223       list->rounds = 1;
00224       return false;
00225       }
00226    else
00227       {
00228       return true;
00229       }
00230    }
00231 
00232 if (tp->rounds > 0)
00233     {
00234     return true;
00235     }
00236 else
00237     {
00238     return false;
00239     }
00240 }
00241 
00242 /*********************************************************************/
00243 
00244 void AppendTwoDimItem(liststart,itemlist,sep)
00245 
00246 struct TwoDimList **liststart;
00247 struct Item *itemlist;
00248 char sep;
00249 
00250 { struct TwoDimList *ip, *lp;
00251 
00252 Debug1("AppendTwoDimItem(itemlist, sep=%c)\n",sep);
00253 
00254  if (liststart == NULL)
00255     {
00256     Debug("SOFTWARE ERROR in AppendTwoDimItem()\n ");
00257     return;
00258     }
00259  
00260 if ((ip = (struct TwoDimList *)malloc(sizeof(struct TwoDimList))) == NULL)
00261    {
00262    CfLog(cferror,"AppendTwoDimItem","malloc");
00263    FatalError("");
00264    }
00265 
00266 if (*liststart == NULL)
00267    {
00268    *liststart = ip;
00269    }
00270 else
00271    {
00272    for (lp = *liststart; lp->next != NULL; lp=lp->next)
00273       {
00274       }
00275 
00276    lp->next = ip;
00277    }
00278 
00279 ip->ilist = itemlist;
00280 ip->current = itemlist; /* init to start of list */
00281 ip->next = NULL;
00282 ip->rounds = 0;
00283 ip->sep = sep;
00284 
00285 if (itemlist == NULL || itemlist->next == NULL)
00286    {
00287    ip->is2d = false;
00288    }
00289 else
00290    {
00291    ip->is2d = true;
00292    }
00293 }
00294 
00295 /*********************************************************************/
00296 
00297 void Delete2DList(item)
00298 
00299 struct TwoDimList *item;
00300 
00301 {
00302 if (item != NULL)
00303    {
00304    Delete2DList(item->next);
00305    item->next = NULL;
00306 
00307    DeleteItemList(item->ilist);
00308    
00309    free((char *)item);
00310    }
00311 }

© sourcejam.com 2005-2008