From 588f3d7f11c87965d3d19a9c8a587b329d7d20be Mon Sep 17 00:00:00 2001 From: Aaron Plattner Date: Wed, 2 May 2012 08:06:32 -0700 Subject: 302.07 --- Makefile | 65 ++++--- backup.c | 15 ++ common-utils/common-utils.c | 338 ++++++++++++++++++++++++++++++++- common-utils/common-utils.h | 78 +++++++- common-utils/gen-manpage-opts-helper.c | 181 ++++++++++++++++++ common-utils/gen-manpage-opts-helper.h | 24 +++ common-utils/nvgetopt.c | 125 ++++++++++++ common-utils/nvgetopt.h | 24 +++ common-utils/src.mk | 6 + crc.c | 1 + dist-files.mk | 4 - format.c | 323 ------------------------------- format.h | 41 ---- gen-manpage-opts.c | 114 +---------- help-args.c | 123 ------------ help-args.h | 28 --- install-from-cwd.c | 2 +- log.c | 1 - makeself-help-script.c | 35 +++- misc.c | 21 +- misc.h | 37 +--- mkprecompiled.c | 32 ++-- nvidia-installer.c | 47 +++-- nvidia-installer.h | 10 - option_table.h | 17 +- stream-ui.c | 18 +- user-interface.c | 3 +- utils.mk | 30 +-- version.mk | 2 +- 29 files changed, 961 insertions(+), 784 deletions(-) create mode 100644 common-utils/gen-manpage-opts-helper.c create mode 100644 common-utils/gen-manpage-opts-helper.h delete mode 100644 format.c delete mode 100644 format.h delete mode 100644 help-args.c delete mode 100644 help-args.h diff --git a/Makefile b/Makefile index 45c9945..087b60e 100644 --- a/Makefile +++ b/Makefile @@ -122,15 +122,15 @@ CFLAGS += -I. -imacros $(CONFIG_H) -I $(OUTPUTDIR) CFLAGS += -I $(COMMON_UTILS_DIR) HOST_CFLAGS += -I. -imacros $(CONFIG_H) -I $(OUTPUTDIR) -LDFLAGS += -L. -ldl +LDFLAGS += -L. +LIBS += -ldl MKPRECOMPILED_SRC = crc.c mkprecompiled.c MKPRECOMPILED_OBJS = $(call BUILD_OBJECT_LIST,$(MKPRECOMPILED_SRC)) MAKESELF_HELP_SCRIPT_SRC = makeself-help-script.c -MAKESELF_HELP_SCRIPT_SRC += help-args.c -MAKESELF_HELP_SCRIPT_SRC += format.c MAKESELF_HELP_SCRIPT_SRC += $(COMMON_UTILS_DIR)/common-utils.c +MAKESELF_HELP_SCRIPT_SRC += $(COMMON_UTILS_DIR)/nvgetopt.c BUILD_MAKESELF_OBJECT_LIST = \ $(patsubst %.o,%.makeself.o,$(call BUILD_OBJECT_LIST,$(1))) @@ -157,45 +157,44 @@ install: NVIDIA_INSTALLER_install MKPRECOMPILED_install MANPAGE_install \ MAKESELF_HELP_SCRIPT_install NVIDIA_INSTALLER_install: $(NVIDIA_INSTALLER) - $(MKDIR) $(bindir) - $(INSTALL) $(INSTALL_BIN_ARGS) $< $(bindir)/$(notdir $<) + $(MKDIR) $(BINDIR) + $(INSTALL) $(INSTALL_BIN_ARGS) $< $(BINDIR)/$(notdir $<) MKPRECOMPILED_install: $(MKPRECOMPILED) - $(MKDIR) $(bindir) - $(INSTALL) $(INSTALL_BIN_ARGS) $< $(bindir)/$(notdir $<) + $(MKDIR) $(BINDIR) + $(INSTALL) $(INSTALL_BIN_ARGS) $< $(BINDIR)/$(notdir $<) MAKESELF_HELP_SCRIPT_install: $(MAKESELF_HELP_SCRIPT) - $(MKDIR) $(bindir) - $(INSTALL) $(INSTALL_BIN_ARGS) $< $(bindir)/$(notdir $<) + $(MKDIR) $(BINDIR) + $(INSTALL) $(INSTALL_BIN_ARGS) $< $(BINDIR)/$(notdir $<) MANPAGE_install: $(MANPAGE) - $(MKDIR) $(mandir) - $(INSTALL) $(INSTALL_DOC_ARGS) $< $(mandir)/$(notdir $<) + $(MKDIR) $(MANDIR) + $(INSTALL) $(INSTALL_DOC_ARGS) $< $(MANDIR)/$(notdir $<) $(MKPRECOMPILED): $(MKPRECOMPILED_OBJS) - $(call quiet_cmd,LINK) -o $@ \ - $(MKPRECOMPILED_OBJS) $(CFLAGS) $(LDFLAGS) $(BIN_LDFLAGS) + $(call quiet_cmd,LINK) $(CFLAGS) $(LDFLAGS) $(BIN_LDFLAGS) \ + $(MKPRECOMPILED_OBJS) -o $@ $(LIBS) $(call quiet_cmd,STRIP_CMD) $@ $(MAKESELF_HELP_SCRIPT): $(MAKESELF_HELP_SCRIPT_OBJS) - $(call quiet_cmd,HOST_LINK) -o $@ \ - $(MAKESELF_HELP_SCRIPT_OBJS) $(HOST_CFLAGS) $(HOST_LDFLAGS) \ - $(HOST_BIN_LDFLAGS) + $(call quiet_cmd,HOST_LINK) $(HOST_CFLAGS) $(HOST_LDFLAGS) \ + $(HOST_BIN_LDFLAGS) $(MAKESELF_HELP_SCRIPT_OBJS) -o $@ $(call quiet_cmd,STRIP_CMD) $@ $(NVIDIA_INSTALLER): $(INSTALLER_OBJS) - $(call quiet_cmd,LINK) -o $@ $(INSTALLER_OBJS) $(CFLAGS) $(LDFLAGS) \ - -Bstatic $(PCI_LDFLAGS) -lpci -Bdynamic $(BIN_LDFLAGS) + $(call quiet_cmd,LINK) $(CFLAGS) $(LDFLAGS) $(PCI_LDFLAGS) \ + $(BIN_LDFLAGS) $(INSTALLER_OBJS) -o $@ \ + $(LIBS) -Bstatic -lpci -Bdynamic $(call quiet_cmd,STRIP_CMD) $@ $(GEN_UI_ARRAY): gen-ui-array.c $(CONFIG_H) - $(call quiet_cmd,HOST_CC) -o $@ $< $(HOST_CFLAGS) $(HOST_LDFLAGS) \ - $(HOST_BIN_LDFLAGS) + $(call quiet_cmd,HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) \ + $(HOST_BIN_LDFLAGS) $< -o $@ $(NCURSES_UI_SO): $(call BUILD_OBJECT_LIST,ncurses-ui.c) - $(call quiet_cmd,LINK) -o $@ -shared $< \ - $(NCURSES_LDFLAGS) -lncurses \ - $(CFLAGS) $(LDFLAGS) $(BIN_LDFLAGS) + $(call quiet_cmd,LINK) -shared $(NCURSES_LDFLAGS) \ + $(CFLAGS) $(LDFLAGS) $(BIN_LDFLAGS) $< -o $@ -lncurses $(LIBS) $(NCURSES_UI_SO_C): $(GEN_UI_ARRAY) $(NCURSES_UI_SO) $(call quiet_cmd,GEN_UI_ARRAY) $(NCURSES_UI_SO) ncurses_ui_array > $@ @@ -237,7 +236,7 @@ $(foreach src,$(MAKESELF_HELP_SCRIPT_SRC),\ # define the rule to generate $(STAMP_C) $(eval $(call DEFINE_STAMP_C_RULE, $(INSTALLER_OBJS),$(NVIDIA_INSTALLER_PROGRAM_NAME))) -$(CONFIG_H): +$(CONFIG_H): $(VERSION_MK) @ $(RM) -f $@ @ $(MKDIR) $(OUTPUTDIR) @ $(ECHO) "#define INSTALLER_OS \"$(TARGET_OS)\"" >> $@ @@ -298,18 +297,24 @@ AUTO_TEXT = ".\\\" WARNING: THIS FILE IS AUTO-GENERATED! Edit $< instead." doc: $(MANPAGE) -$(eval $(call DEFINE_OBJECT_RULE,HOST_CC,gen-manpage-opts.c)) +GEN_MANPAGE_OPTS_SRC = gen-manpage-opts.c +GEN_MANPAGE_OPTS_SRC += $(COMMON_UTILS_DIR)/gen-manpage-opts-helper.c -$(call BUILD_OBJECT_LIST,gen-manpage-opts.c): $(CONFIG_H) +GEN_MANPAGE_OPTS_OBJS = $(call BUILD_OBJECT_LIST,$(GEN_MANPAGE_OPTS_SRC)) -$(GEN_MANPAGE_OPTS): $(call BUILD_OBJECT_LIST,gen-manpage-opts.c) - $(call quiet_cmd,HOST_LINK) $< -o $@ \ - $(HOST_CFLAGS) $(HOST_LDFLAGS) $(HOST_BIN_LDFLAGS) +$(foreach src, $(GEN_MANPAGE_OPTS_SRC), \ + $(eval $(call DEFINE_OBJECT_RULE,HOST_CC,$(src)))) + +$(GEN_MANPAGE_OPTS_OBJS): $(CONFIG_H) + +$(GEN_MANPAGE_OPTS): $(GEN_MANPAGE_OPTS_OBJS) + $(call quiet_cmd,HOST_LINK) \ + $(HOST_CFLAGS) $(HOST_LDFLAGS) $(HOST_BIN_LDFLAGS) $^ -o $@ $(OPTIONS_1_INC): $(GEN_MANPAGE_OPTS) @./$< > $@ -$(MANPAGE): nvidia-installer.1.m4 $(OPTIONS_1_INC) +$(MANPAGE): nvidia-installer.1.m4 $(OPTIONS_1_INC) $(VERSION_MK) $(call quiet_cmd,M4) \ -D__HEADER__=$(AUTO_TEXT) \ -D__VERSION__=$(NVIDIA_INSTALLER_VERSION) \ diff --git a/backup.c b/backup.c index e99ed82..61a44b8 100644 --- a/backup.c +++ b/backup.c @@ -1194,6 +1194,21 @@ int uninstall_existing_driver(Options *op, const int interactive) return TRUE; } + if (interactive && op->uninstall) { + ret = ui_yes_no(op, FALSE, + "If you plan to no longer use the NVIDIA driver, you " + "should make sure that no X screens are configured to " + "use the NVIDIA X driver in your X configuration file. " + "If you used nvidia-xconfig to configure X, it may have " + "created a backup of your original configuration. Would " + "you like to run `nvidia-xconfig --restore-original-" + "backup` to attempt restoration of the original X " + "configuration file?"); + if (ret) { + run_nvidia_xconfig(op, TRUE); + } + } + ret = do_uninstall(op); if (ret) { diff --git a/common-utils/common-utils.c b/common-utils/common-utils.c index 701bb07..98b92fe 100644 --- a/common-utils/common-utils.c +++ b/common-utils/common-utils.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 NVIDIA Corporation + * Copyright (C) 2010-2012 NVIDIA Corporation * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -149,6 +149,35 @@ char *nvstrdup(const char *s) +/* + * nvstrndup() - implementation of strndup() that checks return values; if + * an error occurs, an error is printed to stderr and exit is called + * -- this function will only return on success. + */ + +char *nvstrndup(const char *s, size_t n) +{ + char *m; + + if (!s) return NULL; + + m = malloc(n + 1); + + if (!m) { + fprintf(stderr, "%s: memory allocation failure during malloc (%s)! \n", + PROGRAM_NAME, strerror(errno)); + exit(1); + } + + strncpy (m, s, n); + m[n] = '\0'; + + return m; + +} /* nvstrndup() */ + + + /* * nvstrtolower() - convert the given string to lowercase. */ @@ -250,3 +279,310 @@ char *tilde_expansion(const char *str) return ret; } /* tilde_expansion() */ + + +/****************************************************************************/ +/* TextRows helper functions */ +/****************************************************************************/ + +/* + * nv_format_text_rows() - this function breaks the given string str + * into some number of rows, where each row is not longer than the + * specified width. + * + * If prefix is non-NULL, the first line is prepended with the prefix, + * and subsequent lines are indented to line up with the prefix. + * + * If word_boundary is TRUE, then attempt to only break lines on + * boundaries between words. + */ + +TextRows *nv_format_text_rows(const char *prefix, + const char *str, + int width, int word_boundary) +{ + int len, prefix_len, z, w, i; + char *line, *buf, *local_prefix, *a, *b, *c; + TextRows *t; + + /* initialize the TextRows structure */ + + t = (TextRows *) malloc(sizeof(TextRows)); + + if (!t) return NULL; + + t->t = NULL; + t->n = 0; + t->m = 0; + + if (!str) return t; + + buf = strdup(str); + + if (!buf) return t; + + z = strlen(buf); /* length of entire string */ + a = buf; /* pointer to the start of the string */ + + /* initialize the prefix fields */ + + if (prefix) { + prefix_len = strlen(prefix); + local_prefix = strdup(prefix); + } else { + prefix_len = 0; + local_prefix = NULL; + } + + /* adjust the max width for any prefix */ + + w = width - prefix_len; + + do { + /* + * if the string will fit on one line, point b to the end of the + * string + */ + + if (z < w) b = a + z; + + /* + * if the string won't fit on one line, move b to where the + * end of the line should be, and then move b back until we + * find a space; if we don't find a space before we back b all + * the way up to a, just assign b to where the line should end. + */ + + else { + b = a + w; + + if (word_boundary) { + while ((b >= a) && (!isspace(*b))) b--; + if (b <= a) b = a + w; + } + } + + /* look for any newline inbetween a and b, and move b to it */ + + for (c = a; c < b; c++) if (*c == '\n') { b = c; break; } + + /* + * copy the string that starts at a and ends at b, prepending + * with a prefix, if present + */ + + len = b-a; + len += prefix_len; + line = (char *) malloc(len+1); + if (local_prefix) strncpy(line, local_prefix, prefix_len); + strncpy(line + prefix_len, a, len - prefix_len); + line[len] = '\0'; + + /* append the new line to the array of text rows */ + + t->t = (char **) realloc(t->t, sizeof(char *) * (t->n + 1)); + t->t[t->n] = line; + t->n++; + + if (t->m < len) t->m = len; + + /* + * adjust the length of the string and move the pointer to the + * beginning of the new line + */ + + z -= (b - a + 1); + a = b + 1; + + /* move to the first non whitespace character (excluding newlines) */ + + if (word_boundary && isspace(*b)) { + while ((z) && (isspace(*a)) && (*a != '\n')) a++, z--; + } else { + if (!isspace(*b)) z++, a--; + } + + if (local_prefix) { + for (i = 0; i < prefix_len; i++) local_prefix[i] = ' '; + } + + } while (z > 0); + + if (local_prefix) free(local_prefix); + free(buf); + + return t; +} + + +/* + * nv_text_rows_append() - append the given msg to the existing TextRows + */ + +void nv_text_rows_append(TextRows *t, const char *msg) +{ + int len; + + t->t = realloc(t->t, sizeof(char *) * (t->n + 1)); + + if (msg) { + t->t[t->n] = strdup(msg); + len = strlen(msg); + if (t->m < len) t->m = len; + } else { + t->t[t->n] = NULL; + } + + t->n++; +} + +/* + * nv_concat_text_rows() - concatenate two text rows, storing the + * result in t0 + */ + +#define NV_MAX(x,y) ((x) > (y) ? (x) : (y)) + +void nv_concat_text_rows(TextRows *t0, TextRows *t1) +{ + int n, i; + + n = t0->n + t1->n; + + t0->t = realloc(t0->t, sizeof(char *) * n); + + for (i = 0; i < t1->n; i++) { + t0->t[i + t0->n] = strdup(t1->t[i]); + } + + t0->m = NV_MAX(t0->m, t1->m); + t0->n = n; + +} /* nv_concat_text_rows() */ + + +/* + * nv_free_text_rows() - free the TextRows data structure allocated by + * nv_format_text_rows() + */ + +void nv_free_text_rows(TextRows *t) +{ + int i; + + if (!t) return; + for (i = 0; i < t->n; i++) free(t->t[i]); + if (t->t) free(t->t); + free(t); + +} /* nv_free_text_rows() */ + + +/****************************************************************************/ +/* printing helper functions */ +/****************************************************************************/ + +#define DEFAULT_WIDTH 75 + +static unsigned short __terminal_width = 0; + +/* + * reset_current_terminal_width() - if new_val is zero, then use the + * TIOCGWINSZ ioctl to get the current width of the terminal, and + * assign it the value to __terminal_width. If the ioctl fails, use a + * hardcoded constant. If new_val is non-zero, then use new_val. + */ + +void reset_current_terminal_width(unsigned short new_val) +{ + struct winsize ws; + + if (new_val) { + __terminal_width = new_val; + return; + } + + if (ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) { + __terminal_width = DEFAULT_WIDTH; + } else { + __terminal_width = ws.ws_col - 1; + } +} + +/* + * Call silence_fmt(1) to turn fmtout(), fmtoutp() and format() into noops. + */ +static int __silent = 0; + +void silence_fmt(int val) +{ + __silent = val; +} + + +static void vformat(FILE *stream, const int wb, + const char *prefix, const char *buf) +{ + int i; + TextRows *t; + + if (!__terminal_width) reset_current_terminal_width(0); + + t = nv_format_text_rows(prefix, buf, __terminal_width, wb); + + for (i = 0; i < t->n; i++) fprintf(stream, "%s\n", t->t[i]); + + nv_free_text_rows(t); +} + + +#define NV_VFORMAT(stream, wb, prefix, fmt) \ +do { \ + char *buf; \ + NV_VSNPRINTF(buf, fmt); \ + vformat(stream, wb, prefix, buf); \ + free (buf); \ +} while(0) + + +void fmtout(const char *fmt, ...) +{ + if (__silent > 0) { + return; + } + NV_VFORMAT(stdout, TRUE, NULL, fmt); +} + + +void fmtoutp(const char *prefix, const char *fmt, ...) +{ + if (__silent > 0) { + return; + } + NV_VFORMAT(stdout, TRUE, prefix, fmt); +} + + +void fmterr(const char *fmt, ...) +{ + vformat(stderr, 0, NULL, ""); + NV_VFORMAT(stderr, TRUE, "ERROR: ", fmt); + vformat(stderr, 0, NULL, ""); +} + + +void fmtwarn(const char *fmt, ...) +{ + vformat(stderr, 0, NULL, ""); + NV_VFORMAT(stderr, TRUE, "WARNING: ", fmt); + vformat(stderr, 0, NULL, ""); +} + + +void fmt(FILE *stream, const char *prefix, const char *fmt, ...) +{ + if (__silent > 0) { + return; + } + NV_VFORMAT(stream, TRUE, prefix, fmt); +} diff --git a/common-utils/common-utils.h b/common-utils/common-utils.h index 04d5f3b..e0d9314 100644 --- a/common-utils/common-utils.h +++ b/common-utils/common-utils.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 NVIDIA Corporation + * Copyright (C) 2010-2012 NVIDIA Corporation * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -17,6 +17,9 @@ #ifndef __COMMON_UTILS_H__ #define __COMMON_UTILS_H__ +#include +#include + #if !defined(TRUE) #define TRUE 1 #endif @@ -25,13 +28,86 @@ #define FALSE 0 #endif +#define ARRAY_LEN(_arr) (sizeof(_arr) / sizeof(_arr[0])) + +#define TAB " " +#define BIGTAB " " + +typedef struct { + char **t; /* the text rows */ + int n; /* number of rows */ + int m; /* maximum row length */ +} TextRows; + void *nvalloc(size_t size); char *nvstrcat(const char *str, ...); void *nvrealloc(void *ptr, size_t size); char *nvstrdup(const char *s); +char *nvstrndup(const char *s, size_t n); char *nvstrtolower(char *s); void nvfree(void *s); char *tilde_expansion(const char *str); +TextRows *nv_format_text_rows(const char *prefix, + const char *str, + int width, int word_boundary); +void nv_text_rows_append(TextRows *t, const char *msg); +void nv_concat_text_rows(TextRows *t0, TextRows *t1); +void nv_free_text_rows(TextRows *t); + +void reset_current_terminal_width(unsigned short new_val); + +void silence_fmt(int val); +void fmtout(const char *fmt, ...); +void fmtoutp(const char *prefix, const char *fmt, ...); +void fmterr(const char *fmt, ...); +void fmtwarn(const char *fmt, ...); +void fmt(FILE *stream, const char *prefix, const char *fmt, ...); + +/* + * NV_VSNPRINTF(): macro that assigns buf using vsnprintf(). This is + * correct for differing semantics of the vsnprintf() return value: + * + * -1 when the buffer is not long enough (glibc < 2.1) + * + * or + * + * the length the string would have been if the buffer had been large + * enough (glibc >= 2.1) + * + * This macro allocates memory for buf; the caller should free it when + * done. + */ + +#define NV_FMT_BUF_LEN 256 + +#define NV_VSNPRINTF(buf, fmt) \ +do { \ + if (!fmt) { \ + (buf) = NULL; \ + } else { \ + va_list ap; \ + int len, current_len = NV_FMT_BUF_LEN; \ + \ + (buf) = malloc(current_len); \ + \ + while (1) { \ + va_start(ap, fmt); \ + len = vsnprintf((buf), current_len, (fmt), ap); \ + va_end(ap); \ + \ + if ((len > -1) && (len < current_len)) { \ + break; \ + } else if (len > -1) { \ + current_len = len + 1; \ + } else { \ + current_len += NV_FMT_BUF_LEN; \ + } \ + free(buf); \ + (buf) = malloc(current_len); \ + } \ + } \ +} while (0) + #endif /* __COMMON_UTILS_H__ */ diff --git a/common-utils/gen-manpage-opts-helper.c b/common-utils/gen-manpage-opts-helper.c new file mode 100644 index 0000000..d2abb1c --- /dev/null +++ b/common-utils/gen-manpage-opts-helper.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see . + */ + +#include +#include +#include + +#include "nvgetopt.h" +#include "gen-manpage-opts-helper.h" + +static void print_option(const NVGetoptOption *o) +{ + char scratch[64], *s; + int j, len; + + int italics, bold, omitWhiteSpace; + + /* if we are going to need the argument, process it now */ + if (o->flags & NVGETOPT_HAS_ARGUMENT) { + if (o->arg_name) { + strcpy(scratch, o->arg_name); + } else { + len = strlen(o->name); + for (j = 0; j < len; j++) scratch[j] = toupper(o->name[j]); + scratch[len] = '\0'; + } + } + + printf(".TP\n.BI \""); + /* Print the name of the option */ + /* XXX We should backslashify the '-' characters in o->name. */ + + if (isalpha(o->val)) { + /* '\-c' */ + printf("\\-%c", o->val); + + if (o->flags & NVGETOPT_HAS_ARGUMENT) { + /* ' " "ARG" "' */ + printf(" \" \"%s\" \"", scratch); + } + /* ', ' */ + printf(", "); + } + + /* '\-\-name' */ + printf("\\-\\-%s", o->name); + + /* '=" "ARG' */ + if (o->flags & NVGETOPT_HAS_ARGUMENT) { + printf("=\" \"%s", scratch); + + /* '" "' */ + if ((o->flags & NVGETOPT_IS_BOOLEAN) || + (o->flags & NVGETOPT_ALLOW_DISABLE)) { + printf("\" \""); + } + } + + /* ', \-\-no\-name' */ + if (((o->flags & NVGETOPT_IS_BOOLEAN) && + !(o->flags & NVGETOPT_HAS_ARGUMENT)) || + (o->flags & NVGETOPT_ALLOW_DISABLE)) { + printf(", \\-\\-no\\-%s", o->name); + } + + printf("\"\n"); + + /* Print the option description */ + /* XXX Each sentence should be on its own line! */ + + /* + * Print the option description: write each character one at a + * time (ugh) so that we can special-case a few characters: + * + * '&' : toggles italics on and off + * '^' : toggles bold on and off + * '-' : is backslashified: "\-" + * + * Whitespace is omited when italics or bold is on + */ + + italics = 0; + bold = 0; + omitWhiteSpace = 0; + + for (s = o->description; s && *s; s++) { + + switch (*s) { + case '&': + if (italics) { + printf("\n"); + } else { + printf("\n.I "); + } + omitWhiteSpace = italics; + italics = !italics; + break; + case '^': + if (bold) { + printf("\n"); + } else { + printf("\n.B "); + } + omitWhiteSpace = bold; + bold = !bold; + break; + case '-': + printf("\\-"); + omitWhiteSpace = 0; + break; + case ' ': + if (!omitWhiteSpace) { + printf(" "); + } + break; + default: + printf("%c", *s); + omitWhiteSpace = 0; + break; + } + } + + printf("\n"); +} + +void gen_manpage_opts_helper(const NVGetoptOption *options) +{ + int i; + int has_advanced_options = 0; + + /* Print the "simple" options; i.e. the ones you get with --help. */ + printf(".SH OPTIONS\n"); + for (i = 0; options[i].name; i++) { + const NVGetoptOption *o = &options[i]; + + if (!o->description) { + continue; + } + + if (!(o->flags & NVGETOPT_HELP_ALWAYS)) { + has_advanced_options = 1; + continue; + } + + print_option(o); + } + + if (has_advanced_options) { + /* + * If any exist, print the advanced options; i.e., the ones + * you get with --advanced-help + */ + printf(".SH \"ADVANCED OPTIONS\"\n"); + for (i = 0; options[i].name; i++) { + const NVGetoptOption *o = &options[i]; + + if (!o->description) { + continue; + } + + if (o->flags & NVGETOPT_HELP_ALWAYS) { + continue; + } + + print_option(o); + } + } +} diff --git a/common-utils/gen-manpage-opts-helper.h b/common-utils/gen-manpage-opts-helper.h new file mode 100644 index 0000000..b09852e --- /dev/null +++ b/common-utils/gen-manpage-opts-helper.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see . + */ + +#if !defined(__GEN_MANPAGE_OPTS_HELPER_H__) +#define __GEN_MANPAGE_OPTS_HELPER_H__ + +#include "nvgetopt.h" + +void gen_manpage_opts_helper(const NVGetoptOption *options); + +#endif /* __GEN_MANPAGE_OPTS_HELPER_H__ */ diff --git a/common-utils/nvgetopt.c b/common-utils/nvgetopt.c index a89dcac..f04cef3 100644 --- a/common-utils/nvgetopt.c +++ b/common-utils/nvgetopt.c @@ -21,8 +21,10 @@ #include #include #include +#include #include "nvgetopt.h" +#include "common-utils.h" int nvgetopt(int argc, @@ -309,3 +311,126 @@ int nvgetopt(int argc, return ret; } /* nvgetopt() */ + + +/* + * cook_description() - the description string may contain text within + * special characters which are interpreted by the manpage generator. + * We want to omit those characters here. + */ + +static char *cook_description(const char *description) +{ + const char *src; + char *s, *dst; + + if (!description) { + return NULL; + } + + s = strdup(description); + + if (!s) { + return NULL; + } + + for (src = description, dst = s; *src; src++) { + if ((*src == '&') || (*src == '^')) { + continue; + } + *dst = *src; + dst++; + } + + *dst = '\0'; + + return s; +} + + +void nvgetopt_print_help(const NVGetoptOption *options, + unsigned int include_mask, + nvgetopt_print_help_callback_ptr callback) +{ + const NVGetoptOption *o; + int i; + + for (i = 0; options[i].name; i++) { + + char *msg = NULL, *arg = NULL, *description = NULL; + + o = &options[i]; + + /* Skip options with no help text */ + if (!o->description) { + continue; + } + + /* skip options who don't have all the bits of include_mask */ + if ((o->flags & include_mask) != include_mask) { + continue; + } + + /* if we are going to need the argument, process it now */ + arg = NULL; + if (o->flags & NVGETOPT_HAS_ARGUMENT) { + if (o->arg_name) { + arg = strdup(o->arg_name); + } else { + char *tmp; + arg = strdup(o->name); + for (tmp = arg; tmp && *tmp; tmp++) { + *tmp = toupper(*tmp); + } + } + } + + msg = NULL; + + /* + * create the long version of the option, possibly with an + * argument; e.g., "--foo" or "--foo=BAR" + */ + if (arg) { + msg = nvstrcat("--", o->name, "=", arg, NULL); + } else { + msg = nvstrcat("--", o->name, NULL); + } + + /* + * prepend the single character version of the option, + * possibly with an argument; e.g., "-f" or "-f BAR" + */ + if (isalpha(o->val)) { + char scratch[16]; + char *tmp; + snprintf(scratch, sizeof(scratch), "%c", o->val); + if (arg) { + tmp = nvstrcat("-", scratch, " ", arg, ", ", msg, NULL); + } else { + tmp = nvstrcat("-", scratch, ", ", msg, NULL); + } + free(msg); + msg = tmp; + } + + /* append the boolean version of the option; e.g., "--no-foo" */ + if (((o->flags & NVGETOPT_IS_BOOLEAN) && + !(o->flags & NVGETOPT_HAS_ARGUMENT)) || + (o->flags & NVGETOPT_ALLOW_DISABLE)) { + char *tmp = nvstrcat(msg, ", --no-", o->name, NULL); + free(msg); + msg = tmp; + } + + /* process the description text */ + description = cook_description(o->description); + + /* give the strings to the caller to format and print */ + callback(msg, description); + + free(msg); + free(arg); + free(description); + } +} diff --git a/common-utils/nvgetopt.h b/common-utils/nvgetopt.h index 127f40b..5847546 100644 --- a/common-utils/nvgetopt.h +++ b/common-utils/nvgetopt.h @@ -155,5 +155,29 @@ int nvgetopt(int argc, double *doubleval, int *disable_val); +/* + * nvgetopt_print_help() - print a help message for each option in the + * provided NVGetoptOption array. This is useful for a utility's + * "--help" output. + * + * Options will only be printed if they have every bit set that + * include_mask includes. + * + * For each option, the provided callback function wil be called with + * two strings: a name string that lists the option's name, and a + * description string for the option. The callback function is + * responsible for actually printing these strings. Examples: + * + * name = "-v, --version"; + * description = "Print usage information for the common commandline " + * "options and exit."; + */ + +typedef void nvgetopt_print_help_callback_ptr(const char *name, + const char *description); + +void nvgetopt_print_help(const NVGetoptOption *options, + unsigned int include_mask, + nvgetopt_print_help_callback_ptr callback); #endif /* __NVGETOPT_H__ */ diff --git a/common-utils/src.mk b/common-utils/src.mk index 14e4131..12ba143 100644 --- a/common-utils/src.mk +++ b/common-utils/src.mk @@ -7,3 +7,9 @@ COMMON_UTILS_EXTRA_DIST += nvgetopt.h COMMON_UTILS_EXTRA_DIST += common-utils.h COMMON_UTILS_EXTRA_DIST += src.mk +# gen-manpage-opts-helper.c is listed in EXTRA_DIST, rather than SRC, +# because it is not compiled into the utilities themselves, but used +# when building the utility's gen-manpage-opts +COMMON_UTILS_EXTRA_DIST += gen-manpage-opts-helper.c +COMMON_UTILS_EXTRA_DIST += gen-manpage-opts-helper.h + diff --git a/crc.c b/crc.c index 47ed3a5..9149e73 100644 --- a/crc.c +++ b/crc.c @@ -43,6 +43,7 @@ #include "nvidia-installer.h" #include "user-interface.h" #include "misc.h" +#include "crc.h" #define BIT(x) (1 << (x)) #define CRC_GEN_MASK (BIT(26) | BIT(23) | BIT(22) | BIT(16) | BIT(12) | \ diff --git a/dist-files.mk b/dist-files.mk index d650543..289bf07 100644 --- a/dist-files.mk +++ b/dist-files.mk @@ -30,7 +30,6 @@ SRC := backup.c SRC += command-list.c SRC += crc.c SRC += files.c -SRC += format.c SRC += install-from-cwd.c SRC += kernel.c SRC += log.c @@ -44,7 +43,6 @@ SRC += stream-ui.c SRC += update.c SRC += user-interface.c SRC += sanity.c -SRC += help-args.c DIST_FILES := $(SRC) @@ -52,7 +50,6 @@ DIST_FILES += backup.h DIST_FILES += command-list.h DIST_FILES += crc.h DIST_FILES += files.h -DIST_FILES += format.h DIST_FILES += kernel.h DIST_FILES += misc.h DIST_FILES += nvidia-installer-ui.h @@ -64,7 +61,6 @@ DIST_FILES += snarf-internal.h DIST_FILES += snarf.h DIST_FILES += update.h DIST_FILES += user-interface.h -DIST_FILES += help-args.h DIST_FILES += COPYING DIST_FILES += README diff --git a/format.c b/format.c deleted file mode 100644 index c67773e..0000000 --- a/format.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * nvidia-installer: A tool for installing NVIDIA software packages on - * Unix and Linux systems. - * - * Copyright (C) 2003 NVIDIA Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * 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, see . - * - * - * format.c - this source file contains routines for formatting string - * output. - */ - - -#include -#include -#include -#include -#include -#include - -#include "nvidia-installer.h" -#include "format.h" -#include "misc.h" - -static unsigned short __terminal_width = 0; - - - -#define DEFAULT_WIDTH 75 - -/* - * Format and display a printf style string such that it fits within - * the terminal width - */ - -#define NV_VFORMAT(stream, wb, prefix, fmt) \ -do { \ - char *buf; \ - NV_VSNPRINTF(buf, fmt); \ - vformat(stream, wb, prefix, buf); \ - free (buf); \ -} while(0) - - -static void vformat(FILE *stream, const int wb, - const char *prefix, const char *buf); - - -/* - * reset_current_terminal_width() - if new_val is zero, then use the - * TIOCGWINSZ ioctl to get the current width of the terminal, and - * assign it the value to __terminal_width. If the ioctl fails, use a - * hardcoded constant. If new_val is non-zero, then use new_val. - */ - -void reset_current_terminal_width(unsigned short new_val) -{ - struct winsize ws; - - if (new_val) { - __terminal_width = new_val; - return; - } - - if (ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) { - __terminal_width = DEFAULT_WIDTH; - } else { - __terminal_width = ws.ws_col - 1; - } -} /* get_current_terminal_width() */ - - - -/* - * fmtout() - stdout format function: prints the given string to - * stdout with no prefix. - */ - -void fmtout(const char *fmt, ...) -{ - NV_VFORMAT(stdout, TRUE, NULL, fmt); - -} /* fmtout() */ - - - -/* - * fmtoutp() - stdout format function with prefix: prints the given - * string to stdout with the given prefix. - */ - -void fmtoutp(const char *prefix, const char *fmt, ...) -{ - NV_VFORMAT(stdout, TRUE, prefix, fmt); - -} /* fmtoutp() */ - - - -/* - * fmterr() - stderr format function: prints the given string to - * stderr with no prefix. - */ - -void fmterr(const char *fmt, ...) -{ - NV_VFORMAT(stderr, TRUE, NULL, fmt); - -} /* fmterr() */ - - - -/* - * fmterrp() - stderr format function: prints the given string to - * stderr with the given prefix. - */ - -void fmterrp(const char *prefix, const char *fmt, ...) -{ - NV_VFORMAT(stderr, TRUE, prefix, fmt); - -} /* fmterrp() */ - - - -/* - * format() & vformat() - these takes a printf-style format string and - * a variable list of args. We use NV_VSNPRINTF to generate the - * desired string, and then call nv_format_text_rows() to format the - * string so that not more than __terminal_width characters are - * printed across. - * - * The resulting formatted output is written to the specified stream. - * The output may also include an optional prefix (to be prepended on - * the first line, and filled with spaces on subsequent lines. - * - * The wb argument indicates whether the line wrapping should only - * break on word boundaries. - */ - -void format(FILE *stream, const char *prefix, const char *fmt, ...) -{ - NV_VFORMAT(stream, TRUE, prefix, fmt); - -} /* format() */ - - - -static void vformat(FILE *stream, const int wb, - const char *prefix, const char *buf) -{ - int i; - TextRows *t; - - if (!__terminal_width) reset_current_terminal_width(0); - - t = nv_format_text_rows(prefix, buf, __terminal_width, wb); - - for (i = 0; i < t->n; i++) fprintf(stream, "%s\n", t->t[i]); - - nv_free_text_rows(t); - -} /* vformat() */ - - - -/* - * nv_format_text_rows() - this function breaks the given string str - * into some number of rows, where each row is not longer than the - * specified width. - * - * If prefix is non-NULL, the first line is prepended with the prefix, - * and subsequent lines are indented to line up with the prefix. - * - * If word_boundary is TRUE, then attempt to only break lines on - * boundaries between words. - * - * XXX Note that we don't use nvalloc() or any of the other wrapper - * functions from here, so that this function doesn't require any - * non-c library symbols (so that it can be called from dlopen()'ed - * user interfaces. - */ - -TextRows *nv_format_text_rows(const char *prefix, const char *str, - int width, int word_boundary) -{ - int len, prefix_len, z, w, i; - char *line, *buf, *local_prefix, *a, *b, *c; - TextRows *t; - - /* initialize the TextRows structure */ - - t = (TextRows *) malloc(sizeof(TextRows)); - t->t = NULL; - t->n = 0; - t->m = 0; - - if (!str) return t; - - buf = strdup(str); - - z = strlen(buf); /* length of entire string */ - a = buf; /* pointer to the start of the string */ - - /* initialize the prefix fields */ - - if (prefix) { - prefix_len = strlen(prefix); - local_prefix = nvstrdup(prefix); - } else { - prefix_len = 0; - local_prefix = NULL; - } - - /* adjust the max width for any prefix */ - - w = width - prefix_len; - - do { - /* - * if the string will fit on one line, point b to the end of the - * string - */ - - if (z < w) b = a + z; - - /* - * if the string won't fit on one line, move b to where the - * end of the line should be, and then move b back until we - * find a space; if we don't find a space before we back b all - * the way up to a, just assign b to where the line should end. - */ - - else { - b = a + w; - - if (word_boundary) { - while ((b >= a) && (!isspace(*b))) b--; - if (b <= a) b = a + w; - } - } - - /* look for any newline inbetween a and b, and move b to it */ - - for (c = a; c < b; c++) if (*c == '\n') { b = c; break; } - - /* - * copy the string that starts at a and ends at b, prepending - * with a prefix, if present - */ - - len = b-a; - len += prefix_len; - line = (char *) malloc(len+1); - if (local_prefix) strncpy(line, local_prefix, prefix_len); - strncpy(line + prefix_len, a, len - prefix_len); - line[len] = '\0'; - - /* append the new line to the array of text rows */ - - t->t = (char **) realloc(t->t, sizeof(char *) * (t->n + 1)); - t->t[t->n] = line; - t->n++; - - if (t->m < len) t->m = len; - - /* - * adjust the length of the string and move the pointer to the - * beginning of the new line - */ - - z -= (b - a + 1); - a = b + 1; - - /* move to the first non whitespace character (excluding newlines) */ - - if (word_boundary && isspace(*b)) { - while ((z) && (isspace(*a)) && (*a != '\n')) a++, z--; - } else { - if (!isspace(*b)) z++, a--; - } - - if (local_prefix) { - for (i = 0; i < prefix_len; i++) local_prefix[i] = ' '; - } - - } while (z > 0); - - if (local_prefix) free(local_prefix); - free(buf); - - return t; - -} /* nv_format_text_rows() */ - - - -/* - * nv_free_text_rows() - free the TextRows data structure allocated by - * nv_format_text_rows() - */ - -void nv_free_text_rows(TextRows *t) -{ - int i; - - if (!t) return; - for (i = 0; i < t->n; i++) free(t->t[i]); - if (t->t) free(t->t); - free(t); - -} /* nv_free_text_rows() */ diff --git a/format.h b/format.h deleted file mode 100644 index b9e1423..0000000 --- a/format.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * nvidia-installer: A tool for installing NVIDIA software packages on - * Unix and Linux systems. - * - * Copyright (C) 2003 NVIDIA Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * 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, see . - * - * - * format.h - */ - -#ifndef __NVIDIA_INSTALLER_FORMAT_H__ -#define __NVIDIA_INSTALLER_FORMAT_H__ - -#include -#include - -void reset_current_terminal_width(unsigned short new_val); - -void fmtout(const char *fmt, ...); -void fmtoutp(const char *prefix, const char *fmt, ...); -void fmterr(const char *fmt, ...); -void fmterrp(const char *prefix, const char *fmt, ...); -void format(FILE *stream, const char *prefix, const char *fmt, ...); - -TextRows *nv_format_text_rows(const char *prefix, const char *buf, - int width, int word_boundary); -void nv_free_text_rows(TextRows *t); - -#endif /* __NVIDIA_INSTALLER_FORMAT_H__ */ diff --git a/gen-manpage-opts.c b/gen-manpage-opts.c index c821a31..0875828 100644 --- a/gen-manpage-opts.c +++ b/gen-manpage-opts.c @@ -5,119 +5,11 @@ #include #include -#include "nvidia-installer.h" #include "option_table.h" +#include "gen-manpage-opts-helper.h" -static void print_option(const NVGetoptOption *o) +int main(void) { - char scratch[64], *s; - int j, len; - - int omitWhiteSpace; - - printf(".TP\n.BI "); - /* Print the name of the option */ - /* XXX We should backslashify the '-' characters in o->name. */ - if (o->flags & NVGETOPT_IS_BOOLEAN) { - /* "\-\-name, \-\-no\-name */ - printf("\"\\-\\-%s, \\-\\-no\\-%s", o->name, o->name); - } else if (isalnum(o->val)) { - /* "\-c, \-\-name */ - printf("\"\\-%c, \\-\\-%s", o->val, o->name); - } else { - /* "\-\-name */ - printf("\"\\-\\-%s", o->name); - } - - if (o->flags & NVGETOPT_HAS_ARGUMENT) { - len = strlen(o->name); - for (j = 0; j < len; j++) scratch[j] = toupper(o->name[j]); - scratch[len] = '\0'; - printf("=\" \"%s", scratch); - } - - printf("\"\n"); - - /* - * Print the option description: write each character one at a - * time (ugh) so that we can special-case a few characters: - * - * "[" --> "\n.I " - * "]" --> "\n" - * "-" --> "\-" - * - * Brackets are used to mark the text inbetween as italics. - * '-' is special cased so that we can backslashify it. - * - * XXX Each sentence should be on its own line! - */ - - omitWhiteSpace = 0; - - for (s = o->description; s && *s; s++) { - - switch (*s) { - case '[': - printf("\n.I "); - omitWhiteSpace = 0; - break; - case ']': - printf("\n"); - omitWhiteSpace = 1; - break; - case '-': - printf("\\-"); - omitWhiteSpace = 0; - break; - case ' ': - if (!omitWhiteSpace) { - printf("%c", *s); - } - break; - default: - printf("%c", *s); - omitWhiteSpace = 0; - break; - } - } - - printf("\n"); -} - -int main(int argc, char* argv[]) -{ - int i; - const NVGetoptOption *o; - - /* Print the "simple" options, i.e. the ones you get by running - * nvidia-installer --help. - */ - printf(".SH OPTIONS\n"); - for (i = 0; __options[i].name; i++) { - o = &__options[i]; - - if (!(o->flags & NVGETOPT_HELP_ALWAYS)) - continue; - - if (!o->description) - continue; - - print_option(o); - } - - /* Print the advanced options. */ - printf(".SH \"ADVANCED OPTIONS\"\n"); - for (i = 0; __options[i].name; i++) { - o = &__options[i]; - - if (o->flags & NVGETOPT_HELP_ALWAYS) - continue; - - if (!o->description) - continue; - - print_option(o); - } - + gen_manpage_opts_helper(__options); return 0; } diff --git a/help-args.c b/help-args.c deleted file mode 100644 index 824eda2..0000000 --- a/help-args.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * nvidia-installer: A tool for installing NVIDIA software packages on - * Unix and Linux systems. - * - * Copyright (C) 2003-2009 NVIDIA Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * 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, see . - * - * - * help-args.c: this file contains a utility function that outputs the - * option table in a human readable format. - */ - -#include -#include -#include - -#include "nvidia-installer.h" -#include "format.h" - -#include "option_table.h" - -/* - * cook_description() - the description string may contain text - * within brackets, which is used by the manpage generator - * to denote text to be italicized. We want to omit the bracket - * characters here. - */ - -static char *cook_description(const char *description) -{ - int len; - char *s, *dst; - const char *src; - - len = strlen(description); - s = nvalloc(len + 1); - - for (src = description, dst = s; *src; src++) { - if (*src != '[' && (*src != ']')) { - *dst = *src; - dst++; - } - } - - *dst = '\0'; - - return s; - -} /* cook_description() */ - - - -void print_help_args_only(int is_uninstall, int args_only, int advanced) -{ - int i, j, len; - char *msg, *tmp, scratch[64]; - const NVGetoptOption *o; - - /* - * the args_only parameter is used by makeself.sh to get our - * argument list and description; in this case we don't - * want to format to the width of the terminal, so hardcode - * the width to 65. - */ - if (args_only) reset_current_terminal_width(65); - - for (i = 0; __options[i].name; i++) { - o = &__options[i]; - - /* - * if non-advanced help is requested, and the ALWAYS flag is - * not set, then skip this option - */ - - if (!advanced && !(o->flags & NVGETOPT_HELP_ALWAYS)) continue; - - /* Skip options with no help text */ - if (!o->description) continue; - - /* Skip options that do not apply to nvidia-uninstall if we're - * invoked as nvidia-uninstall. */ - if (is_uninstall - && !(o->flags & NVGETOPT_OPTION_APPLIES_TO_NVIDIA_UNINSTALL)) { - continue; - } - - if (o->flags & NVGETOPT_IS_BOOLEAN) { - msg = nvstrcat("--", o->name, "/--no-", o->name, NULL); - } else if (isalnum(o->val)) { - sprintf(scratch, "%c", o->val); - msg = nvstrcat("-", scratch, ", --", o->name, NULL); - } else { - msg = nvstrcat("--", o->name, NULL); - } - if (o->flags & NVGETOPT_HAS_ARGUMENT) { - len = strlen(o->name); - for (j = 0; j < len; j++) scratch[j] = toupper(o->name[j]); - scratch[len] = '\0'; - tmp = nvstrcat(msg, "=", scratch, NULL); - nvfree(msg); - msg = tmp; - } - fmtoutp(TAB, msg); - if (o->description) { - tmp = cook_description(o->description); - fmtoutp(BIGTAB, tmp); - nvfree(tmp); - } - fmtout(""); - nvfree(msg); - } -} diff --git a/help-args.h b/help-args.h deleted file mode 100644 index 60a6d48..0000000 --- a/help-args.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * nvidia-installer: A tool for installing NVIDIA software packages on - * Unix and Linux systems. - * - * Copyright (C) 2003-2009 NVIDIA Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * 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, see . - * - * - * nvidia-installer.h - */ - -#ifndef __HELP_ARGS_H__ -#define __HELP_ARGS_H__ - -void print_help_args_only(int is_uninstall, int args_only, int advanced); - -#endif /* __HELP_ARGS_H__ */ diff --git a/install-from-cwd.c b/install-from-cwd.c index 671a5da..5fd8159 100644 --- a/install-from-cwd.c +++ b/install-from-cwd.c @@ -276,7 +276,7 @@ int install_from_cwd(Options *op) "file will be backed up."); if (ret) { - ret = run_nvidia_xconfig(op); + ret = run_nvidia_xconfig(op, FALSE); } if (ret) { diff --git a/log.c b/log.c index 8735ff3..743449a 100644 --- a/log.c +++ b/log.c @@ -28,7 +28,6 @@ #include "nvidia-installer.h" #include "misc.h" -#include "format.h" /* global stream for log output */ diff --git a/makeself-help-script.c b/makeself-help-script.c index de28611..47f8a9a 100644 --- a/makeself-help-script.c +++ b/makeself-help-script.c @@ -9,29 +9,50 @@ #include #include "nvidia-installer.h" -#include "help-args.h" +#include "nvgetopt.h" +#include "option_table.h" -void print_usage(char **argv) +static void print_usage(char **argv) { fprintf(stderr, "usage: %s --help-args-only|" "--advanced-options-args-only\n", argv[0]); } +static void print_help_helper(const char *name, const char *description) +{ + fmtoutp(TAB, name); + fmtoutp(BIGTAB, description); + fmtout(""); +} + int main(int argc, char **argv) { + unsigned int include_mask = 0; + if (argc != 2) { print_usage(argv); exit(1); } - if (strcmp(argv[1], "--help-args-only") == 0) - print_help_args_only(FALSE, TRUE, FALSE); - else if (strcmp(argv[1], "--advanced-options-args-only") == 0) - print_help_args_only(FALSE, TRUE, TRUE); - else { + /* + * We are printing help text for use by makeself.sh; we do not + * want this formatted to the width of the current terminal, so + * hardcode the width used by fmtout() to 65. + */ + reset_current_terminal_width(65); + + if (strcmp(argv[1], "--help-args-only") == 0) { + /* only print options with the ALWAYS flag */ + include_mask = NVGETOPT_HELP_ALWAYS; + } else if (strcmp(argv[1], "--advanced-options-args-only") == 0) { + /* print all options */ + include_mask = 0; + } else { print_usage(argv); exit(1); } + nvgetopt_print_help(__options, include_mask, print_help_helper); + return 0; } diff --git a/misc.c b/misc.c index a9b4672..6412273 100644 --- a/misc.c +++ b/misc.c @@ -1723,8 +1723,7 @@ static int rtld_test_internal(Options *op, Package *p, if (!name) continue; s = strstr(name, ".so.1"); - if (!s) goto next; - *(s + strlen(".so.1")) = '\0'; + if (!s || s[strlen(".so.1")] != '\0') goto next; cmd = nvstrcat(op->utils[LDD], " ", tmpfile, " > ", tmpfile1, NULL); @@ -2332,24 +2331,28 @@ int check_selinux(Options *op) /* * run_nvidia_xconfig() - run the `nvidia-xconfig` utility. Without * any options, this will just make sure the X config file uses the - * NVIDIA driver by default. + * NVIDIA driver by default. The restore parameter controls whether + * the --restore-original-backup option is added, which attempts to + * restore the original backed up X config file. */ -int run_nvidia_xconfig(Options *op) +int run_nvidia_xconfig(Options *op, int restore) { int ret, bRet = TRUE; - char *data = NULL, *cmd; + char *data = NULL, *cmd, *args; + + args = restore ? " --restore-original-backup" : ""; - cmd = find_system_util("nvidia-xconfig"); + cmd = nvstrcat(find_system_util("nvidia-xconfig"), args, NULL); - ret = run_command(op, cmd, &data, FALSE, FALSE, TRUE); - nvfree(cmd); + ret = run_command(op, cmd, &data, FALSE, 0, TRUE); if (ret != 0) { - ui_error(op, "Failed to run nvidia-xconfig:\n%s", data); + ui_error(op, "Failed to run `%s`:\n%s", cmd, data); bRet = FALSE; } + nvfree(cmd); nvfree(data); return bRet; diff --git a/misc.h b/misc.h index 73659d6..4a7fcaf 100644 --- a/misc.h +++ b/misc.h @@ -30,41 +30,6 @@ #include "nvidia-installer.h" #include "command-list.h" -#define ARRAY_LEN(_arr) (sizeof(_arr) / sizeof(_arr[0])) - -/* - * NV_VSNPRINTF() - takes a fmt string, and uses vsnprintf to build - * the resulting string whic it assigns to buf. The caller of this - * function is responsible for freeing the returned string. - */ -#define NV_VSNPRINTF(buf, fmt) \ -do { \ - if (!fmt) { \ - (buf) = NULL; \ - } else { \ - va_list ap; \ - int len, current_len = NV_LINE_LEN; \ - \ - (buf) = malloc(current_len); \ - \ - while (1) { \ - va_start(ap, fmt); \ - len = vsnprintf((buf), current_len, (fmt), ap); \ - va_end(ap); \ - \ - if ((len > -1) && (len < current_len)) { \ - break; \ - } else if (len > -1) { \ - current_len = len + 1; \ - } else { \ - current_len += NV_LINE_LEN; \ - } \ - \ - (buf) = realloc(buf, current_len); \ - } \ - } \ -} while (0) - char *read_next_word (char *buf, char **e); int check_euid(Options *op); @@ -96,7 +61,7 @@ Distribution get_distribution(Options *op); int check_for_running_x(Options *op); int check_for_modular_xorg(Options *op); int check_for_nvidia_graphics_devices(Options *op, Package *p); -int run_nvidia_xconfig(Options *op); +int run_nvidia_xconfig(Options *op, int restore); int run_distro_hook(Options *op, const char *hook); int check_for_nouveau(Options *op); diff --git a/mkprecompiled.c b/mkprecompiled.c index e1f23d5..0c75a9f 100644 --- a/mkprecompiled.c +++ b/mkprecompiled.c @@ -85,14 +85,13 @@ typedef struct { #include "crc.h" - /* * nv_alloc() - malloc wrapper that checks for errors, and zeros out * the memory; if an error occurs, an error is printed to stderr and * exit() is called -- this function will only return on success. */ -void *nv_alloc (size_t size) +static void *nv_alloc (size_t size) { void *m = malloc (size); @@ -110,11 +109,15 @@ void *nv_alloc (size_t size) * XXX hack to resolve symbols used by crc.c */ +void *nvalloc(size_t size); + void *nvalloc(size_t size) { return nv_alloc(size); } +void ui_warn(Options *op, const char *fmt, ...); + void ui_warn(Options *op, const char *fmt, ...) { va_list ap; @@ -131,7 +134,7 @@ void ui_warn(Options *op, const char *fmt, ...) * fails and calls exit(). This function only returns on success. */ -int nv_open(const char *pathname, int flags, mode_t mode) +static int nv_open(const char *pathname, int flags, mode_t mode) { int fd; fd = open(pathname, flags, mode); @@ -152,7 +155,7 @@ int nv_open(const char *pathname, int flags, mode_t mode) * on success. */ -int nv_get_file_length(const char *filename) +static int nv_get_file_length(const char *filename) { struct stat stat_buf; int ret; @@ -175,7 +178,7 @@ int nv_get_file_length(const char *filename) * function only returns on success. */ -void nv_set_file_length(const char *filename, int fd, int len) +static void nv_set_file_length(const char *filename, int fd, int len) { if ((lseek(fd, len - 1, SEEK_SET) == -1) || (write(fd, "", 1) == -1)) { @@ -192,7 +195,8 @@ void nv_set_file_length(const char *filename, int fd, int len) * fails and calls exit(). This function only returns on success. */ -void *nv_mmap(const char *filename, size_t len, int prot, int flags, int fd) +static void *nv_mmap(const char *filename, size_t len, int prot, + int flags, int fd) { void *ret; @@ -212,7 +216,7 @@ void *nv_mmap(const char *filename, size_t len, int prot, int flags, int fd) * print_help() */ -void print_help(void) +static void print_help(void) { printf("\n%s [options] \n\n", BINNAME); @@ -254,7 +258,7 @@ void print_help(void) * structure. */ -Options *parse_commandline(int argc, char *argv[]) +static Options *parse_commandline(int argc, char *argv[]) { Options *op; int c, option_index = 0; @@ -336,7 +340,7 @@ Options *parse_commandline(int argc, char *argv[]) -char *read_proc_version(void) +static char *read_proc_version(void) { int fd, ret, len, version_len; char *version, *c = NULL; @@ -390,7 +394,7 @@ char *read_proc_version(void) * Returns 1 if the strings match, 0 if they don't match. */ -int check_match(char *str) +static int check_match(char *str) { int ret = 0; char *version = read_proc_version(); @@ -416,7 +420,7 @@ int check_match(char *str) * the integer to the data buffer. */ -void encode_uint32(uint32 val, uint8 data[4]) +static void encode_uint32(uint32 val, uint8 data[4]) { data[0] = ((val >> 0) & 0xff); data[1] = ((val >> 8) & 0xff); @@ -432,7 +436,7 @@ void encode_uint32(uint32 val, uint8 data[4]) * bytes, and build a uint32. */ -uint32 decode_uint32(char *buf) +static uint32 decode_uint32(char *buf) { uint32 ret = 0; @@ -460,7 +464,7 @@ uint32 decode_uint32(char *buf) * string, and the proc version string. */ -int pack(Options *op) +static int pack(Options *op) { int fd, offset, src_fd; uint8 *out, *src, data[4]; @@ -571,7 +575,7 @@ int pack(Options *op) * unpack() - unpack the specified package */ -int unpack(Options *op) +static int unpack(Options *op) { int dst_fd, fd, ret, offset, len = 0; char *buf, *dst; diff --git a/nvidia-installer.c b/nvidia-installer.c index 173e058..2f3d038 100644 --- a/nvidia-installer.c +++ b/nvidia-installer.c @@ -42,10 +42,8 @@ #include "user-interface.h" #include "backup.h" #include "files.h" -#include "help-args.h" #include "misc.h" #include "update.h" -#include "format.h" #include "sanity.h" #include "option_table.h" @@ -79,17 +77,40 @@ static void print_version(void) * print_help() - print usage information */ +static void print_help_helper(const char *name, const char *description) +{ + fmtoutp(TAB, name); + fmtoutp(BIGTAB, description); + fmtout(""); +} + +static void print_options(int is_uninstall, int advanced) +{ + unsigned int include_mask = 0; + + if (is_uninstall) { + /* only print options with the UNINSTALL flag */ + include_mask |= NVGETOPT_OPTION_APPLIES_TO_NVIDIA_UNINSTALL; + } + + if (!advanced) { + /* only print options with the ALWAYS flag */ + include_mask |= NVGETOPT_HELP_ALWAYS; + } + + nvgetopt_print_help(__options, include_mask, print_help_helper); +} + static void print_help(const char* name, int is_uninstall, int advanced) { print_version(); - + fmtout(""); fmtout("%s [options]", name); fmtout(""); - - print_help_args_only(is_uninstall, FALSE, advanced); -} /* print_help() */ + print_options(is_uninstall, advanced); +} /* @@ -264,7 +285,6 @@ static void parse_commandline(int argc, char *argv[], Options *op) else if (strcasecmp(strval, "classic") == 0) op->which_tls = FORCE_CLASSIC_TLS; else { - fmterr("\n"); fmterr("Invalid parameter for '--force-tls'"); goto fail; } @@ -276,7 +296,6 @@ static void parse_commandline(int argc, char *argv[], Options *op) else if (strcasecmp(strval, "classic") == 0) op->which_tls_compat32 = FORCE_CLASSIC_TLS; else { - fmterr("\n"); fmterr("Invalid parameter for '--force-tls-compat32'"); goto fail; } @@ -322,7 +341,6 @@ static void parse_commandline(int argc, char *argv[], Options *op) else if (strcasecmp(strval, "no") == 0) op->selinux_option = SELINUX_FORCE_NO; else if (strcasecmp(strval, "default")) { - fmterr("\n"); fmterr("Invalid parameter for '--force-selinux'"); goto fail; } @@ -375,7 +393,14 @@ static void parse_commandline(int argc, char *argv[], Options *op) } if (print_help_args_only_after) { - print_help_args_only(op->uninstall, TRUE, print_advanced_help); + /* + * We are printing help text for use by makeself.sh; we do not + * want this formatted to the width of the current terminal, + * so hardcode the width used by fmtout() to 65. + */ + reset_current_terminal_width(65); + + print_options(op->uninstall, print_advanced_help); exit(0); } @@ -393,10 +418,8 @@ static void parse_commandline(int argc, char *argv[], Options *op) return; fail: - fmterr("\n"); fmterr("Invalid commandline, please run `%s --help` " "for usage information.", argv[0]); - fmterr("\n"); nvfree((void*)op); exit(1); } /* parse_commandline() */ diff --git a/nvidia-installer.h b/nvidia-installer.h index 0361375..816a074 100644 --- a/nvidia-installer.h +++ b/nvidia-installer.h @@ -260,16 +260,6 @@ typedef struct __package { } Package; - -typedef struct { - char **t; /* the text rows */ - int n; /* number of rows */ - int m; /* maximum row length */ -} TextRows; - - - - /* flags for passing into install_from_cwd() */ #define ADJUST_CWD 0x01 diff --git a/option_table.h b/option_table.h index 998fbd8..7f755ee 100644 --- a/option_table.h +++ b/option_table.h @@ -24,6 +24,7 @@ #define __OPT_TABLE_H__ #include "nvgetopt.h" +#include "nvidia-installer.h" #define NVGETOPT_OPTION_APPLIES_TO_NVIDIA_UNINSTALL 0x00010000 @@ -316,7 +317,7 @@ static const NVGetoptOption __options[] = { { "ui", USER_INTERFACE_OPTION, NVGETOPT_STRING_ARGUMENT | NVGETOPT_OPTION_APPLIES_TO_NVIDIA_UNINSTALL, NULL, "Specify what user interface to use, if available. " - "Valid values for [UI] are 'ncurses' (the default) or 'none'. " + "Valid values for &UI& are 'ncurses' (the default) or 'none'. " "If the ncurses interface fails to initialize, or 'none' " "is specified, then a simple printf/scanf interface will " "be used." }, @@ -341,7 +342,7 @@ static const NVGetoptOption __options[] = { "nvidia-installer will select the OpenGL libraries appropriate " "for your system; however, you may use this option to force the " "installer to install one library type or another. Valid values " - "for [FORCE-TLS] are 'new' and 'classic'." }, + "for &FORCE-TLS& are 'new' and 'classic'." }, #if defined(NV_X86_64) { "force-tls-compat32", FORCE_TLS_COMPAT32_OPTION, @@ -353,14 +354,14 @@ static const NVGetoptOption __options[] = { { "kernel-name", 'k', NVGETOPT_STRING_ARGUMENT, NULL, "Build and install the NVIDIA kernel module for the " - "non-running kernel specified by [KERNEL-NAME] ([KERNEL-NAME] " + "non-running kernel specified by &KERNEL-NAME& (&KERNEL-NAME& " "should be the output of `uname -r` when the target kernel is " "actually running). This option implies " "'--no-precompiled-interface'. If the options " "'--kernel-install-path' and '--kernel-source-path' are not " - "given, then they will be inferred from [KERNEL-NAME]; eg: " - "'/lib/modules/[KERNEL-NAME]/kernel/drivers/video/' and " - "'/lib/modules/[KERNEL-NAME]/build/', respectively." }, + "given, then they will be inferred from &KERNEL-NAME&; eg: " + "'/lib/modules/&KERNEL-NAME&/kernel/drivers/video/' and " + "'/lib/modules/&KERNEL-NAME&/build/', respectively." }, { "no-precompiled-interface", 'n', 0, NULL, "Disable use of precompiled kernel interfaces." }, @@ -464,7 +465,7 @@ static const NVGetoptOption __options[] = { "use it to also clear the executable stack flag of the libraries. " "Use this option to override nvidia-installer's detection of when " "to set the security type. " - "Valid values for [FORCE-SELINUX] are 'yes' (force setting of the " + "Valid values for &FORCE-SELINUX& are 'yes' (force setting of the " "security type), " "'no' (prevent setting of the security type), and 'default' " "(let nvidia-installer decide when to set the security type)." }, @@ -514,7 +515,7 @@ static const NVGetoptOption __options[] = { { "advanced-options-args-only", ADVANCED_OPTIONS_ARGS_ONLY_OPTION, 0, NULL, NULL }, - { NULL, 0, 0, NULL }, + { NULL, 0, 0, NULL, NULL }, }; #endif /* __OPT_TABLE_H__ */ diff --git a/stream-ui.c b/stream-ui.c index 2ca729f..be0326c 100644 --- a/stream-ui.c +++ b/stream-ui.c @@ -32,7 +32,7 @@ #include "nvidia-installer-ui.h" #include "misc.h" #include "files.h" -#include "format.h" +#include "common-utils.h" /* prototypes of each of the stream ui functions */ @@ -182,8 +182,8 @@ char *stream_get_input(Options *op, const char *def, const char *msg) { char *buf; - format(stdout, NULL, ""); - format(stdout, NULL, msg); + fmt(stdout, NULL, ""); + fmt(stdout, NULL, msg); fprintf(stdout, " [default: '%s']: ", def); fflush(stdout); @@ -271,9 +271,9 @@ void stream_message(Options *op, const int level, const char *msg) if ((level == NV_MSG_LEVEL_LOG) && (d->status_active)) return; - if (msg_attrs[level].newline) format(msg_attrs[level].stream, NULL, ""); - format(msg_attrs[level].stream, msg_attrs[level].prefix, msg); - if (msg_attrs[level].newline) format(msg_attrs[level].stream, NULL, ""); + if (msg_attrs[level].newline) fmt(msg_attrs[level].stream, NULL, ""); + fmt(msg_attrs[level].stream, msg_attrs[level].prefix, msg); + if (msg_attrs[level].newline) fmt(msg_attrs[level].stream, NULL, ""); } /* stream_message() */ @@ -350,7 +350,7 @@ int stream_approve_command_list(Options *op, CommandList *cl, default: - fmterrp("ERROR: ", "Error in CommandList! (cmd: %d; s0: '%s';" + fmterr("Error in CommandList! (cmd: %d; s0: '%s';" "s1: '%s'; s2: '%s'; mode: %04o)", c->cmd, c->s0, c->s1, c->s2, c->mode); fmterr("Aborting installation."); @@ -383,8 +383,8 @@ int stream_yes_no(Options *op, const int def, const char *msg) char *buf; int eof, ret = def; - format(stdout, NULL, ""); - format(stdout, NULL, msg); + fmt(stdout, NULL, ""); + fmt(stdout, NULL, msg); if (def) fprintf(stdout, " [default: (Y)es]: "); else fprintf(stdout, " [default: (N)o]: "); fflush(stdout); diff --git a/user-interface.c b/user-interface.c index fe7001c..aff75a0 100644 --- a/user-interface.c +++ b/user-interface.c @@ -36,9 +36,8 @@ #include "nvidia-installer.h" #include "nvidia-installer-ui.h" #include "misc.h" -#include "format.h" #include "files.h" - +#include "user-interface.h" /* * global user interface pointer diff --git a/utils.mk b/utils.mk index 32014a3..2a7a9cf 100644 --- a/utils.mk +++ b/utils.mk @@ -28,9 +28,10 @@ CC ?= gcc LD ?= ld -CFLAGS ?= -CFLAGS += -Wall -fno-strict-aliasing -Wno-unused-parameter -CFLAGS += -O2 -fno-omit-frame-pointer +# only set these warnings and optimizations if CFLAGS is unset +CFLAGS ?= -Wall -Wno-unused-parameter -O2 +# always set these -f CFLAGS +CFLAGS += -fno-strict-aliasing -fno-omit-frame-pointer CC_ONLY_CFLAGS ?= LDFLAGS ?= BIN_LDFLAGS ?= @@ -93,9 +94,9 @@ ifndef TARGET_ARCH endif ifeq ($(TARGET_OS),Linux) - LIBDL_LDFLAGS = -ldl + LIBDL_LIBS = -ldl else - LIBDL_LDFLAGS = + LIBDL_LIBS = endif OUTPUTDIR ?= _out/$(TARGET_OS)_$(TARGET_ARCH) @@ -124,11 +125,10 @@ endif # the source tarball ############################################################################## -prefix = /usr/local +PREFIX ?= /usr/local -exec_prefix = $(prefix) -bindir = $(exec_prefix)/bin -mandir = $(exec_prefix)/share/man/man1 +BINDIR = $(DESTDIR)$(PREFIX)/bin +MANDIR = $(DESTDIR)$(PREFIX)/share/man/man1 ############################################################################## @@ -145,10 +145,16 @@ default build: all # version.mk may be in one of two places: either in $(OUTPUTDIR) when # building as part of the NVIDIA driver build, or directly in the # source directory when building from the source tarball +# +# Throw an error if one of these two places did not define NVIDIA_VERSION. ############################################################################## -include $(wildcard $(OUTPUTDIR)/version.mk version.mk) +VERSION_MK := $(wildcard $(OUTPUTDIR)/version.mk version.mk) +include $(VERSION_MK) +ifndef NVIDIA_VERSION +$(error NVIDIA_VERSION undefined) +endif ############################################################################## # to generate the dependency files, use the compiler's "-MM" option to @@ -260,7 +266,7 @@ BUILD_DEPENDENCY_LIST = \ define DEFINE_OBJECT_RULE_WITH_OBJECT_NAME $(3): $(2) @$(MKDIR) $(OUTPUTDIR) - $$(call quiet_cmd,$(1)) -c $$< -o $$@ $$(CFLAGS) \ + $$(call quiet_cmd,$(1)) $$(CFLAGS) -c $$< -o $$@ \ $(call AUTO_DEP_CMD,$(1),$(2),$(3)) -include $$(call BUILD_DEPENDENCY_LIST,$(3)) @@ -298,7 +304,7 @@ define DEFINE_STAMP_C_RULE $$(STAMP_C): $$(filter-out \ $$(call BUILD_OBJECT_LIST,$$(STAMP_C)),$(1)) \ - $$(wildcard version.mk $$(OUTPUTDIR)/version.mk) + $$(VERSION_MK) @ $$(RM) $$@ @ $$(PRINTF) "const char NV_ID[] = \"nvidia id: " >> $$@ @ $$(PRINTF) "$(2): " >> $$@ diff --git a/version.mk b/version.mk index 11eb84d..c29a7ba 100644 --- a/version.mk +++ b/version.mk @@ -1 +1 @@ -NVIDIA_VERSION = 295.40 +NVIDIA_VERSION = 302.07 -- cgit v1.2.3