Changeset 4677

Show
Ignore:
Timestamp:
08/16/07 12:06:35 (1 year ago)
Author:
khali
Message:

Chip types can no longer contain dashes. This makes it possible to
rewrite sensors_parse_chip_name() with a simpler algorithm. The new
code is smaller by about one third, and twice as fast on average
(5 times as fast in the most frequent case "foo-*".)

This closes ticket #2221.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • lm-sensors/branches/lm-sensors-3.0.0/CHANGES

    r4676 r4677  
    2323           Drop support for dummy type 
    2424           New function sensors_snprintf_chip_name() 
     25           Drop support for dashes in chip names 
    2526  Makefile: Drop the package and version targets 
    2627  Man page sensors.conf.5: Update the chip statement section 
  • lm-sensors/branches/lm-sensors-3.0.0/lib/data.c

    r4676 r4677  
    22    data.c - Part of libsensors, a Linux library for reading sensor data. 
    33    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> 
     4    Copyright (C) 2007        Jean Delvare <khali@linux-fr.org> 
    45 
    56    This program is free software; you can redistribute it and/or modify 
     
    1718    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
    1819*/ 
     20 
     21/* this define needed for strndup() */ 
     22#define _GNU_SOURCE 
    1923 
    2024#include <stdlib.h> 
     
    4751static int sensors_substitute_chip(sensors_chip_name *name,int lineno); 
    4852 
    49 /* Wow, this must be one of the ugliest functions I have ever written. 
    50    The idea is that it parses a chip name. These are valid names: 
     53/* 
     54   Parse a chip name to the internal representation. These are valid names: 
    5155 
    5256     lm78-i2c-10-5e             *-i2c-10-5e 
     
    5761     lm78-isa-*                 *-isa-* 
    5862     lm78-*                     *-* 
    59                                 * 
    60    Here 'lm78' can be any prefix. To complicate matters, such a prefix 
    61    can also contain dashes (like lm78-j, for example!). 'i2c' and 'isa' are 
     63 
     64   Here 'lm78' can be any prefix. 'i2c' and 'isa' are 
    6265   literal strings, just like all dashes '-' and wildcards '*'. '10' can 
    6366   be any decimal i2c bus number. '5e' can be any hexadecimal i2c device 
    6467   address, and '10dd' any hexadecimal isa address. 
    6568 
    66    If '*' is used in prefixes, together with dashes, ambigious parses are 
    67    introduced. In that case, the prefix is kept as small as possible. 
    68  
    6969   The 'prefix' part in the result is freshly allocated. All old contents 
    7070   of res is overwritten. res itself is not allocated. In case of an error 
    7171   return (ie. != 0), res is undefined, but all allocations are undone. 
    72  
    73    Don't tell me there are bugs in here, because I'll start screaming :-) 
    7472*/ 
    7573 
    76 int sensors_parse_chip_name(const char *orig_name, sensors_chip_name *res) 
    77 
    78   char *part2, *part3, *part4; 
    79   char *name = strdup(orig_name); 
    80   char *endptr; 
    81  
    82   if (! name) 
    83     sensors_fatal_error("sensors_parse_chip_name","Allocating new name"); 
    84   /* First split name in upto four pieces. */ 
    85   if ((part4 = strrchr(name,'-'))) 
    86     *part4++ = '\0'; 
    87   if ((part3 = strrchr(name,'-'))) 
    88     *part3++ = '\0'; 
    89   if ((part2 = strrchr(name,'-')))  
    90     *part2++ = '\0'; 
    91  
    92   /* No dashes found? */ 
    93   if (! part4) { 
    94     if (!strcmp(name,"*")) { 
    95       res->prefix = SENSORS_CHIP_NAME_PREFIX_ANY; 
    96       res->bus = SENSORS_CHIP_NAME_BUS_ANY; 
    97       res->addr = SENSORS_CHIP_NAME_ADDR_ANY; 
    98       goto SUCCES; 
    99     } else  
    100       goto ERROR; 
    101   } 
    102  
    103   /* At least one dash found. Now part4 is either '*', or an address */ 
    104   if (!strcmp(part4,"*")) 
    105     res->addr = SENSORS_CHIP_NAME_ADDR_ANY; 
    106   else { 
    107     res->addr = strtoul(part4, &endptr, 16); 
    108     if (*part4 == '\0' || *endptr != '\0' || res->addr < 0) 
    109       goto ERROR; 
    110   } 
    111  
    112   /* OK. So let's look at part3. It must either be the number of the 
    113      i2c bus (and then part2 *must* be "i2c"), or it must be "isa", 
    114      or, if part4 was "*", it belongs to 'prefix'. Or no second dash 
    115      was found at all, of course. */ 
    116   if (! part3) { 
    117     if (res->addr == SENSORS_CHIP_NAME_ADDR_ANY) { 
    118       res->bus = SENSORS_CHIP_NAME_BUS_ANY; 
    119     } else 
    120       goto ERROR; 
    121   } else if (!strcmp(part3,"isa")) { 
    122     res->bus = SENSORS_CHIP_NAME_BUS_ISA; 
    123     if (part2) 
    124       *(part2-1) = '-'; 
    125   } else if (!strcmp(part3,"pci")) { 
    126     res->bus = SENSORS_CHIP_NAME_BUS_PCI; 
    127     if (part2) 
    128       *(part2-1) = '-'; 
    129   } else if (part2 && !strcmp(part2,"i2c") && !strcmp(part3,"*")) 
    130     res->bus = SENSORS_CHIP_NAME_BUS_ANY_I2C; 
    131   else if (part2 && !strcmp(part2,"i2c")) { 
    132     res->bus = strtoul(part3, &endptr, 10); 
    133     if (*part3 == '\0' || *endptr != '\0' || res->bus < 0) 
    134       goto ERROR; 
    135   } else if (res->addr == SENSORS_CHIP_NAME_ADDR_ANY) { 
    136     res->bus = SENSORS_CHIP_NAME_BUS_ANY; 
    137     if (part2) 
    138       *(part2-1) = '-'; 
    139     *(part3-1) = '-'; 
    140   } else 
    141     goto ERROR; 
    142      
    143   if (!strcmp(name,"*")) 
    144     res->prefix = SENSORS_CHIP_NAME_PREFIX_ANY; 
    145   else if (! (res->prefix = strdup(name))) 
    146     sensors_fatal_error("sensors_parse_chip_name","Allocating new name"); 
    147   goto SUCCES; 
    148  
    149 SUCCES: 
    150   free(name); 
    151   return 0; 
     74int sensors_parse_chip_name(const char *name, sensors_chip_name *res) 
     75
     76        char *dash; 
     77 
     78        /* First, the prefix. It's either "*" or a real chip name. */ 
     79        if (!strncmp(name, "*-", 2)) { 
     80                res->prefix = SENSORS_CHIP_NAME_PREFIX_ANY; 
     81                name += 2; 
     82        } else { 
     83                if (!(dash = strchr(name, '-'))) 
     84                        return -SENSORS_ERR_CHIP_NAME; 
     85                res->prefix = strndup(name, dash - name); 
     86                if (!res->prefix) 
     87                        sensors_fatal_error("sensors_parse_chip_name", 
     88                                            "Allocating name prefix"); 
     89                name = dash + 1; 
     90        } 
     91 
     92        /* Then we have either a sole "*" (all chips with this name) or a bus 
     93           type and an address. */ 
     94        if (!strcmp(name, "*")) { 
     95                res->bus = SENSORS_CHIP_NAME_BUS_ANY; 
     96                res->addr = SENSORS_CHIP_NAME_ADDR_ANY; 
     97                return 0; 
     98        } 
     99 
     100        if (!(dash = strchr(name, '-'))) 
     101                goto ERROR; 
     102        if (!strncmp(name, "i2c", dash - name)) 
     103                res->bus = SENSORS_CHIP_NAME_BUS_ANY_I2C; 
     104        else if (!strncmp(name, "isa", dash - name)) 
     105                res->bus = SENSORS_CHIP_NAME_BUS_ISA; 
     106        else if (!strncmp(name, "pci", dash - name)) 
     107                res->bus = SENSORS_CHIP_NAME_BUS_PCI; 
     108        else 
     109                goto ERROR; 
     110        name = dash + 1; 
     111 
     112        /* Some bus types (i2c) have an additional bus number. For these, the 
     113           next part is either a "*" (any bus of that type) or a decimal 
     114           number. */ 
     115        switch (res->bus) { 
     116        case SENSORS_CHIP_NAME_BUS_ANY_I2C: 
     117                if (!strncmp(name, "*-", 2)) { 
     118                        name += 2; 
     119                        break; 
     120                } 
     121 
     122                res->bus = strtoul(name, &dash, 10); 
     123                if (*name == '\0' || *dash != '-' || res->bus < 0) 
     124                        goto ERROR; 
     125                name = dash + 1; 
     126        } 
     127 
     128        /* Last part is the chip address, or "*" for any address. */ 
     129        if (!strcmp(name, "*")) { 
     130                res->addr = SENSORS_CHIP_NAME_ADDR_ANY; 
     131        } else { 
     132                res->addr = strtoul(name, &dash, 16); 
     133                if (*name == '\0' || *dash != '\0' || res->addr < 0) 
     134                        goto ERROR; 
     135        } 
     136 
     137        return 0; 
    152138 
    153139ERROR: 
    154   free(name); 
    155   return -SENSORS_ERR_CHIP_NAME; 
     140       free(res->prefix); 
     141       return -SENSORS_ERR_CHIP_NAME; 
    156142} 
    157143 
  • lm-sensors/branches/lm-sensors-3.0.0/lib/sensors.conf.5

    r4465 r4677  
    187187 
    188188A chip description is built from a couple of elements, separated by 
    189 dashes. To complicate matters, sometimes an element can also contain 
    190 dashes. This complicates the parsing algorithm, but is not too confusing 
    191 for humans (we hope!). 
     189dashes. 
    192190 
    193191The first element is the name of the chip type. Sometimes a single driver 
     
    217215for this element.  
    218216 
    219 There are some folding rules for wildcards to make things easier for humans 
    220 to read. Also, you can't specify the address if you wildcard the complete 
    221 second element. The following are all valid chip type specification based 
    222 on  
     217Note that it wouldn't make any sense to specify the address without the 
     218bus type. For this reason, the address part is plain omitted when the bus 
     219type isn't specified. 
     220The following are all valid chip type specification based on 
    223221.I lm78\-i2c\-1\-2d 
    224222or 
     
    251249.sp 0 
    252250*\-isa\-* 
    253 .sp 0 
    254 *\-* 
    255 .sp 0 
    256 * 
    257251.RE 
    258252