~ubuntu-branches/ubuntu/karmic/ncbi-tools6/karmic

« back to all changes in this revision

Viewing changes to corelib/ncbifile.c

  • Committer: Bazaar Package Importer
  • Author(s): Aaron M. Ucko
  • Date: 2005-03-27 12:00:15 UTC
  • mfrom: (2.1.2 hoary)
  • Revision ID: james.westby@ubuntu.com-20050327120015-embhesp32nj73p9r
Tags: 6.1.20041020-3
* Fix FTBFS under GCC 4.0 caused by inconsistent use of "static" on
  functions.  (Closes: #295110.)
* Add a watch file, now that we can.  (Upstream's layout needs version=3.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
*
30
30
* Version Creation Date:   3/4/91
31
31
*
32
 
* $Revision: 6.23 $
 
32
* $Revision: 6.37 $
33
33
*
34
34
* File Description: 
35
35
*     portable file routines
43
43
* 11-27-94 Ostell      moved includes to ncbiwin.h to avoid conflict MSC
44
44
*
45
45
* $Log: ncbifile.c,v $
 
46
* Revision 6.37  2004/07/21 18:08:30  kans
 
47
* FileCacheSetup calls _setmode (_fileno (fp), _O_BINARY) if OS_MSWIN
 
48
*
 
49
* Revision 6.36  2004/07/20 19:37:30  kans
 
50
* FileCacheSeek always initializes fields, calls fseek to keep file pointer in sync
 
51
*
 
52
* Revision 6.35  2004/05/07 15:57:14  kans
 
53
* added FileCache functions for buffered read, graceful handing of Unix, Mac, and DOS line endings
 
54
*
 
55
* Revision 6.34  2004/01/23 20:07:16  kans
 
56
* fix to FileGets under Darwin, was losing last character if buffer was shorter than line being read
 
57
*
 
58
* Revision 6.33  2003/11/17 17:17:57  kans
 
59
* changed C++ comments to C comments
 
60
*
 
61
* Revision 6.32  2003/05/05 11:53:37  rsmith
 
62
* Codewarrior compiling for Win32 does not know about setmode or tempnam.
 
63
*
 
64
* Revision 6.31  2003/03/11 14:26:42  rsmith
 
65
* previous change to Nlm_DirCatalog made for only OS_UNIX_DARWIN, not all OS_UNIX
 
66
*
 
67
* Revision 6.30  2003/03/10 15:55:49  rsmith
 
68
* for OS_UNIX change implementation of DirCatalog from using popen with a ls command to using the opendir and readdir library calls.
 
69
*
 
70
* Revision 6.29  2003/02/25 15:31:03  rsmith
 
71
* OS_UNIX_DARWIN (Mach on Macs) uses tempnam for temporary files, not tmpnam.
 
72
*
 
73
* Revision 6.28  2002/11/06 21:23:04  ucko
 
74
* Don't assume MIPS is IRIX; allow Linux too.
 
75
*
 
76
* Revision 6.27  2002/10/03 17:22:29  kans
 
77
* for OS_MAC or OS_UNIX_DARWIN, Nlm_FileGets does fgetc loop, stopping at the first \n or \r character, and leaving a \n as the last character before the null byte
 
78
*
 
79
* Revision 6.26  2002/10/02 14:34:17  kans
 
80
* Nlm_GetOSType and Nlm_FileCreate have ifdef OS_MAC, not WIN_MAC
 
81
*
 
82
* Revision 6.25  2002/06/13 16:14:07  kans
 
83
* fix includes for OS_UNIX_DARWIN with WIN_MAC (EN)
 
84
*
 
85
* Revision 6.24  2002/04/05 19:02:47  ivanov
 
86
* Changed L_tmpnam to PATH_MAX in Nlm_TmpNam()
 
87
*
46
88
* Revision 6.23  2001/08/29 17:33:15  juran
47
89
* Cleanup.
48
90
*
161
203
#define THIS_MODULE g_corelib
162
204
#define THIS_FILE  _this_file
163
205
 
 
206
#include <ncbilcl.h>
 
207
 
164
208
#include "corepriv.h"
165
209
#ifdef OS_MAC
 
210
#ifdef OS_UNIX_DARWIN
 
211
#include <Carbon.h>
 
212
#endif
166
213
#include <Navigation.h>
167
214
#include <Script.h>
168
215
#endif
204
251
 
205
252
#ifdef OS_MAC
206
253
#define INLINE_MOREFILES
207
 
//#include "FullPath.h"
208
 
//#include "MoreFilesExtra.h"
 
254
/* #include "FullPath.h" */
 
255
/* #include "MoreFilesExtra.h" */
209
256
#ifdef INLINE_MOREFILES
210
257
 
211
 
// MoreFilesExtras.c
212
 
// -----------------
 
258
/* MoreFilesExtras.c */
 
259
/* ----------------- */
213
260
 
214
261
/*
215
262
**      Apple Macintosh Developer Technical Support
409
456
                return paramErr;
410
457
        }
411
458
        
412
 
        err = HGetVol(NULL, &vRefNum, &dirID);  // default volume and directory
 
459
        err = HGetVol(NULL, &vRefNum, &dirID);  /* default volume and directory */
413
460
        if (err != noErr) return err;
414
461
        
415
462
        len = strlen(inPathname);
416
463
        
417
464
        p = strchr(inPathname, ':');
418
465
        if (p == NULL) {
419
 
                // Partial pathname -- filename only
 
466
                /* Partial pathname -- filename only */
420
467
                Str31 filename;
421
468
                assert(len <= 31);
422
469
                c2pstrcpy(filename, inPathname);
425
472
                Str31 name;
426
473
                int nameLen;
427
474
                if (inPathname[0] == ':') {
428
 
                        // Relative pathname including directory path
 
475
                        /* Relative pathname including directory path */
429
476
                        
430
477
                } else {
431
 
                        // Absolute pathname
432
 
                        //Str31 volName;  // We would use Str28 if it was defined -- 27, plus 1 for ':'.
 
478
                        /* Absolute pathname */
 
479
                        /* Str31 volName;  We would use Str28 if it was defined -- 27, plus 1 for ':'. */
433
480
                        nameLen = p - inPathname;
434
481
                        assert(nameLen <= 27);
435
482
                        name[0] = nameLen + 1;
436
 
                        memcpy(name + 1, inPathname, nameLen + 1);  // Copy the volume name and the colon.
 
483
                        memcpy(name + 1, inPathname, nameLen + 1);  /* Copy the volume name and the colon. */
437
484
                        err = DetermineVRefNum(name, 0, &vRefNum);
438
485
                        if (err != noErr) return err;
439
486
                        dirID = 2;
440
487
                }
441
 
                // vRefNum and dirID now specify the directory in which we should descend
442
 
                // the path pointed to by p (pointing to the first colon).
 
488
                /* vRefNum and dirID now specify the directory in which we should descend
 
489
                   the path pointed to by p (pointing to the first colon). */
443
490
                p++;
444
491
                while (p != NULL && *p != '\0') {
445
492
                        char *q = strchr(p, ':');
461
508
                                        p = q + 1;
462
509
                                }
463
510
                        } else {
464
 
                                q = strchr(p, '\0');  // go to end of string
 
511
                                q = strchr(p, '\0');  /* go to end of string */
465
512
                                nameLen = q - p;
466
513
                                assert(nameLen > 0);
467
514
                                assert(nameLen <= 31);
489
536
        err = FSpGetFullPath(inFSS, &fullPathLength, &h);
490
537
        if (err != noErr) return err;
491
538
        
492
 
        assert(fullPathLength >= 2);  // An absolute pathname must be at least two chars long
 
539
        assert(fullPathLength >= 2);  /* An absolute pathname must be at least two chars long */
493
540
        fullPath = (char *)Nlm_Malloc(fullPathLength + 1);
494
541
        if (fullPath == NULL) {
495
542
                err = memFullErr;
554
601
        else
555
602
          f = fopen(filename, mode);
556
603
 
557
 
#ifdef WIN32
 
604
#if defined(WIN32)  &&  ! defined(COMP_METRO) 
558
605
        if (strchr(mode, 'b')  &&
559
606
            (f == stdin  ||  f == stdout  ||  f == stderr))
560
607
          setmode(fileno(f), O_BINARY);
641
688
#ifdef WIN_DUMB    
642
689
  if (stream == stdin  ||  stream == stdout  ||  stream == stderr)
643
690
    {
644
 
#ifdef WIN32
 
691
#if defined(WIN32)  &&  ! defined(COMP_METRO) 
645
692
      setmode(fileno(stream), O_TEXT);
646
693
#endif
647
694
      return;
711
758
*****************************************************************************/
712
759
NLM_EXTERN char * LIBCALL  Nlm_FileGets (Nlm_CharPtr ptr, size_t size, FILE *fp)
713
760
{
714
 
        if ((ptr == NULL) || (size <= 0) || (fp == NULL))
715
 
                return NULL;
 
761
#if defined(OS_MAC) || defined (OS_UNIX_DARWIN)
 
762
    int         ch;
 
763
        int         count;
 
764
        Nlm_CharPtr tmp;
 
765
#endif
 
766
 
 
767
        if ((ptr == NULL) || (size < 1) || (fp == NULL))
 
768
                return NULL;
 
769
#if defined(OS_MAC) || defined (OS_UNIX_DARWIN)
 
770
        ch = fgetc (fp);
 
771
        count = 0;
 
772
        tmp = ptr;
 
773
        while (ch != EOF && ch != '\0' && ch != '\n' && ch != '\r' && count < size - 2) {
 
774
          *tmp = ch;
 
775
          tmp++;
 
776
          count++;
 
777
          ch = fgetc (fp);
 
778
        }
 
779
        if (ch == '\n' || ch == '\r') {
 
780
          *tmp = '\n';
 
781
          tmp++;
 
782
          count++;
 
783
        } else if (ch != EOF && ch != '\0') {
 
784
          *tmp = ch;
 
785
          tmp++;
 
786
          count++;
 
787
        }
 
788
        *tmp = '\0';
 
789
        if (count < 1)
 
790
                return NULL;
 
791
        return ptr;
 
792
#else
716
793
        return fgets(ptr,size,fp);
 
794
#endif
717
795
}
718
796
 
719
797
 
928
1006
*   FileCreate()
929
1007
*
930
1008
*****************************************************************************/
931
 
#ifdef WIN_MAC
 
1009
#ifdef OS_MAC
932
1010
static OSType Nlm_GetOSType (Nlm_CharPtr str, OSType dfault)
933
1011
 
934
1012
{
945
1023
NLM_EXTERN void LIBCALL Nlm_FileCreate (Nlm_CharPtr fileName, Nlm_CharPtr type, Nlm_CharPtr creator)
946
1024
 
947
1025
{
948
 
#ifdef WIN_MAC
 
1026
#ifdef OS_MAC
949
1027
  Nlm_Int2  fError;
950
1028
  Nlm_Char  temp [256];
951
1029
  OSType    fType;
957
1035
 
958
1036
  if (fileName != NULL && fileName [0] != '\0') {
959
1037
 
960
 
#ifdef WIN_MAC
961
 
    // note: the following assumes either full pathname or that the current
962
 
    // directory is the proper location to find/create the file
 
1038
#ifdef OS_MAC
 
1039
    /* note: the following assumes either full pathname or that the current
 
1040
       directory is the proper location to find/create the file */
963
1041
 
964
1042
    Nlm_StringNCpy_0(temp, fileName, sizeof(temp));
965
1043
    Nlm_CtoPstr ( temp);
966
1044
    fError = FSMakeFSSpec( 0, 0, (StringPtr)temp, &spec);
967
1045
    
968
 
    // file not found, so create it...
 
1046
    /* file not found, so create it... */
969
1047
    if( fError == fnfErr){
970
1048
        fType = Nlm_GetOSType (type, 'TEXT');
971
1049
        fCreator = Nlm_GetOSType (creator, '    ');
1049
1127
*
1050
1128
*****************************************************************************/
1051
1129
 
 
1130
#ifdef OS_UNIX_DARWIN
 
1131
#include <dirent.h>
 
1132
#endif
 
1133
 
1052
1134
NLM_EXTERN ValNodePtr LIBCALL Nlm_DirCatalog (Nlm_CharPtr pathname)
1053
1135
 
1054
1136
{
1063
1145
  short           vRefNum;
1064
1146
#endif
1065
1147
#ifdef OS_UNIX
 
1148
  Nlm_Uint1       choice;
 
1149
#ifdef OS_UNIX_DARWIN
 
1150
  DIR             *dirp;
 
1151
  struct dirent   *dep;
 
1152
#else
1066
1153
  Nlm_Char        buf [256];
1067
1154
  Nlm_Char        ch;
1068
 
  Nlm_Uint1       choice;
1069
1155
  Nlm_Char        cmmd [PATH_MAX + 20];
1070
1156
  FILE            *fp;
1071
1157
  Nlm_CharPtr     ptr;
1072
1158
#endif
 
1159
#endif
1073
1160
  ValNodePtr      vnp = NULL;
1074
1161
 
1075
1162
  if (pathname != NULL && pathname [0] != '\0') {
1132
1219
    }}
1133
1220
#endif
1134
1221
#ifdef OS_UNIX
 
1222
#ifdef OS_UNIX_DARWIN
 
1223
    dirp = opendir(pathname);
 
1224
    if (dirp == NULL) return NULL;
 
1225
    while ((dep = readdir(dirp)) != NULL) {
 
1226
      /* ignore 'invisible' files. */
 
1227
      if (dep->d_namlen < 1 || dep->d_name[0] == '.')
 
1228
        continue;
 
1229
      if (dep->d_type == DT_DIR) /* directory */
 
1230
        choice = 1;
 
1231
      else          /* all other file types. */
 
1232
        choice = 0;
 
1233
      ValNodeCopyStr (&vnp, choice, dep->d_name);
 
1234
    }
 
1235
    closedir(dirp);
 
1236
#else
1135
1237
    sprintf (cmmd, "ls -1p %s 2>/dev/null", pathname);
1136
1238
    fp = popen (cmmd, "r");
1137
1239
    if (fp == NULL) return NULL;
1153
1255
    }
1154
1256
    pclose (fp);
1155
1257
#endif
 
1258
#endif
1156
1259
#ifdef OS_VMS
1157
1260
#endif
1158
1261
  }
1169
1272
{
1170
1273
#ifdef TEMPNAM_AVAIL
1171
1274
    char *filename;
1172
 
    static Nlm_Char save_filename[L_tmpnam+30];
 
1275
    static Nlm_Char save_filename[PATH_MAX];
1173
1276
 
1174
1277
    /* emulate tmpnam(), except get the benefits of tempnam()'s ability to */
1175
1278
    /* place the files in another directory specified by the environment   */
1176
1279
    /* variable TMPDIR                                                     */
1177
 
 
 
1280
#ifdef OS_UNIX_DARWIN
 
1281
    filename = tempnam("/tmp", "ncbi.");
 
1282
#else
1178
1283
    filename = tempnam(NULL, NULL);
1179
 
 
 
1284
#endif
1180
1285
    if (s == NULL)
1181
1286
    { /* return pointer to static string */
1182
1287
        if (filename != NULL) {
1266
1371
#endif
1267
1372
}
1268
1373
 
 
1374
/* FileCache provides buffered text read for handling Unix, Mac, and DOS line endings gracefully */
 
1375
 
 
1376
/* attach file pointer (text read mode expected) to cache object (usually on stack) */
 
1377
 
 
1378
#ifdef OS_MSWIN
 
1379
#include <fcntl.h>
 
1380
#include <io.h>
 
1381
#endif
 
1382
 
 
1383
NLM_EXTERN Nlm_Boolean Nlm_FileCacheSetup (
 
1384
  Nlm_FileCache PNTR fcp,
 
1385
  FILE *fp
 
1386
)
 
1387
 
 
1388
{
 
1389
  if (fp == NULL || fcp == NULL) return FALSE;
 
1390
 
 
1391
#ifdef OS_MSWIN
 
1392
  _setmode (_fileno (fp), _O_BINARY);
 
1393
#endif
 
1394
 
 
1395
  MemSet ((Nlm_VoidPtr) fcp, 0, sizeof (Nlm_FileCache));
 
1396
 
 
1397
  fcp->fp = fp;
 
1398
  fcp->offset = ftell (fp);
 
1399
 
 
1400
  return TRUE;
 
1401
}
 
1402
 
 
1403
static void Nlm_FileCacheReadBlock (
 
1404
  Nlm_FileCache PNTR fcp
 
1405
)
 
1406
 
 
1407
{
 
1408
  int  total;
 
1409
 
 
1410
  if (fcp == NULL || fcp->fp == NULL) return;
 
1411
 
 
1412
  if (fcp->ctr >= fcp->total) {
 
1413
    fcp->offset += (Nlm_Int4) fcp->total;
 
1414
    fcp->ctr = 0;
 
1415
    fcp->total = 0;
 
1416
 
 
1417
    fcp->buf [0] = '\0';
 
1418
    total = (int) Nlm_FileRead ((Nlm_VoidPtr) fcp->buf, sizeof (Nlm_Char), (size_t) 512, fcp->fp);
 
1419
    if (total < 0 || total > 512) {
 
1420
      total = 512;
 
1421
    }
 
1422
 
 
1423
    fcp->buf [total] = '\0';
 
1424
    fcp->total = Nlm_StringLen (fcp->buf);
 
1425
  }
 
1426
}
 
1427
 
 
1428
/* equivalent of getc */
 
1429
 
 
1430
static Nlm_Char Nlm_FileCacheGetChar (
 
1431
  Nlm_FileCache PNTR fcp
 
1432
)
 
1433
 
 
1434
{
 
1435
  Nlm_Char  ch = '\0', nxt;
 
1436
 
 
1437
  if (fcp == NULL || fcp->fp == NULL) return ch;
 
1438
 
 
1439
  /* read a fresh block if buffer is empty */
 
1440
 
 
1441
  if (fcp->ctr >= fcp->total) {
 
1442
    Nlm_FileCacheReadBlock (fcp);
 
1443
  }
 
1444
 
 
1445
  /* get next character in buffer */
 
1446
 
 
1447
  if (fcp->ctr < fcp->total) {
 
1448
    ch = fcp->buf [(int) fcp->ctr];
 
1449
    (fcp->ctr)++;
 
1450
  }
 
1451
 
 
1452
  if (ch == '\n' || ch == '\r') {
 
1453
    if (fcp->ctr >= fcp->total) {
 
1454
      Nlm_FileCacheReadBlock (fcp);
 
1455
    }
 
1456
    if (fcp->ctr < fcp->total) {
 
1457
 
 
1458
      /* look for carriage return / linefeed pair - DOS file read on Mac or Unix platform */
 
1459
 
 
1460
      nxt = fcp->buf [(int) fcp->ctr];
 
1461
 
 
1462
      /* advance past second character in cr/lf pair */
 
1463
 
 
1464
      if (ch == '\n' && nxt == '\r') {
 
1465
        (fcp->ctr)++;
 
1466
      } else if (ch == '\r' && nxt == '\n') {
 
1467
        (fcp->ctr)++;
 
1468
      }
 
1469
    }
 
1470
 
 
1471
    /* cr or lf returned as newline */
 
1472
 
 
1473
    ch = '\n';
 
1474
  }
 
1475
 
 
1476
  return ch;
 
1477
}
 
1478
 
 
1479
/* equivalent of fgets, leaves /n at end of string */
 
1480
 
 
1481
NLM_EXTERN Nlm_CharPtr Nlm_FileCacheGetString (
 
1482
  Nlm_FileCache PNTR fcp,
 
1483
  Nlm_CharPtr str,
 
1484
  size_t size
 
1485
)
 
1486
 
 
1487
{
 
1488
  Nlm_Char     ch;
 
1489
  Nlm_Int2     count;
 
1490
  Nlm_CharPtr  ptr;
 
1491
 
 
1492
  if (fcp == NULL || fcp->fp == NULL || str == NULL || size < 1) return NULL;
 
1493
 
 
1494
  ch = Nlm_FileCacheGetChar (fcp);
 
1495
  count = 0;
 
1496
  ptr = str;
 
1497
 
 
1498
  while (ch != '\0' && ch != '\n' && ch != '\r' && count < size - 2) {
 
1499
    *ptr = ch;
 
1500
    ptr++;
 
1501
    count++;
 
1502
    ch = Nlm_FileCacheGetChar (fcp);
 
1503
  }
 
1504
 
 
1505
  if (ch == '\n' || ch == '\r') {
 
1506
    *ptr = '\n';
 
1507
    ptr++;
 
1508
    count++;
 
1509
  } else if (ch != '\0') {
 
1510
    *ptr = ch;
 
1511
    ptr++;
 
1512
    count++;
 
1513
  }
 
1514
  *ptr = '\0';
 
1515
 
 
1516
  if (count < 1) return NULL;
 
1517
 
 
1518
  return str;
 
1519
}
 
1520
 
 
1521
/* smarter fgets removes newline from end of string */
 
1522
 
 
1523
NLM_EXTERN Nlm_CharPtr Nlm_FileCacheReadLine (
 
1524
  Nlm_FileCache PNTR fcp,
 
1525
  Nlm_CharPtr str,
 
1526
  size_t size,
 
1527
  Nlm_BoolPtr nonewline
 
1528
)
 
1529
 
 
1530
{
 
1531
  Nlm_Char     ch;
 
1532
  Nlm_CharPtr  ptr;
 
1533
  Nlm_CharPtr  tmp;
 
1534
 
 
1535
  if (fcp == NULL || fcp->fp == NULL || str == NULL || size < 1) return NULL;
 
1536
  *str = '\0';
 
1537
  tmp = Nlm_FileCacheGetString (fcp, str, size);
 
1538
  if (tmp != NULL) {
 
1539
    ptr = str;
 
1540
    ch = *ptr;
 
1541
    while (ch != '\0' && ch != '\n' && ch != '\r') {
 
1542
      ptr++;
 
1543
      ch = *ptr;
 
1544
    }
 
1545
    *ptr = '\0';
 
1546
    if (nonewline != NULL) {
 
1547
      if (ch != '\n' && ch != '\r') {
 
1548
        *nonewline = TRUE;
 
1549
      } else {
 
1550
        *nonewline = FALSE;
 
1551
      }
 
1552
    }
 
1553
  }
 
1554
  return tmp;
 
1555
}
 
1556
 
 
1557
NLM_EXTERN void Nlm_FileCacheSeek (
 
1558
  Nlm_FileCache PNTR fcp,
 
1559
  Nlm_Int4 pos
 
1560
)
 
1561
 
 
1562
{
 
1563
  if (fcp == NULL || fcp->fp == NULL) return;
 
1564
 
 
1565
  /*
 
1566
  if (fcp->offset <= pos && fcp->offset + (Nlm_Int4) fcp->total >= pos) {
 
1567
    fcp->ctr = (Nlm_Int2) (pos - fcp->offset);
 
1568
    return;
 
1569
  }
 
1570
  */
 
1571
 
 
1572
  fcp->ctr = 0;
 
1573
  fcp->total = 0;
 
1574
  fcp->offset = pos;
 
1575
 
 
1576
  fseek (fcp->fp, pos, SEEK_SET);
 
1577
}
 
1578
 
 
1579
NLM_EXTERN Nlm_Int4 Nlm_FileCacheTell (
 
1580
  Nlm_FileCache PNTR fcp
 
1581
)
 
1582
 
 
1583
{
 
1584
  Nlm_Int4  bytes;
 
1585
  Nlm_Int4  offset;
 
1586
 
 
1587
  if (fcp == NULL || fcp->fp == NULL) return 0L;
 
1588
 
 
1589
  offset = ftell (fcp->fp);
 
1590
  bytes = (Nlm_Int4) (fcp->total - fcp->ctr);
 
1591
  offset -= bytes;
 
1592
 
 
1593
  return offset;
 
1594
}
 
1595
 
 
1596
NLM_EXTERN Nlm_Boolean Nlm_FileCacheFree (
 
1597
  Nlm_FileCache PNTR fcp,
 
1598
  Nlm_Boolean restoreFilePos
 
1599
)
 
1600
 
 
1601
{
 
1602
  Nlm_Int4  pos;
 
1603
 
 
1604
  if (fcp == NULL || fcp->fp == NULL) return FALSE;
 
1605
 
 
1606
  if (restoreFilePos) {
 
1607
 
 
1608
    /* correct position of file pointer */
 
1609
 
 
1610
    pos = Nlm_FileCacheTell (fcp);
 
1611
    fseek (fcp->fp, pos, SEEK_SET); 
 
1612
  }
 
1613
 
 
1614
  MemSet ((Nlm_VoidPtr) fcp, 0, sizeof (Nlm_FileCache));
 
1615
 
 
1616
  return TRUE;
 
1617
}
 
1618