bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug-gnulib] new module: progname


From: Bruno Haible
Subject: [Bug-gnulib] new module: progname
Date: Mon, 18 Aug 2003 19:27:17 +0200
User-agent: KMail/1.5

Simon Josefsson wrote:
> Simon Josefsson <address@hidden> writes:
> >     * argp.m4: New file.
>
> I noticed I had made some modifications in another version of the
> file, here's what I really uses, which works on several platforms.
>
> I had one idea to make a 'program_invocation_name' module, so that
> error.c could use that instead of 'program_name'.  I don't like the
> current 'program_name' stuff, it pollute all applications that uses my
> library.  Making a module out of it would allow other modules (and
> applications) to rely on program_invocation_name, which is a useful
> thing to have, but I haven't done anything about this.  Instead of
> being declared 'extern', it should, on platforms that doesn't have
> program_invocation_name (or a similar way to get the executable name),
> be defined to a static string, say 'gnulib' and there could be a
> function to set it to something else.  What do you think?

What would be the benefit of calling it 'program_invocation_name', i.e.
differently from what the 'error' module expects?

I'd like to propose for inclusion in gnulib the facility that I'm using
in gettext:

  progname.h
  progname.c
  progreloc.c

When using this module, all main() functions start out like this:


int
main (int argc, char **argv)
{
  /* Set program name for messages.  */
  set_program_name (argv[0]);
  error_print_progname = maybe_print_progname;

#ifdef HAVE_SETLOCALE
  /* Set locale via LC_ALL.  */
  setlocale (LC_ALL, "");
#endif


The idea of set_program_name() as a function-like macro is that it
enables the relocatable executable stuff (which may one day move into
automake). The idea of the error_with_progname variable and
maybe_print_progname() function is that programs that read files want
to omit the program name sometimes, e.g. 'msgfmt' wants to print

     de.po:4: invalid multibyte sequence

instead of

     msgfmt: de.po:4: invalid multibyte sequence

Bruno


============================== progname.h =============================
/* Program name management.
   Copyright (C) 2001-2003 Free Software Foundation, Inc.
   Written by Bruno Haible <address@hidden>, 2001.

   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, or (at your option)
   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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

#ifndef _PROGNAME_H
#define _PROGNAME_H

#include <stdbool.h>

/* This file supports selectively prefixing or nor prefixing error messages
   with the program name.

   Programs using this file should do the following in main():
     set_program_name (argv[0]);
     error_print_progname = maybe_print_progname;
 */

/* String containing name the program is called with.  */
extern const char *program_name;

/* Set program_name, based on argv[0].  */
extern void set_program_name (const char *argv0);

#if ENABLE_RELOCATABLE

/* Set program_name, based on argv[0], and original installation prefix and
   directory, for relocatability.  */
extern void set_program_name_and_installdir (const char *argv0,
                                             const char *orig_installprefix,
                                             const char *orig_installdir);
#define set_program_name(ARG0) \
  set_program_name_and_installdir (ARG0, INSTALLPREFIX, INSTALLDIR)

/* Return the full pathname of the current executable, based on the earlier
   call to set_program_name_and_installdir.  Return NULL if unknown.  */
extern char *get_full_program_name (void);

#endif

/* Indicates whether errors and warnings get prefixed with program_name.
   Default is true.
   A reason to omit the prefix is for better interoperability with Emacs'
   compile.el.  */
extern bool error_with_progname;

/* Print program_name prefix on stderr if and only if error_with_progname
   is true.  */
extern void maybe_print_progname (void);

#endif /* _PROGNAME_H */
============================== progname.c =============================
/* Program name management.
   Copyright (C) 2001-2003 Free Software Foundation, Inc.
   Written by Bruno Haible <address@hidden>, 2001.

   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, or (at your option)
   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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */


#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

/* Specification.  */
#include "progname.h"

#include <stdio.h>
#include <string.h>

#undef set_program_name


/* String containing name the program is called with.
   To be initialized by main().  */
const char *program_name;

/* Set program_name, based on argv[0].  */
void
set_program_name (const char *argv0)
{
  /* libtool creates a temporary executable whose name is sometimes prefixed
     with "lt-" (depends on the platform).  It also makes argv[0] absolute.
     Remove this "<dirname>/.libs/" or "<dirname>/.libs/lt-" prefix here.  */
  const char *slash;
  const char *base;

  slash = strrchr (argv0, '/');
  base = (slash != NULL ? slash + 1 : argv0);
  if (base - argv0 >= 7 && memcmp (base - 7, "/.libs/", 7) == 0)
    argv0 = base;
  if (strncmp (base, "lt-", 3) == 0)
    argv0 = base + 3;
  program_name = argv0;
}


/* Indicates whether errors and warnings get prefixed with program_name.
   Default is true.  */
bool error_with_progname = true;

/* Print program_name prefix on stderr if and only if error_with_progname
   is true.  */
void
maybe_print_progname ()
{
  if (error_with_progname)
    fprintf (stderr, "%s: ", program_name);
}





reply via email to

[Prev in Thread] Current Thread [Next in Thread]