ed7392d56d2ae1e6d059a2819871a733d79ac7ef
[mw/micromonitor-lm32.git] / umon_main / host / src / utils / monsym.c
1 #include <stdio.h>
2 #include <ctype.h>
3 #include <sys/stat.h>
4 #include <string.h>
5 #include "utils.h"
6
7 #define LINESIZE 256
8
9 extern  int optind;
10 extern  char *optarg;
11 extern  long strtol();
12
13 char    *getword(char *,int,int);
14
15 #define MAXSYMSIZE 63
16
17 struct symline {
18         char                    symbol[MAXSYMSIZE+1];
19         unsigned long   value;
20 };
21
22 int             debug, symTot, truncTot, verbose;
23 FILE    *symfp = (FILE *)NULL;
24
25 /* getword():
26         return the "word"th whitespace delimited character string found on
27         the "line"th line of "string".
28         String is assumed to be null terminated.
29 */
30
31 char *
32 getword(char *string, int word, int line)
33 {
34         int             i;
35         char    *retword, *p;
36
37         while (isspace((int)*string))
38                 string++;
39         for (i=1;i<line;i++) {
40                 while (*string != '\n') {
41                         if (*string++ == '\0')
42                                 return("");
43                 }
44                 while (isspace((int)*string))
45                         string++;
46         }
47         for (i=1;i<word;i++) {
48                 while ((*string != ' ') && (*string != '\t')) {
49                         if (*string++ == '\0')
50                                 return("");
51                 }
52                 while (isspace((int)*string))
53                         string++;
54         }
55         retword = Malloc(strlen(string));
56         p = retword;
57         while (!isspace((int)*string)) {
58                 if (*string == '\0')
59                         break;
60                 *p++ = *string++;
61         }
62         *p = '\0';
63         if (strlen(retword) > MAXSYMSIZE) {
64                 if (verbose)
65                         fprintf(stderr,"Symbol truncated: %s\n",retword);
66                 truncTot++;
67         }
68         return(retword);
69 }
70
71 char *usage_txt[] = {
72         "Usage: monsym [options] {infile}",
73         " Convert a tabulated file of symbol/value combinations to the format",
74         " used by MicroMonitor's command line symbol retrieval...",
75         "",
76         " Options:",
77         " -d{data_col}     column in input file that contains data (default=1)",
78         " -s{symbol_col}   column in input file that contains symbol (default=3)",
79         " -l{max_ln_size}  maximum accepted line size (default=64)",
80         " -p{data_prefix}  prefix added to data column",
81         " -P{sym_prefix}   prefix added to symbol column",
82         " -S{x|d}          sort numerically based on data column (hex or decimal)",
83         " -V               display version of tool",
84         " -v               verbose mode",
85         0,
86 };
87
88 main(int argc,char *argv[])
89 {
90         char *dataPrefix, *symbolPrefix, *fmt, line[LINESIZE];
91         int     opt, i, j, sortbase;
92         int     symbolColumn, dataColumn, lineMax;
93         struct  stat    finfo;
94         struct symline  *symLines, *slp;
95
96         truncTot = symTot = 0;
97         symLines = (struct symline *)0;
98         sortbase = debug = verbose = 0;
99         symbolColumn = 3;
100         dataColumn = 1;
101         dataPrefix = "";
102         symbolPrefix = "";
103         lineMax = 64;
104         while((opt=getopt(argc,argv,"d:l:P:p:s:S:vV")) != EOF) {
105                 switch(opt) {
106                 case 'd':
107                         dataColumn = atoi(optarg);
108                         break;
109                 case 'l':
110                         lineMax = atoi(optarg);
111                         break;
112                 case 'P':
113                         symbolPrefix = optarg;
114                         break;
115                 case 'p':
116                         dataPrefix = optarg;
117                         break;
118                 case 'S':
119                         if (*optarg == 'x')
120                                 sortbase = 16;
121                         else if (*optarg == 'd')
122                                 sortbase = 10;
123                         else
124                                 usage(0);
125                         break;
126                 case 's':
127                         symbolColumn = atoi(optarg);
128                         break;
129                 case 'V':
130                         showVersion();
131                         break;
132                 case 'v':  
133                         verbose = 1;
134                         break;
135                 default:
136                         usage(0);
137                 }
138         }
139
140         if (argc != optind+1)
141                 usage(0);
142
143         /* Open the symbol file (built by nm): */
144         if ((symfp = fopen(argv[optind],"r")) == (FILE *)NULL) {
145                 perror(argv[optind]);
146                 usage(0);
147         }
148
149         if (stat(argv[optind],&finfo) == -1) {
150                 perror(argv[optind]);
151                 usage(0);
152         }
153
154         if (sortbase) {
155                 int     lsize, line_cnt;
156                 char *symbol, *data, outline[LINESIZE];
157
158                 line_cnt = 0;
159                 while(1) {
160                         if (fgets(line,LINESIZE,symfp) == NULL)
161                                 break;
162                         line_cnt++;
163                 }
164
165                 symLines = (struct symline *)Malloc(line_cnt * sizeof(struct symline));
166                 slp = symLines;
167                 rewind(symfp);
168
169                 while(1)
170                 {
171                         if (fgets(line,LINESIZE,symfp) == NULL)
172                                 break;
173         
174                         /* Get the symbolname in column "symbolColumn": */
175                         symbol = getword(line,symbolColumn,1);
176                         if (*symbol == '\0')
177                                 continue;
178         
179                         /* Get the data in column "dataColumn": */
180                         data = getword(line,dataColumn,1);
181                         if (*data == '\0') {
182                                 free(symbol);
183                                 continue;
184                         }
185                         
186                         symTot++;
187                         slp->value = strtoul(data,0,sortbase);
188                         strncpy(slp->symbol,symbol,MAXSYMSIZE);
189                         slp->symbol[MAXSYMSIZE] = 0;
190                         free(symbol);
191                         free(data);
192                         slp++;
193                 }
194
195                 /* Run a bubble sort on that list based on slp->value, then print
196                  * out the list...
197                  */
198                 for(i=1;i<line_cnt;++i) {
199                         struct symline tmpsymline;
200
201                         for(j=line_cnt-1;j>=i;--j) {
202                                 if ((symLines[j-1].value > symLines[j].value) > 0) {
203                                         tmpsymline = symLines[j-1];
204                                         symLines[j-1] = symLines[j];
205                                         symLines[j] = tmpsymline;
206                                 }
207                         }
208                 }
209
210                 if (sortbase == 16)
211                         fmt = "%s%s %s%x\n";
212                 else
213                         fmt = "%s%s %s%d\n";
214
215                 for(i=0;i<line_cnt;i++) {
216                         printf(fmt,
217                                 symbolPrefix,symLines[i].symbol,
218                                 dataPrefix,symLines[i].value);
219                 }
220                 
221                 free(symLines);
222         }
223         else {
224                 while(1)
225                 {
226                         int     lsize;
227                         char *symbol, *data, outline[LINESIZE];
228         
229                         if (fgets(line,LINESIZE,symfp) == NULL)
230                                 break;
231         
232                         /* Get the symbolname in column "symbolColumn": */
233                         symbol = getword(line,symbolColumn,1);
234                         if (*symbol == '\0')
235                                 continue;
236         
237                         /* Get the data in column "dataColumn": */
238                         data = getword(line,dataColumn,1);
239                         if (*data == '\0') {
240                                 free(symbol);
241                                 continue;
242                         }
243                         symTot++;
244                         lsize = sprintf(outline,"%s%s %s%s",
245                                 symbolPrefix,symbol,dataPrefix,data);
246                         if (lsize <= lineMax)
247                                 puts(outline);
248                         free(symbol);
249                         free(data);
250                 }
251         }
252         fprintf(stderr,"%d symbols processed\n",symTot);
253         if (truncTot)
254                 fprintf(stderr,"%d symbols truncated\n",truncTot);
255         if (symfp)
256                 fclose(symfp);
257         exit(0);
258 }
259