Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members  

fileTable.c

Go to the documentation of this file.
00001 /*
00002 ** LCLint - annotation-assisted static program checker
00003 ** Copyright (C) 1994-2000 University of Virginia,
00004 **         Massachusetts Institute of Technology
00005 **
00006 ** This program is free software; you can redistribute it and/or modify it
00007 ** under the terms of the GNU General Public License as published by the
00008 ** Free Software Foundation; either version 2 of the License, or (at your
00009 ** option) any later version.
00010 ** 
00011 ** This program is distributed in the hope that it will be useful, but
00012 ** WITHOUT ANY WARRANTY; without even the implied warranty of
00013 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 ** General Public License for more details.
00015 ** 
00016 ** The GNU General Public License is available from http://www.gnu.org/ or
00017 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00018 ** MA 02111-1307, USA.
00019 **
00020 ** For information on lclint: lclint-request@cs.virginia.edu
00021 ** To report a bug: lclint-bug@cs.virginia.edu
00022 ** For more information: http://lclint.cs.virginia.edu
00023 */
00024 /*
00025 ** fileTable.c
00026 **
00027 ** replaces filenamemap.c
00028 ** based (loosely) on typeTable.c
00029 **
00030 ** entries in the fileTable are:
00031 **
00032 **        name - name of the file
00033 **        type - kind of file (a temp file to be deleted?)
00034 **        link - derived from this file
00035 **
00036 */
00037 /*
00038  * Herbert 04/1997:
00039  * - Added conditional stuff (macros OS2 and MSDOS) to make names of temporary 
00040  *   files under Windows or OS/2 not larger than 8+3 characters to avoid 
00041  *   trouble with FAT file systems or Novell Netware volumes.
00042  * - Added include of new header file portab.h containing OS dependent stuff.
00043  * - Changed occurance of '/' as path delimiter to a macro.
00044  * - Added conditional stuff (#define and #include) for IBM's compiler.
00045  */
00046 
00047 # include "lclintMacros.nf"
00048 # include "llbasic.h"
00049 # include "osd.h"
00050 # include "llmain.h"
00051 # include "portab.h"
00052 # if defined(__IBMC__) && defined(OS2)
00053 # include <process.h>
00054 # define getpid _getpid
00055 # endif
00056 
00057 /*@access fileId*/
00058 
00059 static bool fileTable_inRange (fileTable ft, fileId fid) /*@*/ 
00060 {
00061   return (fileTable_isDefined (ft) && (fid >= 0) && (fid < ft->nentries));
00062 }
00063 
00064 static fileId fileTable_internAddEntry (fileTable p_ft, /*@only@*/ ftentry p_e) 
00065    /*@modifies p_ft@*/ ;
00066 static /*@only@*/ char *makeTempName (char *p_dir, char *p_pre, char *p_suf);
00067 
00068 static /*@only@*/ cstring
00069 fileType_unparse (fileType ft)
00070 {
00071   switch (ft)
00072     {
00073     case FILE_NORMAL:  return cstring_makeLiteral ("normal");
00074     case FILE_NODELETE:  return cstring_makeLiteral ("normal");
00075     case FILE_LSLTEMP: return cstring_makeLiteral ("ltemp");
00076     case FILE_HEADER:  return cstring_makeLiteral ("header");
00077     case FILE_MACROS:  return cstring_makeLiteral ("macros");
00078     }
00079 
00080   BADEXIT;
00081 }
00082 
00083 static int
00084 fileTable_getIndex (fileTable ft, cstring s)
00085 {
00086   if (ft == NULL) return NOT_FOUND;
00087   return (hashTable_lookup (ft->htable, s));
00088 }
00089 
00090 /*@only@*/ cstring
00091 fileTable_unparse (fileTable ft)
00092 {
00093   cstring s = cstring_undefined;
00094   int i;
00095 
00096   if (fileTable_isUndefined (ft))
00097     {
00098       return (cstring_makeLiteral ("<fileTable undefined>"));
00099     }
00100 
00101   for (i = 0; i < ft->nentries; i++)
00102     {
00103       if (fileId_isValid (ft->elements[i]->fder))
00104         {
00105           s = message ("%s\n[%d] %s %q %d (%s)", 
00106                        s, i, 
00107                        ft->elements[i]->fname, 
00108                        fileType_unparse (ft->elements[i]->ftype),
00109                        ft->elements[i]->fder,
00110                        ft->elements[ft->elements[i]->fder]->fname);
00111         }
00112       else
00113         {
00114           s = message ("%s\n[%d] %s %q", s, i, ft->elements[i]->fname,
00115                        fileType_unparse (ft->elements[i]->ftype));
00116         }
00117           }
00118 
00119   return s;
00120 }
00121 
00122 void fileTable_printTemps (fileTable ft)
00123 {
00124   if (fileTable_isDefined (ft))
00125     {
00126       int i;
00127 
00128       for (i = 0; i < ft->nentries; i++)
00129         {
00130           if (ft->elements[i]->ftemp)
00131             {
00132               if (fileId_isValid (ft->elements[i]->fder))
00133                 {
00134                   fprintf (stderr, "  %s:1\n\t%s:1\n", 
00135                            cstring_toCharsSafe (ft->elements[ft->elements[i]->fder]->fname),
00136                            cstring_toCharsSafe (ft->elements[i]->fname));
00137                 }
00138               else
00139                 {
00140                   fprintf (stderr, "[no file]\n\t%s:1\n",
00141                            cstring_toCharsSafe (ft->elements[i]->fname));
00142                 }
00143             }
00144         }
00145     }
00146 }
00147 
00148 /*
00149 ** loads in fileTable from fileTable_dump
00150 */
00151 
00152 static /*@notnull@*/ ftentry
00153 ftentry_create (/*@keep@*/ cstring tn, bool temp, fileType typ, fileId der)
00154 {
00155   ftentry t = (ftentry) dmalloc (sizeof (*t));
00156   
00157   if (cstring_isUndefined (tn))
00158     {
00159       llbug (cstring_makeLiteral ("Undefined filename!"));
00160     }
00161   
00162   t->fname = tn;
00163   
00164   t->basename = cstring_undefined;
00165   t->ftemp = temp;
00166   t->ftype = typ;
00167   t->fder  = der;
00168 
00169   /* Don't set these until the basename is needed. */
00170   t->fsystem = FALSE;
00171   t->fspecial = FALSE;
00172 
00173       return t;
00174 }
00175 
00176 static void
00177 ftentry_free (/*@only@*/ ftentry t)
00178 {
00179   cstring_free (t->fname);
00180   cstring_free (t->basename);
00181   sfree (t);
00182 }
00183 
00184 /*@only@*/ /*@notnull@*/ fileTable
00185 fileTable_create ()
00186 {
00187   fileTable ft = (fileTable) dmalloc (sizeof (*ft));
00188   
00189   ft->nentries = 0;
00190   ft->nspace = FTBASESIZE;
00191   ft->elements = (ftentry *) dmalloc (FTBASESIZE * sizeof (*ft->elements));
00192   ft->htable = hashTable_create (FTHASHSIZE);
00193   
00194   return (ft);
00195 }
00196 
00197 static void
00198 fileTable_grow (fileTable ft)
00199 {
00200   int i;
00201   ftentry *newent;
00202 
00203   llassert (fileTable_isDefined (ft));
00204 
00205   ft->nspace = FTBASESIZE;
00206 
00207   newent = (ftentry *) dmalloc ((ft->nentries + ft->nspace) * sizeof (*newent));
00208 
00209   for (i = 0; i < ft->nentries; i++)
00210     {
00211       newent[i] = ft->elements[i];
00212     }
00213 
00214   sfree (ft->elements);
00215   ft->elements = newent;
00216 }
00217 
00218 static fileId
00219 fileTable_internAddEntry (fileTable ft, /*@only@*/ ftentry e)
00220 {
00221   llassert (fileTable_isDefined (ft));
00222 
00223   if (ft->nspace <= 0)
00224     fileTable_grow (ft);
00225 
00226   ft->nspace--;
00227 
00228   hashTable_insert (ft->htable, e->fname, ft->nentries);
00229   ft->elements[ft->nentries] = e;
00230 
00231   ft->nentries++;
00232 
00233   return (ft->nentries - 1);
00234 }
00235 
00236 void fileTable_noDelete (fileTable ft, cstring name)
00237 {
00238   fileId fid = fileTable_lookup (ft, name);
00239 
00240   if (fileId_isValid (fid)) {
00241     llassert (fileTable_isDefined (ft));
00242 
00243     ft->elements[fid]->ftype = FILE_NODELETE;
00244   }
00245 }
00246 
00247 static fileId
00248 fileTable_addFilePrim (fileTable ft, /*@only@*/ cstring name, 
00249                        bool temp, fileType typ, fileId der)
00250    /*@modifies ft@*/
00251 {
00252   int tindex = fileTable_getIndex (ft, name);
00253 
00254   llassert (ft != fileTable_undefined);
00255 
00256   if (tindex != NOT_FOUND)
00257     {
00258       llcontbug (message ("fileTable_addFilePrim: duplicate entry: %q", name));
00259 
00260       return tindex;
00261     }
00262   else
00263     {
00264       ftentry e = ftentry_create (name, temp, typ, der);
00265       
00266       if (der == fileId_invalid)
00267         {
00268           llassert (cstring_isUndefined (e->basename));
00269 
00270           e->basename = cstring_fromChars
00271             (removePathFree (removeAnyExtension
00272                              (cstring_toCharsSafe (name))));
00273           e->fsystem = context_isSystemDir (name);
00274           e->fspecial = context_isSpecialFile (name);
00275 
00276           if (e->fspecial)
00277             {
00278               cstring srcname = cstring_concatFree (cstring_fromChars (removeAnyExtension (cstring_toCharsSafe (name))), cstring_makeLiteral (".c"));
00279               fileId fid = fileTable_lookup (ft, srcname);
00280 
00281               cstring_free (srcname);
00282 
00283               if (fileId_isValid (fid))
00284                 {
00285                   fileId derid = ft->elements[fid]->fder;
00286 
00287                   ft->elements[fid]->fspecial = TRUE;
00288 
00289                   if (fileId_isValid (derid))
00290                     {
00291                       ft->elements[derid]->fspecial = TRUE;
00292                     }
00293                 }
00294             }
00295         }
00296       else
00297         {
00298           ftentry de = ft->elements[der];
00299 
00300           llassert (cstring_isUndefined (e->basename));
00301           e->basename = cstring_copy (de->basename);
00302           e->fsystem = de->fsystem;
00303           e->fspecial = de->fspecial;
00304         }
00305 
00306       return (fileTable_internAddEntry (ft, e));
00307     }
00308 }
00309 
00310 fileId
00311 fileTable_addFile (fileTable ft, cstring name)
00312 {
00313   /* while (*name == '.' && *(name + 1) == '/') name += 2; */
00314   return (fileTable_addFilePrim (ft, cstring_copy (name), 
00315                                  FALSE, FILE_NORMAL, fileId_invalid));
00316 }
00317 
00318 fileId
00319 fileTable_addFileOnly (fileTable ft, /*@only@*/ cstring name)
00320 {
00321   return (fileTable_addFilePrim (ft, name, FALSE, FILE_NORMAL, fileId_invalid));
00322 }
00323 
00324 fileId
00325 fileTable_addHeaderFile (fileTable ft, cstring name)
00326 {
00327   DPRINTF (("Add header: %s", name));
00328   return (fileTable_addFilePrim (ft, cstring_copy (name), FALSE, 
00329                                  FILE_HEADER, fileId_invalid));
00330 }
00331 
00332 bool
00333 fileTable_isHeader (fileTable ft, fileId fid)
00334 {
00335   if (fileId_isInvalid (fid))
00336     {
00337       return FALSE;
00338     }
00339 
00340   llassert (fileTable_isDefined (ft) && fileTable_inRange (ft, fid));
00341   return (ft->elements[fid]->ftype == FILE_HEADER);
00342 }
00343 
00344 bool
00345 fileTable_isSystemFile (fileTable ft, fileId fid)
00346 {
00347   if (fileId_isInvalid (fid))
00348     {
00349       return FALSE;
00350     }
00351 
00352   llassert (fileTable_isDefined (ft) && fileTable_inRange (ft, fid));
00353   return (ft->elements[fid]->fsystem);
00354 }
00355 
00356 bool
00357 fileTable_isSpecialFile (fileTable ft, fileId fid)
00358 {
00359   if (fileId_isInvalid (fid))
00360     {
00361       return FALSE;
00362     }
00363 
00364   llassert (fileTable_isDefined (ft) && fileTable_inRange (ft, fid));
00365   return (ft->elements[fid]->fspecial);
00366 }
00367 
00368 fileId
00369 fileTable_addLibraryFile (fileTable ft, cstring name)
00370 {
00371   return (fileTable_addFilePrim (ft, cstring_copy (name),
00372                                  FALSE, FILE_HEADER, fileId_invalid));
00373 }
00374 
00375 # ifndef NOLCL
00376 fileId
00377 fileTable_addImportFile (fileTable ft, cstring name)
00378 {
00379   return (fileTable_addFilePrim (ft, cstring_copy (name), 
00380                                  FALSE, FILE_HEADER, fileId_invalid));
00381 }
00382 
00383 fileId
00384 fileTable_addLCLFile (fileTable ft, cstring name)
00385 {
00386   return (fileTable_addFilePrim (ft, cstring_copy (name), 
00387                                  FALSE, FILE_HEADER, fileId_invalid));
00388 }
00389 # endif
00390 
00391 # ifndef NOLCL
00392 static int tmpcounter = 0;
00393 # endif
00394 
00395 fileId
00396 fileTable_addMacrosFile (fileTable ft)
00397 {
00398   cstring newname = cstring_fromChars 
00399     (makeTempName (cstring_toCharsSafe (context_tmpdir ()), "lmx", ".llm"));
00400 
00401   return (fileTable_addFilePrim (ft, newname, TRUE, FILE_MACROS, fileId_invalid));
00402 }
00403 
00404 fileId
00405 fileTable_addCTempFile (fileTable ft, fileId fid)
00406 {
00407 # if FALSE
00408   /* Can't control output file name for cl preprocessor */
00409   cstring newname = cstring_concatChars (removeAnyExtension (fileName (fid)), ".i");
00410 # else
00411   cstring newname = cstring_fromChars 
00412     (makeTempName (cstring_toCharsSafe (context_tmpdir ()), "cl", ".c"));
00413 # endif
00414 
00415   llassert (fileTable_isDefined (ft));
00416 
00417   if (!fileId_isValid (ft->elements[fid]->fder))
00418     {
00419       return (fileTable_addFilePrim (ft, newname, TRUE, FILE_NORMAL, fid));
00420     }
00421   else 
00422     {
00423       return (fileTable_addFilePrim (ft, newname, TRUE, FILE_NORMAL,
00424                                      ft->elements[fid]->fder));
00425     }
00426 }
00427 
00428 # ifndef NOLCL
00429 fileId
00430 fileTable_addltemp (fileTable ft)
00431 {
00432   char *newname = makeTempName (cstring_toCharsSafe (context_tmpdir ()),
00433                                 "ls", ".lsl");
00434   char *onewname;
00435   fileId ret;
00436   
00437   if (cstring_hasNonAlphaNumBar (cstring_fromChars (newname)))
00438     {
00439       char *lastpath = (char *)NULL;
00440 
00441       if (tmpcounter == 0)
00442         {
00443           lldiagmsg
00444             (message
00445              ("Operating system generates tmp filename containing invalid charater: %s",
00446               cstring_fromChars (newname)));
00447           lldiagmsg (cstring_makeLiteral 
00448                      ("Try cleaning up the tmp directory.  Attempting to continue."));
00449         }
00450       
00451       lastpath = strrchr (newname, CONNECTCHAR); /* get the directory */
00452       llassert (lastpath != NULL);
00453       *lastpath = '\0';
00454 
00455       onewname = newname;
00456       newname = cstring_toCharsSafe (message ("%s%hlsl%d.lsl", 
00457                                               cstring_fromChars (newname),
00458                                               CONNECTCHAR,
00459                                               tmpcounter));
00460       sfree (onewname);
00461       tmpcounter++;
00462     }
00463   
00464   /*
00465   ** this is kind of yucky...need to make the result of cstring_fromChars
00466   ** refer to the same storage as its argument.  Of course, this loses,
00467   ** since cstring is abstract.  Should make it an only?
00468   */
00469 
00470   ret = fileTable_addFilePrim (ft, cstring_copy (cstring_fromChars (newname)),
00471                                TRUE, FILE_LSLTEMP, fileId_invalid);
00472   sfree (newname);
00473   return (ret);
00474 }
00475 # endif
00476 
00477 bool
00478 fileTable_exists (fileTable ft, cstring s)
00479 {
00480   int tindex = fileTable_getIndex (ft, s);
00481 
00482   if (tindex == NOT_FOUND)
00483     return FALSE;
00484   else
00485     return TRUE;
00486 }
00487 
00488 fileId
00489 fileTable_lookup (fileTable ft, cstring s)
00490 {
00491   int tindex = fileTable_getIndex (ft, s);
00492 
00493   if (tindex == NOT_FOUND)
00494     {
00495       return fileId_invalid;
00496     }
00497   else
00498     {
00499       return tindex;
00500     }
00501 }
00502 
00503 fileId
00504 fileTable_lookupBase (fileTable ft, cstring base)
00505 {
00506   int tindex = fileTable_getIndex (ft, base);
00507 
00508   if (tindex == NOT_FOUND)
00509     {
00510       
00511       return fileId_invalid;
00512     }
00513   else
00514     {
00515       fileId der;
00516 
00517       llassert (fileTable_isDefined (ft));
00518 
00519       der = ft->elements[tindex]->fder;
00520       
00521       if (!fileId_isValid (der))
00522         {
00523           der = tindex;
00524         }
00525 
00526       return der; 
00527     }
00528 }
00529 
00530 cstring
00531 fileTable_getName (fileTable ft, fileId fid)
00532 {
00533   if (!fileId_isValid (fid))
00534     {
00535       llcontbug 
00536         (message ("fileTable_getName: called with invalid type id: %d", fid));
00537       return cstring_makeLiteralTemp ("<invalid>");
00538     }
00539 
00540   llassert (fileTable_isDefined (ft));
00541   return (ft->elements[fid]->fname);
00542 }
00543 
00544 cstring
00545 fileTable_getRootName (fileTable ft, fileId fid)
00546 {
00547   fileId fder;
00548 
00549   if (!fileId_isValid (fid))
00550     {
00551       llcontbug (message ("fileTable_getName: called with invalid id: %d", fid));
00552       return cstring_makeLiteralTemp ("<invalid>");
00553     }
00554 
00555   if (!fileTable_isDefined (ft))
00556     {
00557       return cstring_makeLiteralTemp ("<no file table>");
00558     }
00559 
00560   fder = ft->elements[fid]->fder;
00561 
00562   if (fileId_isValid (fder))
00563     {
00564       return (ft->elements[fder]->fname);
00565     }
00566   else
00567     {
00568       return (ft->elements[fid]->fname);
00569     }
00570 }
00571 
00572 cstring
00573 fileTable_getNameBase (fileTable ft, fileId fid)
00574 {
00575   if (!fileId_isValid (fid))
00576     {
00577       llcontbug (message ("fileTable_getName: called with invalid id: %d", fid));
00578       return cstring_makeLiteralTemp ("<invalid>");
00579     }
00580   
00581   if (!fileTable_isDefined (ft))
00582     {
00583       return cstring_makeLiteralTemp ("<no file table>");
00584     }
00585   
00586   return (ft->elements[fid]->basename);
00587 }
00588 
00589 bool
00590 fileTable_sameBase (fileTable ft, fileId f1, fileId f2)
00591 {
00592   fileId fd1, fd2;
00593 
00594   if (!fileId_isValid (f1))
00595     {
00596       return FALSE;
00597     }
00598 
00599   if (!fileId_isValid (f2))
00600     {
00601       return FALSE;
00602     }
00603 
00604   llassert (fileTable_isDefined (ft));
00605 
00606   if (f1 == f2) 
00607     {
00608       return TRUE;
00609     }
00610 
00611   fd1 = ft->elements[f1]->fder;
00612 
00613   if (!fileId_isValid (fd1))
00614     {
00615       fd1 = f1;
00616     }
00617 
00618   fd2 = ft->elements[f2]->fder;
00619 
00620 
00621   if (!fileId_isValid (fd2))
00622     {
00623       fd2 = f2;
00624     }
00625 
00626   return (fd1 == fd2);
00627 }
00628 
00629 void
00630 fileTable_cleanup (fileTable ft)
00631 {
00632   int i;
00633   bool msg;
00634   int skip;
00635   
00636   llassert (fileTable_isDefined (ft));
00637 
00638   msg = ((ft->nentries > 40) && context_getFlag (FLG_SHOWSCAN));
00639   skip = ft->nentries / 10;
00640 
00641   if (msg)
00642     {
00643       (void) fflush (g_msgstream);
00644       fprintf (stderr, "< cleaning");
00645     }
00646 
00647   for (i = 0; i < ft->nentries; i++)
00648     {
00649       ftentry fe = ft->elements[i];
00650 
00651       if (fe->ftemp)
00652         {
00653           /* let's be real careful now, hon! */
00654           
00655           /*
00656           ** Make sure it is really a derived file
00657           */
00658           
00659           if (fe->ftype == FILE_LSLTEMP || fe->ftype == FILE_NODELETE)
00660             {
00661               ; /* already removed */ 
00662             }
00663           else if (fileId_isValid (fe->fder)) 
00664             {
00665               (void) osd_unlink (cstring_toCharsSafe (fe->fname));
00666             }
00667           else if (fe->ftype == FILE_MACROS)
00668             {
00669               (void) osd_unlink (cstring_toCharsSafe (fe->fname));
00670             }
00671           else
00672             {
00673               llbug (message ("Temporary file is not derivative: %s "
00674                               "(not deleted)", fe->fname));
00675             }
00676         }
00677       else
00678         {
00679           ;
00680         }
00681 
00682       if (msg && ((i % skip) == 0))
00683         {
00684           (void) fflush (g_msgstream);
00685 
00686           if (i == 0) {
00687             fprintf (stderr, " ");
00688           } else {
00689             fprintf (stderr, ".");
00690           }
00691 
00692           (void) fflush (stderr);
00693         }
00694     }
00695   
00696   if (msg)
00697     {
00698       fprintf (stderr, " >\n");
00699     }
00700 }
00701 
00702 void
00703 fileTable_free (/*@only@*/ fileTable f)
00704 {
00705   int i = 0;
00706   
00707   if (f == (fileTable)NULL) 
00708     {
00709       return;
00710     }
00711 
00712   while ( i < f->nentries ) 
00713     {
00714       ftentry_free (f->elements[i]);
00715       i++;
00716     }
00717   
00718   hashTable_free (f->htable);
00719   sfree (f->elements);
00720   sfree (f);
00721 }
00722 
00723 /*
00724 ** unique temp filename are constructed from <dir><pre><pid><msg>.<suf>
00725 ** requires: <dir> must end in '/'
00726 */
00727 
00728 static void nextMsg (char *msg)
00729 {
00730   /*@+charint@*/
00731   if (msg[0] < 'Z') 
00732     {
00733       msg[0]++; 
00734     }
00735   else 
00736     {
00737       msg[0] = 'A';
00738       if (msg[1] < 'Z')
00739         { 
00740           msg[1]++; 
00741         }
00742       else
00743         {
00744           msg[1] = 'A';
00745           if (msg[2] < 'Z') 
00746             {
00747               msg[2]++;
00748             }
00749           else
00750             {
00751               msg[2] = 'A';
00752               if (msg[3] < 'Z') 
00753                 {
00754                   msg[3]++; 
00755                 }
00756               else
00757                 {
00758                   llassertprint (FALSE, ("nextMsg: out of unique names!!!"));
00759                 }
00760             }
00761         }
00762     }
00763   /*@-charint@*/
00764 }
00765 
00766 static /*@only@*/ char *makeTempName (char *dir, char *pre, char *suf)
00767 {
00768   static int pid = 0; 
00769   static /*@owned@*/ char *msg = NULL; 
00770   static /*@only@*/ char *pidname = NULL;
00771   size_t maxlen;
00772   char *buf;
00773 
00774   llassert (strlen (pre) <= 3);
00775 
00776   /*
00777   ** We limit the temp name to 8 characters:
00778   **   pre: 3 or less
00779   **   msg: 3
00780   **   pid: 2  (% 100)
00781   */
00782 
00783   if (msg == NULL)
00784     {
00785       msg = mstring_copy ("AAA"); /* there are 26^3 temp names */
00786     }
00787 
00788   if (pid == 0) 
00789     {
00790       /*@+matchanyintegral@*/
00791       pid = osd_getPid ();
00792       /*@=matchanyintegral@*/
00793     }
00794 
00795   if (pidname == NULL) 
00796     {
00797       pidname = cstring_toCharsSafe (message ("%d", pid % 100));
00798     }
00799   else 
00800     {
00801       pidname = mstring_createEmpty ();
00802     }
00803   
00804   maxlen = (strlen (dir) + strlen (pre) + strlen (msg) 
00805             + strlen (pidname) + strlen (suf) + 2);
00806 
00807   buf = mstring_create (size_toInt (maxlen));
00808 
00809   sprintf (buf, "%s%s%s%s%s", dir, pre, pidname, msg, suf);
00810   nextMsg (msg);
00811 
00812   while (osd_fileExists (buf))
00813     {
00814       sprintf (buf, "%s%s%s%s%s", dir, pre, pidname, msg, suf);
00815       nextMsg (msg);
00816     }
00817 
00818   return buf;
00819 }
00820   
00821 
00822 

Generated at Fri Nov 3 18:57:41 2000 for LCLint by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000