@@ -32,6 +32,13 @@ typedef struct {
3232 char * buffer ;
3333} vstring ;
3434
35+ /* Define readtags' own off_t. */
36+ #ifdef _WIN32
37+ typedef long long rt_off_t ;
38+ #else
39+ typedef off_t rt_off_t ;
40+ #endif
41+
3542/* Information about current tag file */
3643struct sTagFile {
3744 /* has the file been opened and this structure initialized? */
@@ -43,17 +50,17 @@ struct sTagFile {
4350 /* pointer to file structure */
4451 FILE * fp ;
4552 /* file position of first character of `line' */
46- off_t pos ;
53+ rt_off_t pos ;
4754 /* size of tag file in seekable positions */
48- off_t size ;
55+ rt_off_t size ;
4956 /* last line read */
5057 vstring line ;
5158 /* name of tag in last line read */
5259 vstring name ;
5360 /* defines tag search state */
5461 struct {
5562 /* file position of last match for tag */
56- off_t pos ;
63+ rt_off_t pos ;
5764 /* name of tag last searched for */
5865 char * name ;
5966 /* length of name for partial matches */
@@ -97,6 +104,32 @@ static const size_t PseudoTagPrefixLength = 2;
97104* FUNCTION DEFINITIONS
98105*/
99106
107+ static rt_off_t readtags_ftell (FILE * fp )
108+ {
109+ rt_off_t pos ;
110+
111+ #ifdef _WIN32
112+ pos = _ftelli64 (fp );
113+ #else
114+ pos = ftell (fp );
115+ #endif
116+
117+ return pos ;
118+ }
119+
120+ static int readtags_fseek (FILE * fp , rt_off_t pos , int whence )
121+ {
122+ int ret ;
123+
124+ #ifdef _WIN32
125+ ret = _fseeki64 (fp , pos , whence );
126+ #else
127+ ret = fseek (fp , pos , whence );
128+ #endif
129+
130+ return ret ;
131+ }
132+
100133/* Converts a hexadecimal digit to its value */
101134static int xdigitValue (char digit )
102135{
@@ -285,7 +318,7 @@ static int readTagLineRaw (tagFile *const file, int *err)
285318 char * const pLastChar = file -> line .buffer + file -> line .size - 2 ;
286319 char * line ;
287320
288- file -> pos = ftell (file -> fp );
321+ file -> pos = readtags_ftell (file -> fp );
289322 if (file -> pos < 0 )
290323 {
291324 * err = errno ;
@@ -312,7 +345,8 @@ static int readTagLineRaw (tagFile *const file, int *err)
312345 * err = ENOMEM ;
313346 result = 0 ;
314347 }
315- if (fseek (file -> fp , file -> pos , SEEK_SET ) < 0 )
348+
349+ if (readtags_fseek (file -> fp , file -> pos , SEEK_SET ) < 0 )
316350 {
317351 * err = errno ;
318352 result = 0 ;
@@ -748,7 +782,7 @@ static tagResult gotoFirstLogicalTag (tagFile *const file)
748782{
749783 fpos_t startOfLine ;
750784
751- if (fseek (file -> fp , 0L , SEEK_SET ) == -1 )
785+ if (readtags_fseek (file -> fp , 0 , SEEK_SET ) == -1 )
752786 {
753787 file -> err = errno ;
754788 return TagFailure ;
@@ -804,31 +838,40 @@ static tagFile *initialize (const char *const filePath, tagFileInfo *const info)
804838 info -> status .error_number = errno ;
805839 goto file_error ;
806840 }
807- else
808- {
809- if (fseek (result -> fp , 0 , SEEK_END ) == -1 )
810- {
811- info -> status .error_number = errno ;
812- goto file_error ;
813- }
814- result -> size = ftell (result -> fp );
815- if (result -> size == -1 )
816- {
817- info -> status .error_number = errno ;
818- goto file_error ;
819- }
820- if (fseek (result -> fp , 0L , SEEK_SET ) == -1 )
821- {
822- info -> status .error_number = errno ;
823- goto file_error ;
824- }
825841
826- if (readPseudoTags (result , info ) == TagFailure )
827- goto file_error ;
842+ /* Record the size of the tags file to `size` field of result. */
843+ if (readtags_fseek (result -> fp , 0 , SEEK_END ) == -1 )
844+ {
845+ info -> status .error_number = errno ;
846+ goto file_error ;
847+ }
848+ result -> size = readtags_ftell (result -> fp );
849+ if (result -> size == -1 )
850+ {
851+ /* fseek() retruns an int value.
852+ * We observed following behavior on Windows;
853+ * if sizeof(int) of the platform is too small for
854+ * representing the size of the tags file, fseek()
855+ * returns -1 and it doesn't set errno.
856+ */
857+ info -> status .error_number = errno ;
858+ if (info -> status .error_number == 0 )
859+ info -> status .error_number = TagErrnoFileMaybeTooBig ;
828860
829- info -> status .opened = 1 ;
830- result -> initialized = 1 ;
861+ goto file_error ;
831862 }
863+ if (readtags_fseek (result -> fp , 0 , SEEK_SET ) == -1 )
864+ {
865+ info -> status .error_number = errno ;
866+ goto file_error ;
867+ }
868+
869+ if (readPseudoTags (result , info ) == TagFailure )
870+ goto file_error ;
871+
872+ info -> status .opened = 1 ;
873+ result -> initialized = 1 ;
874+
832875 return result ;
833876 mem_error :
834877 info -> status .error_number = ENOMEM ;
@@ -905,9 +948,9 @@ static const char *readFieldValue (
905948 return result ;
906949}
907950
908- static int readTagLineSeek (tagFile * const file , const off_t pos )
951+ static int readTagLineSeek (tagFile * const file , const rt_off_t pos )
909952{
910- if (fseek (file -> fp , pos , SEEK_SET ) < 0 )
953+ if (readtags_fseek (file -> fp , pos , SEEK_SET ) < 0 )
911954 {
912955 file -> err = errno ;
913956 return 0 ;
@@ -951,11 +994,11 @@ static tagResult findFirstNonMatchBefore (tagFile *const file)
951994#define JUMP_BACK 512
952995 int more_lines ;
953996 int comp ;
954- off_t start = file -> pos ;
955- off_t pos = start ;
997+ rt_off_t start = file -> pos ;
998+ rt_off_t pos = start ;
956999 do
9571000 {
958- if (pos < (off_t ) JUMP_BACK )
1001+ if (pos < (rt_off_t ) JUMP_BACK )
9591002 pos = 0 ;
9601003 else
9611004 pos = pos - JUMP_BACK ;
@@ -971,7 +1014,7 @@ static tagResult findFirstMatchBefore (tagFile *const file)
9711014{
9721015 tagResult result = TagFailure ;
9731016 int more_lines ;
974- off_t start = file -> pos ;
1017+ rt_off_t start = file -> pos ;
9751018 if (findFirstNonMatchBefore (file ) != TagSuccess )
9761019 return TagFailure ;
9771020 do
@@ -988,10 +1031,10 @@ static tagResult findFirstMatchBefore (tagFile *const file)
9881031static tagResult findBinary (tagFile * const file )
9891032{
9901033 tagResult result = TagFailure ;
991- off_t lower_limit = 0 ;
992- off_t upper_limit = file -> size ;
993- off_t last_pos = 0 ;
994- off_t pos = upper_limit / 2 ;
1034+ rt_off_t lower_limit = 0 ;
1035+ rt_off_t upper_limit = file -> size ;
1036+ rt_off_t last_pos = 0 ;
1037+ rt_off_t pos = upper_limit / 2 ;
9951038 while (result != TagSuccess )
9961039 {
9971040 if (! readTagLineSeek (file , pos ))
@@ -1083,18 +1126,18 @@ static tagResult find (tagFile *const file, tagEntry *const entry,
10831126 file -> search .nameLength = strlen (name );
10841127 file -> search .partial = (options & TAG_PARTIALMATCH ) != 0 ;
10851128 file -> search .ignorecase = (options & TAG_IGNORECASE ) != 0 ;
1086- if (fseek (file -> fp , 0 , SEEK_END ) < 0 )
1129+ if (readtags_fseek (file -> fp , 0 , SEEK_END ) < 0 )
10871130 {
10881131 file -> err = errno ;
10891132 return TagFailure ;
10901133 }
1091- file -> size = ftell (file -> fp );
1134+ file -> size = readtags_ftell (file -> fp );
10921135 if (file -> size == -1 )
10931136 {
10941137 file -> err = errno ;
10951138 return TagFailure ;
10961139 }
1097- if (fseek (file -> fp , 0L , SEEK_SET ) == -1 )
1140+ if (readtags_fseek (file -> fp , 0 , SEEK_SET ) == -1 )
10981141 {
10991142 file -> err = errno ;
11001143 return TagFailure ;
@@ -1167,7 +1210,7 @@ static tagResult findPseudoTag (tagFile *const file, int rewindBeforeFinding, ta
11671210
11681211 if (rewindBeforeFinding )
11691212 {
1170- if (fseek (file -> fp , 0L , SEEK_SET ) == -1 )
1213+ if (readtags_fseek (file -> fp , 0 , SEEK_SET ) == -1 )
11711214 {
11721215 file -> err = errno ;
11731216 return TagFailure ;
0 commit comments