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