FreeBASIC  0.91.0
dev_file_readline.c
Go to the documentation of this file.
1 /* file device */
2 
3 #include "fb.h"
4 
5 static char *hWrapper( char *buffer, size_t count, FILE *fp )
6 {
7  return fgets( buffer, count, fp );
8 }
9 
11  (
12  FILE *fp,
13  FBSTRING *dst,
14  fb_FnDevReadString pfnReadString
15  )
16 {
17  int res = fb_ErrorSetNum( FB_RTERROR_OK );
18  size_t buffer_len;
19  int found, first_run;
20  char buffer[512];
21  FBSTRING src = { &buffer[0], 0, 0 };
22 
23  DBG_ASSERT( dst!=NULL );
24 
25  buffer_len = sizeof(buffer);
26  first_run = TRUE;
27 
28  FB_LOCK();
29 
30  if( pfnReadString == NULL )
31  pfnReadString = hWrapper;
32 
33  found = FALSE;
34  while (!found)
35  {
36  memset( buffer, 0, buffer_len );
37 
38  if( pfnReadString( buffer, sizeof( buffer ), fp ) == NULL )
39  {
40  /* EOF reached ... this is not an error !!! */
41  res = FB_RTERROR_ENDOFFILE; /* but we have to notify the caller */
42 
43  if( first_run )
44  fb_StrDelete( dst );
45 
46  break;
47  }
48 
49  /* the last character always is NUL */
50  buffer_len = sizeof(buffer) - 1;
51 
52  /* now let's find the end of the buffer */
53  while (buffer_len--)
54  {
55  char ch = buffer[buffer_len];
56  if (ch==13 || ch==10)
57  {
58  /* accept both CR and LF */
59  found = TRUE;
60  break;
61  }
62  else if( ch!=0 )
63  {
64  /* a character other than CR/LF found ... i.e. buffer full */
65  break;
66  }
67  }
68 
69  ssize_t tmp_buf_len;
70 
71  if( !found )
72  {
73  /* remember the real length */
74  tmp_buf_len = buffer_len += 1;
75 
76  /* not found ... so simply add this to the result string */
77  }
78  else
79  {
80  /* remember the real length */
81  tmp_buf_len = buffer_len + 1;
82 
83  /* filter a (possibly valid) CR/LF sequence */
84  if( buffer[buffer_len]==10 && buffer_len!=0 )
85  {
86  if( buffer[buffer_len-1]==13 )
87  {
88  --buffer_len;
89  }
90  }
91 
92  /* set the CR or LF to NUL */
93  buffer[buffer_len] = 0;
94  }
95 
96  src.size = src.len = buffer_len;
97 
98  /* assign or concatenate */
99  if( first_run )
100  fb_StrAssign( dst, -1, &src, -1, FALSE );
101  else
102  fb_StrConcatAssign( dst, -1, &src, -1, FALSE );
103 
104  first_run = FALSE;
105 
106  buffer_len = tmp_buf_len;
107  }
108 
109  FB_UNLOCK();
110 
111  return res;
112 
113 }
114 
116 {
117  int res;
118  FILE *fp;
119 
120  FB_LOCK();
121 
122  fp = (FILE*) handle->opaque;
123  if( fp==stdout || fp==stderr )
124  fp = stdin;
125 
126  if( fp == NULL )
127  {
128  FB_UNLOCK();
130  }
131 
132  res = fb_DevFileReadLineDumb( fp, dst, NULL );
133 
134  FB_UNLOCK();
135 
136  return res;
137 }