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