root/lm-sensors/branches/lm-sensors-3.0.0/lib/data.c @ 4674

Revision 4674, 7.8 KB (checked in by khali, 6 years ago)

Don't handle the isa bus in sensors_parse_i2cbus_name(). We really
don't need to, as there is a single ISA bus, there's no need for
substituting anything.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2    data.c - Part of libsensors, a Linux library for reading sensor data.
3    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9
10    This program 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
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19
20#include <stdlib.h>
21#include <string.h>
22
23#include "error.h"
24#include "data.h"
25#include "sensors.h"
26#include "../version.h"
27
28const char *libsensors_version = LM_VERSION;
29
30sensors_chip *sensors_config_chips = NULL;
31int sensors_config_chips_count = 0;
32int sensors_config_chips_max = 0;
33
34sensors_bus *sensors_config_busses = NULL;
35int sensors_config_busses_count = 0;
36int sensors_config_busses_max = 0;
37
38sensors_chip_features *sensors_proc_chips = NULL;
39int sensors_proc_chips_count = 0;
40int sensors_proc_chips_max = 0;
41
42sensors_bus *sensors_proc_bus = NULL;
43int sensors_proc_bus_count = 0;
44int sensors_proc_bus_max = 0;
45
46static int sensors_substitute_chip(sensors_chip_name *name,int lineno);
47
48/* Wow, this must be one of the ugliest functions I have ever written.
49   The idea is that it parses a chip name. These are valid names:
50
51     lm78-i2c-10-5e             *-i2c-10-5e
52     lm78-i2c-10-*              *-i2c-10-*
53     lm78-i2c-*-5e              *-i2c-*-5e
54     lm78-i2c-*-*               *-i2c-*-*
55     lm78-isa-10dd              *-isa-10dd
56     lm78-isa-*                 *-isa-*
57     lm78-*                     *-*
58                                *
59   Here 'lm78' can be any prefix. To complicate matters, such a prefix
60   can also contain dashes (like lm78-j, for example!). 'i2c' and 'isa' are
61   literal strings, just like all dashes '-' and wildcards '*'. '10' can
62   be any decimal i2c bus number. '5e' can be any hexadecimal i2c device
63   address, and '10dd' any hexadecimal isa address.
64
65   If '*' is used in prefixes, together with dashes, ambigious parses are
66   introduced. In that case, the prefix is kept as small as possible.
67
68   The 'prefix' part in the result is freshly allocated. All old contents
69   of res is overwritten. res itself is not allocated. In case of an error
70   return (ie. != 0), res is undefined, but all allocations are undone.
71
72   Don't tell me there are bugs in here, because I'll start screaming :-)
73*/
74
75int sensors_parse_chip_name(const char *orig_name, sensors_chip_name *res)
76{
77  char *part2, *part3, *part4;
78  char *name = strdup(orig_name);
79  int i;
80
81  if (! name)
82    sensors_fatal_error("sensors_parse_chip_name","Allocating new name");
83  /* First split name in upto four pieces. */
84  if ((part4 = strrchr(name,'-')))
85    *part4++ = '\0';
86  if ((part3 = strrchr(name,'-')))
87    *part3++ = '\0';
88  if ((part2 = strrchr(name,'-'))) 
89    *part2++ = '\0';
90
91  /* No dashes found? */
92  if (! part4) {
93    if (!strcmp(name,"*")) {
94      res->prefix = SENSORS_CHIP_NAME_PREFIX_ANY;
95      res->bus = SENSORS_CHIP_NAME_BUS_ANY;
96      res->addr = SENSORS_CHIP_NAME_ADDR_ANY;
97      goto SUCCES;
98    } else 
99      goto ERROR;
100  }
101
102  /* At least one dash found. Now part4 is either '*', or an address */
103  if (!strcmp(part4,"*"))
104    res->addr = SENSORS_CHIP_NAME_ADDR_ANY;
105  else {
106    if ((strlen(part4) > 4) || (strlen(part4) == 0))
107      goto ERROR;
108    res->addr = 0;
109    for (i = 0; ; i++) { 
110      switch (part4[i]) {
111      case '0': case '1': case '2': case '3': case '4':
112      case '5': case '6': case '7': case '8': case '9':
113        res->addr = res->addr * 16 + part4[i] - '0';
114        break;
115      case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
116        res->addr = res->addr * 16 + part4[i] - 'a' + 10;
117        break;
118      case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
119        res->addr = res->addr * 16 + part4[i] - 'A' + 10;
120        break;
121      case 0:
122        goto DONE;
123      default:
124        goto ERROR;
125      }
126    }
127DONE:;
128  }
129
130  /* OK. So let's look at part3. It must either be the number of the
131     i2c bus (and then part2 *must* be "i2c"), or it must be "isa",
132     or, if part4 was "*", it belongs to 'prefix'. Or no second dash
133     was found at all, of course. */
134  if (! part3) {
135    if (res->addr == SENSORS_CHIP_NAME_ADDR_ANY) {
136      res->bus = SENSORS_CHIP_NAME_BUS_ANY;
137    } else
138      goto ERROR;
139  } else if (!strcmp(part3,"isa")) {
140    res->bus = SENSORS_CHIP_NAME_BUS_ISA;
141    if (part2)
142      *(part2-1) = '-';
143  } else if (!strcmp(part3,"pci")) {
144    res->bus = SENSORS_CHIP_NAME_BUS_PCI;
145    if (part2)
146      *(part2-1) = '-';
147  } else if (part2 && !strcmp(part2,"i2c") && !strcmp(part3,"*"))
148    res->bus = SENSORS_CHIP_NAME_BUS_ANY_I2C;
149  else if (part2 && !strcmp(part2,"i2c")) {
150    if ((strlen(part3) > 3) || (strlen(part3) == 0))
151      goto ERROR;
152    res->bus = 0;
153    for (i = 0; ; i++) { 
154      switch (part3[i]) {
155      case '0': case '1': case '2': case '3': case '4':
156      case '5': case '6': case '7': case '8': case '9':
157        res->bus = res->bus * 10 + part3[i] - '0';
158        break;
159      case 0:
160        goto DONE2;
161      default:
162        goto ERROR;
163      }
164    }
165DONE2:;
166  } else if (res->addr == SENSORS_CHIP_NAME_ADDR_ANY) {
167    res->bus = SENSORS_CHIP_NAME_BUS_ANY;
168    if (part2)
169      *(part2-1) = '-';
170    *(part3-1) = '-';
171  } else
172    goto ERROR;
173   
174  if (!strcmp(name,"*"))
175    res->prefix = SENSORS_CHIP_NAME_PREFIX_ANY;
176  else if (! (res->prefix = strdup(name)))
177    sensors_fatal_error("sensors_parse_chip_name","Allocating new name");
178  goto SUCCES;
179
180SUCCES:
181  free(name);
182  return 0;
183
184ERROR:
185  free(name);
186  return -SENSORS_ERR_CHIP_NAME;
187}
188
189int sensors_parse_i2cbus_name(const char *name, int *res)
190{
191  int i;
192
193  if (strncmp(name,"i2c-",4)) {
194    return -SENSORS_ERR_BUS_NAME;
195  }
196  name += 4;
197  if ((strlen(name) > 3) || (strlen(name) == 0))
198    return -SENSORS_ERR_BUS_NAME;
199  *res = 0;
200  for (i = 0; ; i++) { 
201    switch (name[i]) {
202    case '0': case '1': case '2': case '3': case '4':
203    case '5': case '6': case '7': case '8': case '9':
204      *res = *res * 10 + name[i] - '0';
205      break;
206    case 0:
207      return 0;
208    default:
209      return -SENSORS_ERR_BUS_NAME;
210    }
211  }
212}
213
214
215int sensors_substitute_chip(sensors_chip_name *name,int lineno)
216{
217  int i,j;
218  for (i = 0; i < sensors_config_busses_count; i++)
219    if (sensors_config_busses[i].number == name->bus)
220      break;
221
222  if (i == sensors_config_busses_count) {
223    sensors_parse_error("Undeclared i2c bus referenced",lineno);
224    name->bus = sensors_proc_bus_count;
225    return -SENSORS_ERR_BUS_NAME;
226  }
227
228  /* Compare the adapter names */
229  for (j = 0; j < sensors_proc_bus_count; j++) {
230    if (!strcmp(sensors_config_busses[i].adapter,
231                sensors_proc_bus[j].adapter)) {
232      name->bus = sensors_proc_bus[j].number;
233      return 0;
234    }
235  }
236
237  /* We did not find anything. sensors_proc_bus_count is not a valid
238     bus number, so it will never be matched. Good. */
239  name->bus = sensors_proc_bus_count;
240  return 0;
241}
242
243     
244int sensors_substitute_busses(void)
245{
246  int err,i,j,lineno;
247  sensors_chip_name_list *chips;
248  int res=0;
249 
250  for(i = 0; i < sensors_config_chips_count; i++) {
251    lineno = sensors_config_chips[i].lineno;
252    chips = &sensors_config_chips[i].chips;
253    for(j = 0; j < chips->fits_count; j++)
254      if ((chips->fits[j].bus != SENSORS_CHIP_NAME_BUS_ISA) &&
255          (chips->fits[j].bus != SENSORS_CHIP_NAME_BUS_PCI) &&
256          (chips->fits[j].bus != SENSORS_CHIP_NAME_BUS_ANY) &&
257          (chips->fits[j].bus != SENSORS_CHIP_NAME_BUS_ANY_I2C))
258        if ((err = sensors_substitute_chip(chips->fits+j, lineno)))
259          res = err;
260  }
261  return res;
262}
Note: See TracBrowser for help on using the browser.