Changeset 5194

Show
Ignore:
Timestamp:
04/20/08 19:29:53 (7 months ago)
Author:
khali
Message:

Split print_i2c_busses into a gathering part and a printing part.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • i2c-tools/trunk/tools/i2cbusses.c

    r5193 r5194  
    55    Copyright (c) 1999-2003  Frodo Looijaard <frodol@dds.nl> and 
    66                             Mark D. Studebaker <mdsxyz123@yahoo.com> 
     7    Copyright (C) 2008       Jean Delvare <khali@linux-fr.org> 
    78 
    89    This program is free software; you can redistribute it and/or modify 
     
    5556}; 
    5657 
     58struct i2c_adap { 
     59        int nr; 
     60        char *name; 
     61        const char *funcs; 
     62        const char *algo; 
     63}; 
     64 
    5765static enum adt i2c_get_funcs(int i2cbus) 
    5866{ 
     
    8189} 
    8290 
    83 /* 
    84    this just prints out the installed i2c busses in a consistent format, whether 
    85    on a 2.4 kernel using /proc or a 2.6 kernel using /sys. 
    86    If procfmt == 1, print out exactly /proc/bus/i2c format on stdout. 
    87    This allows this to be used in a program to emulate /proc/bus/i2c on a 
    88    sysfs system. 
    89 */ 
    90 void print_i2c_busses(int procfmt) 
     91/* Remove trailing spaces from a string 
     92   Return the new string length including the trailing NUL */ 
     93static int rtrim(char *s) 
     94
     95        int i; 
     96 
     97        for (i = strlen(s) - 1; i >= 0 && (s[i] == ' ' || s[i] == '\n'); i--) 
     98                s[i] = '\0'; 
     99        return i + 2; 
     100
     101 
     102static void free_adapters(struct i2c_adap *adapters) 
     103
     104        int i; 
     105 
     106        for (i = 0; adapters[i].name; i++) 
     107                free(adapters[i].name); 
     108        free(adapters); 
     109
     110 
     111/* We allocate space for the adapters in bunches. The last item is a 
     112   terminator, so here we start with room for 7 adapters, which should 
     113   be enough in most cases. If not, we allocate more later as needed. */ 
     114#define BUNCH   8 
     115 
     116/* n must match the size of adapters at calling time */ 
     117static struct i2c_adap *more_adapters(struct i2c_adap *adapters, int n) 
     118
     119        struct i2c_adap *new_adapters; 
     120 
     121        new_adapters = realloc(adapters, (n + BUNCH) * sizeof(struct i2c_adap)); 
     122        if (!new_adapters) { 
     123                free_adapters(adapters); 
     124                return NULL; 
     125        } 
     126        memset(new_adapters + n, 0, BUNCH * sizeof(struct i2c_adap)); 
     127 
     128        return new_adapters; 
     129
     130 
     131static struct i2c_adap *gather_i2c_busses(void) 
    91132{ 
    92133        FILE *fptr; 
     
    99140        int foundsysfs = 0; 
    100141        int count=0; 
    101  
     142        struct i2c_adap *adapters; 
     143 
     144        adapters = calloc(BUNCH, sizeof(struct i2c_adap)); 
     145        if (!adapters) 
     146                return NULL; 
    102147 
    103148        /* look in /proc/bus/i2c */ 
    104149        if((fptr = fopen("/proc/bus/i2c", "r"))) { 
    105150                while(fgets(s, 100, fptr)) { 
    106                         if(count++ == 0 && !procfmt) 
    107                                 fprintf(stderr,"  Installed I2C busses:\n"); 
    108                         if(procfmt) 
    109                                 printf("%s", s);         
    110                         else 
    111                                 fprintf(stderr, "    %s", s);    
     151                        char *algo, *name, *type, *all; 
     152                        int len_algo, len_name, len_type; 
     153                        int i2cbus; 
     154 
     155                        algo = strrchr(s, '\t'); 
     156                        *(algo++) = '\0'; 
     157                        len_algo = rtrim(algo); 
     158 
     159                        name = strrchr(s, '\t'); 
     160                        *(name++) = '\0'; 
     161                        len_name = rtrim(name); 
     162 
     163                        type = strrchr(s, '\t'); 
     164                        *(type++) = '\0'; 
     165                        len_type = rtrim(type); 
     166 
     167                        sscanf(s, "i2c-%d", &i2cbus); 
     168 
     169                        if ((count + 1) % BUNCH == 0) { 
     170                                /* We need more space */ 
     171                                adapters = more_adapters(adapters, count + 1); 
     172                                if (!adapters) 
     173                                        return NULL; 
     174                        } 
     175 
     176                        all = malloc(len_name + len_type + len_algo); 
     177                        if (all == NULL) { 
     178                                free_adapters(adapters); 
     179                                return NULL; 
     180                        } 
     181                        adapters[count].nr = i2cbus; 
     182                        adapters[count].name = strcpy(all, name); 
     183                        adapters[count].funcs = strcpy(all + len_name, type); 
     184                        adapters[count].algo = strcpy(all + len_name + len_type, 
     185                                                      algo); 
     186                        count++; 
    112187                } 
    113188                fclose(fptr); 
     
    190265                        if ((border = strchr(x, '\n')) != NULL) 
    191266                                *border = 0; 
    192                         if(count++ == 0 && !procfmt) 
    193                                 fprintf(stderr,"  Installed I2C busses:\n"); 
    194                         /* match 2.4 /proc/bus/i2c format as closely as possible */ 
     267                        if (!sscanf(de->d_name, "i2c-%d", &i2cbus)) 
     268                                continue; 
    195269                        if(!strncmp(x, "ISA ", 4)) { 
    196270                                type = adt_isa; 
    197                         } else if(!sscanf(de->d_name, "i2c-%d", &i2cbus)) { 
    198                                 type = adt_dummy; 
    199271                        } else { 
    200272                                /* Attempt to probe for adapter capabilities */ 
     
    202274                        } 
    203275 
    204                         if (procfmt) 
    205                                 printf("%s\t%-10s\t%-32s\t%s\n", de->d_name, 
    206                                         adap_types[type].funcs, x, adap_types[type].algo); 
    207                         else 
    208                                 fprintf(stderr, "    %s\t%-10s\t%s\n", de->d_name, 
    209                                         adap_types[type].funcs, x); 
     276                        if ((count + 1) % BUNCH == 0) { 
     277                                /* We need more space */ 
     278                                adapters = more_adapters(adapters, count + 1); 
     279                                if (!adapters) 
     280                                        return NULL; 
     281                        } 
     282 
     283                        adapters[count].nr = i2cbus; 
     284                        adapters[count].name = strdup(x); 
     285                        if (adapters[count].name == NULL) { 
     286                                free_adapters(adapters); 
     287                                return NULL; 
     288                        } 
     289                        adapters[count].funcs = adap_types[type].funcs; 
     290                        adapters[count].algo = adap_types[type].algo; 
     291                        count++; 
    210292                } 
    211293        } 
     
    213295 
    214296done: 
     297        return adapters; 
     298} 
     299 
     300/* 
     301   this just prints out the installed i2c busses in a consistent format, whether 
     302   on a 2.4 kernel using /proc or a 2.6 kernel using /sys. 
     303   If procfmt == 1, print out exactly /proc/bus/i2c format on stdout. 
     304   This allows this to be used in a program to emulate /proc/bus/i2c on a 
     305   sysfs system. 
     306*/ 
     307void print_i2c_busses(int procfmt) 
     308{ 
     309        struct i2c_adap *adapters; 
     310        int count; 
     311 
     312        adapters = gather_i2c_busses(); 
     313        if (adapters == NULL) { 
     314                fprintf(stderr, "Error: Out of memory!\n"); 
     315                return; 
     316        } 
     317 
     318        for (count = 0; adapters[count].name; count++) { 
     319                if (count == 0 && !procfmt) 
     320                        fprintf(stderr,"  Installed I2C busses:\n"); 
     321                if (procfmt) 
     322                        /* match 2.4 /proc/bus/i2c format as closely as possible */ 
     323                        printf("i2c-%d\t%-10s\t%-32s\t%s\n", 
     324                                adapters[count].nr, 
     325                                adapters[count].funcs, 
     326                                adapters[count].name, 
     327                                adapters[count].algo); 
     328                else 
     329                        fprintf(stderr, "    i2c-%d\t%-10s\t%s\n", 
     330                                adapters[count].nr, 
     331                                adapters[count].funcs, 
     332                                adapters[count].name); 
     333        } 
     334 
    215335        if(count == 0 && !procfmt) 
    216336                fprintf(stderr,"Error: No I2C busses found!\n" 
    217337                               "Be sure you have done 'modprobe i2c-dev'\n" 
    218338                               "and also modprobed your i2c bus drivers\n"); 
     339 
     340        free_adapters(adapters); 
    219341} 
    220342