Enable -Werror for romcc
[coreboot.git] / util / options / build_opt_tbl.c
index ae36f87e03c9940f448496e2ab25cb6cd215c1c8..b89bb4f1d52be4e834d43c284a2430fe96ade93e 100644 (file)
@@ -25,6 +25,7 @@
 #include <ctype.h>
 #include <errno.h>
 #include <libgen.h>
+#define UTIL_BUILD_OPTION_TABLE
 #include "../../src/include/pc80/mc146818rtc.h"
 #include "../../src/include/boot/coreboot_tables.h"
 
@@ -32,7 +33,7 @@
 #define INPUT_LINE_MAX 256
 #define MAX_VALUE_BYTE_LENGTH 64
 
-#define TMPFILE_LEN 256
+#define TMPFILE_LEN 25600
 #define TMPFILE_TEMPLATE "/build_opt_tbl_XXXXXX"
 
 static unsigned char cmos_table[4096];
@@ -99,7 +100,7 @@ static void test_for_entry_overlaps(void *entry_start, void *entry_end)
                                        ce->name);
                                exit(1);
                        }
-                       /* test if entries 8 or more in length are even bytes */ 
+                       /* test if entries 8 or more in length are even bytes */
                        if(ce->length%8){
                                 printf("Error - Entry %s length over 8 must be a multiple of 8\n",
                                         ce->name);
@@ -141,8 +142,9 @@ static void display_usage(char *name)
        printf("                       [--option filename]\n");
        printf("                       [--header filename]\n\n");
        printf("--config = Build the definitions table from the given file.\n");
+       printf("--binary = Output a binary file with the definitions.\n");
        printf("--option = Output a C source file with the definitions.\n");
-       printf("--header = Ouput a C header file with the definitions.\n");
+       printf("--header = Output a C header file with the definitions.\n");
        exit(1);
 }
 
@@ -164,7 +166,7 @@ static unsigned long get_number(char *line, char **ptr, int base)
        char *ptr2;
        value = strtoul(*ptr, &ptr2, base);
        if (ptr2 == *ptr) {
-               printf("Error missing digits at: \n%s\n in line:\n%s\n", 
+               printf("Error missing digits at: \n%s\n in line:\n%s\n",
                        *ptr, line);
                exit(1);
        }
@@ -237,21 +239,22 @@ static int is_ident(char *str)
  *
  * The input comes from the configuration file which contains two parts
  * entries and enumerations.  Each section is started with the key words
- * entries and enumerations.  Records then follow in their respective 
+ * entries and enumerations.  Records then follow in their respective
  * formats.
  *
  * The output of this program is the cmos definitions table.  It is stored
- * in the cmos_table array. If this module is called, and the global 
+ * in the cmos_table array. If this module is called, and the global
  * table_file has been implimented by the user, the table is also written
  * to the specified file.
  *
- * This program exits with a return code of 1 on error.  It returns 0 on 
+ * This program exits with a return code of 1 on error.  It returns 0 on
  * successful completion
  */
 int main(int argc, char **argv)
 {
        int i;
        char *config=0;
+       char *binary=0;
        char *option=0;
        char *header=0;
        FILE *fp;
@@ -273,6 +276,7 @@ int main(int argc, char **argv)
        int enum_length;
        int len;
        char buf[16];
+       char val;
 
         for(i=1;i<argc;i++) {
                 if(argv[i][0]!='-') {
@@ -287,6 +291,12 @@ int main(int argc, char **argv)
                                                 }
                                                 config=argv[++i];
                                                 break;
+                                        case 'b':  /* Emit a binary file */
+                                                if(strcmp(&argv[i][2],"binary")) {
+                                                        display_usage(argv[0]);
+                                                }
+                                                binary=argv[++i];
+                                                break;
                                         case 'o':  /* use a cmos definitions table file */
                                                 if(strcmp(&argv[i][2],"option")) {
                                                         display_usage(argv[0]);
@@ -336,7 +346,7 @@ int main(int argc, char **argv)
        ce=(struct cmos_entries*)(cmos_table+(ct->header_length));
        cptr = (char*)ce;
        for(;;){  /* this section loops through the entry records */
-               if(fgets(line,INPUT_LINE_MAX,fp)==NULL) 
+               if(fgets(line,INPUT_LINE_MAX,fp)==NULL)
                        break; /* end if no more input */
                // FIXME mode should be a single enum.
                if(!entry_mode) {  /* skip input until the entries key word */
@@ -362,8 +372,9 @@ int main(int argc, char **argv)
                }
 
                /* skip commented and blank lines */
-               if(line[0]=='#') continue;
-               if(line[strspn(line," ")]=='\n') continue;
+               val = line[strspn(line," ")];
+               /* takes care of *nix, Mac and Windows line ending formats */
+               if (val=='#' || val=='\n' || val=='\r') continue;
                /* scan in the input data */
                sscanf(line,"%d %d %c %d %s",
                        &ce->bit,&ce->length,&uc,&ce->config_id,&ce->name[0]);
@@ -378,8 +389,8 @@ int main(int argc, char **argv)
                        exit(1);
                }
                if (!is_ident((char *)ce->name)) {
-                       fprintf(stderr, 
-                               "Error - Name %s is an invalid identifier in line\n %s\n", 
+                       fprintf(stderr,
+                               "Error - Name %s is an invalid identifier in line\n %s\n",
                                ce->name, line);
                        exit(1);
                }
@@ -408,7 +419,7 @@ int main(int argc, char **argv)
 
        for(;enum_mode;){ /* loop to build the enumerations section */
                long ptr;
-               if(fgets(line,INPUT_LINE_MAX,fp)==NULL) 
+               if(fgets(line,INPUT_LINE_MAX,fp)==NULL)
                        break; /* go till end of input */
 
                if (strstr(line, "checksums") != 0) {
@@ -432,7 +443,7 @@ int main(int argc, char **argv)
                for(cnt=0;(line[ptr]!='\n')&&(cnt<31);ptr++,cnt++)
                        c_enums->text[cnt]=line[ptr];
                c_enums->text[cnt]=0;
-       
+
                /* make the record int aligned */
                cnt++;
                if(cnt%4)
@@ -473,7 +484,7 @@ int main(int argc, char **argv)
 
                skip_spaces(line, &ptr);
                cs->location = get_number(line, &ptr, 10);
-               
+
                /* Make certain there are spaces until the end of the line */
                skip_spaces(line, &ptr);
 
@@ -498,7 +509,7 @@ int main(int argc, char **argv)
                        exit(1);
                }
                if ((cs->location >= (CMOS_IMAGE_BUFFER_SIZE*8)) ||
-                       ((cs->location + 16) > (CMOS_IMAGE_BUFFER_SIZE*8))) 
+                       ((cs->location + 16) > (CMOS_IMAGE_BUFFER_SIZE*8)))
                {
                        fprintf(stderr, "Error - location is to big in line\n%s\n", line);
                        exit(1);
@@ -518,8 +529,7 @@ int main(int argc, char **argv)
        /* See if we want to output a C source file */
        if(option) {
                int err=0;
-               strncpy(tempfilename, dirname(strdup(option)), TMPFILE_LEN);
-               strncat(tempfilename, TMPFILE_TEMPLATE, TMPFILE_LEN);
+               snprintf(tempfilename, TMPFILE_LEN, "%s%s", dirname(strdup(option)), TMPFILE_TEMPLATE);
                tempfile = mkstemp(tempfilename);
                if(tempfile == -1) {
                         perror("Error - Could not create temporary file");
@@ -533,7 +543,7 @@ int main(int argc, char **argv)
                }
 
                /* write the header */
-               if(!fwrite("unsigned char option_table[] = {",1,32,fp)) {
+               if(fwrite("unsigned char option_table[] = {",1,32,fp) != 32) {
                        perror("Error - Could not write image file");
                        fclose(fp);
                        unlink(tempfilename);
@@ -541,14 +551,14 @@ int main(int argc, char **argv)
                }
                /* write the array values */
                for(i=0; i<(int)(ct->size-1); i++) {
-                       if(!(i%10) && !err) err=!fwrite("\n\t",1,2,fp);
+                       if(!(i%10) && !err) err=(fwrite("\n\t",1,2,fp) != 2);
                        sprintf(buf,"0x%02x,",cmos_table[i]);
-                       if(!err) err=!fwrite(buf,1,5,fp);
+                       if(!err) err=(fwrite(buf,1,5,fp) != 5);
                }
                /* write the end */
                sprintf(buf,"0x%02x\n",cmos_table[i]);
-               if(!err) err=!fwrite(buf,1,4,fp);
-               if(!fwrite("};\n",1,3,fp)) {
+               if(!err) err=(fwrite(buf,1,4,fp) != 4);
+               if(fwrite("};\n",1,3,fp) != 3) {
                        perror("Error - Could not write image file");
                        fclose(fp);
                        unlink(tempfilename);
@@ -565,13 +575,46 @@ int main(int argc, char **argv)
                }
        }
 
+       /* See if we also want to output a binary file */
+       if(binary) {
+               int err=0;
+               snprintf(tempfilename, TMPFILE_LEN, "%s%s", dirname(strdup(binary)), TMPFILE_TEMPLATE);
+               tempfile = mkstemp(tempfilename);
+               if(tempfile == -1) {
+                        perror("Error - Could not create temporary file");
+                        exit(1);
+               }
+
+               if((fp=fdopen(tempfile,"wb"))==NULL){
+                       perror("Error - Could not open temporary file");
+                       unlink(tempfilename);
+                       exit(1);
+               }
+
+               /* write the array values */
+               if(fwrite(cmos_table, (int)(ct->size-1), 1, fp) != 1) {
+                       perror("Error - Could not write image file");
+                       fclose(fp);
+                       unlink(tempfilename);
+                       exit(1);
+               }
+
+               fclose(fp);
+               UNLINK_IF_NECESSARY(binary);
+               if (rename(tempfilename, binary)) {
+                       fprintf(stderr, "Error - Could not write %s: ", binary);
+                       perror(NULL);
+                       unlink(tempfilename);
+                       exit(1);
+               }
+       }
+
        /* See if we also want to output a C header file */
        if (header) {
                struct cmos_option_table *hdr;
                struct lb_record *ptr, *end;
 
-               strncpy(tempfilename, dirname(strdup(header)), TMPFILE_LEN);
-               strncat(tempfilename, TMPFILE_TEMPLATE, TMPFILE_LEN);
+               snprintf(tempfilename, TMPFILE_LEN, "%s%s", dirname(strdup(header)), TMPFILE_TEMPLATE);
                tempfile = mkstemp(tempfilename);
                if(tempfile == -1) {
                        perror("Error - Could not create temporary file");
@@ -590,6 +633,10 @@ int main(int argc, char **argv)
                /* Walk through the entry records */
                ptr = (struct lb_record *)(cmos_table + hdr->header_length);
                end = (struct lb_record *)(cmos_table + hdr->size);
+               fprintf(fp, "/* This file is autogenerated.\n"
+                           " * See mainboard's cmos.layout file.\n */\n\n"
+                           "#ifndef __OPTION_TABLE_H\n#define __OPTION_TABLE_H\n\n");
+
                for(;ptr < end; ptr = (struct lb_record *)(((char *)ptr) + ptr->size)) {
                        if (ptr->tag != LB_TAG_OPTION) {
                                continue;
@@ -619,6 +666,7 @@ int main(int argc, char **argv)
                        unlink(tempfilename);
                        exit(1);
                }
+               fprintf(fp, "\n#endif // __OPTION_TABLE_H\n");
                fclose(fp);
 
                UNLINK_IF_NECESSARY(header);