334.16

parent af1b5d9e
......@@ -42,7 +42,7 @@ ifeq ($(MANPAGE_GZIP),1)
else
MANPAGE = $(MANPAGE_not_gzipped)
endif
GEN_MANPAGE_OPTS = $(OUTPUTDIR)/gen-manpage-opts
GEN_MANPAGE_OPTS = $(OUTPUTDIR_ABSOLUTE)/gen-manpage-opts
OPTIONS_1_INC = $(OUTPUTDIR)/options.1.inc
......@@ -151,7 +151,7 @@ $(GEN_MANPAGE_OPTS): $(GEN_MANPAGE_OPTS_OBJS)
$(HOST_CFLAGS) $(HOST_LDFLAGS) $(HOST_BIN_LDFLAGS) $^ -o $@
$(OPTIONS_1_INC): $(GEN_MANPAGE_OPTS)
@./$< > $@
@$< > $@
$(MANPAGE_not_gzipped): nvidia-modprobe.1.m4 $(OPTIONS_1_INC) $(VERSION_MK)
$(call quiet_cmd,M4) -D__HEADER__=$(AUTO_TEXT) -I $(OUTPUTDIR) \
......
......@@ -29,8 +29,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/termios.h>
#include "common-utils.h"
......@@ -354,311 +352,6 @@ char *nv_prepend_to_string_list(char *list, const char *item, const char *delim)
}
/****************************************************************************/
/* 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 between 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
*/
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);
}
/*
* Read from the given FILE stream until a newline, EOF, or nul
* terminator is encountered, writing data into a growable buffer.
......
......@@ -22,6 +22,8 @@
#include <sys/types.h>
#include <stdint.h>
#include "msg.h"
#if !defined(TRUE)
#define TRUE 1
#endif
......@@ -38,32 +40,6 @@
#define TAB " "
#define BIGTAB " "
#define VERBOSITY_NONE 0 /* nothing */
#define VERBOSITY_ERROR 1 /* errors only */
#define VERBOSITY_DEPRECATED 2 /* errors, deprecation messages and warnings */
#define VERBOSITY_WARNING 3 /* errors and warnings */
#define VERBOSITY_ALL 4 /* errors, warnings and other info */
#define VERBOSITY_DEFAULT VERBOSITY_ERROR
/*
* Define a printf format attribute macro. This definition is based on the one
* from Xfuncproto.h, available in the 'xproto' package at
* http://xorg.freedesktop.org/releases/individual/proto/
*/
#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)
# define NV_ATTRIBUTE_PRINTF(x,y) __attribute__((__format__(__printf__,x,y)))
#else /* not gcc >= 2.3 */
# define NV_ATTRIBUTE_PRINTF(x,y)
#endif
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);
......@@ -79,22 +55,6 @@ void nvfree(void *s);
char *tilde_expansion(const char *str);
char *nv_prepend_to_string_list(char *list, const char *item, const char *delim);
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, ...) NV_ATTRIBUTE_PRINTF(1, 2);
void fmtoutp(const char *prefix, const char *fmt, ...) NV_ATTRIBUTE_PRINTF(2, 3);
void fmterr(const char *fmt, ...) NV_ATTRIBUTE_PRINTF(1, 2);
void fmtwarn(const char *fmt, ...) NV_ATTRIBUTE_PRINTF(1, 2);
void fmt(FILE *stream, const char *prefix, const char *fmt, ...) NV_ATTRIBUTE_PRINTF(3, 4);
char *fget_next_line(FILE *fp, int *eof);
int nv_open(const char *pathname, int flags, mode_t mode);
......@@ -107,51 +67,6 @@ char *nv_trim_space(char *string);
char *nv_trim_char(char *string, char trim);
char *nv_trim_char_strict(char *string, char trim);
/*
* 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; \
\
while (1) { \
(buf) = nvalloc(current_len); \
\
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; \
} \
\
nvfree(buf); \
} \
} \
} while (0)
#if defined(__GNUC__)
# define NV_INLINE __inline__
#else
......
......@@ -17,16 +17,18 @@
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "nvgetopt.h"
#include "gen-manpage-opts-helper.h"
#include "common-utils.h"
static void print_option(const NVGetoptOption *o)
{
char scratch[64], *s;
int j, len;
int italics, bold, omitWhiteSpace;
int italics, bold, omitWhiteSpace, firstchar;
/* if we are going to need the argument, process it now */
if (o->flags & NVGETOPT_HAS_ARGUMENT) {
......@@ -88,13 +90,15 @@ static void print_option(const NVGetoptOption *o)
* '&' : toggles italics on and off
* '^' : toggles bold on and off
* '-' : is backslashified: "\-"
* '.' : must not be the first character of a line
*
* Whitespace is omitted when italics or bold is on
* Trailing whitespace is omitted when italics or bold is on
*/
italics = 0;
bold = 0;
omitWhiteSpace = 0;
italics = FALSE;
bold = FALSE;
omitWhiteSpace = FALSE;
firstchar = TRUE;
for (s = o->description; s && *s; s++) {
......@@ -107,6 +111,7 @@ static void print_option(const NVGetoptOption *o)
}
omitWhiteSpace = italics;
italics = !italics;
firstchar = TRUE;
break;
case '^':
if (bold) {
......@@ -116,19 +121,33 @@ static void print_option(const NVGetoptOption *o)
}
omitWhiteSpace = bold;
bold = !bold;
firstchar = TRUE;
break;
case '-':
printf("\\-");
omitWhiteSpace = 0;
omitWhiteSpace = FALSE;
firstchar = FALSE;
break;
case ' ':
if (!omitWhiteSpace) {
printf(" ");
firstchar = FALSE;
}
break;
case '.':
if (firstchar) {
fprintf(stderr, "Error: *roff can't start a line with '.' "
"If you used '&' or '^' to format text in the "
"description of the '%s' option, please add some "
"text before the end of the sentence, so that a "
"valid manpage can be generated.\n", o->name);
exit(1);
}
/* fall through */
default:
printf("%c", *s);
omitWhiteSpace = 0;
omitWhiteSpace = FALSE;
firstchar = FALSE;
break;
}
}
......
This diff is collapsed.
/*
* Copyright (C) 2004 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 <http://www.gnu.org/licenses>.
*/
#ifndef __MSG_H__
#define __MSG_H__
#include <stdarg.h>
#include <stdio.h>
/*
* Define a printf format attribute macro. This definition is based on the one
* from Xfuncproto.h, available in the 'xproto' package at
* http://xorg.freedesktop.org/releases/individual/proto/
*/
#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)
# define NV_ATTRIBUTE_PRINTF(x,y) __attribute__((__format__(__printf__,x,y)))
#else /* not gcc >= 2.3 */
# define NV_ATTRIBUTE_PRINTF(x,y)
#endif
/*
* 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; \
\
while (1) { \
(buf) = nvalloc(current_len); \
\
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; \
} \
\
nvfree(buf); \
} \
} \
} while (0)
/*
* verbosity, controls output of errors, warnings and other
* information.
*/
typedef enum {
NV_VERBOSITY_NONE = 0, /* no errors, warnings or info */
NV_VERBOSITY_ERROR, /* errors only */
NV_VERBOSITY_DEPRECATED, /* errors and deprecation messages */
NV_VERBOSITY_WARNING, /* errors and all warnings */
NV_VERBOSITY_ALL, /* errors, all warnings and other info */
NV_VERBOSITY_DEFAULT = NV_VERBOSITY_ALL
} NvVerbosity;
NvVerbosity nv_get_verbosity(void);
void nv_set_verbosity(NvVerbosity level);
/*
* Formatted I/O functions
*/
void reset_current_terminal_width(unsigned short new_val);
void nv_error_msg(const char *fmt, ...) NV_ATTRIBUTE_PRINTF(1, 2);
void nv_deprecated_msg(const char *fmt, ...) NV_ATTRIBUTE_PRINTF(1, 2);
void nv_warning_msg(const char *fmt, ...) NV_ATTRIBUTE_PRINTF(1, 2);
void nv_info_msg(const char *prefix,
const char *fmt, ...) NV_ATTRIBUTE_PRINTF(2, 3);
void nv_info_msg_to_file(FILE *stream,
const char *prefix,
const char *fmt, ...) NV_ATTRIBUTE_PRINTF(3, 4);
void nv_msg(const char *prefix, const char *fmt, ...) NV_ATTRIBUTE_PRINTF(2, 3);
void nv_msg_preserve_whitespace(const char *prefix,
const char *fmt, ...) NV_ATTRIBUTE_PRINTF(2, 3);
/*
* TextRows structure and helper functions
*/
typedef struct {
char **t; /* the text rows */
int n; /* number of rows */
int m; /* maximum row length */
} TextRows;
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);
#endif /* __MSG_H__ */
......@@ -2,9 +2,11 @@
COMMON_UTILS_SRC += nvgetopt.c
COMMON_UTILS_SRC += common-utils.c
COMMON_UTILS_SRC += msg.c
COMMON_UTILS_EXTRA_DIST += nvgetopt.h
COMMON_UTILS_EXTRA_DIST += common-utils.h
COMMON_UTILS_EXTRA_DIST += msg.h
COMMON_UTILS_EXTRA_DIST += src.mk
# gen-manpage-opts-helper.c is listed in EXTRA_DIST, rather than SRC,
......
......@@ -42,37 +42,39 @@
#include "nvgetopt.h"
#include "option-table.h"
#include "common-utils.h"
#include "msg.h"
extern const char *pNV_ID;
static void print_version(void)
{
fmtout("");
fmtout("%s", pNV_ID);
fmtout("");
fmtoutp(TAB, "Copyright (C) 2013 NVIDIA Corporation.");
fmtout("");
nv_info_msg(NULL, "");
nv_info_msg(NULL, "%s", pNV_ID);
nv_info_msg(NULL, "");
nv_info_msg(TAB, "Copyright (C) 2013 NVIDIA Corporation.");
nv_info_msg(NULL, "");
}
static void print_summary(void)
{
fmtout("");
fmtoutp(TAB, "This setuid program is used to create, in a Linux "
"distribution-independent way, NVIDIA Linux device "
"files and load the NVIDIA kernel module, on behalf of NVIDIA "
"Linux driver components which may not have sufficient "
"privileges to perform these actions on their own.");
fmtout("");
nv_info_msg(NULL, "");
nv_info_msg(TAB, "This setuid program is used to create, in a Linux "
"distribution-independent way, NVIDIA Linux device "
"files and load the NVIDIA kernel module, on behalf of "
"NVIDIA Linux driver components which may not have "
"sufficient privileges to perform these actions on their "
"own.");
nv_info_msg(NULL, "");
}
static void print_help_helper(const char *name, const char *description)
{
fmtoutp(TAB, "%s", name);
fmtoutp(BIGTAB, "%s", description);
fmtout("");
nv_info_msg(TAB, "%s", name);
nv_info_msg(BIGTAB, "%s", description);
nv_info_msg(NULL, "");
}
......@@ -81,9 +83,9 @@ static void print_help(void)
print_version();
print_summary();