public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* c++/4373: groff -O3 ICE
@ 2001-09-21 11:16 Golubev I. N.
  0 siblings, 0 replies; only message in thread
From: Golubev I. N. @ 2001-09-21 11:16 UTC (permalink / raw)
  To: gcc-gnats

>Number:         4373
>Category:       c++
>Synopsis:       groff -O3 ICE
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    unassigned
>State:          open
>Class:          ice-on-legal-code
>Submitter-Id:   net
>Arrival-Date:   Fri Sep 21 11:16:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     groff -O3 ICE
>Release:        3.0.1
>Organization:
>Environment:
System: SCO_SV d-fens 3.2 2 i386


host: i586-pc-sco3.2v5.0.2
build: i586-pc-sco3.2v5.0.2
target: i586-pc-sco3.2v5.0.2
configured with:  : (reconfigured)  : (reconfigured) ../gcc-3.0/configure --without-included-gettext --prefix=/usr --with-as=/usr/bin/gas --enable-multilib --disable-static --enable-shared --with-system-zlib --program-transform-name=s/cpp/gcpp/ : (reconfigured) ../gcc-3.0.1/configure --without-included-gettext --prefix=/usr --with-as=/usr/bin/gas --enable-multilib --disable-static --enable-shared --with-system-zlib --program-transform-name=s/cpp/gcpp/
>Description:
	>g++ -S -o /dev/null -g -O3
/groff-1.17.2/src/preproc/refer/ref.cc: In function `void 
   sortify_name(const char*, int, string&)':
/groff-1.17.2/src/preproc/refer/ref.cc:362: Internal compiler 
   error in add_abstract_origin_attribute, at dwarf2out.c:8718
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL: http://www.gnu.org/software/gcc/bugs.html > for instructions.

>How-To-Repeat:
	
# 21 "/groff-1.17.2/src/preproc/refer/ref.cc"
# 1 "/groff-1.17.2/src/preproc/refer/refer.h" 1
# 21 "/groff-1.17.2/src/preproc/refer/refer.h"
# 1 "/usr/include/stdio.h" 1 3
# 39 "/usr/include/stdio.h" 3
#pragma comment(exestr, "xpg4plus @(#) stdio.h 20.1 94/12/04 ")

#pragma pack(4)


extern "C" {




typedef unsigned int size_t;




typedef long fpos_t;




typedef long wchar_t;




typedef long wint_t;
# 128 "/usr/include/stdio.h" 3
typedef struct _FILE_
{
        int __cnt;
        unsigned char *__ptr;
        unsigned char *__base;
        unsigned char __flag;
        unsigned char __file;
        unsigned char __buf[2];
} FILE;



extern FILE __iob[];
# 151 "/usr/include/stdio.h" 3
extern int remove(const char *);
extern int rename(const char *, const char *);
extern FILE *tmpfile(void);
extern char *tmpnam(char *);
extern int fclose(FILE *);
extern int fflush(FILE *);
extern FILE *fopen(const char *, const char *);
extern FILE *freopen(const char *, const char *, FILE *);
extern void setbuf(FILE *, char *);
extern int setvbuf(FILE *, char *, int, size_t);

extern int fprintf(FILE *, const char *, ...);

extern int fscanf(FILE *, const char *, ...);

extern int printf(const char *, ...);

extern int scanf(const char *, ...);

extern int sprintf(char *, const char *, ...);

extern int sscanf(const char *, const char *, ...);
extern int vfprintf(FILE *, const char *, char *);
extern int vprintf(const char *, char *);
extern int vsprintf(char *, const char *, char *);
extern int fgetc(FILE *);
extern char *fgets(char *, int, FILE *);
extern int fputc(int, FILE *);
extern int fputs(const char *, FILE *);
extern int getc(FILE *);
extern int getchar(void);
extern char *gets(char *);
extern int putc(int, FILE *);
extern int putchar(int);
extern int puts(const char *);
extern int ungetc(int, FILE *);
extern size_t fread(void *, size_t, size_t, FILE *);
#pragma int_to_unsigned fread
extern size_t fwrite(const void *, size_t, size_t, FILE *);
#pragma int_to_unsigned fwrite
extern int fgetpos(FILE *, fpos_t *);
extern int fseek(FILE *, long, int);
extern int fsetpos(FILE *, const fpos_t *);
extern long ftell(FILE *);
extern void rewind(FILE *);
extern void clearerr(FILE *);
extern int feof(FILE *);
extern int ferror(FILE *);
extern void perror(const char *);

extern int __filbuf(FILE *);
extern int __flsbuf(int, FILE *);
# 220 "/usr/include/stdio.h" 3
extern int (fileno)(FILE *);
extern char *ctermid(char *);
extern FILE *fdopen(int, const char *);

extern FILE *popen(const char *, const char *);
extern char *tempnam(const char *, const char *);
extern int getw(FILE *);
extern int putw(int, FILE *);
extern int pclose(FILE *);





extern char *optarg;
extern int optind, opterr, optopt;
extern char *cuserid(char *);
extern int getopt(int, char *const*, const char *);
# 261 "/usr/include/stdio.h" 3
extern int system(const char *);
extern wint_t fgetwc(FILE *);
extern wchar_t *fgetws(wchar_t *, int, FILE *);
extern wint_t fputwc(wint_t, FILE *);
extern int fputws(const wchar_t *, FILE *);
extern wint_t getwc(FILE *);
extern wint_t getwchar(void);
extern wint_t putwc(wint_t, FILE *);
extern wint_t putwchar(wint_t);
extern wint_t ungetwc(wint_t, FILE *);

extern int fwprintf(FILE *, const wchar_t *, ...);

extern int fwscanf(FILE *, const wchar_t *, ...);

extern int wprintf(const wchar_t *, ...);

extern int wscanf(const wchar_t *, ...);

extern int swprintf(wchar_t *, size_t, const wchar_t *, ...);

extern int swscanf(const wchar_t *, const wchar_t *, ...);
extern int vfwprintf(FILE *, const wchar_t *, char *);
extern int vfwscanf(FILE *, const wchar_t *, char *);
extern int vwprintf(const wchar_t *, char *);
extern int vwscanf(const wchar_t *, char *);
extern int vswprintf(wchar_t *, size_t, const wchar_t *, char *);
extern int vswscanf(const wchar_t *, const wchar_t *, char *);
extern void funflush(FILE *);

extern int snprintf(char *, size_t, const char *, ...);
extern int vsnprintf(char *, size_t, const char *, char *);
extern int vfscanf(FILE *, const char *, char *);
extern int vscanf(const char *, char *);
extern int vsscanf(const char *, const char *, char *);
# 304 "/usr/include/stdio.h" 3
extern int nl_fprintf(FILE *, const char *, ...);

extern int nl_fscanf(FILE *, const char *, ...);

extern int nl_printf(const char *, ...);

extern int nl_scanf(const char *, ...);

extern int nl_sprintf(char *, const char *, ...);

extern int nl_sscanf(const char *, const char *, ...);




}


#pragma pack()
# 22 "/groff-1.17.2/src/preproc/refer/refer.h" 2
# 1 "/usr/include/stdlib.h" 1 3
# 39 "/usr/include/stdlib.h" 3
#pragma comment(exestr, "xpg4plus @(#) stdlib.h 20.1 94/12/04 ")


extern "C" {


#pragma pack(4)



typedef struct
{
        int quot;
        int rem;
} div_t;




typedef struct
{
        long quot;
        long rem;
} ldiv_t;
# 72 "/usr/include/stdlib.h" 3
typedef int ssize_t;
# 100 "/usr/include/stdlib.h" 3
extern unsigned char __ctype[];



extern double atof(const char *);
extern int atoi(const char *);
extern long atol(const char *);
extern double strtod(const char *, char **);
extern float strtof(const char *, char **);
extern long strtol(const char *, char **, int);
extern unsigned long strtoul(const char *, char **, int);

extern int rand(void);
extern void srand(unsigned int);

extern void *calloc(size_t, size_t);
extern void free(void *);
extern void *malloc(size_t);
extern void *realloc(void *, size_t);

extern void abort(void);
extern int atexit(void (*)(void));
extern void exit(int);
extern char *getenv(const char *);
extern int system(const char *);

extern void *bsearch(const void *, const void *, size_t, size_t,
                        int (*)(const void *, const void *));
extern void qsort(void *, size_t, size_t,
                        int (*)(const void *, const void *));




inline int (abs)(int i) {return (i > 0) ? i : -i;}





extern div_t div(int, int);
extern long labs(long);
extern ldiv_t ldiv(long, long);

extern int mbtowc(wchar_t *, const char *, size_t);
extern int mblen(const char *, size_t);
extern int wctomb(char *, wchar_t);

extern size_t mbstowcs(wchar_t *, const char *, size_t);
extern size_t wcstombs(char *, const wchar_t *, size_t);


extern long a64l(const char *);
extern int dup2(int, int);
extern char *ecvt(double, int, int *, int *);
extern char *ecvtl(long double, int, int *, int *);
extern char *fcvt(double, int, int *, int *);
extern char *fcvtl(long double, int, int *, int *);
extern char *getcwd(char *, size_t);
extern char *getlogin(void);
extern int getopt(int, char *const *, const char *);
extern int getsubopt(char **, char *const *, char **);
extern char *initstate(unsigned, char *, int);
extern int grantpt(int);
extern char *optarg;
extern int optind, opterr, optopt;
extern char *getpass(const char *);
extern int getpw(int, char *);
extern char *gcvt(double, int, char *);
extern char *gcvtl(long double, int, char *);
extern int isatty(int);
extern void l3tol(long *, const char *, int);
extern char *l64a(long);
extern char *l64a_r(long, char *, size_t);
extern void ltol3(char *, const long *, int);
extern void *memalign(size_t, size_t);
extern char *mktemp(char *);
extern int mkstemp(char *);
extern char *ptsname(int);
extern long random(void);
extern int rand_r(unsigned int *);
extern char *realpath(const char *, char *);
extern char *setstate(char *);
extern void srandom(unsigned);
extern long double strtold(const char *, char **);
extern void swab(const void *, void *, ssize_t);
extern char *ttyname(int);
extern int ttyslot(void);
extern int unlockpt(int);
extern void *valloc(size_t);
extern double wcstod(const wchar_t *, wchar_t **);
extern float wcstof(const wchar_t *, wchar_t **);
extern long wcstol(const wchar_t *, wchar_t **, int);
extern long double wcstold(const wchar_t *, wchar_t **);
extern unsigned long wcstoul(const wchar_t *, wchar_t **, int);



extern double drand48(void);
extern double erand48(unsigned short *);
extern long jrand48(unsigned short *);
extern void lcong48(unsigned short *);
extern long lrand48(void);
extern long mrand48(void);
extern long nrand48(unsigned short *);
extern int putenv(const char *);
extern unsigned short *seed48(unsigned short *);
extern void setkey(const char *);
extern void srand48(long);






}


#pragma pack()
# 23 "/groff-1.17.2/src/preproc/refer/refer.h" 2
# 1 "/groff-1.17.2/src/include/assert.h" 1
# 24 "/groff-1.17.2/src/include/assert.h"
void assertion_failed(int, const char *);

inline void do_assert(int expr, int line, const char *file)
{
  if (!expr)
    assertion_failed(line, file);
}
# 24 "/groff-1.17.2/src/preproc/refer/refer.h" 2
# 1 "/usr/include/string.h" 1 3
# 39 "/usr/include/string.h" 3
#pragma comment(exestr, "xpg4plus @(#) string.h 20.1 94/12/04 ")


extern "C" {
# 56 "/usr/include/string.h" 3
extern void *memchr(const void *, int, size_t);
extern void *memcpy(void *, const void *, size_t);
extern void *memccpy(void *, const void *, int, size_t);
extern void *memmove(void *, const void *, size_t);
extern void *memset(void *, int, size_t);

extern char *strchr(const char *, int);
extern char *strcpy(char *, const char *);
extern char *strncpy(char *, const char *, size_t);
extern char *strcat(char *, const char *);
extern char *strncat(char *, const char *, size_t);
extern char *strpbrk(const char *, const char *);
extern char *strrchr(const char *, int);
extern char *strstr(const char *, const char *);
extern char *strtok(char *, const char *);
extern char *strtok_r(char *, const char *, char **);
extern char *strerror(int);
extern char *strlist(char *, const char *, ...);

extern int memcmp(const void *, const void *, size_t);
extern int strcmp(const char *, const char *);
extern int strcoll(const char *, const char *);
extern int strncmp(const char *, const char *, size_t);

extern void perror(const char *);
extern char *strdup(const char *);
extern int strncoll(const char *, const char *, int);
extern size_t strnxfrm(char *, const char *, size_t , int);

extern size_t strxfrm(char *, const char *, size_t);
extern size_t strcspn(const char *, const char *);
extern size_t strspn(const char *, const char *);
extern size_t strlen(const char *);
# 110 "/usr/include/string.h" 3
extern int ffs(int);




extern int nl_strcmp(char *, char *);
extern int nl_strncmp(char *, char *, int n);




}
# 25 "/groff-1.17.2/src/preproc/refer/refer.h" 2
# 1 "/usr/include/errno.h" 1 3
# 39 "/usr/include/errno.h" 3
#pragma comment(exestr, "xpg4plus @(#) errno.h 20.1 94/12/04 ")


# 1 "/usr/include/sys/errno.h" 1 3



#pragma comment(exestr, "@(#) errno.h 25.4 94/04/06 ")
# 43 "/usr/include/errno.h" 2 3



extern "C" {
# 57 "/usr/include/errno.h" 3
extern int errno;



extern int sys_nerr;
extern char *sys_errlist[];
extern void perror(const char *);


}
# 26 "/groff-1.17.2/src/preproc/refer/refer.h" 2

# 1 "/groff-1.17.2/src/include/errarg.h" 1
# 21 "/groff-1.17.2/src/include/errarg.h"
class errarg {
  enum { EMPTY, STRING, CHAR, INTEGER, DOUBLE } type;
  union {
    const char *s;
    int n;
    char c;
    double d;
  };
 public:
  errarg();
  errarg(const char *);
  errarg(char);
  errarg(unsigned char);
  errarg(int);
  errarg(double);
  int empty() const;
  void print() const;
};

extern errarg empty_errarg;

extern void errprint(const char *,
                     const errarg &arg1 = empty_errarg,
                     const errarg &arg2 = empty_errarg,
                     const errarg &arg3 = empty_errarg);
# 28 "/groff-1.17.2/src/preproc/refer/refer.h" 2
# 1 "/groff-1.17.2/src/include/error.h" 1
# 21 "/groff-1.17.2/src/include/error.h"
extern void fatal_with_file_and_line(const char *filename, int lineno,
                                     const char *format,
                                     const errarg &arg1 = empty_errarg,
                                     const errarg &arg2 = empty_errarg,
                                     const errarg &arg3 = empty_errarg);

extern void error_with_file_and_line(const char *filename, int lineno,
                                     const char *format,
                                     const errarg &arg1 = empty_errarg,
                                     const errarg &arg2 = empty_errarg,
                                     const errarg &arg3 = empty_errarg);

extern void warning_with_file_and_line(const char *filename, int lineno,
                                     const char *format,
                                     const errarg &arg1 = empty_errarg,
                                     const errarg &arg2 = empty_errarg,
                                     const errarg &arg3 = empty_errarg);

extern void fatal(const char *,
                  const errarg &arg1 = empty_errarg,
                  const errarg &arg2 = empty_errarg,
                  const errarg &arg3 = empty_errarg);

extern void error(const char *,
                  const errarg &arg1 = empty_errarg,
                  const errarg &arg2 = empty_errarg,
                  const errarg &arg3 = empty_errarg);

extern void warning(const char *,
                    const errarg &arg1 = empty_errarg,
                    const errarg &arg2 = empty_errarg,
                    const errarg &arg3 = empty_errarg);


extern const char *program_name;
extern int current_lineno;
extern const char *current_filename;
# 29 "/groff-1.17.2/src/preproc/refer/refer.h" 2
# 1 "/groff-1.17.2/src/include/lib.h" 1
# 21 "/groff-1.17.2/src/include/lib.h"
extern "C" {



  const char *i_to_a(int);
  const char *if_to_a(int, int);
}






# 1 "/groff-1.17.2/src/include/groff-getopt.h" 1
# 30 "/groff-1.17.2/src/include/groff-getopt.h"
extern "C" {


extern char *optarg;
extern int optind;
extern int opterr;
extern int optopt;

struct option
{
  const char *name;
  int has_arg;
  int *flag;
  int val;
};





extern int getopt(int,
                  char *const *,
                  const char *);
extern int getopt_long(int,
                       char *const *,
                       const char *,
                       const struct option *,
                       int *);
extern int getopt_long_only(int,
                            char *const *,
                            const char *,
                            const struct option *,
                            int *);


}
# 35 "/groff-1.17.2/src/include/lib.h" 2


char *strsave(const char *s);
int is_prime(unsigned);

# 1 "/usr/include/stdio.h" 1 3
# 41 "/groff-1.17.2/src/include/lib.h" 2
# 1 "/usr/include/string.h" 1 3
# 42 "/groff-1.17.2/src/include/lib.h" 2

# 1 "/usr/include/strings.h" 1 3
# 31 "/usr/include/strings.h" 3
#pragma comment(exestr, "xpg4plus @(#) strings.h 20.1 94/12/04 ")

# 1 "/usr/include/sys/types.h" 1 3



#pragma comment(exestr, "@(#) types.h 25.16 95/02/03 ")
# 32 "/usr/include/sys/types.h" 3
#pragma pack(4)
# 47 "/usr/include/sys/types.h" 3
typedef long daddr_t;




typedef char * caddr_t;





typedef struct { int r[1]; } *physadr;







typedef unsigned char unchar;




typedef unsigned char u_char;




typedef unsigned short ushort;




typedef unsigned short u_short;




typedef unsigned int uint;




typedef unsigned int u_int;




typedef unsigned long ulong;




typedef unsigned long u_long;
# 110 "/usr/include/sys/types.h" 3
typedef unsigned char uchar_t;




typedef unsigned short ushort_t;




typedef unsigned int uint_t;




typedef unsigned long ulong_t;




typedef unsigned long ino32_t;
typedef unsigned short ino16_t;


typedef unsigned long ino_t;
# 144 "/usr/include/sys/types.h" 3
typedef short cnt_t;







typedef long time_t;







typedef struct __label { int __val[6]; } label_t;





typedef unsigned short mode_t;




typedef short nlink_t;





typedef long id_t;







typedef short dev_t;




typedef long off_t;




typedef unsigned long paddr_t;




typedef unsigned short mloc_t;




typedef long key_t;




typedef int pfn_t;




typedef unsigned short use_t;
# 225 "/usr/include/sys/types.h" 3
typedef char * faddr_t;
# 239 "/usr/include/sys/types.h" 3
struct saddr {
        unsigned short sa_seg;
        long sa_off;
};





typedef short sysid_t;




typedef short index_t;




typedef short lock_t;
# 273 "/usr/include/sys/types.h" 3
typedef ushort_t sel_t;





typedef long clock_t;




typedef int ptrdiff_t;
# 294 "/usr/include/sys/types.h" 3
typedef int sig_atomic_t;
# 318 "/usr/include/sys/types.h" 3
typedef unsigned short uid_t;




typedef unsigned short gid_t;




typedef short pid_t;
# 350 "/usr/include/sys/types.h" 3
typedef long fd_mask;
# 361 "/usr/include/sys/types.h" 3
typedef struct fd_set {
        fd_mask fds_bits[(((150)+(((sizeof(fd_mask) * 8))-1))/((sizeof(fd_mask) * 8)))];
} fd_set;
# 375 "/usr/include/sys/types.h" 3
typedef unsigned long mask_t;




typedef mask_t priv_t;




typedef enum _boolean { B_FALSE, B_TRUE } boolean_t;
# 401 "/usr/include/sys/types.h" 3
typedef long hostid_t;
# 412 "/usr/include/sys/types.h" 3
#pragma pack()
# 34 "/usr/include/strings.h" 2 3


extern "C" {



extern int bcmp(const void *, const void *, size_t);
extern void bcopy(const void *, void *, size_t);
extern void bzero(void *, size_t);
extern int ffs(int);
extern char * index(const char *, char);
extern char * rindex(const char *, char);
extern int strcasecmp(const char *, const char *);
extern int strncasecmp(const char *, const char *, size_t);



};
# 44 "/groff-1.17.2/src/include/lib.h" 2


FILE *xtmpfile(char **namep = 0, char *postfix = 0, int do_unlink = 1);
char *xtmptemplate(char *extension = 0);
# 61 "/groff-1.17.2/src/include/lib.h"
size_t file_name_max(const char *fname);

int interpret_lf_args(const char *p);

extern char illegal_char_table[];

inline int illegal_input_char(int c)
{
  return c >= 0 && illegal_char_table[c];
}
# 92 "/groff-1.17.2/src/include/lib.h"
# 1 "/usr/include/limits.h" 1 3
# 39 "/usr/include/limits.h" 3
#pragma comment(exestr, "xpg4plus @(#) limits.h 20.2 94/12/15 ")
# 286 "/usr/include/limits.h" 3
extern "C" {

extern long _sysconf(int);

}
# 93 "/groff-1.17.2/src/include/lib.h" 2
# 124 "/groff-1.17.2/src/include/lib.h"
const double PI = 3.14159265358979323846;
# 30 "/groff-1.17.2/src/preproc/refer/refer.h" 2
# 1 "/groff-1.17.2/src/include/stringclass.h" 1
# 21 "/groff-1.17.2/src/include/stringclass.h"
# 1 "/usr/include/string.h" 1 3
# 22 "/groff-1.17.2/src/include/stringclass.h" 2
# 1 "/usr/include/stdio.h" 1 3
# 23 "/groff-1.17.2/src/include/stringclass.h" 2
# 1 "/groff-1.17.2/src/include/assert.h" 1
# 24 "/groff-1.17.2/src/include/stringclass.h" 2




class string;

inline string operator+(const string &, const string &);
inline string operator+(const string &, const char *);
inline string operator+(const char *, const string &);
inline string operator+(const string &, char);
inline string operator+(char, const string &);
inline int operator==(const string &, const string &);
inline int operator!=(const string &, const string &);

class string {
public:
  string();
  string(const string &);
  string(const char *);
  string(const char *, int);
  string(char);

  ~string();

  string &operator=(const string &);
  string &operator=(const char *);
  string &operator=(char);

  string &operator+=(const string &);
  string &operator+=(const char *);
  string &operator+=(char);
  void append(const char *, int);

  int length() const;
  int empty() const;
  int operator*() const;

  string substring(int i, int n) const;

  char &operator[](int);
  char operator[](int) const;

  void set_length(int i);
  const char *contents() const;
  int search(char) const;
  char *extract() const;
  void clear();
  void move(string &);

  friend string operator+(const string &, const string &);
  friend string operator+(const string &, const char *);
  friend string operator+(const char *, const string &);
  friend string operator+(const string &, char);
  friend string operator+(char, const string &);

  friend int operator==(const string &, const string &);
  friend int operator!=(const string &, const string &);
  friend int operator<=(const string &, const string &);
  friend int operator<(const string &, const string &);
  friend int operator>=(const string &, const string &);
  friend int operator>(const string &, const string &);

private:
  char *ptr;
  int len;
  int sz;

  string(const char *, int, const char *, int);
  void grow1();
};


inline char &string::operator[](int i)
{
  do_assert(i >= 0 && i < len, 98, "/groff-1.17.2/src/include/stringclass.h");
  return ptr[i];
}

inline char string::operator[](int i) const
{
  do_assert(i >= 0 && i < len, 104, "/groff-1.17.2/src/include/stringclass.h");
  return ptr[i];
}

inline int string::length() const
{
  return len;
}

inline int string::empty() const
{
  return len == 0;
}

inline int string::operator*() const
{
  return len;
}

inline const char *string::contents() const
{
  return ptr;
}

inline string operator+(const string &s1, const string &s2)
{
  return string(s1.ptr, s1.len, s2.ptr, s2.len);
}

inline string operator+(const string &s1, const char *s2)
{

  if (s2 == 0)
    return s1;
  else
    return string(s1.ptr, s1.len, s2, strlen(s2));



}

inline string operator+(const char *s1, const string &s2)
{

  if (s1 == 0)
    return s2;
  else
    return string(s1, strlen(s1), s2.ptr, s2.len);



}

inline string operator+(const string &s, char c)
{
  return string(s.ptr, s.len, &c, 1);
}

inline string operator+(char c, const string &s)
{
  return string(&c, 1, s.ptr, s.len);
}

inline int operator==(const string &s1, const string &s2)
{
  return (s1.len == s2.len
          && (s1.len == 0 || memcmp(s1.ptr, s2.ptr, s1.len) == 0));
}

inline int operator!=(const string &s1, const string &s2)
{
  return (s1.len != s2.len
          || (s1.len != 0 && memcmp(s1.ptr, s2.ptr, s1.len) != 0));
}

inline string string::substring(int i, int n) const
{
  do_assert(i >= 0 && i + n <= len, 181, "/groff-1.17.2/src/include/stringclass.h");
  return string(ptr + i, n);
}

inline string &string::operator+=(char c)
{
  if (len >= sz)
    grow1();
  ptr[len++] = c;
  return *this;
}

void put_string(const string &, FILE *);

string as_string(int);
# 31 "/groff-1.17.2/src/preproc/refer/refer.h" 2
# 1 "/groff-1.17.2/src/include/cset.h" 1
# 22 "/groff-1.17.2/src/include/cset.h"
# 1 "/usr/include/limits.h" 1 3
# 23 "/groff-1.17.2/src/include/cset.h" 2






enum cset_builtin { CSET_BUILTIN };

class cset {
public:
  cset();
  cset(cset_builtin);
  cset(const char *);
  cset(const unsigned char *);
  int operator()(unsigned char) const;

  cset &operator|=(const cset &);
  cset &operator|=(unsigned char);

  friend class cset_init;
private:
  char v[255 +1];
  void clear();
};

inline int cset::operator()(unsigned char c) const
{
  return v[c];
}

inline cset &cset::operator|=(unsigned char c)
{
  v[c] = 1;
  return *this;
}

extern cset csalpha;
extern cset csupper;
extern cset cslower;
extern cset csdigit;
extern cset csxdigit;
extern cset csspace;
extern cset cspunct;
extern cset csalnum;
extern cset csprint;
extern cset csgraph;
extern cset cscntrl;

static class cset_init {
  static int initialised;
public:
  cset_init();
} _cset_init;
# 32 "/groff-1.17.2/src/preproc/refer/refer.h" 2
# 1 "/groff-1.17.2/src/include/cmap.h" 1
# 25 "/groff-1.17.2/src/include/cmap.h"
enum cmap_builtin { CMAP_BUILTIN };

class cmap {
public:
  cmap();
  cmap(cmap_builtin);
  int operator()(unsigned char) const;
  unsigned char &operator[](unsigned char);

  friend class cmap_init;
private:
  unsigned char v[255 +1];
};

inline int cmap::operator()(unsigned char c) const
{
  return v[c];
}

inline unsigned char &cmap::operator[](unsigned char c)
{
  return v[c];
}

extern cmap cmlower;
extern cmap cmupper;

static class cmap_init {
  static int initialised;
public:
  cmap_init();
} _cmap_init;
# 33 "/groff-1.17.2/src/preproc/refer/refer.h" 2

# 1 "/groff-df/src/include/defs.h" 1
# 35 "/groff-1.17.2/src/preproc/refer/refer.h" 2

unsigned hash_string(const char *, int);
int next_size(int);

extern string capitalize_fields;
extern string reverse_fields;
extern string abbreviate_fields;
extern string period_before_last_name;
extern string period_before_initial;
extern string period_before_hyphen;
extern string period_before_other;
extern string sort_fields;
extern int annotation_field;
extern string annotation_macro;
extern string discard_fields;
extern string articles;
extern int abbreviate_label_ranges;
extern string label_range_indicator;
extern int date_as_label;
extern string join_authors_exactly_two;
extern string join_authors_last_two;
extern string join_authors_default;
extern string separate_label_second_parts;
extern string et_al;
extern int et_al_min_elide;
extern int et_al_min_total;

extern int compatible_flag;

extern int set_label_spec(const char *);
extern int set_date_label_spec(const char *);
extern int set_short_label_spec(const char *);

extern int short_label_flag;

void clear_labels();
void command_error(const char *,
                   const errarg &arg1 = empty_errarg,
                   const errarg &arg2 = empty_errarg,
                   const errarg &arg3 = empty_errarg);

struct reference;

void compute_labels(reference **, int);
# 22 "/groff-1.17.2/src/preproc/refer/ref.cc" 2
# 1 "/groff-1.17.2/src/include/refid.h" 1
# 21 "/groff-1.17.2/src/include/refid.h"
class reference_id {
  int filename_id;
  int pos;
public:
  reference_id() : filename_id(-1) { }
  reference_id(int fid, int off) : filename_id(fid), pos(off) { }
  unsigned hash() const { return (filename_id << 4) + pos; }
  int is_null() const { return filename_id < 0; }
  friend inline int operator==(const reference_id &, const reference_id &);
};

inline int operator==(const reference_id &r1, const reference_id &r2)
{
  return r1.filename_id == r2.filename_id && r1.pos == r2.pos;
}
# 23 "/groff-1.17.2/src/preproc/refer/ref.cc" 2
# 1 "/groff-1.17.2/src/preproc/refer/ref.h" 1
# 21 "/groff-1.17.2/src/preproc/refer/ref.h"
struct label_info;

enum label_type { NORMAL_LABEL, SHORT_LABEL };
const int N_LABEL_TYPES = 2;

struct substring_position {
  int start;
  int length;
  substring_position() : start(-1) { }
};

class int_set {
  string v;
public:
  int_set() { }
  void set(int i);
  int get(int i) const;
};

class reference {
private:
  unsigned h;
  reference_id rid;
  int merged;
  string sort_key;
  int no;
  string *field;
  int nfields;
  unsigned char field_index[256];
  enum { NULL_FIELD_INDEX = 255 };
  string label;
  substring_position separator_pos;
  string short_label;
  substring_position short_separator_pos;
  label_info *label_ptr;
  string authors;
  int computed_authors;
  int last_needed_author;
  int nauthors;
  int_set last_name_unambiguous;

  int contains_field(char) const;
  void insert_field(unsigned char, string &s);
  void delete_field(unsigned char);
  void set_date(string &);
  const char *get_sort_field(int i, int si, int ssi, const char **endp) const;
  int merge_labels_by_parts(reference **, int, label_type, string &);
  int merge_labels_by_number(reference **, int, label_type, string &);
public:
  reference(const char * = 0, int = -1, reference_id * = 0);
  ~reference();
  void output(FILE *);
  void print_sort_key_comment(FILE *);
  void set_number(int);
  int get_number() const { return no; }
  unsigned hash() const { return h; }
  const string &get_label(label_type type) const;
  const substring_position &get_separator_pos(label_type) const;
  int is_merged() const { return merged; }
  void compute_sort_key();
  void compute_hash_code();
  void pre_compute_label();
  void compute_label();
  void immediate_compute_label();
  int classify();
  void merge(reference &);
  int merge_labels(reference **, int, label_type, string &);
  int get_nauthors() const;
  void need_author(int);
  void set_last_name_unambiguous(int);
  void sortify_authors(int, string &) const;
  void canonicalize_authors(string &) const;
  void sortify_field(unsigned char, int, string &) const;
  const char *get_author(int, const char **) const;
  const char *get_author_last_name(int, const char **) const;
  const char *get_date(const char **) const;
  const char *get_year(const char **) const;
  const char *get_field(unsigned char, const char **) const;
  const label_info *get_label_ptr() const { return label_ptr; }
  const char *get_authors(const char **) const;

  friend int compare_reference(const reference &r1, const reference &r2);

  friend int same_reference(const reference &, const reference &);
  friend int same_year(const reference &, const reference &);
  friend int same_date(const reference &, const reference &);
  friend int same_author_last_name(const reference &, const reference &, int);
  friend int same_author_name(const reference &, const reference &, int);
};

const char *find_year(const char *, const char *, const char **);
const char *find_last_name(const char *, const char *, const char **);

const char *nth_field(int i, const char *start, const char **endp);

void capitalize(const char *ptr, const char *end, string &result);
void reverse_name(const char *ptr, const char *end, string &result);
void uppercase(const char *ptr, const char *end, string &result);
void lowercase(const char *ptr, const char *end, string &result);
void abbreviate_name(const char *ptr, const char *end, string &result);
# 24 "/groff-1.17.2/src/preproc/refer/ref.cc" 2
# 1 "/groff-1.17.2/src/preproc/refer/token.h" 1
# 21 "/groff-1.17.2/src/preproc/refer/token.h"
enum token_type {
  TOKEN_OTHER,
  TOKEN_UPPER,
  TOKEN_LOWER,
  TOKEN_ACCENT,
  TOKEN_PUNCT,
  TOKEN_HYPHEN,
  TOKEN_RANGE_SEP
};

class token_info {
private:
  token_type type;
  const char *sort_key;
  const char *other_case;
public:
  token_info();
  void set(token_type, const char *sk = 0, const char *oc = 0);
  void lower_case(const char *start, const char *end, string &result) const;
  void upper_case(const char *start, const char *end, string &result) const;
  void sortify(const char *start, const char *end, string &result) const;
  int sortify_non_empty(const char *start, const char *end) const;
  int is_upper() const;
  int is_lower() const;
  int is_accent() const;
  int is_other() const;
  int is_punct() const;
  int is_hyphen() const;
  int is_range_sep() const;
};

inline int token_info::is_upper() const
{
  return type == TOKEN_UPPER;
}

inline int token_info::is_lower() const
{
  return type == TOKEN_LOWER;
}

inline int token_info::is_accent() const
{
  return type == TOKEN_ACCENT;
}

inline int token_info::is_other() const
{
  return type == TOKEN_OTHER;
}

inline int token_info::is_punct() const
{
  return type == TOKEN_PUNCT;
}

inline int token_info::is_hyphen() const
{
  return type == TOKEN_HYPHEN;
}

inline int token_info::is_range_sep() const
{
  return type == TOKEN_RANGE_SEP;
}

int get_token(const char **ptr, const char *end);
const token_info *lookup_token(const char *start, const char *end);
# 25 "/groff-1.17.2/src/preproc/refer/ref.cc" 2

static const char *find_day(const char *, const char *, const char **);
static int find_month(const char *start, const char *end);
static void abbreviate_names(string &);



string articles("the\000a\000an", sizeof("the\000a\000an"));


const char FIELD_SEPARATOR = '\0';

const char MULTI_FIELD_NAMES[] = "AE";
const char *AUTHOR_FIELDS = "AQ";

enum { OTHER, JOURNAL_ARTICLE, BOOK, ARTICLE_IN_BOOK, TECH_REPORT, BELL_TM };

const char *reference_types[] = {
  "other",
  "journal-article",
  "book",
  "article-in-book",
  "tech-report",
  "bell-tm",
};

static string temp_fields[256];

reference::reference(const char *start, int len, reference_id *ridp)
: h(0), merged(0), no(-1), field(0), nfields(0), label_ptr(0),
  computed_authors(0), last_needed_author(-1), nauthors(-1)
{
  int i;
  for (i = 0; i < 256; i++)
    field_index[i] = NULL_FIELD_INDEX;
  if (ridp)
    rid = *ridp;
  if (start == 0)
    return;
  if (len <= 0)
    return;
  const char *end = start + len;
  const char *ptr = start;
  do_assert(*ptr == '%', 68, "/groff-1.17.2/src/preproc/refer/ref.cc");
  while (ptr < end) {
    if (ptr + 1 < end && ptr[1] != '\0'
        && ((ptr[1] != '%' && ptr[1] == annotation_field)
            || (ptr + 2 < end && ptr[1] == '%' && ptr[2] != '\0'
                && discard_fields.search(ptr[2]) < 0))) {
      if (ptr[1] == '%')
        ptr++;
      string &f = temp_fields[(unsigned char)ptr[1]];
      ptr += 2;
      while (ptr < end && csspace(*ptr))
        ptr++;
      for (;;) {
        for (;;) {
          if (ptr >= end) {
            f += '\n';
            break;
          }
          f += *ptr;
          if (*ptr++ == '\n')
            break;
        }
        if (ptr >= end || *ptr == '%')
          break;
      }
    }
    else if (ptr + 1 < end && ptr[1] != '\0' && ptr[1] != '%'
             && discard_fields.search(ptr[1]) < 0) {
      string &f = temp_fields[(unsigned char)ptr[1]];
      if (f.length() > 0) {
        if (strchr(MULTI_FIELD_NAMES, ptr[1]) != 0)
          f += FIELD_SEPARATOR;
        else
          f.clear();
      }
      ptr += 2;
      if (ptr < end) {
        if (*ptr == ' ')
          ptr++;
        for (;;) {
          const char *p = ptr;
          while (ptr < end && *ptr != '\n')
            ptr++;

          const char *q = ptr;
          while (q > p && q[-1] != '\n' && csspace(q[-1]))
            q--;
          while (p < q)
            f += *p++;
          if (ptr >= end)
            break;
          ptr++;
          if (ptr >= end)
            break;
          if (*ptr == '%')
            break;
          f += ' ';
        }
      }
    }
    else {

      for (;;) {
        while (ptr < end && *ptr++ != '\n')
          ;
        if (ptr >= end || *ptr == '%')
          break;
      }
    }
  }
  for (i = 0; i < 256; i++)
    if (temp_fields[i].length() > 0)
      nfields++;
  field = new string[nfields];
  int j = 0;
  for (i = 0; i < 256; i++)
    if (temp_fields[i].length() > 0) {
      field[j].move(temp_fields[i]);
      if (abbreviate_fields.search(i) >= 0)
        abbreviate_names(field[j]);
      field_index[i] = j;
      j++;
    }
}

reference::~reference()
{
  if (nfields > 0)
    delete [] field;
}



void reference::merge(reference &ref)
{
  int i;
  for (i = 0; i < 256; i++)
    if (field_index[i] != NULL_FIELD_INDEX)
      temp_fields[i].move(field[field_index[i]]);
  for (i = 0; i < 256; i++)
    if (ref.field_index[i] != NULL_FIELD_INDEX)
      temp_fields[i].move(ref.field[ref.field_index[i]]);
  for (i = 0; i < 256; i++)
    field_index[i] = NULL_FIELD_INDEX;
  int old_nfields = nfields;
  nfields = 0;
  for (i = 0; i < 256; i++)
    if (temp_fields[i].length() > 0)
      nfields++;
  if (nfields != old_nfields) {
    if (old_nfields > 0)
      delete [] field;
    field = new string[nfields];
  }
  int j = 0;
  for (i = 0; i < 256; i++)
    if (temp_fields[i].length() > 0) {
      field[j].move(temp_fields[i]);
      field_index[i] = j;
      j++;
    }
  merged = 1;
}

void reference::insert_field(unsigned char c, string &s)
{
  do_assert(s.length() > 0, 194, "/groff-1.17.2/src/preproc/refer/ref.cc");
  if (field_index[c] != NULL_FIELD_INDEX) {
    field[field_index[c]].move(s);
    return;
  }
  do_assert(field_index[c] == NULL_FIELD_INDEX, 199, "/groff-1.17.2/src/preproc/refer/ref.cc");
  string *old_field = field;
  field = new string[nfields + 1];
  int pos = 0;
  int i;
  for (i = 0; i < int(c); i++)
    if (field_index[i] != NULL_FIELD_INDEX)
      pos++;
  for (i = 0; i < pos; i++)
    field[i].move(old_field[i]);
  field[pos].move(s);
  for (i = pos; i < nfields; i++)
    field[i + 1].move(old_field[i]);
  if (nfields > 0)
    delete [] old_field;
  nfields++;
  field_index[c] = pos;
  for (i = c + 1; i < 256; i++)
    if (field_index[i] != NULL_FIELD_INDEX)
      field_index[i] += 1;
}

void reference::delete_field(unsigned char c)
{
  if (field_index[c] == NULL_FIELD_INDEX)
    return;
  string *old_field = field;
  field = new string[nfields - 1];
  int i;
  for (i = 0; i < int(field_index[c]); i++)
    field[i].move(old_field[i]);
  for (i = field_index[c]; i < nfields - 1; i++)
    field[i].move(old_field[i + 1]);
  if (nfields > 0)
    delete [] old_field;
  nfields--;
  field_index[c] = NULL_FIELD_INDEX;
  for (i = c + 1; i < 256; i++)
    if (field_index[i] != NULL_FIELD_INDEX)
      field_index[i] -= 1;
}

void reference::compute_hash_code()
{
  if (!rid.is_null())
    h = rid.hash();
  else {
    h = 0;
    for (int i = 0; i < nfields; i++)
      if (field[i].length() > 0) {
        h <<= 4;
        h ^= hash_string(field[i].contents(), field[i].length());
      }
  }
}

void reference::set_number(int n)
{
  no = n;
}

const char SORT_SEP = '\001';
const char SORT_SUB_SEP = '\002';
const char SORT_SUB_SUB_SEP = '\003';



void sortify_words(const char *s, const char *end, const char *sep,
                   string &result)
{
  int non_empty = 0;
  int need_separator = 0;
  for (;;) {
    const char *token_start = s;
    if (!get_token(&s, end))
      break;
    if ((s - token_start == 1
         && (*token_start == ' '
             || *token_start == '\n'
             || (sep && *token_start != '\0'
                 && strchr(sep, *token_start) != 0)))
        || (s - token_start == 2
            && token_start[0] == '\\' && token_start[1] == ' ')) {
      if (non_empty)
        need_separator = 1;
    }
    else {
      const token_info *ti = lookup_token(token_start, s);
      if (ti->sortify_non_empty(token_start, s)) {
        if (need_separator) {
          result += ' ';
          need_separator = 0;
        }
        ti->sortify(token_start, s, result);
        non_empty = 1;
      }
    }
  }
}

void sortify_word(const char *s, const char *end, string &result)
{
  for (;;) {
    const char *token_start = s;
    if (!get_token(&s, end))
      break;
    const token_info *ti = lookup_token(token_start, s);
    ti->sortify(token_start, s, result);
  }
}

void sortify_other(const char *s, int len, string &key)
{
  sortify_words(s, s + len, 0, key);
}

void sortify_title(const char *s, int len, string &key)
{
  const char *end = s + len;
  for (; s < end && (*s == ' ' || *s == '\n'); s++)
    ;
  const char *ptr = s;
  for (;;) {
    const char *token_start = ptr;
    if (!get_token(&ptr, end))
      break;
    if (ptr - token_start == 1
        && (*token_start == ' ' || *token_start == '\n'))
      break;
  }
  if (ptr < end) {
    unsigned int first_word_len = ptr - s - 1;
    const char *ae = articles.contents() + articles.length();
    for (const char *a = articles.contents();
         a < ae;
         a = strchr(a, '\0') + 1)
      if (first_word_len == strlen(a)) {
        unsigned int j;
        for (j = 0; j < first_word_len; j++)
          if (a[j] != cmlower(s[j]))
            break;
        if (j >= first_word_len) {
          s = ptr;
          for (; s < end && (*s == ' ' || *s == '\n'); s++)
            ;
          break;
        }
      }
  }
  sortify_words(s, end, 0, key);
}

void sortify_name(const char *s, int len, string &key)
{
  const char *last_name_end;
  const char *last_name = find_last_name(s, s + len, &last_name_end);
  sortify_word(last_name, last_name_end, key);
  key += SORT_SUB_SUB_SEP;
  if (last_name > s)
    sortify_words(s, last_name, ".", key);
  key += SORT_SUB_SUB_SEP;
  if (last_name_end < s + len)
    sortify_words(last_name_end, s + len, ".,", key);
}

void sortify_date(const char *s, int len, string &key)
{
  const char *year_end;
  const char *year_start = find_year(s, s + len, &year_end);
  if (!year_start) {


    key += 'A';
    sortify_words(s, s + len, 0, key);
    return;
  }
  int n = year_end - year_start;
  while (n < 4) {
    key += '0';
    n++;
  }
  while (year_start < year_end)
    key += *year_start++;
  int m = find_month(s, s + len);
  if (m < 0)
    return;
  key += 'A' + m;
  const char *day_end;
  const char *day_start = find_day(s, s + len, &day_end);
  if (!day_start)
    return;
  if (day_end - day_start == 1)
    key += '0';
  while (day_start < day_end)
    key += *day_start++;
}



void sortify_label(const char *s, int len, string &key)
{
  const char *end = s + len;
  for (;;) {
    const char *ptr;
    for (ptr = s;
         ptr < end && *ptr != SORT_SUB_SEP && *ptr != SORT_SUB_SUB_SEP;
         ptr++)
      ;
    if (ptr > s)
      sortify_words(s, ptr, 0, key);
    s = ptr;
    if (s >= end)
      break;
    key += *s++;
  }
}

void reference::compute_sort_key()
{
  if (sort_fields.length() == 0)
    return;
  sort_fields += '\0';
  const char *sf = sort_fields.contents();
  while (*sf != '\0') {
    if (sf > sort_fields)
      sort_key += SORT_SEP;
    char f = *sf++;
    int n = 1;
    if (*sf == '+') {
      n = 2147483647;
      sf++;
    }
    else if (csdigit(*sf)) {
      char *ptr;
      long l = strtol(sf, &ptr, 10);
      if (l == 0 && ptr == sf)
        ;
      else {
        sf = ptr;
        if (l < 0) {
          n = 1;
        }
        else {
          n = int(l);
        }
      }
    }
    if (f == '.')
      sortify_label(label.contents(), label.length(), sort_key);
    else if (f == AUTHOR_FIELDS[0])
      sortify_authors(n, sort_key);
    else
      sortify_field(f, n, sort_key);
  }
  sort_fields.set_length(sort_fields.length() - 1);
}

void reference::sortify_authors(int n, string &result) const
{
  for (const char *p = AUTHOR_FIELDS; *p != '\0'; p++)
    if (contains_field(*p)) {
      sortify_field(*p, n, result);
      return;
    }
  sortify_field(AUTHOR_FIELDS[0], n, result);
}

void reference::canonicalize_authors(string &result) const
{
  int len = result.length();
  sortify_authors(2147483647, result);
  if (result.length() > len)
    result += SORT_SUB_SEP;
}

void reference::sortify_field(unsigned char f, int n, string &result) const
{
  typedef void (*sortify_t)(const char *, int, string &);
  sortify_t sortifier = sortify_other;
  switch (f) {
  case 'A':
  case 'E':
    sortifier = sortify_name;
    break;
  case 'D':
    sortifier = sortify_date;
    break;
  case 'B':
  case 'J':
  case 'T':
    sortifier = sortify_title;
    break;
  }
  int fi = field_index[(unsigned char)f];
  if (fi != NULL_FIELD_INDEX) {
    string &str = field[fi];
    const char *start = str.contents();
    const char *end = start + str.length();
    for (int i = 0; i < n && start < end; i++) {
      const char *p = start;
      while (start < end && *start != FIELD_SEPARATOR)
        start++;
      if (i > 0)
        result += SORT_SUB_SEP;
      (*sortifier)(p, start - p, result);
      if (start < end)
        start++;
    }
  }
}

int compare_reference(const reference &r1, const reference &r2)
{
  do_assert(r1.no >= 0, 512, "/groff-1.17.2/src/preproc/refer/ref.cc");
  do_assert(r2.no >= 0, 513, "/groff-1.17.2/src/preproc/refer/ref.cc");
  const char *s1 = r1.sort_key.contents();
  int n1 = r1.sort_key.length();
  const char *s2 = r2.sort_key.contents();
  int n2 = r2.sort_key.length();
  for (; n1 > 0 && n2 > 0; --n1, --n2, ++s1, ++s2)
    if (*s1 != *s2)
      return (int)(unsigned char)*s1 - (int)(unsigned char)*s2;
  if (n2 > 0)
    return -1;
  if (n1 > 0)
    return 1;
  return r1.no - r2.no;
}

int same_reference(const reference &r1, const reference &r2)
{
  if (!r1.rid.is_null() && r1.rid == r2.rid)
    return 1;
  if (r1.h != r2.h)
    return 0;
  if (r1.nfields != r2.nfields)
    return 0;
  int i = 0;
  for (i = 0; i < 256; i++)
    if (r1.field_index != r2.field_index)
      return 0;
  for (i = 0; i < r1.nfields; i++)
    if (r1.field[i] != r2.field[i])
      return 0;
  return 1;
}

const char *find_last_name(const char *start, const char *end,
                           const char **endp)
{
  const char *ptr = start;
  const char *last_word = start;
  for (;;) {
    const char *token_start = ptr;
    if (!get_token(&ptr, end))
      break;
    if (ptr - token_start == 1) {
      if (*token_start == ',') {
        *endp = token_start;
        return last_word;
      }
      else if (*token_start == ' ' || *token_start == '\n') {
        if (ptr < end && *ptr != ' ' && *ptr != '\n')
          last_word = ptr;
      }
    }
  }
  *endp = end;
  return last_word;
}

void abbreviate_name(const char *ptr, const char *end, string &result)
{
  const char *last_name_end;
  const char *last_name_start = find_last_name(ptr, end, &last_name_end);
  int need_period = 0;
  for (;;) {
    const char *token_start = ptr;
    if (!get_token(&ptr, last_name_start))
      break;
    const token_info *ti = lookup_token(token_start, ptr);
    if (need_period) {
      if ((ptr - token_start == 1 && *token_start == ' ')
          || (ptr - token_start == 2 && token_start[0] == '\\'
              && token_start[1] == ' '))
        continue;
      if (ti->is_upper())
        result += period_before_initial;
      else
        result += period_before_other;
      need_period = 0;
    }
    result.append(token_start, ptr - token_start);
    if (ti->is_upper()) {
      const char *lower_ptr = ptr;
      int first_token = 1;
      for (;;) {
        token_start = ptr;
        if (!get_token(&ptr, last_name_start))
          break;
        if ((ptr - token_start == 1 && *token_start == ' ')
            || (ptr - token_start == 2 && token_start[0] == '\\'
                && token_start[1] == ' '))
          break;
        ti = lookup_token(token_start, ptr);
        if (ti->is_hyphen()) {
          const char *ptr1 = ptr;
          if (get_token(&ptr1, last_name_start)) {
            ti = lookup_token(ptr, ptr1);
            if (ti->is_upper()) {
              result += period_before_hyphen;
              result.append(token_start, ptr1 - token_start);
              ptr = ptr1;
            }
          }
        }
        else if (ti->is_upper()) {

          result.append(lower_ptr, ptr - lower_ptr);
          lower_ptr = ptr;
          first_token = 1;
        }
        else if (first_token && ti->is_accent()) {
          result.append(token_start, ptr - token_start);
          lower_ptr = ptr;
        }
        first_token = 0;
      }
      need_period = 1;
    }
  }
  if (need_period)
    result += period_before_last_name;
  result.append(last_name_start, end - last_name_start);
}

static void abbreviate_names(string &result)
{
  string str;
  str.move(result);
  const char *ptr = str.contents();
  const char *end = ptr + str.length();
  while (ptr < end) {
    const char *name_end = (char *)memchr(ptr, FIELD_SEPARATOR, end - ptr);
    if (name_end == 0)
      name_end = end;
    abbreviate_name(ptr, name_end, result);
    if (name_end >= end)
      break;
    ptr = name_end + 1;
    result += FIELD_SEPARATOR;
  }
}

void reverse_name(const char *ptr, const char *name_end, string &result)
{
  const char *last_name_end;
  const char *last_name_start = find_last_name(ptr, name_end, &last_name_end);
  result.append(last_name_start, last_name_end - last_name_start);
  while (last_name_start > ptr
         && (last_name_start[-1] == ' ' || last_name_start[-1] == '\n'))
    last_name_start--;
  if (last_name_start > ptr) {
    result += ", ";
    result.append(ptr, last_name_start - ptr);
  }
  if (last_name_end < name_end)
    result.append(last_name_end, name_end - last_name_end);
}

void reverse_names(string &result, int n)
{
  if (n <= 0)
    return;
  string str;
  str.move(result);
  const char *ptr = str.contents();
  const char *end = ptr + str.length();
  while (ptr < end) {
    if (--n < 0) {
      result.append(ptr, end - ptr);
      break;
    }
    const char *name_end = (char *)memchr(ptr, FIELD_SEPARATOR, end - ptr);
    if (name_end == 0)
      name_end = end;
    reverse_name(ptr, name_end, result);
    if (name_end >= end)
      break;
    ptr = name_end + 1;
    result += FIELD_SEPARATOR;
  }
}



int join_fields(string &f)
{
  const char *ptr = f.contents();
  int len = f.length();
  int nfield_seps = 0;
  int j;
  for (j = 0; j < len; j++)
    if (ptr[j] == FIELD_SEPARATOR)
      nfield_seps++;
  if (nfield_seps == 0)
    return 0;
  string temp;
  int field_seps_left = nfield_seps;
  for (j = 0; j < len; j++) {
    if (ptr[j] == FIELD_SEPARATOR) {
      if (nfield_seps == 1)
        temp += join_authors_exactly_two;
      else if (--field_seps_left == 0)
        temp += join_authors_last_two;
      else
        temp += join_authors_default;
    }
    else
      temp += ptr[j];
  }
  f = temp;
  return nfield_seps;
}

void uppercase(const char *start, const char *end, string &result)
{
  for (;;) {
    const char *token_start = start;
    if (!get_token(&start, end))
      break;
    const token_info *ti = lookup_token(token_start, start);
    ti->upper_case(token_start, start, result);
  }
}

void lowercase(const char *start, const char *end, string &result)
{
  for (;;) {
    const char *token_start = start;
    if (!get_token(&start, end))
      break;
    const token_info *ti = lookup_token(token_start, start);
    ti->lower_case(token_start, start, result);
  }
}

void capitalize(const char *ptr, const char *end, string &result)
{
  int in_small_point_size = 0;
  for (;;) {
    const char *start = ptr;
    if (!get_token(&ptr, end))
      break;
    const token_info *ti = lookup_token(start, ptr);
    const char *char_end = ptr;
    int is_lower = ti->is_lower();
    if ((is_lower || ti->is_upper()) && get_token(&ptr, end)) {
      const token_info *ti2 = lookup_token(char_end, ptr);
      if (!ti2->is_accent())
        ptr = char_end;
    }
    if (is_lower) {
      if (!in_small_point_size) {
        result += "\\s-2";
        in_small_point_size = 1;
      }
      ti->upper_case(start, char_end, result);
      result.append(char_end, ptr - char_end);
    }
    else {
      if (in_small_point_size) {
        result += "\\s+2";
        in_small_point_size = 0;
      }
      result.append(start, ptr - start);
    }
  }
  if (in_small_point_size)
    result += "\\s+2";
}

void capitalize_field(string &str)
{
  string temp;
  capitalize(str.contents(), str.contents() + str.length(), temp);
  str.move(temp);
}

int is_terminated(const char *ptr, const char *end)
{
  const char *last_token = end;
  for (;;) {
    const char *p = ptr;
    if (!get_token(&ptr, end))
      break;
    last_token = p;
  }
  return end - last_token == 1
    && (*last_token == '.' || *last_token == '!' || *last_token == '?');
}

void reference::output(FILE *fp)
{
  fputs(".]-\n", fp);
  for (int i = 0; i < 256; i++)
    if (field_index[i] != NULL_FIELD_INDEX && i != annotation_field) {
      string &f = field[field_index[i]];
      if (!csdigit(i)) {
        int j = reverse_fields.search(i);
        if (j >= 0) {
          int n;
          int len = reverse_fields.length();
          if (++j < len && csdigit(reverse_fields[j])) {
            n = reverse_fields[j] - '0';
            for (++j; j < len && csdigit(reverse_fields[j]); j++)

              n = n*10 + reverse_fields[j] - '0';
          }
          else
            n = 2147483647;
          reverse_names(f, n);
        }
      }
      int is_multiple = join_fields(f) > 0;
      if (capitalize_fields.search(i) >= 0)
        capitalize_field(f);
      if (memchr(f.contents(), '\n', f.length()) == 0) {
        fprintf(fp, ".ds [%c ", i);
        if (f[0] == ' ' || f[0] == '\\' || f[0] == '"')
          (--(fp)->__cnt < 0 ? __flsbuf((unsigned char) ('"'), (fp)) : (int)(*(fp)->__ptr++ = (unsigned char) ('"')));
        put_string(f, fp);
        (--(fp)->__cnt < 0 ? __flsbuf((unsigned char) ('\n'), (fp)) : (int)(*(fp)->__ptr++ = (unsigned char) ('\n')));
      }
      else {
        fprintf(fp, ".de [%c\n", i);
        put_string(f, fp);
        fputs("..\n", fp);
      }
      if (i == 'P') {
        int multiple_pages = 0;
        const char *s = f.contents();
        const char *end = f.contents() + f.length();
        for (;;) {
          const char *token_start = s;
          if (!get_token(&s, end))
            break;
          const token_info *ti = lookup_token(token_start, s);
          if (ti->is_hyphen() || ti->is_range_sep()) {
            multiple_pages = 1;
            break;
          }
        }
        fprintf(fp, ".nr [P %d\n", multiple_pages);
      }
      else if (i == 'E')
        fprintf(fp, ".nr [E %d\n", is_multiple);
    }
  for (const char *p = "TAO"; *p; p++) {
    int fi = field_index[(unsigned char)*p];
    if (fi != NULL_FIELD_INDEX) {
      string &f = field[fi];
      fprintf(fp, ".nr [%c %d\n", *p,
              is_terminated(f.contents(), f.contents() + f.length()));
    }
  }
  int t = classify();
  fprintf(fp, ".][ %d %s\n", t, reference_types[t]);
  if (annotation_macro.length() > 0 && annotation_field >= 0
      && field_index[annotation_field] != NULL_FIELD_INDEX) {
    (--(fp)->__cnt < 0 ? __flsbuf((unsigned char) ('.'), (fp)) : (int)(*(fp)->__ptr++ = (unsigned char) ('.')));
    put_string(annotation_macro, fp);
    (--(fp)->__cnt < 0 ? __flsbuf((unsigned char) ('\n'), (fp)) : (int)(*(fp)->__ptr++ = (unsigned char) ('\n')));
    put_string(field[field_index[annotation_field]], fp);
  }
}

void reference::print_sort_key_comment(FILE *fp)
{
  fputs(".\\\"", fp);
  put_string(sort_key, fp);
  (--(fp)->__cnt < 0 ? __flsbuf((unsigned char) ('\n'), (fp)) : (int)(*(fp)->__ptr++ = (unsigned char) ('\n')));
}

const char *find_year(const char *start, const char *end, const char **endp)
{
  for (;;) {
    while (start < end && !csdigit(*start))
      start++;
    const char *ptr = start;
    if (start == end)
      break;
    while (ptr < end && csdigit(*ptr))
      ptr++;
    if (ptr - start == 4 || ptr - start == 3
        || (ptr - start == 2
            && (start[0] >= '4' || (start[0] == '3' && start[1] >= '2')))) {
      *endp = ptr;
      return start;
    }
    start = ptr;
  }
  return 0;
}

static const char *find_day(const char *start, const char *end,
                            const char **endp)
{
  for (;;) {
    while (start < end && !csdigit(*start))
      start++;
    const char *ptr = start;
    if (start == end)
      break;
    while (ptr < end && csdigit(*ptr))
      ptr++;
    if ((ptr - start == 1 && start[0] != '0')
        || (ptr - start == 2 &&
            (start[0] == '1'
             || start[0] == '2'
             || (start[0] == '3' && start[1] <= '1')
             || (start[0] == '0' && start[1] != '0')))) {
      *endp = ptr;
      return start;
    }
    start = ptr;
  }
  return 0;
}

static int find_month(const char *start, const char *end)
{
  static const char *months[] = {
    "january",
    "february",
    "march",
    "april",
    "may",
    "june",
    "july",
    "august",
    "september",
    "october",
    "november",
    "december",
  };
  for (;;) {
    while (start < end && !csalpha(*start))
      start++;
    const char *ptr = start;
    if (start == end)
      break;
    while (ptr < end && csalpha(*ptr))
      ptr++;
    if (ptr - start >= 3) {
      for (unsigned int i = 0; i < sizeof(months)/sizeof(months[0]); i++) {
        const char *q = months[i];
        const char *p = start;
        for (; p < ptr; p++, q++)
          if (cmlower(*p) != *q)
            break;
        if (p >= ptr)
          return i;
      }
    }
    start = ptr;
  }
  return -1;
}

int reference::contains_field(char c) const
{
  return field_index[(unsigned char)c] != NULL_FIELD_INDEX;
}

int reference::classify()
{
  if (contains_field('J'))
    return JOURNAL_ARTICLE;
  if (contains_field('B'))
    return ARTICLE_IN_BOOK;
  if (contains_field('G'))
    return TECH_REPORT;
  if (contains_field('R'))
    return TECH_REPORT;
  if (contains_field('I'))
    return BOOK;
  if (contains_field('M'))
    return BELL_TM;
  return OTHER;
}

const char *reference::get_year(const char **endp) const
{
  if (field_index['D'] != NULL_FIELD_INDEX) {
    string &date = field[field_index['D']];
    const char *start = date.contents();
    const char *end = start + date.length();
    return find_year(start, end, endp);
  }
  else
    return 0;
}

const char *reference::get_field(unsigned char c, const char **endp) const
{
  if (field_index[c] != NULL_FIELD_INDEX) {
    string &f = field[field_index[c]];
    const char *start = f.contents();
    *endp = start + f.length();
    return start;
  }
  else
    return 0;
}

const char *reference::get_date(const char **endp) const
{
  return get_field('D', endp);
}

const char *nth_field(int i, const char *start, const char **endp)
{
  while (--i >= 0) {
    start = (char *)memchr(start, FIELD_SEPARATOR, *endp - start);
    if (!start)
      return 0;
    start++;
  }
  const char *e = (char *)memchr(start, FIELD_SEPARATOR, *endp - start);
  if (e)
    *endp = e;
  return start;
}

const char *reference::get_author(int i, const char **endp) const
{
  for (const char *f = AUTHOR_FIELDS; *f != '\0'; f++) {
    const char *start = get_field(*f, endp);
    if (start) {
      if (strchr(MULTI_FIELD_NAMES, *f) != 0)
        return nth_field(i, start, endp);
      else if (i == 0)
        return start;
      else
        return 0;
    }
  }
  return 0;
}

const char *reference::get_author_last_name(int i, const char **endp) const
{
  for (const char *f = AUTHOR_FIELDS; *f != '\0'; f++) {
    const char *start = get_field(*f, endp);
    if (start) {
      if (strchr(MULTI_FIELD_NAMES, *f) != 0) {
        start = nth_field(i, start, endp);
        if (!start)
          return 0;
      }
      if (*f == 'A')
        return find_last_name(start, *endp, endp);
      else
        return start;
    }
  }
  return 0;
}

void reference::set_date(string &d)
{
  if (d.length() == 0)
    delete_field('D');
  else
    insert_field('D', d);
}

int same_year(const reference &r1, const reference &r2)
{
  const char *ye1;
  const char *ys1 = r1.get_year(&ye1);
  const char *ye2;
  const char *ys2 = r2.get_year(&ye2);
  if (ys1 == 0) {
    if (ys2 == 0)
      return same_date(r1, r2);
    else
      return 0;
  }
  else if (ys2 == 0)
    return 0;
  else if (ye1 - ys1 != ye2 - ys2)
    return 0;
  else
    return memcmp(ys1, ys2, ye1 - ys1) == 0;
}

int same_date(const reference &r1, const reference &r2)
{
  const char *e1;
  const char *s1 = r1.get_date(&e1);
  const char *e2;
  const char *s2 = r2.get_date(&e2);
  if (s1 == 0)
    return s2 == 0;
  else if (s2 == 0)
    return 0;
  else if (e1 - s1 != e2 - s2)
    return 0;
  else
    return memcmp(s1, s2, e1 - s1) == 0;
}

const char *reference::get_sort_field(int i, int si, int ssi,
                                      const char **endp) const
{
  const char *start = sort_key.contents();
  const char *end = start + sort_key.length();
  if (i < 0) {
    *endp = end;
    return start;
  }
  while (--i >= 0) {
    start = (char *)memchr(start, SORT_SEP, end - start);
    if (!start)
      return 0;
    start++;
  }
  const char *e = (char *)memchr(start, SORT_SEP, end - start);
  if (e)
    end = e;
  if (si < 0) {
    *endp = end;
    return start;
  }
  while (--si >= 0) {
    start = (char *)memchr(start, SORT_SUB_SEP, end - start);
    if (!start)
      return 0;
    start++;
  }
  e = (char *)memchr(start, SORT_SUB_SEP, end - start);
  if (e)
    end = e;
  if (ssi < 0) {
    *endp = end;
    return start;
  }
  while (--ssi >= 0) {
    start = (char *)memchr(start, SORT_SUB_SUB_SEP, end - start);
    if (!start)
      return 0;
    start++;
  }
  e = (char *)memchr(start, SORT_SUB_SUB_SEP, end - start);
  if (e)
    end = e;
  *endp = end;
  return start;
}
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2001-09-21 11:16 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-09-21 11:16 c++/4373: groff -O3 ICE Golubev I. N.

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).