blob: 1e58b9951a1314fe0b71687ba171bf0b9506be55 [file] [log] [blame]
Lucas De Marchi4462c4a2011-11-29 18:05:43 -02001/*
2 * libkmod - interface to kernel module operations
3 *
4 * Copyright (C) 2011 ProFUSION embedded systems
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation version 2.1.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <stddef.h>
23#include <stdarg.h>
24#include <unistd.h>
25#include <errno.h>
26#include <string.h>
27#include <ctype.h>
28
29#include "libkmod.h"
30#include "libkmod-private.h"
31
32/*
33 * Read one logical line from a configuration file.
34 *
35 * Line endings may be escaped with backslashes, to form one logical line from
36 * several physical lines. No end of line character(s) are included in the
37 * result.
38 *
39 * If linenum is not NULL, it is incremented by the number of physical lines
40 * which have been read.
41 */
42char *getline_wrapped(FILE *fp, unsigned int *linenum)
43{
44 int size = 256;
45 int i = 0;
46 char *buf = malloc(size);
47 for(;;) {
48 int ch = getc_unlocked(fp);
49
50 switch(ch) {
51 case EOF:
52 if (i == 0) {
53 free(buf);
54 return NULL;
55 }
56 /* else fall through */
57
58 case '\n':
59 if (linenum)
60 (*linenum)++;
61 if (i == size)
62 buf = realloc(buf, size + 1);
63 buf[i] = '\0';
64 return buf;
65
66 case '\\':
67 ch = getc_unlocked(fp);
68
69 if (ch == '\n') {
70 if (linenum)
71 (*linenum)++;
72 continue;
73 }
74 /* else fall through */
75
76 default:
77 buf[i++] = ch;
78
79 if (i == size) {
80 size *= 2;
81 buf = realloc(buf, size);
82 }
83 }
84 }
85}
Lucas De Marchi8185fc92011-11-30 02:14:33 -020086
87/*
88 * Replace dashes with underscores.
89 * Dashes inside character range patterns (e.g. [0-9]) are left unchanged.
90 */
91char *underscores(struct kmod_ctx *ctx, char *s)
92{
93 unsigned int i;
94
95 if (!s)
96 return NULL;
97
98 for (i = 0; s[i]; i++) {
99 switch (s[i]) {
100 case '-':
101 s[i] = '_';
102 break;
103
104 case ']':
105 INFO(ctx, "Unmatched bracket in %s\n", s);
106 break;
107
108 case '[':
109 i += strcspn(&s[i], "]");
110 if (!s[i])
111 INFO(ctx, "Unmatched bracket in %s\n", s);
112 break;
113 }
114 }
115 return s;
116}
117