LCOV - code coverage report
Current view: top level - libreoffice/dmake/unix - arlib.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 142 0.0 %
Date: 2012-12-17 Functions: 0 11 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             : --
       3             : -- SYNOPSIS
       4             : --      Unix archive manipulation code.
       5             : --
       6             : -- DESCRIPTION
       7             : --  Originally this code was provided by Eric Gisin of MKS.  I took
       8             : --  his code and completely rewrote it adding cacheing of lib members
       9             : --  and other various optimizations.  I kept the overal functional
      10             : --  idea of the library routines as they are similar to those in GNU
      11             : --  make and felt it advantageous to maintain a similar interface.
      12             : --
      13             : -- AUTHOR
      14             : --      Dennis Vadura, dvadura@dmake.wticorp.com
      15             : --
      16             : -- WWW
      17             : --      http://dmake.wticorp.com/
      18             : --
      19             : -- COPYRIGHT
      20             : --      Copyright (c) 1996,1997 by WTI Corp.  All rights reserved.
      21             : --
      22             : --      This program is NOT free software; you can redistribute it and/or
      23             : --      modify it under the terms of the Software License Agreement Provided
      24             : --      in the file <distribution-root>/readme/license.txt.
      25             : --
      26             : -- LOG
      27             : --      Use cvs log to obtain detailed change logs.
      28             : */
      29             : 
      30             : /* Sun unix on 386i's has a broken ar.h that does not assume PORTAR format
      31             :  * by default, so we fix it here. */
      32             : #if defined(i386) || defined(__DGUX__)
      33             : #define PORTAR 1
      34             : #endif
      35             : 
      36             : #if !defined (COHERENT) && !defined(__COHERENT__)
      37             : #include <ar.h>
      38             : #else
      39             : #include <arcoff.h>
      40             : #endif /* COHERENT, __COHERENT__ */
      41             : #include "extern.h"
      42             : #include "sysintf.h"
      43             : 
      44             : /* By defining the defines below it is possible to configure the library
      45             :  * code for library cacheing/non-cacheing, ASCII archive headers, and a full
      46             :  * decode of the ar_hdr fields in the scan_ar function. */
      47             : 
      48             : #ifndef ASCARCH
      49             : #define ASCARCH         1   /* ASCII time stored in archive */
      50             : #endif
      51             : 
      52             : #ifndef LC
      53             : #define LC          1   /* Turn on library cacheing */
      54             : #endif
      55             : 
      56             : #ifndef CHECKELF
      57             : #define CHECKELF        1   /* Enable Elf long member names */
      58             : #endif
      59             : 
      60             : #ifndef DECODE_ALL_AR_FIELDS
      61             : #define DECODE_ALL_AR_FIELDS    0   /* decode only fields make needs*/
      62             : #endif
      63             : 
      64             : #ifndef AR_TRUNCATE_MEMBER_NAMES
      65             : #define AR_TRUNCATE_MEMBER_NAMES 0  /* truncate member names for */
      66             : #endif                  /* comparison.               */
      67             : 
      68             : #if LC
      69             : #  define FOUND_MEMBER  FALSE
      70             : #else
      71             : #  define FOUND_MEMBER  TRUE
      72             : #  define _cache_member(a, b, c)
      73             : #  define _check_cache(a, b, c, d)  FALSE
      74             : #endif
      75             : 
      76             : #define MAXFNAME      255       /* Max length of member name    */
      77             : #define MAXMNAME    8   /* Max module name < MAXFNAME   */
      78             : 
      79             : 
      80             : /* This struct is used to pass the library and member inrmation about the
      81             :  * routines that perform the library seeking/cacheing */
      82             : struct ar_args {
      83             :    char   *lib;
      84             :    char   *member;
      85             :    time_t time;
      86             : };
      87             : 
      88             : 
      89             : typedef struct AR {
      90             :    char    ar_name[MAXFNAME+1];      /* File name */
      91             :    long    ar_size;                  /* Size in bytes */
      92             :    time_t  ar_time;                  /* Modification time */
      93             : 
      94             : #ifdef DOS
      95             :    char    ar_modname[MAXMNAME+1];   /* DOS module name */
      96             : #endif
      97             : 
      98             : #if DECODE_ALL_AR_FIELDS
      99             :    uint16  ar_mode;                  /* File mode */
     100             :    uint16  ar_uid;                   /* File owner */
     101             :    uint16  ar_gid;                   /* File group owner */
     102             : #endif
     103             : } AR, *ARPTR;
     104             : 
     105             : 
     106             : static int ar_scan  ANSI((FILE *,
     107             :               int (*) ANSI((FILE *, struct AR *,struct ar_args *)),
     108             :               struct ar_args *));
     109             : static int ar_touch ANSI(( FILE *, time_t ));
     110             : static int time_function  ANSI(( FILE *, struct AR *, struct ar_args * ));
     111             : static int touch_function ANSI(( FILE *, struct AR *, struct ar_args * ));
     112             : static int ar_name_equal ANSI((char *, char *));
     113             : 
     114             : #if LC
     115             : static int _cache_member ANSI((char *, char *, time_t));
     116             : static int _check_cache  ANSI((char *, char *, time_t *, int));
     117             : #endif
     118             : 
     119             : /* decoded archive header */
     120             : static AR    _ar;
     121             : static off_t arhdroffset;  /* member seek offset */
     122             : 
     123             : 
     124             : PUBLIC time_t
     125           0 : seek_arch(name, lib)/*
     126             : ======================
     127             :    Look for module 'name' inside 'lib'.  If compiled with cacheing then first
     128             :    check to see if the specified lib is cached.  If so then return that time
     129             :    stamp instead of looking into the library. */
     130             : char    *name;
     131             : char    *lib;
     132             : {
     133             :    FILE   *f;
     134             :    int    rv;
     135             :    time_t mtime;
     136             :    struct ar_args args;
     137             : 
     138             :    /* Check the cache first (if there is a cache) */
     139           0 :    if( _check_cache(name, lib, &mtime, FALSE) )  return( mtime );
     140             : 
     141             :    /* Open the lib file and perform the scan of the members, looking
     142             :     * for our particular member.  If cacheing is enabled it will be
     143             :     * taken care of automatically during the scan. */
     144             : 
     145           0 :    args.lib    = lib;
     146           0 :    args.member = name;
     147           0 :    args.time   = (time_t)0L;
     148             : 
     149           0 :    if( (f = fopen(lib, "r")) == NIL(FILE) ) return( (time_t)0L );
     150           0 :    rv = ar_scan(f, time_function, &args );
     151           0 :    fclose( f );
     152             : 
     153           0 :    if( rv < 0 ) Fatal("(%s): Invalid library format", lib);
     154             : 
     155           0 :    return( args.time );
     156             : }
     157             : 
     158             : 
     159             : PUBLIC int
     160           0 : touch_arch(name, lib)/*
     161             : =======================
     162             :    Look for module 'name' inside 'lib'.  If compiled with cacheing then first
     163             :    check to see if the specified lib is cached.  If so then set that time
     164             :    stamp and write it into the library.  Returns 0 on success, non-zero
     165             :    on failure. */
     166             : char   *name;
     167             : char   *lib;
     168             : {
     169             :    FILE   *f;
     170             :    int    rv;
     171             :    struct ar_args args;
     172             : 
     173             :    /* Open the lib file and perform the scan of the members, looking
     174             :     * for our particular member.  If cacheing is enabled it will be
     175             :     * taken care of automatically during the scan. */
     176             : 
     177           0 :    args.lib    = lib;
     178           0 :    args.member = name;
     179           0 :    args.time   = (time_t)0L;
     180             : 
     181           0 :    if( (f = fopen(lib, "r+")) == NIL(FILE) ) return( (time_t)1L );
     182           0 :    rv = ar_scan(f, touch_function, &args );
     183           0 :    fclose( f );
     184             : 
     185           0 :    if( rv < 0 ) Fatal("(%s): Invalid library format", lib);
     186             : 
     187           0 :    return( 0 );
     188             : }
     189             : 
     190             : 
     191             : 
     192             : static int
     193           0 : time_function(f, arp, argp)/*
     194             : =============================
     195             :    get library member's time, if it matches than return it in argp, if
     196             :    cacheing is enabled than cache the library members also. */
     197             : FILE           *f;      /* library file          */
     198             : struct AR      *arp;    /* library member header */
     199             : struct ar_args *argp;
     200             : {
     201           0 :    int rv = _cache_member( arp->ar_name, argp->lib, arp->ar_time );
     202             : 
     203           0 :    if( ar_name_equal (argp->member, arp->ar_name)) {
     204           0 :       argp->time = arp->ar_time;
     205             : 
     206           0 :       if( arp->ar_time == 0 && !(Glob_attr & A_SILENT) )
     207           0 :          Warning( "(%s): Can't extract library member timestamp; using EPOCH",
     208             :               argp->member);
     209             : 
     210           0 :       return( rv );  /* 1 => no cacheing, 0 => cacheing */
     211             :    }
     212             : 
     213           0 :    return( FALSE ); /* continue scan */
     214             : }
     215             : 
     216             : 
     217             : 
     218             : static int
     219           0 : touch_function(f, arp, argp)/*
     220             : ==============================
     221             :    Update library member's time stamp, and write new time value into cache
     222             :    if required. */
     223             : FILE           *f;      /* library file */
     224             : struct AR      *arp;    /* library member header */
     225             : struct ar_args *argp;
     226             : {
     227             :    extern time_t time ANSI(( time_t * ));
     228           0 :    time_t now = time((time_t*) NULL);  /* Current time.       */
     229             : 
     230           0 :    if( ar_name_equal(argp->member, arp->ar_name) ) {
     231           0 :       _check_cache( argp->member, argp->lib, &now, TRUE );
     232           0 :       ar_touch(f, now );
     233             : 
     234           0 :       return( TRUE );
     235             :    }
     236             : 
     237           0 :    return( FALSE ); /* continue scan */
     238             : }
     239             : 
     240             : 
     241             : static int
     242           0 : ar_name_equal (char * name1, char * name2)
     243             : {
     244             :   int equal;
     245             : 
     246             : #if AR_TRUNCATE_MEMBER_NAMES
     247             :   struct ar_hdr hdr;
     248             : 
     249             :   equal = !strncmp (name1, name2, sizeof (hdr.ar_name)-1);
     250             : #else
     251           0 :   equal = !strcmp (name1, name2);
     252             : #endif
     253             : 
     254           0 :   return equal;
     255             : }
     256             : 
     257             : 
     258             : static int
     259           0 : ar_scan(f, function, arg)/*
     260             : ===========================
     261             :    Scan the opened archive, and call the given function for each member found.
     262             :    The function will be called with the file positioned at the beginning of
     263             :    the member and it can read up to arp->ar_size bytes of the archive member.
     264             :    If the function returns 1, we stop and return 1.  We return 0 at the end
     265             :    of the archive, or -1 if the archive has invalid format.  This interface
     266             :    is more general than required by "make", but it can be used by other
     267             :    utilities.  */
     268             : register FILE *f;
     269             : int      (*function) ANSI((FILE *, struct AR *, struct ar_args *));
     270             : struct   ar_args *arg;
     271             : {
     272             :    extern long atol ();
     273             :    register char *p;
     274             :    struct ar_hdr arhdr;   /* archive member header   */
     275             :    long      nsize;   /* size of member name     */
     276           0 :    long          arind=0; /* archive index offset    */
     277             :    int           process;
     278             : #if defined(_AIX)
     279             :    struct fl_hdr flhdr;   /* archive file header     */
     280             :    char   magic[SAIAMAG]; /* size of magic string    */
     281             : #else
     282             : #if ASCARCH
     283             :    char magic[SARMAG];
     284             : #else
     285             :    unsigned short word;
     286             : #endif
     287             : #endif
     288             : 
     289           0 :    fseek( f, 0L, 0 );   /* Start at the beginning of the archive file */
     290             : 
     291             : #if ASCARCH
     292             : #if defined(_AIX)
     293             :    if( fread( (char *)&flhdr, sizeof(flhdr), 1, f ) != 1 ) return (-1);
     294             :    if( strncmp(flhdr.fl_magic,AIAMAG, SAIAMAG) != 0 ) return(-1);
     295             :    fseek(f, atol(flhdr.fl_fstmoff), 0 ); /* postition to first member */
     296             : #else
     297           0 :    if( fread( magic, sizeof(magic), 1, f ) != 1 ) return( -1 );
     298           0 :    if( strncmp(magic, ARMAG, SARMAG) != 0 ) return( -1 );
     299             : #endif
     300             : #else
     301             :    if( fread( (char*)&word, sizeof(word), 1, f ) != 1 ) return( -1 );
     302             :    if( word != ARMAG ) return( -1 );
     303             : #endif
     304             : 
     305             :    /* scan the library, calling `function' for each member
     306             :     */
     307             :    while( 1 ) {
     308           0 :       arhdroffset = ftell(f);
     309             : #if defined(_AIX)
     310             :       if( fread((char*)&arhdr,sizeof(arhdr)-sizeof(arhdr._ar_name),1,f)!=1)
     311             :          break;
     312             :       nsize = atoi(arhdr.ar_namlen);
     313             :       fseek(f, arhdroffset+(unsigned long)(((struct ar_hdr *)0)->_ar_name.ar_name), 0);
     314             :       if( fread((char*)_ar.ar_name,nsize,1,f)!=1)
     315             :          break;
     316             :       _ar.ar_name[nsize]='\0';
     317             : #else
     318           0 :       if( fread((char*) &arhdr, sizeof(arhdr), 1, f) != 1 ) break;
     319           0 :       strncpy(_ar.ar_name, arhdr.ar_name, nsize = sizeof(arhdr.ar_name));
     320             : #endif
     321             : 
     322           0 :       for( p = &_ar.ar_name[nsize];
     323           0 :            --p >= _ar.ar_name && *p == ' ';);
     324             : 
     325           0 :       p[1] = '\0';
     326           0 :       if( *p == '/' ) *p = 0;   /* SysV has trailing '/' */
     327             : 
     328             :       /* check to see if this is an archive index using SsysV Index scheme.
     329             :        * see ar(4) man page for more info */
     330             : #if CHECKELF
     331           0 :       if( _ar.ar_name[0] == '/' && _ar.ar_name[1] == '\0' ) {
     332           0 :      arind = arhdroffset+sizeof(arhdr);
     333           0 :      process = 0;
     334             :       }
     335             :       else
     336             : #endif
     337           0 :      process = 1;
     338             : 
     339             : #if !defined(_AIX)
     340             : #if ASCARCH
     341           0 :       if( strncmp(arhdr.ar_fmag, ARFMAG, sizeof(arhdr.ar_fmag)) != 0 )
     342           0 :      return( -1 );
     343           0 :       _ar.ar_time = atol(arhdr.ar_date);
     344           0 :       _ar.ar_size = atol(arhdr.ar_size);
     345             : #else
     346             :       _ar.ar_time = arhdr.ar_date;
     347             :       _ar.ar_size = arhdr.ar_size;
     348             : #endif
     349             : #if CHECKELF
     350             :       /* check for names of the form /xxxx where xxxx is an offset into the
     351             :        * name table pointed at by arind. */
     352           0 :       if(arind && _ar.ar_name[0] == '/') {
     353           0 :      long offset = atol(_ar.ar_name+1);
     354           0 :      long here = ftell(f);
     355             :      int  c;
     356             : 
     357           0 :      fseek(f, arind+offset, 0);
     358           0 :      p = _ar.ar_name;
     359           0 :      while((c=fgetc(f)) != EOF) {
     360           0 :         *p++ = c;
     361           0 :         if(c == '/') {
     362           0 :            p[-1] = '\0';
     363           0 :            break;
     364             :         }
     365             :      }
     366             : 
     367           0 :      if (c==EOF) return(-1);          /* 'c' should never be EOF */
     368           0 :      fseek(f, here, 0);
     369             :       }
     370             : #endif
     371             : #else
     372             : #if ASCARCH
     373             :       _ar.ar_time = atol(arhdr.ar_date);
     374             :       _ar.ar_size = atol(arhdr.ar_nxtmem);
     375             : #else
     376             :       _ar.ar_time = arhdr.ar_date;
     377             :       _ar.ar_size = arhdr.ar_nxtmem;
     378             : #endif
     379             : #endif
     380             : 
     381             : 
     382             : #if DECODE_ALL_AR_FIELDS
     383             : #if ASCARCH
     384             :       _ar.ar_mode = atoi(arhdr.ar_mode);
     385             :       _ar.ar_uid  = atoi(arhdr.ar_uid);
     386             :       _ar.ar_gid  = atoi(arhdr.ar_gid);
     387             : #else
     388             :       _ar.ar_mode = arhdr.ar_mode;
     389             :       _ar.ar_uid = arhdr.ar_uid;
     390             :       _ar.ar_gid = arhdr.ar_gid;
     391             : #endif
     392             : #endif
     393           0 :       if( process && (*function)(f, &_ar, arg) ) return( 1 );
     394             : 
     395             : #if defined(_AIX)
     396             :       if( _ar.ar_size == 0L ) break;
     397             :       fseek( f, (long) _ar.ar_size, 0 );
     398             : #else
     399           0 :       fseek( f, arhdroffset + sizeof(arhdr) + ((_ar.ar_size+1) & ~1L), 0 );
     400             : #endif
     401           0 :    }
     402             : 
     403             : #if !defined(_AIX)
     404           0 :    if( !feof(f) ) return( -1 );
     405             : #endif
     406           0 :    return 0;
     407             : }
     408             : 
     409             : 
     410             : 
     411             : static int
     412           0 : ar_touch( f, now )/*
     413             : ====================
     414             :    touch module header timestamp. */
     415             : FILE   *f;
     416             : time_t now;
     417             : {
     418             : 
     419           0 :    fseek(f, arhdroffset + (unsigned long)(((struct ar_hdr *)0)->ar_date), 0);
     420             : 
     421             : #if ASCARCH
     422           0 :    fprintf(f, "%lu", now);
     423             : #else
     424             :    fwrite((char *)now, sizeof(now), 1, f);
     425             : #endif
     426             : 
     427           0 :    return( ferror(f) ? 0 : 1 );
     428             : }
     429             : 
     430             : 
     431             : #if LC
     432             : typedef struct mem {
     433             :    time_t   m_time;     /* modify time of member*/
     434             :    struct mem   *m_next;    /* next member in lib   */
     435             :    char     m_valid;    /* valid cache entry    */
     436             :    char     m_name[1];  /* lib member name  */
     437             : } MEM, *MEMPTR;
     438             : 
     439             : typedef struct lib {
     440             :    struct lib   *lb_next;   /* next library in list */
     441             :    struct mem   *lb_members;    /* list of lib members  */
     442             :    char     lb_valid;   /* valid cache entry    */
     443             :    char     *lb_name;   /* library name     */
     444             : } LIB, *LIBPTR;
     445             : 
     446             : static LIBPTR _cache = NIL(LIB);
     447             : static MEMPTR _find_member ANSI(( LIBPTR, char * ));
     448             : 
     449             : static int
     450           0 : _check_cache( name, lib, pmtime, touch )/*
     451             : ==========================================
     452             :    Check to see if we have cached member in lib, if so return time in pmtime
     453             :    and return TRUE, otherwise return FALSE, if touch is TRUE then touch
     454             :    the archive member instead. */
     455             : char   *name;
     456             : char   *lib;
     457             : time_t *pmtime;
     458             : int    touch;
     459             : {
     460             :    register MEMPTR mp;
     461             :    register LIBPTR lp;
     462             : 
     463           0 :    for( lp=_cache; lp != NIL(LIB) && lp->lb_name != lib; lp=lp->lb_next );
     464           0 :    if( lp == NIL(LIB) ) return( FALSE );
     465             : 
     466           0 :    mp = _find_member( lp, name );
     467           0 :    if( mp == NIL(MEM) || !mp->m_valid ) return( FALSE );
     468             : 
     469           0 :    if( touch == TRUE )
     470             :    {
     471           0 :       mp->m_time = *pmtime;
     472           0 :       mp->m_valid = 1;
     473             :    }
     474             :    else
     475           0 :       *pmtime = mp->m_time;
     476             : 
     477           0 :    lp->lb_valid   = 1;
     478           0 :    lp->lb_members = mp;
     479             : 
     480           0 :    return( TRUE );
     481             : }
     482             : 
     483             : 
     484             : 
     485             : static int
     486           0 : _cache_member( name, lib, mtime )/*
     487             : ===================================
     488             :    Cache name in lib along with it's time */
     489             : char   *name;
     490             : char   *lib;
     491             : time_t mtime;
     492             : {
     493             :    register MEMPTR mp;
     494             :    register LIBPTR lp;
     495             : 
     496           0 :    for( lp=_cache;
     497           0 :     lp != NIL(LIB) && lp->lb_name != NIL(char) && lp->lb_name != lib;
     498           0 :     lp=lp->lb_next);
     499             : 
     500           0 :    if( lp == NIL(LIB) )
     501             :    {
     502           0 :       lp = (LIBPTR) malloc(sizeof(LIB));
     503           0 :       if( lp == NIL(LIB) ) No_ram();
     504             : 
     505           0 :       lp->lb_name    = lib;
     506           0 :       lp->lb_members = NIL(MEM);
     507           0 :       lp->lb_next    = _cache;
     508           0 :       lp->lb_valid   = 0;
     509           0 :       _cache = lp;
     510             :    }
     511             : 
     512             :    /* On UNIX ar does not allow multiple copies of the same .o file to live
     513             :     * in the same AR file.  If this is not TRUE then use the commented out
     514             :     * version to set the value of mp. */
     515             : 
     516             :    /*mp = _find_member(lp, name);*/
     517           0 :    mp = NIL(MEM);
     518             : 
     519           0 :    if( mp == NIL(MEM) )
     520             :    {
     521           0 :       mp = (MEMPTR) malloc(sizeof(char)*offsetof(MEM,m_name[strlen(name)+1]));
     522           0 :       if( mp == NIL(MEM) ) No_ram();
     523             : 
     524           0 :       strcpy( mp->m_name, name );
     525           0 :       mp->m_time     = mtime;
     526             : 
     527           0 :       if( lp->lb_members == NIL(MEM) ) {
     528           0 :      mp->m_next     = mp;
     529           0 :      lp->lb_members = mp;
     530             :       }
     531             :       else {
     532           0 :      mp->m_next = lp->lb_members->m_next;
     533           0 :      lp->lb_members->m_next = mp;
     534           0 :      lp->lb_members = mp;
     535             :       }
     536             :    }
     537             :    else
     538           0 :       mp->m_time = mtime;
     539             : 
     540           0 :    mp->m_valid = 1;
     541             : 
     542           0 :    return( lp->lb_valid );
     543             : }
     544             : 
     545             : 
     546             : static MEMPTR
     547           0 : _find_member( lp, name )
     548             : LIBPTR lp;
     549             : char   *name;
     550             : {
     551           0 :    register MEMPTR mp = lp->lb_members;
     552             : 
     553           0 :    if( mp == NIL(MEM) ) return(mp);
     554             : 
     555             :    do {
     556           0 :       if( !strcmp(mp->m_name, name ) ) return( mp );
     557           0 :       mp = mp->m_next;
     558             :    }
     559           0 :    while( mp != lp->lb_members );
     560             : 
     561           0 :    return( NIL(MEM) );
     562             : }
     563             : #endif
     564             : 
     565             : 
     566             : 
     567             : PUBLIC void
     568           0 : void_lcache( lib, member )/*
     569             : ============================
     570             :    Void the library cache for lib.  If member is NIL(char) then nuke all
     571             :    of the members, if member is NOT NIL(char) then invalidate only that
     572             :    member. */
     573             : char *lib;
     574             : char *member;
     575             : {
     576             : #if LC
     577             :    register LIBPTR lp;
     578             :    register MEMPTR mp;
     579             :    register MEMPTR tmp;
     580             : 
     581           0 :    for( lp=_cache; lp != NIL(LIB) && lp->lb_name != lib; lp=lp->lb_next );
     582           0 :    if( lp == NIL(LIB) ) return;
     583             : 
     584           0 :    if( member == NIL(char) ) {
     585           0 :       mp = lp->lb_members;
     586             :       do {
     587           0 :      tmp = mp->m_next;
     588           0 :      (void) free( mp );
     589           0 :      mp = tmp;
     590           0 :       } while( mp != lp->lb_members );
     591             : 
     592           0 :       lp->lb_valid   = 0;
     593           0 :       lp->lb_members = NIL(MEM);
     594           0 :       lp->lb_name    = NIL(char);
     595             :    }
     596             :    else {
     597           0 :       mp=lp->lb_members;
     598             :       do {
     599           0 :      if( strcmp( member, mp->m_name) == 0 ) {
     600           0 :         lp->lb_members = mp->m_next;
     601           0 :         mp->m_valid = 0;
     602             :      }
     603             : 
     604           0 :      mp=mp->m_next;
     605           0 :       } while( mp != lp->lb_members );
     606             :    }
     607             : #endif
     608             : }

Generated by: LCOV version 1.10