Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / util / einfo.c
diff --git a/qemu/roms/ipxe/src/util/einfo.c b/qemu/roms/ipxe/src/util/einfo.c
new file mode 100644 (file)
index 0000000..d215589
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2010 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <getopt.h>
+
+#define eprintf(...) fprintf ( stderr, __VA_ARGS__ )
+
+/** Command-line options */
+struct options {
+};
+
+/** Error usage information */
+struct einfo {
+       /** Size of error information record */
+       uint32_t size;
+       /** Error number */
+       uint32_t error;
+       /** Offset to error description (NUL-terminated) */
+       uint32_t desc;
+       /** Offset to file name (NUL-terminated) */
+       uint32_t file;
+       /** Line number */
+       uint32_t line;
+} __attribute__ (( packed ));
+
+/**
+ * Process einfo file
+ *
+ * @v infile           Filename
+ * @v opts             Command-line options
+ */
+static void einfo ( const char *infile,
+                   struct options *opts __attribute__ (( unused )) ) {
+       int fd;
+       struct stat stat;
+       size_t len;
+       void *start;
+       struct einfo *einfo;
+
+       /* Open einfo file */
+       if ( ( fd = open ( infile, O_RDONLY ) ) < 0 ) {
+               eprintf ( "Cannot open \"%s\": %s\n",
+                         infile, strerror ( errno ) );
+               exit ( 1 );
+       }
+
+       /* Get file size */
+       if ( fstat ( fd, &stat ) < 0 ) {
+               eprintf ( "Cannot stat \"%s\": %s\n",
+                         infile, strerror ( errno ) );
+               exit ( 1 );
+       }
+       len = stat.st_size;
+
+       if ( len ) {
+
+               /* Map file */
+               if ( ( start = mmap ( NULL, len, PROT_READ, MAP_SHARED,
+                                     fd, 0 ) ) == MAP_FAILED ) {
+                       eprintf ( "Cannot mmap \"%s\": %s\n",
+                                 infile, strerror ( errno ) );
+                       exit ( 1 );
+               }
+
+               /* Iterate over einfo records */
+               for ( einfo = start ; ( ( void * ) einfo ) < ( start + len ) ;
+                     einfo = ( ( ( void * ) einfo ) + einfo->size ) ) {
+                       printf ( "%08x\t%s\t%d\t%s\n", einfo->error,
+                                ( ( ( char * ) einfo ) + einfo->file ),
+                                einfo->line,
+                                ( ( ( char * ) einfo ) + einfo->desc ) );
+               }
+
+               /* Unmap file */
+               munmap ( start, len );
+       }
+
+       /* Close file */
+       close ( fd );
+}
+
+/**
+ * Print help
+ *
+ * @v program_name     Program name
+ */
+static void print_help ( const char *program_name ) {
+       eprintf ( "Syntax: %s file1.einfo [file2.einfo...]\n",
+                 program_name );
+}
+
+/**
+ * Parse command-line options
+ *
+ * @v argc             Argument count
+ * @v argv             Argument list
+ * @v opts             Options structure to populate
+ */
+static int parse_options ( const int argc, char **argv,
+                          struct options *opts __attribute__ (( unused )) ) {
+       int c;
+
+       while (1) {
+               int option_index = 0;
+               static struct option long_options[] = {
+                       { "help", 0, NULL, 'h' },
+                       { 0, 0, 0, 0 }
+               };
+
+               if ( ( c = getopt_long ( argc, argv, "s:h",
+                                        long_options,
+                                        &option_index ) ) == -1 ) {
+                       break;
+               }
+
+               switch ( c ) {
+               case 'h':
+                       print_help ( argv[0] );
+                       exit ( 0 );
+               case '?':
+               default:
+                       exit ( 2 );
+               }
+       }
+       return optind;
+}
+
+int main ( int argc, char **argv ) {
+       struct options opts = {
+       };
+       int infile_index;
+       const char *infile;
+
+       /* Parse command-line arguments */
+       infile_index = parse_options ( argc, argv, &opts );
+       if ( argc <= infile_index ) {
+               print_help ( argv[0] );
+               exit ( 2 );
+       }
+
+       /* Process each einfo file */
+       for ( ; infile_index < argc ; infile_index++ ) {
+               infile = argv[infile_index];
+               einfo ( infile, &opts );
+       }
+
+       return 0;
+}