Changeset 4846

Show
Ignore:
Timestamp:
09/23/07 14:30:28 (1 year ago)
Author:
khali
Message:

New public library function: sensors_get_subfeature(). Applications can
use it to retrieve a specific subfeature by type. While it is slighly
less efficient than looping over sensors_get_all_subfeatures(), it
often makes the application code much more elegant.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • lm-sensors/branches/lm-sensors-3.0.0/lib/access.c

    r4845 r4846  
    392392                return subfeature; 
    393393        return NULL;    /* end of subfeature list */ 
     394} 
     395 
     396const sensors_subfeature * 
     397sensors_get_subfeature(const sensors_chip_name *name, 
     398                       const sensors_feature *feature, 
     399                       sensors_subfeature_type type) 
     400{ 
     401        const sensors_chip_features *chip; 
     402        int i; 
     403 
     404        if (!(chip = sensors_lookup_chip(name))) 
     405                return NULL;    /* No such chip */ 
     406 
     407        for (i = feature->first_subfeature; i < chip->subfeature_count && 
     408             chip->subfeature[i].mapping == feature->number; i++) { 
     409                if (chip->subfeature[i].type == type) 
     410                        return &chip->subfeature[i]; 
     411        } 
     412        return NULL;    /* No such subfeature */ 
    394413} 
    395414 
  • lm-sensors/branches/lm-sensors-3.0.0/lib/libsensors.3

    r4838 r4846  
    4747.B const sensors_feature *sensors_get_features(const sensors_chip_name *name, int *nr);\fP 
    4848.B const sensors_subfeature *sensors_get_all_subfeatures(const sensors_chip_name *name, const sensors_feature *feature, int *nr);\fP 
     49.B const sensors_subfeature *sensors_get_subfeature(const sensors_chip_name *name, const sensors_feature *feature, sensors_subfeature_type type);\fP 
    4950.B const char *libsensors_version; 
    5051.fi 
     
    141142data structures. 
    142143 
     144\fBconst sensors_subfeature *sensors_get_subfeature(const sensors_chip_name *name, const sensors_feature *feature, sensors_subfeature_type type);\fP 
     145.br 
     146This returns the subfeature of the given type for a given main feature, 
     147if it exists, NULL otherwise. 
     148Do not try to change the returned structure; you will corrupt internal 
     149data structures. 
     150 
    143151\fBconst char *libsensors_version;\fP 
    144152.br 
  • lm-sensors/branches/lm-sensors-3.0.0/lib/sensors.h

    r4838 r4846  
    222222                            const sensors_feature *feature, int *nr); 
    223223 
     224/* This returns the subfeature of the given type for a given main feature, 
     225   if it exists, NULL otherwise. 
     226   Do not try to change the returned structure; you will corrupt internal 
     227   data structures. */ 
     228const sensors_subfeature * 
     229sensors_get_subfeature(const sensors_chip_name *name, 
     230                       const sensors_feature *feature, 
     231                       sensors_subfeature_type type); 
     232 
    224233#ifdef __cplusplus 
    225234} 
  • lm-sensors/branches/lm-sensors-3.0.0/prog/sensord/chips.c

    r4838 r4846  
    141141} 
    142142 
    143 static void getAvailableFeatures (const sensors_chip_name *name, 
    144                                   const sensors_feature *feature, 
    145                                   short *has_features, 
    146                                   int *feature_nrs, int size, 
    147                                   int first_val) 
    148 { 
    149   const sensors_subfeature *iter; 
    150   int i = 0; 
    151  
    152   while ((iter = sensors_get_all_subfeatures(name, feature, &i))) { 
    153     int index0; 
    154  
    155     index0 = iter->type - first_val; 
    156     if (index0 < 0 || index0 >= size) 
    157       /* New feature in libsensors? Ignore. */ 
    158       continue; 
    159  
    160     has_features[index0] = 1; 
    161     feature_nrs[index0] = iter->number; 
    162   } 
    163 } 
    164  
    165 #define IN_FEATURE(x)      has_features[x - SENSORS_SUBFEATURE_IN_INPUT] 
    166 #define IN_FEATURE_NR(x)   feature_nrs[x - SENSORS_SUBFEATURE_IN_INPUT] 
    167143static void fillChipVoltage (FeatureDescriptor *voltage, 
    168144                             const sensors_chip_name *name, 
    169145                             const sensors_feature *feature) 
    170146{ 
    171   const int size = SENSORS_SUBFEATURE_IN_BEEP - SENSORS_SUBFEATURE_IN_INPUT + 1; 
    172   short has_features[SENSORS_SUBFEATURE_IN_BEEP - SENSORS_SUBFEATURE_IN_INPUT + 1] = { 0, }; 
    173   int feature_nrs[SENSORS_SUBFEATURE_IN_BEEP - SENSORS_SUBFEATURE_IN_INPUT + 1]; 
     147  const sensors_subfeature *sf, *sfmin, *sfmax; 
    174148  int pos = 0; 
    175149 
     
    177151  voltage->type = DataType_voltage; 
    178152 
    179   getAvailableFeatures (name, feature, has_features, 
    180                         feature_nrs, size, SENSORS_SUBFEATURE_IN_INPUT); 
    181  
    182   voltage->dataNumbers[pos++] = IN_FEATURE_NR(SENSORS_SUBFEATURE_IN_INPUT); 
    183  
    184   if (IN_FEATURE(SENSORS_SUBFEATURE_IN_MIN) && 
    185       IN_FEATURE(SENSORS_SUBFEATURE_IN_MAX)) { 
     153  sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_IN_INPUT); 
     154  if (sf) 
     155    voltage->dataNumbers[pos++] = sf->number; 
     156 
     157  sfmin = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_IN_MIN); 
     158  sfmax = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_IN_MAX); 
     159  if (sfmin && sfmax) { 
    186160    voltage->format = fmtVolts_2; 
    187     voltage->dataNumbers[pos++] = IN_FEATURE_NR(SENSORS_SUBFEATURE_IN_MIN)
    188     voltage->dataNumbers[pos++] = IN_FEATURE_NR(SENSORS_SUBFEATURE_IN_MAX)
     161    voltage->dataNumbers[pos++] = sfmin->number
     162    voltage->dataNumbers[pos++] = sfmax->number
    189163  } else { 
    190164    voltage->format = fmtVolt_2; 
     
    195169 
    196170  /* alarm if applicable */ 
    197   if (IN_FEATURE(SENSORS_SUBFEATURE_IN_ALARM)) { 
    198     voltage->alarmNumber = IN_FEATURE_NR(SENSORS_SUBFEATURE_IN_ALARM); 
    199   } else if (IN_FEATURE(SENSORS_SUBFEATURE_IN_MIN_ALARM)) { 
    200     voltage->alarmNumber = IN_FEATURE_NR(SENSORS_SUBFEATURE_IN_MIN_ALARM); 
    201   } else if (IN_FEATURE(SENSORS_SUBFEATURE_IN_MAX_ALARM)) { 
    202     voltage->alarmNumber = IN_FEATURE_NR(SENSORS_SUBFEATURE_IN_MAX_ALARM); 
     171  if ((sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_IN_ALARM)) || 
     172      (sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_IN_MIN_ALARM)) || 
     173      (sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_IN_MAX_ALARM))) { 
     174    voltage->alarmNumber = sf->number; 
    203175  } else { 
    204176    voltage->alarmNumber = -1; 
    205177  } 
    206178  /* beep if applicable */ 
    207   if (IN_FEATURE(SENSORS_SUBFEATURE_IN_BEEP)) { 
    208     voltage->beepNumber = IN_FEATURE_NR(SENSORS_SUBFEATURE_IN_ALARM)
     179  if ((sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_IN_BEEP))) { 
     180    voltage->beepNumber = sf->number
    209181  } else { 
    210182    voltage->beepNumber = -1; 
     
    212184} 
    213185 
    214 #define TEMP_FEATURE(x)      has_features[x - SENSORS_SUBFEATURE_TEMP_INPUT] 
    215 #define TEMP_FEATURE_NR(x)   feature_nrs[x - SENSORS_SUBFEATURE_TEMP_INPUT] 
    216186static void fillChipTemperature (FeatureDescriptor *temperature, 
    217187                                 const sensors_chip_name *name, 
    218188                                 const sensors_feature *feature) 
    219189{ 
    220   const int size = SENSORS_SUBFEATURE_TEMP_BEEP - SENSORS_SUBFEATURE_TEMP_INPUT + 1; 
    221   short has_features[SENSORS_SUBFEATURE_TEMP_BEEP - SENSORS_SUBFEATURE_TEMP_INPUT + 1] = { 0, }; 
    222   int feature_nrs[SENSORS_SUBFEATURE_TEMP_BEEP - SENSORS_SUBFEATURE_TEMP_INPUT + 1]; 
     190  const sensors_subfeature *sf, *sfmin, *sfmax, *sfhyst; 
    223191  int pos = 0; 
    224192 
     
    226194  temperature->type = DataType_temperature; 
    227195 
    228   getAvailableFeatures (name, feature, has_features, 
    229                         feature_nrs, size, SENSORS_SUBFEATURE_TEMP_INPUT); 
    230  
    231   temperature->dataNumbers[pos++] = TEMP_FEATURE_NR(SENSORS_SUBFEATURE_TEMP_INPUT); 
    232  
    233   if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_MIN) && 
    234       TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_MAX)) { 
     196  sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_TEMP_INPUT); 
     197  if (sf) 
     198    temperature->dataNumbers[pos++] = sf->number; 
     199 
     200  sfmin = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_TEMP_MIN); 
     201  sfmax = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_TEMP_MAX); 
     202  sfhyst = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_TEMP_MAX_HYST); 
     203  if (sfmin && sfmax) { 
    235204    temperature->format = fmtTemps_minmax_1; 
    236     temperature->dataNumbers[pos++] = TEMP_FEATURE_NR(SENSORS_SUBFEATURE_TEMP_MIN); 
    237     temperature->dataNumbers[pos++] = TEMP_FEATURE_NR(SENSORS_SUBFEATURE_TEMP_MAX); 
    238   } else if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_MAX) && 
    239              TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_MAX_HYST)) { 
     205    temperature->dataNumbers[pos++] = sfmin->number; 
     206    temperature->dataNumbers[pos++] = sfmax->number; 
     207  } else if (sfmax && sfhyst) { 
    240208    temperature->format = fmtTemps_1; 
    241     temperature->dataNumbers[pos++] = TEMP_FEATURE_NR(SENSORS_SUBFEATURE_TEMP_MAX)
    242     temperature->dataNumbers[pos++] = TEMP_FEATURE_NR(SENSORS_SUBFEATURE_TEMP_MAX_HYST)
     209    temperature->dataNumbers[pos++] = sfmax->number
     210    temperature->dataNumbers[pos++] = sfhyst->number
    243211  } else { 
    244212    temperature->format = fmtTemp_only; 
     
    249217 
    250218  /* alarm if applicable */ 
    251   if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_ALARM)) { 
    252     temperature->alarmNumber = TEMP_FEATURE_NR(SENSORS_SUBFEATURE_TEMP_ALARM); 
    253   } else if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_MAX_ALARM)) { 
    254     temperature->alarmNumber = TEMP_FEATURE_NR(SENSORS_SUBFEATURE_TEMP_MAX_ALARM); 
     219  if ((sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_TEMP_ALARM)) || 
     220      (sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_TEMP_MAX_ALARM))) { 
     221    temperature->alarmNumber = sf->number; 
    255222  } else { 
    256223    temperature->alarmNumber = -1; 
    257224  } 
    258225  /* beep if applicable */ 
    259   if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_BEEP)) { 
    260     temperature->beepNumber = TEMP_FEATURE_NR(SENSORS_SUBFEATURE_TEMP_BEEP)
     226  if ((sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_TEMP_BEEP))) { 
     227    temperature->beepNumber = sf->number
    261228  } else { 
    262229    temperature->beepNumber = -1; 
     
    264231} 
    265232 
    266 #define FAN_FEATURE(x)      has_features[x - SENSORS_SUBFEATURE_FAN_INPUT] 
    267 #define FAN_FEATURE_NR(x)   feature_nrs[x - SENSORS_SUBFEATURE_FAN_INPUT] 
    268233static void fillChipFan (FeatureDescriptor *fan, 
    269234                         const sensors_chip_name *name, 
    270235                         const sensors_feature *feature) 
    271236{ 
    272   const int size = SENSORS_SUBFEATURE_FAN_BEEP - SENSORS_SUBFEATURE_FAN_INPUT + 1; 
    273   short has_features[SENSORS_SUBFEATURE_FAN_BEEP - SENSORS_SUBFEATURE_FAN_INPUT + 1] = { 0, }; 
    274   int feature_nrs[SENSORS_SUBFEATURE_FAN_BEEP - SENSORS_SUBFEATURE_FAN_INPUT + 1]; 
     237  const sensors_subfeature *sf, *sfmin, *sfdiv; 
    275238  int pos = 0; 
    276239 
     
    278241  fan->type = DataType_rpm; 
    279242 
    280   getAvailableFeatures (name, feature, has_features, 
    281                         feature_nrs, size, SENSORS_SUBFEATURE_FAN_INPUT); 
    282  
    283   fan->dataNumbers[pos++] = FAN_FEATURE_NR(SENSORS_SUBFEATURE_FAN_INPUT); 
    284  
    285   if (FAN_FEATURE(SENSORS_SUBFEATURE_FAN_MIN)) { 
    286     fan->dataNumbers[pos++] = FAN_FEATURE_NR(SENSORS_SUBFEATURE_FAN_MIN); 
    287     if (FAN_FEATURE(SENSORS_SUBFEATURE_FAN_DIV)) { 
     243  sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_FAN_INPUT); 
     244  if (sf) 
     245    fan->dataNumbers[pos++] = sf->number; 
     246 
     247  sfmin = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_FAN_MIN); 
     248  if (sfmin) { 
     249    fan->dataNumbers[pos++] = sfmin->number; 
     250    sfdiv = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_FAN_DIV); 
     251    if (sfdiv) { 
    288252      fan->format = fmtFans_0; 
    289       fan->dataNumbers[pos++] = FAN_FEATURE_NR(SENSORS_SUBFEATURE_FAN_DIV)
     253      fan->dataNumbers[pos++] = sfdiv->number
    290254    } else { 
    291255      fan->format = fmtFans_nodiv_0; 
     
    299263 
    300264  /* alarm if applicable */ 
    301   if (FAN_FEATURE(SENSORS_SUBFEATURE_FAN_ALARM)) { 
    302     fan->alarmNumber = FAN_FEATURE_NR(SENSORS_SUBFEATURE_FAN_ALARM); 
     265  sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_FAN_ALARM); 
     266  if (sf) { 
     267    fan->alarmNumber = sf->number; 
    303268  } else { 
    304269    fan->alarmNumber = -1; 
    305270  } 
    306271  /* beep if applicable */ 
    307   if (FAN_FEATURE(SENSORS_SUBFEATURE_FAN_BEEP)) { 
    308     fan->beepNumber = FAN_FEATURE_NR(SENSORS_SUBFEATURE_FAN_BEEP); 
     272  sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_FAN_BEEP); 
     273  if (sf) { 
     274    fan->beepNumber = sf->number; 
    309275  } else { 
    310276    fan->beepNumber = -1; 
     
    316282                         const sensors_feature *feature) 
    317283{ 
    318   int i = 0; 
    319284  const sensors_subfeature *sub; 
    320285 
    321   sub = sensors_get_all_subfeatures(name, feature, &i); 
     286  sub = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_VID); 
    322287  if (!sub) 
    323288    return; 
     
    336301                                const sensors_feature *feature) 
    337302{ 
    338   int i = 0; 
    339303  const sensors_subfeature *sub; 
    340304 
    341   sub = sensors_get_all_subfeatures(name, feature, &i); 
     305  sub = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_BEEP_ENABLE); 
    342306  if (!sub) 
    343307    return; 
  • lm-sensors/branches/lm-sensors-3.0.0/prog/sensors/chips.c

    r4838 r4846  
    7171} 
    7272 
    73 static void sensors_get_available_features(const sensors_chip_name *name, 
    74                                            const sensors_feature *feature, 
    75                                            short *has_features, 
    76                                            double *feature_vals, int size, 
    77                                            int first_val) 
    78 
    79         const sensors_subfeature *iter; 
    80         int i = 0; 
    81  
    82         while ((iter = sensors_get_all_subfeatures(name, feature, &i))) { 
    83                 int indx, err; 
    84  
    85                 indx = iter->type - first_val; 
    86                 if (indx < 0 || indx >= size) 
    87                         /* New feature in libsensors? Ignore. */ 
    88                         continue; 
    89  
    90                 err = sensors_get_value(name, iter->number, &feature_vals[indx]); 
    91                 if (err) { 
    92                         printf("ERROR: Can't get %s data: %s\n", iter->name, 
    93                                sensors_strerror(err)); 
    94                         continue; 
    95                 } 
    96  
    97                 has_features[indx] = 1; 
    98         } 
     73static double get_value(const sensors_chip_name *name, int subfeat_nr) 
     74
     75        double val; 
     76        int err; 
     77 
     78        err = sensors_get_value(name, subfeat_nr, &val); 
     79        if (err) { 
     80                printf("ERROR: Can't get value of subfeature %d: %s\n", 
     81                       subfeat_nr, sensors_strerror(err)); 
     82                val = 0; 
     83        } 
     84        return val; 
    9985} 
    10086 
     
    139125} 
    140126 
    141 #define TEMP_FEATURE(x)         has_features[x - SENSORS_SUBFEATURE_TEMP_INPUT] 
    142 #define TEMP_FEATURE_VAL(x)     feature_vals[x - SENSORS_SUBFEATURE_TEMP_INPUT] 
    143127static void print_chip_temp(const sensors_chip_name *name, 
    144128                            const sensors_feature *feature, 
    145129                            int label_size) 
    146130{ 
     131        const sensors_subfeature *sf, *sfmin, *sfmax, *sfcrit, *sfhyst; 
    147132        double val, limit1, limit2; 
    148133        const char *s1, *s2; 
    149134        int alarm, crit_displayed = 0; 
    150135        char *label; 
    151         const int size = SENSORS_SUBFEATURE_TEMP_TYPE - SENSORS_SUBFEATURE_TEMP_INPUT + 1; 
    152         short has_features[SENSORS_SUBFEATURE_TEMP_TYPE - SENSORS_SUBFEATURE_TEMP_INPUT + 1] = { 0, }; 
    153         double feature_vals[SENSORS_SUBFEATURE_TEMP_TYPE - SENSORS_SUBFEATURE_TEMP_INPUT + 1] = { 0.0, }; 
    154136 
    155137        if (!(label = sensors_get_label(name, feature))) { 
     
    157139                return; 
    158140        } 
    159  
    160         sensors_get_available_features(name, feature, has_features, 
    161                                        feature_vals, size, 
    162                                        SENSORS_SUBFEATURE_TEMP_INPUT); 
    163         val = TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_INPUT); 
    164  
    165         alarm = TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_ALARM) && 
    166                 TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_ALARM); 
    167         if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_MAX)) { 
    168                 if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_MAX_ALARM) && 
    169                     TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_MAX_ALARM)) 
     141        print_label(label, label_size); 
     142        free(label); 
     143 
     144        sf = sensors_get_subfeature(name, feature, 
     145                                    SENSORS_SUBFEATURE_TEMP_INPUT); 
     146        val = sf ? get_value(name, sf->number) : 0; 
     147 
     148        sf = sensors_get_subfeature(name, feature, 
     149                                    SENSORS_SUBFEATURE_TEMP_ALARM); 
     150        alarm = sf && get_value(name, sf->number); 
     151 
     152        sfmin = sensors_get_subfeature(name, feature, 
     153                                       SENSORS_SUBFEATURE_TEMP_MIN); 
     154        sfmax = sensors_get_subfeature(name, feature, 
     155                                       SENSORS_SUBFEATURE_TEMP_MAX); 
     156        sfcrit = sensors_get_subfeature(name, feature, 
     157                                        SENSORS_SUBFEATURE_TEMP_CRIT); 
     158        if (sfmax) { 
     159                sf = sensors_get_subfeature(name, feature, 
     160                                        SENSORS_SUBFEATURE_TEMP_MAX_ALARM); 
     161                if (sf && get_value(name, sf->number)) 
    170162                        alarm |= 1; 
    171163 
    172                 if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_MIN)) { 
    173                         limit1 = TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_MIN); 
     164                if (sfmin) { 
     165                        limit1 = get_value(name, sfmin->number); 
    174166                        s1 = "low"; 
    175                         limit2 = TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_MAX); 
     167                        limit2 = get_value(name, sfmax->number); 
    176168                        s2 = "high"; 
    177169 
    178                         if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_MIN_ALARM) && 
    179                             TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_MIN_ALARM)) 
     170                        sf = sensors_get_subfeature(name, feature, 
     171                                        SENSORS_SUBFEATURE_TEMP_MIN_ALARM); 
     172                        if (sf && get_value(name, sf->number)) 
    180173                                alarm |= 1; 
    181174                } else { 
    182                         limit1 = TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_MAX); 
     175                        limit1 = get_value(name, sfmax->number); 
    183176                        s1 = "high"; 
    184177 
    185                         if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_MAX_HYST)) { 
    186                                 limit2 = TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_MAX_HYST); 
     178                        sfhyst = sensors_get_subfeature(name, feature, 
     179                                        SENSORS_SUBFEATURE_TEMP_MAX_HYST); 
     180                        if (sfhyst) { 
     181                                limit2 = get_value(name, sfhyst->number); 
    187182                                s2 = "hyst"; 
    188                         } else if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_CRIT)) { 
    189                                 limit2 = TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_CRIT); 
     183                        } else if (sfcrit) { 
     184                                limit2 = get_value(name, sfcrit->number); 
    190185                                s2 = "crit"; 
    191186 
    192                                 if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_CRIT_ALARM) && 
    193                                     TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_CRIT_ALARM)) 
     187                                sf = sensors_get_subfeature(name, feature, 
     188                                        SENSORS_SUBFEATURE_TEMP_CRIT_ALARM); 
     189                                if (sf && get_value(name, sf->number)) 
    194190                                        alarm |= 1; 
    195191                                crit_displayed = 1; 
     
    199195                        } 
    200196                } 
    201         } else if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_CRIT)) { 
    202                 limit1 = TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_CRIT); 
     197        } else if (sfcrit) { 
     198                limit1 = get_value(name, sfcrit->number); 
    203199                s1 = "crit"; 
    204200 
    205                 if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_CRIT_HYST)) { 
    206                         limit2 = TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_CRIT_HYST); 
     201                sfhyst = sensors_get_subfeature(name, feature, 
     202                                        SENSORS_SUBFEATURE_TEMP_CRIT_HYST); 
     203                if (sfhyst) { 
     204                        limit2 = get_value(name, sfhyst->number); 
    207205                        s2 = "hyst"; 
    208206                } else { 
     
    211209                } 
    212210 
    213                 if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_CRIT_ALARM) && 
    214                     TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_CRIT_ALARM)) 
     211                sf = sensors_get_subfeature(name, feature, 
     212                                        SENSORS_SUBFEATURE_TEMP_CRIT_ALARM); 
     213                if (sf && get_value(name, sf->number)) 
    215214                        alarm |= 1; 
    216215                crit_displayed = 1; 
     
    220219        } 
    221220 
    222         print_label(label, label_size); 
    223         free(label); 
    224  
    225         if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_FAULT) && 
    226             TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_FAULT)) { 
     221 
     222        sf = sensors_get_subfeature(name, feature, 
     223                                    SENSORS_SUBFEATURE_TEMP_FAULT); 
     224        if (sf && get_value(name, sf->number)) { 
    227225                printf("   FAULT  "); 
    228226        } else { 
     
    233231        print_temp_limits(limit1, limit2, s1, s2, alarm); 
    234232 
    235         if (!crit_displayed && TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_CRIT)) { 
    236                 limit1 = TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_CRIT); 
     233        if (!crit_displayed && sfcrit) { 
     234                limit1 = get_value(name, sfcrit->number); 
    237235                s1 = "crit"; 
    238236 
    239                 if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_CRIT_HYST)) { 
    240                         limit2 = TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_CRIT_HYST); 
     237                sfhyst = sensors_get_subfeature(name, feature, 
     238                                        SENSORS_SUBFEATURE_TEMP_CRIT_HYST); 
     239                if (sfhyst) { 
     240                        limit2 = get_value(name, sfhyst->number); 
    241241                        s2 = "hyst"; 
    242242                } else { 
     
    245245                } 
    246246 
    247                 alarm = TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_CRIT_ALARM) && 
    248                         TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_CRIT_ALARM); 
     247                sf = sensors_get_subfeature(name, feature, 
     248                                        SENSORS_SUBFEATURE_TEMP_CRIT_ALARM); 
     249                if (sf && get_value(name, sf->number)) 
     250                        alarm |= 1; 
    249251 
    250252                printf("\n%*s", label_size + 10, ""); 
     
    253255 
    254256        /* print out temperature sensor info */ 
    255         if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_TYPE)) { 
    256                 int sens = (int)TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_TYPE); 
     257        sf = sensors_get_subfeature(name, feature, 
     258                                    SENSORS_SUBFEATURE_TEMP_TYPE); 
     259        if (sf) { 
     260                int sens = (int)get_value(name, sf->number); 
    257261 
    258262                /* older kernels / drivers sometimes report a beta value for 
     
    272276} 
    273277 
    274 #define IN_FEATURE(x)           has_features[x - SENSORS_SUBFEATURE_IN_INPUT] 
    275 #define IN_FEATURE_VAL(x)       feature_vals[x - SENSORS_SUBFEATURE_IN_INPUT] 
    276278static void print_chip_in(const sensors_chip_name *name, 
    277279                          const sensors_feature *feature, 
    278280                          int label_size) 
    279281{ 
    280         const int size = SENSORS_SUBFEATURE_IN_MAX_ALARM - SENSORS_SUBFEATURE_IN_INPUT + 1; 
    281         short has_features[SENSORS_SUBFEATURE_IN_MAX_ALARM - SENSORS_SUBFEATURE_IN_INPUT + 1] = { 0, }; 
    282         double feature_vals[SENSORS_SUBFEATURE_IN_MAX_ALARM - SENSORS_SUBFEATURE_IN_INPUT + 1] = { 0.0, }; 
     282        const sensors_subfeature *sf, *sfmin, *sfmax; 
    283283        double val, alarm_max, alarm_min; 
    284284        char *label; 
     
    288288                return; 
    289289        } 
    290  
    291         sensors_get_available_features(name, feature, has_features, 
    292                                        feature_vals, size, 
    293                                        SENSORS_SUBFEATURE_IN_INPUT); 
    294         val = IN_FEATURE_VAL(SENSORS_SUBFEATURE_IN_INPUT); 
    295  
    296290        print_label(label, label_size); 
    297291        free(label); 
     292 
     293        sf = sensors_get_subfeature(name, feature, 
     294                                    SENSORS_SUBFEATURE_IN_INPUT); 
     295        val = sf ? get_value(name, sf->number) : 0; 
    298296        printf("%+6.2f V", val); 
    299297 
    300         if (IN_FEATURE(SENSORS_SUBFEATURE_IN_MIN) && 
    301             IN_FEATURE(SENSORS_SUBFEATURE_IN_MAX)) 
     298        sfmin = sensors_get_subfeature(name, feature, 
     299                                       SENSORS_SUBFEATURE_IN_MIN); 
     300        sfmax = sensors_get_subfeature(name, feature, 
     301                                       SENSORS_SUBFEATURE_IN_MAX); 
     302        if (sfmin && sfmax) 
    302303                printf("  (min = %+6.2f V, max = %+6.2f V)", 
    303                        IN_FEATURE_VAL(SENSORS_SUBFEATURE_IN_MIN), 
    304                        IN_FEATURE_VAL(SENSORS_SUBFEATURE_IN_MAX)); 
    305         else if (IN_FEATURE(SENSORS_SUBFEATURE_IN_MIN)
     304                       get_value(name, sfmin->number), 
     305                       get_value(name, sfmax->number)); 
     306        else if (sfmin
    306307                printf("  (min = %+6.2f V)", 
    307                        IN_FEATURE_VAL(SENSORS_SUBFEATURE_IN_MIN)); 
    308         else if (IN_FEATURE(SENSORS_SUBFEATURE_IN_MAX)
     308                       get_value(name, sfmin->number)); 
     309        else if (sfmax
    309310                printf("  (max = %+6.2f V)", 
    310                        IN_FEATURE_VAL(SENSORS_SUBFEATURE_IN_MAX)); 
    311  
    312         if (IN_FEATURE(SENSORS_SUBFEATURE_IN_MAX_ALARM) || 
    313             IN_FEATURE(SENSORS_SUBFEATURE_IN_MIN_ALARM)) { 
    314                 alarm_max = IN_FEATURE_VAL(SENSORS_SUBFEATURE_IN_MAX_ALARM); 
    315                 alarm_min = IN_FEATURE_VAL(SENSORS_SUBFEATURE_IN_MIN_ALARM); 
     311                       get_value(name, sfmax->number)); 
     312 
     313        sf = sensors_get_subfeature(name, feature, 
     314                                    SENSORS_SUBFEATURE_IN_ALARM); 
     315        sfmin = sensors_get_subfeature(name, feature, 
     316                                       SENSORS_SUBFEATURE_IN_MIN_ALARM); 
     317        sfmax = sensors_get_subfeature(name, feature, 
     318                                       SENSORS_SUBFEATURE_IN_MAX_ALARM); 
     319        if (sfmin || sfmax) { 
     320                alarm_max = sfmax ? get_value(name, sfmax->number) : 0; 
     321                alarm_min = sfmin ? get_value(name, sfmin->number) : 0; 
    316322 
    317323                if (alarm_min || alarm_max) { 
     
    325331                        printf(")"); 
    326332                } 
    327         } else if (IN_FEATURE(SENSORS_SUBFEATURE_IN_ALARM)) { 
     333        } else if (sf) { 
    328334                printf("   %s", 
    329                 IN_FEATURE_VAL(SENSORS_SUBFEATURE_IN_ALARM) ? "ALARM" : ""); 
     335                       get_value(name, sf->number) ? "ALARM" : ""); 
    330336        } 
    331337 
     
    333339} 
    334340 
    335 #define FAN_FEATURE(x)          has_features[x - SENSORS_SUBFEATURE_FAN_INPUT] 
    336 #define FAN_FEATURE_VAL(x)      feature_vals[x - SENSORS_SUBFEATURE_FAN_INPUT] 
    337341static void print_chip_fan(const sensors_chip_name *name, 
    338342                           const sensors_feature *feature, 
    339343                           int label_size) 
    340344{ 
    341         char *label; 
    342         const int size = SENSORS_SUBFEATURE_FAN_DIV - SENSORS_SUBFEATURE_FAN_INPUT + 1; 
    343         short has_features[SENSORS_SUBFEATURE_FAN_DIV - SENSORS_SUBFEATURE_FAN_INPUT + 1] = { 0, }; 
    344         double feature_vals[SENSORS_SUBFEATURE_FAN_DIV - SENSORS_SUBFEATURE_FAN_INPUT + 1] = { 0.0, }; 
     345        const sensors_subfeature *sf, *sfmin, *sfdiv; 
     346        char *label; 
    345347        double val; 
    346348 
     
    349351                return; 
    350352        } 
    351  
    352353        print_label(label, label_size); 
    353354        free(label); 
    354355 
    355         sensors_get_available_features(name, feature, has_features, 
    356                                        feature_vals, size, 
    357                                        SENSORS_SUBFEATURE_FAN_INPUT); 
    358         val = FAN_FEATURE_VAL(SENSORS_SUBFEATURE_FAN_INPUT); 
    359  
    360         if (FAN_FEATURE(SENSORS_SUBFEATURE_FAN_FAULT) && 
    361             FAN_FEATURE_VAL(SENSORS_SUBFEATURE_FAN_FAULT)) 
     356        sf = sensors_get_subfeature(name, feature, 
     357                                    SENSORS_SUBFEATURE_FAN_INPUT); 
     358        val = sf ? get_value(name, sf->number) : 0; 
     359        sf = sensors_get_subfeature(name, feature, 
     360                                    SENSORS_SUBFEATURE_FAN_FAULT); 
     361        if (sf && get_value(name, sf->number)) 
    362362                printf("   FAULT"); 
    363363        else 
    364364                printf("%4.0f RPM", val); 
    365365 
    366         if (FAN_FEATURE(SENSORS_SUBFEATURE_FAN_MIN) && 
    367             FAN_FEATURE(SENSORS_SUBFEATURE_FAN_DIV)) 
     366        sfmin = sensors_get_subfeature(name, feature, 
     367                                       SENSORS_SUBFEATURE_FAN_MIN); 
     368        sfdiv = sensors_get_subfeature(name, feature, 
     369                                       SENSORS_SUBFEATURE_FAN_DIV); 
     370        if (sfmin && sfdiv) 
    368371                printf("  (min = %4.0f RPM, div = %1.0f)", 
    369                        FAN_FEATURE_VAL(SENSORS_SUBFEATURE_FAN_MIN), 
    370                        FAN_FEATURE_VAL(SENSORS_SUBFEATURE_FAN_DIV)); 
    371         else if (FAN_FEATURE(SENSORS_SUBFEATURE_FAN_MIN)
     372                       get_value(name, sfmin->number), 
     373                       get_value(name, sfdiv->number)); 
     374        else if (sfmin
    372375                printf("  (min = %4.0f RPM)", 
    373                        FAN_FEATURE_VAL(SENSORS_SUBFEATURE_FAN_MIN)); 
    374         else if (FAN_FEATURE(SENSORS_SUBFEATURE_FAN_DIV)
     376                       get_value(name, sfmin->number)); 
     377        else if (sfdiv
    375378                printf("  (div = %1.0f)", 
    376                        FAN_FEATURE_VAL(SENSORS_SUBFEATURE_FAN_DIV)); 
    377  
    378         if (FAN_FEATURE(SENSORS_SUBFEATURE_FAN_ALARM) && 
    379             FAN_FEATURE_VAL(SENSORS_SUBFEATURE_FAN_ALARM)) { 
     379                       get_value(name, sfdiv->number)); 
     380 
     381        sf = sensors_get_subfeature(name, feature, 
     382                                    SENSORS_SUBFEATURE_FAN_ALARM); 
     383        if (sf && get_value(name, sf->number)) { 
    380384                printf("  ALARM"); 
    381385        } 
     
    391395        const sensors_subfeature *subfeature; 
    392396        double vid; 
    393         int i = 0; 
    394  
    395         subfeature = sensors_get_all_subfeatures(name, feature, &i); 
     397 
     398        subfeature = sensors_get_subfeature(name, feature, 
     399                                           SENSORS_SUBFEATURE_VID); 
    396400        if (!subfeature) 
    397401                return; 
     
    412416        const sensors_subfeature *subfeature; 
    413417        double beep_enable; 
    414         int i = 0; 
    415  
    416         subfeature = sensors_get_all_subfeatures(name, feature, &i); 
     418 
     419        subfeature = sensors_get_subfeature(name, feature, 
     420                                           SENSORS_SUBFEATURE_BEEP_ENABLE); 
    417421        if (!subfeature) 
    418422                return;