11 read_line(std::string
*str
, FILE *file
, bool do_chomp
)
18 ptr
= fgets(buf
, 4096, file
);
23 if ((*str
)[str
->length() - 1] == '\n') {
28 if (ferror(file
) || str
->length() == 0)
38 read_string(std::string
*str
, size_t length
, FILE *file
)
49 size_t buf_size
= 4096;
51 if (length
< buf_size
)
53 size_t ret
= fread(buf
, buf_size
, 1, file
);
57 str
->append(buf
, buf_size
);
64 bool read_file(std::string
*str
, FILE *file
, size_t length
)
66 const int chunk_size
= 4096;
70 // Read file buffer by buffer and process
73 // Grow the string for the next chunk
74 size_t pos
= str
->length();
75 size_t new_size
= pos
+ chunk_size
;
76 if (length
> 0 && new_size
> length
)
78 str
->resize(new_size
);
80 // Read the next chunk
81 int bytes_read
= fread(buf
, 1, str
->length() - pos
, file
);
82 for (int i
= 0; i
< bytes_read
; i
++)
83 (*str
)[pos
+ i
] = buf
[i
];
84 if (bytes_read
< chunk_size
) {
85 str
->resize(pos
+ bytes_read
);
91 if (str
->length() == length
)
97 chomp(std::string
*str
)
102 if ((*str
)[str
->length() - 1] == '\n')
103 str
->resize(str
->length() - 1);
107 clean(std::string
*str
, const char *chars
)
111 // Clean trailing chars
112 for (i
= str
->length(); i
> 0; i
--)
113 if (!strchr(chars
, (*str
)[i
- 1]))
117 // Clean leading chars
118 for (i
= 0; i
< (int)str
->length(); i
++)
119 if (!strchr(chars
, (*str
)[i
]))
125 split(const std::string
*str
, const char *delims
, bool group
,
126 std::vector
<std::string
> *fields
, int num_fields
)
132 while (begin
< (int)str
->length()) {
134 // If 'fields' fields was requested and, this is the last field,
136 if (num_fields
> 0 && (int)fields
->size() == num_fields
- 1) {
137 fields
->push_back(str
->substr(begin
));
141 // Find the string before the next delim
142 while (end
< (int)str
->length() && !strchr(delims
, (*str
)[end
]))
144 fields
->push_back(str
->substr(begin
, end
- begin
));
146 // Eat the delim or group of delims
149 while (end
< (int)str
->length() && strchr(delims
, (*str
)[end
]))
157 split_with_quotes(std::string
*str
, const char *delims
, bool group
,
158 std::vector
<std::string
> *fields
)
160 enum { NONE
, BACKSLASH
, SINGLE
, DOUBLE
} mode
= NONE
;
166 while (src
< str
->length()) {
168 // Find the string before the next delim while processing
170 while (src
< str
->length()) {
172 switch ((*str
)[src
]) {
178 (*str
)[tgt
++] = '\\';
184 else if (mode
== SINGLE
)
187 (*str
)[tgt
++] = '\'';
193 else if (mode
== DOUBLE
)
200 (*str
)[tgt
++] = (*str
)[src
];
201 if (mode
== NONE
&& strchr(delims
, (*str
)[src
])) {
208 if (mode
== BACKSLASH
&& (*str
)[src
] != '\\')
214 fields
->push_back(str
->substr(begin
, tgt
- begin
));
217 // Eat the delim or group of delims
219 while (src
< str
->length() && strchr(delims
, (*str
)[src
]))
226 str2long(const char *str
, bool *ok
)
230 long value
= strtol(str
, &endptr
, 10);
231 if (value
== LONG_MIN
|| value
== LONG_MAX
) {
232 fprintf(stderr
, "str2long(): value out of range\n");
236 if (*str
== '\0' || *endptr
!= '\0')
243 str2float(const char *str
, bool *ok
)
247 float value
= strtod(str
, &endptr
);
249 if (value
== HUGE_VALF
|| value
== -HUGE_VALF
) {
250 fprintf(stderr
, "str2float(): value out of range\n");
254 if (value
== HUGE_VAL
|| value
== -HUGE_VAL
) {
255 fprintf(stderr
, "str2float(): value out of range\n");
260 if (*str
== '\0' || *endptr
!= '\0')
267 str2long(std::string
*str
, bool *ok
)
269 return str2long(str
->c_str(), ok
);
273 str2float(std::string
*str
, bool *ok
)
275 return str2float(str
->c_str(), ok
);