175584Sru// -*- C++ -*-
2151497Sru/* Copyright (C) 1989, 1990, 1991, 1992, 2005 Free Software Foundation, Inc.
375584Sru     Written by James Clark (jjc@jclark.com)
475584Sru
575584SruThis file is part of groff.
675584Sru
775584Srugroff is free software; you can redistribute it and/or modify it under
875584Sruthe terms of the GNU General Public License as published by the Free
975584SruSoftware Foundation; either version 2, or (at your option) any later
1075584Sruversion.
1175584Sru
1275584Srugroff is distributed in the hope that it will be useful, but WITHOUT ANY
1375584SruWARRANTY; without even the implied warranty of MERCHANTABILITY or
1475584SruFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1575584Srufor more details.
1675584Sru
1775584SruYou should have received a copy of the GNU General Public License along
1875584Sruwith groff; see the file COPYING.  If not, write to the Free Software
19151497SruFoundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
2075584Sru
21151497Sru// declarations to avoid friend name injection problems
22151497Sruint compare_reference(const reference &, const reference &);
23151497Sruint same_reference(const reference &, const reference &);
24151497Sruint same_year(const reference &, const reference &);
25151497Sruint same_date(const reference &, const reference &);
26151497Sruint same_author_last_name(const reference &, const reference &, int);
27151497Sruint same_author_name(const reference &, const reference &, int);
28151497Sru
2975584Srustruct label_info;
3075584Sru
3175584Sruenum label_type { NORMAL_LABEL, SHORT_LABEL };
3275584Sruconst int N_LABEL_TYPES = 2;
3375584Sru
3475584Srustruct substring_position {
3575584Sru  int start;
3675584Sru  int length;
3775584Sru  substring_position() : start(-1) { }
3875584Sru};
3975584Sru
4075584Sruclass int_set {
4175584Sru  string v;
4275584Srupublic:
4375584Sru  int_set() { }
4475584Sru  void set(int i);
4575584Sru  int get(int i) const;
4675584Sru};
4775584Sru
4875584Sruclass reference {
4975584Sruprivate:
5075584Sru  unsigned h;
5175584Sru  reference_id rid;
5275584Sru  int merged;
5375584Sru  string sort_key;
5475584Sru  int no;
5575584Sru  string *field;
5675584Sru  int nfields;
5775584Sru  unsigned char field_index[256];
5875584Sru  enum { NULL_FIELD_INDEX = 255 };
5975584Sru  string label;
6075584Sru  substring_position separator_pos;
6175584Sru  string short_label;
6275584Sru  substring_position short_separator_pos;
6375584Sru  label_info *label_ptr;
6475584Sru  string authors;
6575584Sru  int computed_authors;
6675584Sru  int last_needed_author;
6775584Sru  int nauthors;
6875584Sru  int_set last_name_unambiguous;
6975584Sru
7075584Sru  int contains_field(char) const;
7175584Sru  void insert_field(unsigned char, string &s);
7275584Sru  void delete_field(unsigned char);
7375584Sru  void set_date(string &);
7475584Sru  const char *get_sort_field(int i, int si, int ssi, const char **endp) const;
7575584Sru  int merge_labels_by_parts(reference **, int, label_type, string &);
7675584Sru  int merge_labels_by_number(reference **, int, label_type, string &);
7775584Srupublic:
7875584Sru  reference(const char * = 0, int = -1, reference_id * = 0);
7975584Sru  ~reference();
8075584Sru  void output(FILE *);
8175584Sru  void print_sort_key_comment(FILE *);
8275584Sru  void set_number(int);
8375584Sru  int get_number() const { return no; }
8475584Sru  unsigned hash() const { return h; }
8575584Sru  const string &get_label(label_type type) const;
8675584Sru  const substring_position &get_separator_pos(label_type) const;
8775584Sru  int is_merged() const { return merged; }
8875584Sru  void compute_sort_key();
8975584Sru  void compute_hash_code();
9075584Sru  void pre_compute_label();
9175584Sru  void compute_label();
9275584Sru  void immediate_compute_label();
9375584Sru  int classify();
9475584Sru  void merge(reference &);
9575584Sru  int merge_labels(reference **, int, label_type, string &);
9675584Sru  int get_nauthors() const;
9775584Sru  void need_author(int);
9875584Sru  void set_last_name_unambiguous(int);
9975584Sru  void sortify_authors(int, string &) const;
10075584Sru  void canonicalize_authors(string &) const;
10175584Sru  void sortify_field(unsigned char, int, string &) const;
10275584Sru  const char *get_author(int, const char **) const;
10375584Sru  const char *get_author_last_name(int, const char **) const;
10475584Sru  const char *get_date(const char **) const;
10575584Sru  const char *get_year(const char **) const;
10675584Sru  const char *get_field(unsigned char, const char **) const;
10775584Sru  const label_info *get_label_ptr() const { return label_ptr; }
10875584Sru  const char *get_authors(const char **) const;
10975584Sru  // for sorting
11075584Sru  friend int compare_reference(const reference &r1, const reference &r2);
11175584Sru  // for merging
11275584Sru  friend int same_reference(const reference &, const reference &);
11375584Sru  friend int same_year(const reference &, const reference &);
11475584Sru  friend int same_date(const reference &, const reference &);
11575584Sru  friend int same_author_last_name(const reference &, const reference &, int);
11675584Sru  friend int same_author_name(const reference &, const reference &, int);
11775584Sru};
11875584Sru
11975584Sruconst char *find_year(const char *, const char *, const char **);
12075584Sruconst char *find_last_name(const char *, const char *, const char **);
12175584Sru
12275584Sruconst char *nth_field(int i, const char *start, const char **endp);
12375584Sru
12475584Sruvoid capitalize(const char *ptr, const char *end, string &result);
12575584Sruvoid reverse_name(const char *ptr, const char *end, string &result);
12675584Sruvoid uppercase(const char *ptr, const char *end, string &result);
12775584Sruvoid lowercase(const char *ptr, const char *end, string &result);
12875584Sruvoid abbreviate_name(const char *ptr, const char *end, string &result);
129