1// -*- C++ -*-
2/* Copyright (C) 1989, 1990, 1991, 1992, 2005 Free Software Foundation, Inc.
3     Written by James Clark (jjc@jclark.com)
4
5This file is part of groff.
6
7groff is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12groff is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License along
18with groff; see the file COPYING.  If not, write to the Free Software
19Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
20
21// declarations to avoid friend name injection problems
22int compare_reference(const reference &, const reference &);
23int same_reference(const reference &, const reference &);
24int same_year(const reference &, const reference &);
25int same_date(const reference &, const reference &);
26int same_author_last_name(const reference &, const reference &, int);
27int same_author_name(const reference &, const reference &, int);
28
29struct label_info;
30
31enum label_type { NORMAL_LABEL, SHORT_LABEL };
32const int N_LABEL_TYPES = 2;
33
34struct substring_position {
35  int start;
36  int length;
37  substring_position() : start(-1) { }
38};
39
40class int_set {
41  string v;
42public:
43  int_set() { }
44  void set(int i);
45  int get(int i) const;
46};
47
48class reference {
49private:
50  unsigned h;
51  reference_id rid;
52  int merged;
53  string sort_key;
54  int no;
55  string *field;
56  int nfields;
57  unsigned char field_index[256];
58  enum { NULL_FIELD_INDEX = 255 };
59  string label;
60  substring_position separator_pos;
61  string short_label;
62  substring_position short_separator_pos;
63  label_info *label_ptr;
64  string authors;
65  int computed_authors;
66  int last_needed_author;
67  int nauthors;
68  int_set last_name_unambiguous;
69
70  int contains_field(char) const;
71  void insert_field(unsigned char, string &s);
72  void delete_field(unsigned char);
73  void set_date(string &);
74  const char *get_sort_field(int i, int si, int ssi, const char **endp) const;
75  int merge_labels_by_parts(reference **, int, label_type, string &);
76  int merge_labels_by_number(reference **, int, label_type, string &);
77public:
78  reference(const char * = 0, int = -1, reference_id * = 0);
79  ~reference();
80  void output(FILE *);
81  void print_sort_key_comment(FILE *);
82  void set_number(int);
83  int get_number() const { return no; }
84  unsigned hash() const { return h; }
85  const string &get_label(label_type type) const;
86  const substring_position &get_separator_pos(label_type) const;
87  int is_merged() const { return merged; }
88  void compute_sort_key();
89  void compute_hash_code();
90  void pre_compute_label();
91  void compute_label();
92  void immediate_compute_label();
93  int classify();
94  void merge(reference &);
95  int merge_labels(reference **, int, label_type, string &);
96  int get_nauthors() const;
97  void need_author(int);
98  void set_last_name_unambiguous(int);
99  void sortify_authors(int, string &) const;
100  void canonicalize_authors(string &) const;
101  void sortify_field(unsigned char, int, string &) const;
102  const char *get_author(int, const char **) const;
103  const char *get_author_last_name(int, const char **) const;
104  const char *get_date(const char **) const;
105  const char *get_year(const char **) const;
106  const char *get_field(unsigned char, const char **) const;
107  const label_info *get_label_ptr() const { return label_ptr; }
108  const char *get_authors(const char **) const;
109  // for sorting
110  friend int compare_reference(const reference &r1, const reference &r2);
111  // for merging
112  friend int same_reference(const reference &, const reference &);
113  friend int same_year(const reference &, const reference &);
114  friend int same_date(const reference &, const reference &);
115  friend int same_author_last_name(const reference &, const reference &, int);
116  friend int same_author_name(const reference &, const reference &, int);
117};
118
119const char *find_year(const char *, const char *, const char **);
120const char *find_last_name(const char *, const char *, const char **);
121
122const char *nth_field(int i, const char *start, const char **endp);
123
124void capitalize(const char *ptr, const char *end, string &result);
125void reverse_name(const char *ptr, const char *end, string &result);
126void uppercase(const char *ptr, const char *end, string &result);
127void lowercase(const char *ptr, const char *end, string &result);
128void abbreviate_name(const char *ptr, const char *end, string &result);
129