1
2/*-
3 * SPDX-License-Identifier: BSD-2-Clause
4 *
5 * Copyright (C) 2009 Gabor Kovesdan <gabor@FreeBSD.org>
6 * Copyright (C) 2012 Oleg Moskalenko <mom040267@gmail.com>
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#if !defined(__COLL_H__)
32#define	__COLL_H__
33
34#include "bwstring.h"
35#include "sort.h"
36
37/*
38 * Sort hint data for -n
39 */
40struct n_hint
41{
42	unsigned long long	 n1;
43	unsigned char		 si;
44	bool			 empty;
45	bool			 neg;
46};
47
48/*
49 * Sort hint data for -g
50 */
51struct g_hint
52{
53	double			 d;
54	bool			 nan;
55	bool			 notnum;
56};
57
58/*
59 * Sort hint data for -M
60 */
61struct M_hint
62{
63	int			 m;
64};
65
66/*
67 * Sort hint data for -R
68 *
69 * This stores the first 12 bytes of the digest rather than the full output to
70 * avoid increasing the size of the 'key_hint' object via the 'v' union.
71 */
72struct R_hint
73{
74	unsigned char		 cached[12];
75};
76
77/*
78 * Status of a sort hint object
79 */
80typedef enum
81{
82	HS_ERROR = -1, HS_UNINITIALIZED = 0, HS_INITIALIZED = 1
83} hint_status;
84
85/*
86 * Sort hint object
87 */
88struct key_hint
89{
90	hint_status		status;
91	union
92	{
93		struct n_hint		nh;
94		struct g_hint		gh;
95		struct M_hint		Mh;
96		struct R_hint		Rh;
97	}			v;
98};
99
100/*
101 * Key value
102 */
103struct key_value
104{
105	struct bwstring		*k; /* key string */
106	struct key_hint		 hint[0]; /* key sort hint */
107} __packed;
108
109/*
110 * Set of keys container object.
111 */
112struct keys_array
113{
114	struct key_value	 key[0];
115};
116
117/*
118 * Parsed -k option data
119 */
120struct key_specs
121{
122	struct sort_mods	 sm;
123	size_t			 c1;
124	size_t			 c2;
125	size_t			 f1;
126	size_t			 f2;
127	bool			 pos1b;
128	bool			 pos2b;
129};
130
131/*
132 * Single entry in sort list.
133 */
134struct sort_list_item
135{
136	struct bwstring		*str;
137	struct keys_array	 ka;
138};
139
140/*
141 * Function type, used to compare two list objects
142 */
143typedef int (*listcoll_t)(struct sort_list_item **ss1, struct sort_list_item **ss2);
144
145extern struct key_specs *keys;
146extern size_t keys_num;
147
148/*
149 * Main localised symbols. These must be wint_t as they may hold WEOF.
150 */
151extern wint_t symbol_decimal_point;
152extern wint_t symbol_thousands_sep;
153extern wint_t symbol_negative_sign;
154extern wint_t symbol_positive_sign;
155
156/* funcs */
157
158cmpcoll_t get_sort_func(struct sort_mods *sm);
159
160struct keys_array *keys_array_alloc(void);
161size_t keys_array_size(void);
162struct key_value *get_key_from_keys_array(struct keys_array *ka, size_t ind);
163void set_key_on_keys_array(struct keys_array *ka, struct bwstring *s, size_t ind);
164void clean_keys_array(const struct bwstring *s, struct keys_array *ka);
165
166struct sort_list_item *sort_list_item_alloc(void);
167void sort_list_item_set(struct sort_list_item *si, struct bwstring *str);
168void sort_list_item_clean(struct sort_list_item *si);
169size_t sort_list_item_size(struct sort_list_item *si);
170
171int preproc(struct bwstring *s, struct keys_array *ka);
172int top_level_str_coll(const struct bwstring *, const struct bwstring *);
173int key_coll(struct keys_array *ks1, struct keys_array *ks2, size_t offset);
174int str_list_coll(struct bwstring *str1, struct sort_list_item **ss2);
175int list_coll_by_str_only(struct sort_list_item **ss1, struct sort_list_item **ss2);
176int list_coll(struct sort_list_item **ss1, struct sort_list_item **ss2);
177int list_coll_offset(struct sort_list_item **ss1, struct sort_list_item **ss2, size_t offset);
178
179listcoll_t get_list_call_func(size_t offset);
180
181#endif /* __COLL_H__ */
182