]> andersk Git - splint.git/blob - src/fileTable.c
*** empty log message ***
[splint.git] / src / fileTable.c
1 /*
2 ** LCLint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2001 University of Virginia,
4 **         Massachusetts Institute of Technology
5 **
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
10 ** 
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 ** General Public License for more details.
15 ** 
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
19 **
20 ** For information on lclint: lclint-request@cs.virginia.edu
21 ** To report a bug: lclint-bug@cs.virginia.edu
22 ** For more information: http://lclint.cs.virginia.edu
23 */
24 /*
25 ** fileTable.c
26 **
27 ** replaces filenamemap.c
28 ** based (loosely) on typeTable.c
29 **
30 ** entries in the fileTable are:
31 **
32 **        name - name of the file
33 **        type - kind of file (a temp file to be deleted?)
34 **        link - derived from this file
35 **
36 */
37 /*
38  * Herbert 04/1997:
39  * - Added conditional stuff (macros OS2 and MSDOS) to make names of temporary 
40  *   files under Windows or OS/2 not larger than 8+3 characters to avoid 
41  *   trouble with FAT file systems or Novell Netware volumes.
42  * - Added include of new header file portab.h containing OS dependent stuff.
43  * - Changed occurance of '/' as path delimiter to a macro.
44  * - Added conditional stuff (#define and #include) for IBM's compiler.
45  */
46
47 # include "lclintMacros.nf"
48 # include "llbasic.h"
49 # include "osd.h"
50 # include "llmain.h"
51 # include "portab.h"
52 # if defined(__IBMC__) && defined(OS2)
53 # include <process.h>
54 # define getpid _getpid
55 # endif
56
57 /*@access fileId*/
58
59 static bool fileTable_inRange (fileTable ft, fileId fid) /*@*/ 
60 {
61   return (fileTable_isDefined (ft) && (fid >= 0) && (fid < ft->nentries));
62 }
63
64 static fileId fileTable_internAddEntry (fileTable p_ft, /*@only@*/ ftentry p_e) 
65    /*@modifies p_ft@*/ ;
66 static /*@only@*/ cstring makeTempName (cstring p_dir, cstring p_pre, cstring p_suf);
67
68 static /*@only@*/ cstring
69 fileType_unparse (fileType ft)
70 {
71   switch (ft)
72     {
73     case FILE_NORMAL:  return cstring_makeLiteral ("normal");
74     case FILE_NODELETE:  return cstring_makeLiteral ("normal");
75     case FILE_LSLTEMP: return cstring_makeLiteral ("ltemp");
76     case FILE_HEADER:  return cstring_makeLiteral ("header");
77     case FILE_XH:  return cstring_makeLiteral ("xh");
78     case FILE_MACROS:  return cstring_makeLiteral ("macros");
79     case FILE_METASTATE:  return cstring_makeLiteral ("metastate");
80     }
81
82   BADEXIT;
83 }
84
85 static int
86 fileTable_getIndex (fileTable ft, cstring s)
87 {
88   if (ft == NULL) return NOT_FOUND;
89   return (cstringTable_lookup (ft->htable, s));
90 }
91
92 /*@only@*/ cstring
93 fileTable_unparse (fileTable ft)
94 {
95   cstring s = cstring_undefined;
96   int i;
97
98   if (fileTable_isUndefined (ft))
99     {
100       return (cstring_makeLiteral ("<fileTable undefined>"));
101     }
102
103   for (i = 0; i < ft->nentries; i++)
104     {
105       if (fileId_isValid (ft->elements[i]->fder))
106         {
107           s = message ("%s\n[%d] %s %q %d (%s)", 
108                        s, i, 
109                        ft->elements[i]->fname, 
110                        fileType_unparse (ft->elements[i]->ftype),
111                        ft->elements[i]->fder,
112                        ft->elements[ft->elements[i]->fder]->fname);
113         }
114       else
115         {
116           s = message ("%s\n[%d] %s %q", s, i, ft->elements[i]->fname,
117                        fileType_unparse (ft->elements[i]->ftype));
118         }
119           }
120
121   return s;
122 }
123
124 void fileTable_printTemps (fileTable ft)
125 {
126   if (fileTable_isDefined (ft))
127     {
128       int i;
129
130       for (i = 0; i < ft->nentries; i++)
131         {
132           if (ft->elements[i]->ftemp)
133             {
134               if (fileId_isValid (ft->elements[i]->fder))
135                 {
136                   fprintf (stderr, "  %s:1\n\t%s:1\n", 
137                            cstring_toCharsSafe (ft->elements[ft->elements[i]->fder]->fname),
138                            cstring_toCharsSafe (ft->elements[i]->fname));
139                 }
140               else
141                 {
142                   fprintf (stderr, "[no file]\n\t%s:1\n",
143                            cstring_toCharsSafe (ft->elements[i]->fname));
144                 }
145             }
146         }
147     }
148 }
149
150 /*
151 ** loads in fileTable from fileTable_dump
152 */
153
154 static /*@notnull@*/ ftentry
155 ftentry_create (/*@keep@*/ cstring tn, bool temp, fileType typ, fileId der)
156 {
157   ftentry t = (ftentry) dmalloc (sizeof (*t));
158   
159   if (cstring_isUndefined (tn))
160     {
161       llbug (cstring_makeLiteral ("Undefined filename!"));
162     }
163   
164   t->fname = tn;
165   
166   t->basename = cstring_undefined;
167   t->ftemp = temp;
168   t->ftype = typ;
169   t->fder  = der;
170
171   /* Don't set these until the basename is needed. */
172   t->fsystem = FALSE;
173   t->fspecial = FALSE;
174
175   return t;
176 }
177
178 static void
179 ftentry_free (/*@only@*/ ftentry t)
180 {
181   cstring_free (t->fname);
182   cstring_free (t->basename);
183   sfree (t);
184 }
185
186 /*@only@*/ /*@notnull@*/ fileTable
187 fileTable_create ()
188 {
189   fileTable ft = (fileTable) dmalloc (sizeof (*ft));
190   
191   ft->nentries = 0;
192   ft->nspace = FTBASESIZE;
193   ft->elements = (ftentry *) dmalloc (FTBASESIZE * sizeof (*ft->elements));
194   ft->htable = cstringTable_create (FTHASHSIZE);
195   
196   return (ft);
197 }
198
199 static void
200 fileTable_grow (fileTable ft)
201 {
202   int i;
203   ftentry *newent;
204
205   llassert (fileTable_isDefined (ft));
206
207   ft->nspace = FTBASESIZE;
208
209   newent = (ftentry *) dmalloc ((ft->nentries + ft->nspace) * sizeof (*newent));
210
211   for (i = 0; i < ft->nentries; i++)
212     {
213       newent[i] = ft->elements[i];
214     }
215
216   sfree (ft->elements);
217   ft->elements = newent;
218 }
219
220 static fileId
221 fileTable_internAddEntry (fileTable ft, /*@only@*/ ftentry e)
222 {
223   llassert (fileTable_isDefined (ft));
224
225   if (ft->nspace <= 0)
226     fileTable_grow (ft);
227
228   ft->nspace--;
229
230   cstringTable_insert (ft->htable, e->fname, ft->nentries);
231   ft->elements[ft->nentries] = e;
232
233   ft->nentries++;
234   return (ft->nentries - 1);
235 }
236
237 void fileTable_noDelete (fileTable ft, cstring name)
238 {
239   fileId fid = fileTable_lookup (ft, name);
240
241   if (fileId_isValid (fid)) {
242     llassert (fileTable_isDefined (ft));
243
244     ft->elements[fid]->ftype = FILE_NODELETE;
245   }
246 }
247
248 static fileId
249 fileTable_addFilePrim (fileTable ft, /*@only@*/ cstring name, 
250                        bool temp, fileType typ, fileId der)
251    /*@modifies ft@*/
252 {
253   int tindex = fileTable_getIndex (ft, name);
254
255   llassert (ft != fileTable_undefined);
256
257   if (tindex != NOT_FOUND)
258     {
259       llcontbug (message ("fileTable_addFilePrim: duplicate entry: %q", name));
260
261       return tindex;
262     }
263   else
264     {
265       ftentry e = ftentry_create (name, temp, typ, der);
266
267       if (der == fileId_invalid)
268         {
269           llassert (cstring_isUndefined (e->basename));
270
271           e->basename = fileLib_removePathFree (fileLib_removeAnyExtension (name));
272           e->fsystem = context_isSystemDir (name);
273           e->fspecial = context_isSpecialFile (name);
274
275           if (e->fspecial)
276             {
277               cstring srcname = cstring_concatFree1 (fileLib_removeAnyExtension (name), 
278                                                      C_EXTENSION);
279               fileId fid = fileTable_lookup (ft, srcname);
280
281               cstring_free (srcname);
282
283               if (fileId_isValid (fid))
284                 {
285                   fileId derid = ft->elements[fid]->fder;
286
287                   ft->elements[fid]->fspecial = TRUE;
288
289                   if (fileId_isValid (derid))
290                     {
291                       ft->elements[derid]->fspecial = TRUE;
292                     }
293                 }
294             }
295         }
296       else
297         {
298           ftentry de = ft->elements[der];
299
300           llassert (cstring_isUndefined (e->basename));
301           e->basename = cstring_copy (de->basename);
302           e->fsystem = de->fsystem;
303           e->fspecial = de->fspecial;
304         }
305
306       return (fileTable_internAddEntry (ft, e));
307     }
308 }
309
310 fileId
311 fileTable_addFile (fileTable ft, cstring name)
312 {
313   /* while (*name == '.' && *(name + 1) == '/') name += 2; */
314
315   return (fileTable_addFilePrim (ft, cstring_copy (name), 
316                                  FALSE, FILE_NORMAL, fileId_invalid));
317 }
318
319 fileId
320 fileTable_addFileOnly (fileTable ft, /*@only@*/ cstring name)
321 {
322   return (fileTable_addFilePrim (ft, name, FALSE, FILE_NORMAL, fileId_invalid));
323 }
324
325 fileId
326 fileTable_addHeaderFile (fileTable ft, cstring name)
327 {
328   fileId res;
329
330   res = fileTable_addFilePrim (ft, cstring_copy (name), FALSE, 
331                                FILE_HEADER, fileId_invalid);
332   return res;
333
334 }
335
336 bool
337 fileTable_isHeader (fileTable ft, fileId fid)
338 {
339   if (fileId_isInvalid (fid))
340     {
341       return FALSE;
342     }
343
344   llassert (fileTable_isDefined (ft) && fileTable_inRange (ft, fid));
345   return (ft->elements[fid]->ftype == FILE_HEADER);
346 }
347
348 bool
349 fileTable_isSystemFile (fileTable ft, fileId fid)
350 {
351   if (fileId_isInvalid (fid))
352     {
353       return FALSE;
354     }
355
356   llassert (fileTable_isDefined (ft) && fileTable_inRange (ft, fid));
357   return (ft->elements[fid]->fsystem);
358 }
359
360 bool
361 fileTable_isXHFile (fileTable ft, fileId fid)
362 {
363   if (fileId_isInvalid (fid))
364     {
365       return FALSE;
366     }
367
368   if (!(fileTable_isDefined (ft) && fileTable_inRange (ft, fid)))
369     {
370       llcontbug (message ("Bad file table or id: %s %d", bool_unparse (fileTable_isDefined (ft)), fid));
371       return FALSE;
372     }
373   else
374     {
375       return (ft->elements[fid]->ftype == FILE_XH);
376     }
377 }
378
379 bool
380 fileTable_isSpecialFile (fileTable ft, fileId fid)
381 {
382   if (fileId_isInvalid (fid))
383     {
384       return FALSE;
385     }
386   
387   llassert (fileTable_isDefined (ft) && fileTable_inRange (ft, fid));
388   return (ft->elements[fid]->fspecial);
389 }
390
391 fileId
392 fileTable_addLibraryFile (fileTable ft, cstring name)
393 {
394   return (fileTable_addFilePrim (ft, cstring_copy (name),
395                                  FALSE, FILE_HEADER, fileId_invalid));
396 }
397
398 fileId
399 fileTable_addXHFile (fileTable ft, cstring name)
400 {
401   return (fileTable_addFilePrim (ft, cstring_copy (name),
402                                  FALSE, FILE_XH, fileId_invalid));
403 }
404
405 # ifndef NOLCL
406 fileId
407 fileTable_addImportFile (fileTable ft, cstring name)
408 {
409   return (fileTable_addFilePrim (ft, cstring_copy (name), 
410                                  FALSE, FILE_HEADER, fileId_invalid));
411 }
412
413 fileId
414 fileTable_addLCLFile (fileTable ft, cstring name)
415 {
416   return (fileTable_addFilePrim (ft, cstring_copy (name), 
417                                  FALSE, FILE_HEADER, fileId_invalid));
418 }
419 # endif
420
421 # ifndef NOLCL
422 static int tmpcounter = 0;
423 # endif
424
425 fileId
426 fileTable_addMacrosFile (fileTable ft)
427 {
428   cstring newname =
429     makeTempName (context_tmpdir (), cstring_makeLiteralTemp ("lmx"),
430                   cstring_makeLiteralTemp (".llm"));
431
432   return (fileTable_addFilePrim (ft, newname, TRUE, FILE_MACROS, fileId_invalid));
433 }
434
435 fileId
436 fileTable_addMetastateFile (fileTable ft, cstring name)
437 {
438   return (fileTable_addFilePrim (ft, cstring_copy (name), 
439                                  FALSE, FILE_METASTATE, fileId_invalid));
440 }
441
442 fileId
443 fileTable_addCTempFile (fileTable ft, fileId fid)
444 {
445 # if FALSE
446   /* Can't control output file name for cl preprocessor */
447   cstring newname = cstring_concatChars (fileLib_removeAnyExtension (fileName (fid)), ".i");
448 # else
449   cstring newname =
450     makeTempName (context_tmpdir (), cstring_makeLiteralTemp ("cl"), 
451                   C_EXTENSION);
452 # endif
453
454   llassert (fileTable_isDefined (ft));
455
456   if (!fileId_isValid (ft->elements[fid]->fder))
457     {
458       if (fileTable_isXHFile (ft, fid))
459         {
460           return (fileTable_addFilePrim (ft, newname, TRUE, FILE_XH, fid));
461         }
462       else
463         {
464           return (fileTable_addFilePrim (ft, newname, TRUE, FILE_NORMAL, fid));
465         }
466     }
467   else 
468     {
469       if (fileTable_isXHFile (ft, fid))
470         {
471           return (fileTable_addFilePrim (ft, newname, TRUE, FILE_XH,
472                                          ft->elements[fid]->fder));
473         }
474       else
475         {
476           return (fileTable_addFilePrim (ft, newname, TRUE, FILE_NORMAL,
477                                          ft->elements[fid]->fder));
478         }
479     }
480 }
481
482 # ifndef NOLCL
483 fileId
484 fileTable_addltemp (fileTable ft)
485 {
486   cstring newname = makeTempName (context_tmpdir (),
487                                   cstring_makeLiteralTemp ("ls"), 
488                                   cstring_makeLiteralTemp (".lsl"));
489   fileId ret;
490   
491   if (cstring_hasNonAlphaNumBar (newname))
492     {
493       char *lastpath = (char *)NULL;
494
495       if (tmpcounter == 0)
496         {
497           lldiagmsg
498             (message
499              ("Operating system generates tmp filename containing invalid charater: %s",
500               newname));
501           lldiagmsg (cstring_makeLiteral 
502                      ("Try cleaning up the tmp directory.  Attempting to continue."));
503         }
504       
505       /*@access cstring@*/
506       llassert (cstring_isDefined (newname));
507       lastpath = strrchr (newname, CONNECTCHAR); /* get the directory */
508       llassert (lastpath != NULL);
509       *lastpath = '\0';
510
511       newname = message ("%q%hlsl%d.lsl", 
512                          newname,
513                          CONNECTCHAR,
514                          tmpcounter);
515       /*@noaccess cstring@*/
516       tmpcounter++;
517     }
518   
519   /*
520   ** this is kind of yucky...need to make the result of cstring_fromChars
521   ** refer to the same storage as its argument.  Of course, this loses,
522   ** since cstring is abstract.  Should make it an only?
523   */
524
525   ret = fileTable_addFilePrim (ft, cstring_copy (newname),
526                                TRUE, FILE_LSLTEMP, fileId_invalid);
527   cstring_free (newname);
528   return (ret);
529 }
530 # endif
531
532 bool
533 fileTable_exists (fileTable ft, cstring s)
534 {
535   int tindex = fileTable_getIndex (ft, s);
536
537   if (tindex == NOT_FOUND)
538     return FALSE;
539   else
540     return TRUE;
541 }
542
543 fileId
544 fileTable_lookup (fileTable ft, cstring s)
545 {
546   int tindex = fileTable_getIndex (ft, s);
547
548   if (tindex == NOT_FOUND)
549     {
550       return fileId_invalid;
551     }
552   else
553     {
554       return tindex;
555     }
556 }
557
558 /*
559 ** This is pretty awkward --- when we find the real path of 
560 ** a .xh file, we may need to change the recorded name.  [Sigh]
561 */
562
563 void
564 fileTable_setFilePath (fileTable ft, fileId fid, cstring path)
565 {
566   llassert (fileId_isValid (fid));
567   llassert (fileTable_isDefined (ft));
568   /* Need to put new string in hash table */
569   cstringTable_insert (ft->htable, cstring_copy (path), fid);
570   ft->elements[fid]->fname = cstring_copy (path);
571 }
572
573 fileId
574 fileTable_lookupBase (fileTable ft, cstring base)
575 {
576   int tindex = fileTable_getIndex (ft, base);
577
578   if (tindex == NOT_FOUND)
579     {
580       return fileId_invalid;
581     }
582   else
583     {
584       fileId der;
585
586       llassert (fileTable_isDefined (ft));
587
588       der = ft->elements[tindex]->fder;
589       
590       if (!fileId_isValid (der))
591         {
592           der = tindex;
593         }
594
595       return der; 
596     }
597 }
598
599 cstring
600 fileTable_getName (fileTable ft, fileId fid)
601 {
602   if (!fileId_isValid (fid))
603     {
604       llcontbug 
605         (message ("fileTable_getName: called with invalid type id: %d", fid));
606       return cstring_makeLiteralTemp ("<invalid>");
607     }
608
609   llassert (fileTable_isDefined (ft));
610   return (ft->elements[fid]->fname);
611 }
612
613 cstring
614 fileTable_getRootName (fileTable ft, fileId fid)
615 {
616   fileId fder;
617
618   if (!fileId_isValid (fid))
619     {
620       llcontbug (message ("fileTable_getName: called with invalid id: %d", fid));
621       return cstring_makeLiteralTemp ("<invalid>");
622     }
623
624   if (!fileTable_isDefined (ft))
625     {
626       return cstring_makeLiteralTemp ("<no file table>");
627     }
628
629   fder = ft->elements[fid]->fder;
630
631   if (fileId_isValid (fder))
632     {
633       return (ft->elements[fder]->fname);
634     }
635   else
636     {
637       return (ft->elements[fid]->fname);
638     }
639 }
640
641 cstring
642 fileTable_getNameBase (fileTable ft, fileId fid)
643 {
644   if (!fileId_isValid (fid))
645     {
646       llcontbug (message ("fileTable_getName: called with invalid id: %d", fid));
647       return cstring_makeLiteralTemp ("<invalid>");
648     }
649   
650   if (!fileTable_isDefined (ft))
651     {
652       return cstring_makeLiteralTemp ("<no file table>");
653     }
654   
655   return (ft->elements[fid]->basename);
656 }
657
658 bool
659 fileTable_sameBase (fileTable ft, fileId f1, fileId f2)
660 {
661   fileId fd1, fd2;
662
663   if (!fileId_isValid (f1))
664     {
665       return FALSE;
666     }
667
668   if (!fileId_isValid (f2))
669     {
670       return FALSE;
671     }
672
673   llassert (fileTable_isDefined (ft));
674
675   if (f1 == f2) 
676     {
677       return TRUE;
678     }
679
680   fd1 = ft->elements[f1]->fder;
681
682   if (!fileId_isValid (fd1))
683     {
684       fd1 = f1;
685     }
686
687   fd2 = ft->elements[f2]->fder;
688
689
690   if (!fileId_isValid (fd2))
691     {
692       fd2 = f2;
693     }
694
695   return (fd1 == fd2);
696 }
697
698 void
699 fileTable_cleanup (fileTable ft)
700 {
701   int i;
702   bool msg;
703   int skip;
704   
705   llassert (fileTable_isDefined (ft));
706
707   msg = ((ft->nentries > 40) && context_getFlag (FLG_SHOWSCAN));
708   skip = ft->nentries / 10;
709
710   if (msg)
711     {
712       (void) fflush (g_msgstream);
713       fprintf (stderr, "< cleaning");
714     }
715
716   for (i = 0; i < ft->nentries; i++)
717     {
718       ftentry fe = ft->elements[i];
719
720       if (fe->ftemp)
721         {
722           /* let's be real careful now, hon! */
723           
724           /*
725           ** Make sure it is really a derived file
726           */
727           
728           if (fe->ftype == FILE_LSLTEMP || fe->ftype == FILE_NODELETE)
729             {
730               ; /* already removed */ 
731             }
732           else if (fileId_isValid (fe->fder)) 
733             {
734               /*@i423 this should use close (fd) also... */
735               (void) osd_unlink (fe->fname);
736             }
737           else if (fe->ftype == FILE_MACROS)
738             {
739               (void) osd_unlink (fe->fname);
740             }
741           else
742             {
743               llbug (message ("Temporary file is not derivative: %s "
744                               "(not deleted)", fe->fname));
745             }
746         }
747       else
748         {
749           ;
750         }
751
752       if (msg && ((i % skip) == 0))
753         {
754           (void) fflush (g_msgstream);
755
756           if (i == 0) {
757             fprintf (stderr, " ");
758           } else {
759             fprintf (stderr, ".");
760           }
761
762           (void) fflush (stderr);
763         }
764     }
765   
766   if (msg)
767     {
768       fprintf (stderr, " >\n");
769     }
770 }
771
772 void
773 fileTable_free (/*@only@*/ fileTable f)
774 {
775   int i = 0;
776   
777   if (f == (fileTable)NULL) 
778     {
779       return;
780     }
781
782   while ( i < f->nentries ) 
783     {
784       ftentry_free (f->elements[i]);
785       i++;
786     }
787   
788   cstringTable_free (f->htable);
789   sfree (f->elements);
790   sfree (f);
791 }
792
793 /*
794 ** unique temp filename are constructed from <dir><pre><pid><msg>.<suf>
795 ** requires: <dir> must end in '/'
796 */
797
798 static void nextMsg (char *msg)
799 {
800   /*@+charint@*/
801   if (msg[0] < 'Z') 
802     {
803       msg[0]++; 
804     }
805   else 
806     {
807       msg[0] = 'A';
808       if (msg[1] < 'Z')
809         { 
810           msg[1]++; 
811         }
812       else
813         {
814           msg[1] = 'A';
815           if (msg[2] < 'Z') 
816             {
817               msg[2]++;
818             }
819           else
820             {
821               msg[2] = 'A';
822               if (msg[3] < 'Z') 
823                 {
824                   msg[3]++; 
825                 }
826               else
827                 {
828                   llassertprint (FALSE, ("nextMsg: out of unique names!!!"));
829                 }
830             }
831         }
832     }
833   /*@-charint@*/
834 }
835
836 static /*@only@*/ cstring makeTempName (cstring dir, cstring pre, cstring suf)
837 {
838   static int pid = 0; 
839   static /*@owned@*/ char *msg = NULL; 
840   static /*@only@*/ cstring pidname = NULL;
841   int maxlen;
842   cstring smsg;
843
844   llassert (cstring_length (pre) <= 3);
845
846   /*
847   ** We limit the temp name to 8 characters:
848   **   pre: 3 or less
849   **   msg: 3
850   **   pid: 2  (% 100)
851   */
852
853   if (msg == NULL)
854     {
855       msg = mstring_copy ("AAA"); /* there are 26^3 temp names */
856     }
857
858   if (pid == 0) 
859     {
860       /*@+matchanyintegral@*/
861       pid = osd_getPid ();
862       /*@=matchanyintegral@*/
863     }
864
865   if (cstring_isUndefined (pidname)) 
866     {
867       pidname = message ("%d", pid % 100);
868     }
869   
870   maxlen = (cstring_length (dir) + cstring_length (pre) + mstring_length (msg) 
871             + cstring_length (pidname) + cstring_length (suf) + 2);
872
873   smsg = message ("%s%s%s%s%s", dir, pre, pidname, cstring_fromChars (msg), suf);
874   nextMsg (msg);
875
876   while (osd_fileExists (smsg))
877     {
878       cstring_free (smsg);
879       smsg = message ("%s%s%s%s%s", dir, pre, pidname, cstring_fromChars (msg), suf);
880       nextMsg (msg);
881     }
882   
883
884   return smsg;
885 }
This page took 0.112764 seconds and 5 git commands to generate.