Prusa MINI Firmware overview
ini.c File Reference
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "ini.h"

Classes

struct  ini_parse_string_ctx
 

Macros

#define MAX_SECTION   50
 
#define MAX_NAME   50
 
#define HANDLER(u, s, n, v)   handler(u, s, n, v)
 

Functions

static char * rstrip (char *s)
 
static char * lskip (const char *s)
 
static char * find_chars_or_comment (const char *s, const char *chars)
 
static char * strncpy0 (char *dest, const char *src, size_t size)
 
int ini_parse_stream (ini_reader reader, void *stream, ini_handler handler, void *user)
 
int ini_parse_file (FILE *file, ini_handler handler, void *user)
 
int ini_parse (const char *filename, ini_handler handler, void *user)
 
static char * ini_reader_string (char *str, int num, void *stream)
 
int ini_parse_string (const char *string, ini_handler handler, void *user)
 

Macro Definition Documentation

◆ MAX_SECTION

#define MAX_SECTION   50

◆ MAX_NAME

#define MAX_NAME   50

◆ HANDLER

#define HANDLER (   u,
  s,
  n,
 
)    handler(u, s, n, v)

Function Documentation

◆ rstrip()

static char* rstrip ( char *  s)
static
39 {
40  char* p = s + strlen(s);
41  while (p > s && isspace((unsigned char)(*--p)))
42  *p = '\0';
43  return s;
44 }
Here is the caller graph for this function:

◆ lskip()

static char* lskip ( const char *  s)
static
48 {
49  while (*s && isspace((unsigned char)(*s)))
50  s++;
51  return (char*)s;
52 }
Here is the caller graph for this function:

◆ find_chars_or_comment()

static char* find_chars_or_comment ( const char *  s,
const char *  chars 
)
static
58 {
59 #if INI_ALLOW_INLINE_COMMENTS
60  int was_space = 0;
61  while (*s && (!chars || !strchr(chars, *s)) &&
62  !(was_space && strchr(INI_INLINE_COMMENT_PREFIXES, *s))) {
63  was_space = isspace((unsigned char)(*s));
64  s++;
65  }
66 #else
67  while (*s && (!chars || !strchr(chars, *s))) {
68  s++;
69  }
70 #endif
71  return (char*)s;
72 }
Here is the caller graph for this function:

◆ strncpy0()

static char* strncpy0 ( char *  dest,
const char *  src,
size_t  size 
)
static
76 {
77  strncpy(dest, src, size - 1);
78  dest[size - 1] = '\0';
79  return dest;
80 }
Here is the caller graph for this function:

◆ ini_parse_stream()

int ini_parse_stream ( ini_reader  reader,
void stream,
ini_handler  handler,
void user 
)
85 {
86  /* Uses a fair bit of stack (use heap instead if you need to) */
87 #if INI_USE_STACK
88  char line[INI_MAX_LINE];
89  int max_line = INI_MAX_LINE;
90 #else
91  char* line;
92  size_t max_line = INI_INITIAL_ALLOC;
93 #endif
94 #if INI_ALLOW_REALLOC && !INI_USE_STACK
95  char* new_line;
96  size_t offset;
97 #endif
98  char section[MAX_SECTION] = "";
99  char prev_name[MAX_NAME] = "";
100 
101  char* start;
102  char* end;
103  char* name;
104  char* value;
105  int lineno = 0;
106  int error = 0;
107 
108 #if !INI_USE_STACK
109  line = (char*)malloc(INI_INITIAL_ALLOC);
110  if (!line) {
111  return -2;
112  }
113 #endif
114 
115 #if INI_HANDLER_LINENO
116 #define HANDLER(u, s, n, v) handler(u, s, n, v, lineno)
117 #else
118 #define HANDLER(u, s, n, v) handler(u, s, n, v)
119 #endif
120 
121  /* Scan through stream line by line */
122  while (reader(line, (int)max_line, stream) != NULL) {
123 #if INI_ALLOW_REALLOC && !INI_USE_STACK
124  offset = strlen(line);
125  while (offset == max_line - 1 && line[offset - 1] != '\n') {
126  max_line *= 2;
127  if (max_line > INI_MAX_LINE)
128  max_line = INI_MAX_LINE;
129  new_line = realloc(line, max_line);
130  if (!new_line) {
131  free(line);
132  return -2;
133  }
134  line = new_line;
135  if (reader(line + offset, (int)(max_line - offset), stream) == NULL)
136  break;
137  if (max_line >= INI_MAX_LINE)
138  break;
139  offset += strlen(line + offset);
140  }
141 #endif
142 
143  lineno++;
144 
145  start = line;
146 #if INI_ALLOW_BOM
147  if (lineno == 1 && (unsigned char)start[0] == 0xEF &&
148  (unsigned char)start[1] == 0xBB &&
149  (unsigned char)start[2] == 0xBF) {
150  start += 3;
151  }
152 #endif
153  start = lskip(rstrip(start));
154 
155  if (strchr(INI_START_COMMENT_PREFIXES, *start)) {
156  /* Start-of-line comment */
157  }
158 #if INI_ALLOW_MULTILINE
159  else if (*prev_name && *start && start > line) {
160  /* Non-blank line with leading whitespace, treat as continuation
161  of previous name's value (as per Python configparser). */
162  if (!HANDLER(user, section, prev_name, start) && !error)
163  error = lineno;
164  }
165 #endif
166  else if (*start == '[') {
167  /* A "[section]" line */
168  end = find_chars_or_comment(start + 1, "]");
169  if (*end == ']') {
170  *end = '\0';
171  strncpy0(section, start + 1, sizeof(section));
172  *prev_name = '\0';
173 #if INI_CALL_HANDLER_ON_NEW_SECTION
174  if (!HANDLER(user, section, NULL, NULL) && !error)
175  error = lineno;
176 #endif
177  }
178  else if (!error) {
179  /* No ']' found on section line */
180  error = lineno;
181  }
182  }
183  else if (*start) {
184  /* Not a comment, must be a name[=:]value pair */
186  if (*end == '=' || *end == ':') {
187  *end = '\0';
188  name = rstrip(start);
189  value = end + 1;
190 #if INI_ALLOW_INLINE_COMMENTS
191  end = find_chars_or_comment(value, NULL);
192  if (*end)
193  *end = '\0';
194 #endif
195  value = lskip(value);
196  rstrip(value);
197 
198  /* Valid name[=:]value pair found, call handler */
199  strncpy0(prev_name, name, sizeof(prev_name));
200  if (!HANDLER(user, section, name, value) && !error)
201  error = lineno;
202  }
203  else if (!error) {
204  /* No '=' or ':' found on name[=:]value line */
205 #if INI_ALLOW_NO_VALUE
206  *end = '\0';
207  name = rstrip(start);
208  if (!HANDLER(user, section, name, NULL) && !error)
209  error = lineno;
210 #else
211  error = lineno;
212 #endif
213  }
214  }
215 
216 #if INI_STOP_ON_FIRST_ERROR
217  if (error)
218  break;
219 #endif
220  }
221 
222 #if !INI_USE_STACK
223  free(line);
224 #endif
225 
226  return error;
227 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ini_parse_file()

int ini_parse_file ( FILE *  file,
ini_handler  handler,
void user 
)
231 {
232  return ini_parse_stream((ini_reader)fgets, file, handler, user);
233 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ini_parse()

int ini_parse ( const char *  filename,
ini_handler  handler,
void user 
)
237 {
238  FILE* file;
239  int error;
240 
241  file = fopen(filename, "r");
242  if (!file)
243  return -1;
244  error = ini_parse_file(file, handler, user);
245  fclose(file);
246  return error;
247 }
Here is the call graph for this function:

◆ ini_reader_string()

static char* ini_reader_string ( char *  str,
int  num,
void stream 
)
static
251  {
253  const char* ctx_ptr = ctx->ptr;
254  size_t ctx_num_left = ctx->num_left;
255  char* strp = str;
256  char c;
257 
258  if (ctx_num_left == 0 || num < 2)
259  return NULL;
260 
261  while (num > 1 && ctx_num_left != 0) {
262  c = *ctx_ptr++;
263  ctx_num_left--;
264  *strp++ = c;
265  if (c == '\n')
266  break;
267  num--;
268  }
269 
270  *strp = '\0';
271  ctx->ptr = ctx_ptr;
272  ctx->num_left = ctx_num_left;
273  return str;
274 }
Here is the caller graph for this function:

◆ ini_parse_string()

int ini_parse_string ( const char *  string,
ini_handler  handler,
void user 
)
277  {
279 
280  ctx.ptr = string;
281  ctx.num_left = strlen(string);
282  return ini_parse_stream((ini_reader)ini_reader_string, &ctx, handler,
283  user);
284 }
Here is the call graph for this function:
Here is the caller graph for this function:
HANDLER
#define HANDLER(u, s, n, v)
ini_reader
char *(* ini_reader)(char *str, int num, void *stream)
Definition: ini.h:40
INI_INITIAL_ALLOC
#define INI_INITIAL_ALLOC
Definition: ini.h:122
auto_build.error
bool error
Definition: auto_build.py:637
ini_parse_string_ctx::num_left
size_t num_left
Definition: ini.c:34
g29_auto.start
start
Definition: g29_auto.py:150
INI_MAX_LINE
#define INI_MAX_LINE
Definition: ini.h:109
lskip
static char * lskip(const char *s)
Definition: ini.c:47
NULL
#define NULL
Definition: usbd_def.h:53
createSpeedLookupTable.end
end
Definition: createSpeedLookupTable.py:33
netif::num
u8_t num
Definition: netif.h:309
ini_parse_string_ctx
Definition: ini.c:32
ini_parse_stream
int ini_parse_stream(ini_reader reader, void *stream, ini_handler handler, void *user)
Definition: ini.c:83
ini_parse_file
int ini_parse_file(FILE *file, ini_handler handler, void *user)
Definition: ini.c:230
netif::name
char name[2]
Definition: netif.h:307
find_chars_or_comment
static char * find_chars_or_comment(const char *s, const char *chars)
Definition: ini.c:57
INI_START_COMMENT_PREFIXES
#define INI_START_COMMENT_PREFIXES
Definition: ini.h:88
ini_reader_string
static char * ini_reader_string(char *str, int num, void *stream)
Definition: ini.c:251
INI_INLINE_COMMENT_PREFIXES
#define INI_INLINE_COMMENT_PREFIXES
Definition: ini.h:98
ini_parse_string_ctx::ptr
const char * ptr
Definition: ini.c:33
strncpy0
static char * strncpy0(char *dest, const char *src, size_t size)
Definition: ini.c:75
rstrip
static char * rstrip(char *s)
Definition: ini.c:38
MAX_NAME
#define MAX_NAME
Definition: ini.c:29
MAX_SECTION
#define MAX_SECTION
Definition: ini.c:28
size
static png_bytep size_t size
Definition: pngwrite.c:2170