1124758Semax
2124758Semax/*-
3124758Semax * SPDX-License-Identifier: BSD-2-Clause
4124758Semax *
5124758Semax * Copyright (C) 2009 Gabor Kovesdan <gabor@FreeBSD.org>
6124758Semax * Copyright (C) 2012 Oleg Moskalenko <mom040267@gmail.com>
7124758Semax * All rights reserved.
8124758Semax *
9124758Semax * Redistribution and use in source and binary forms, with or without
10124758Semax * modification, are permitted provided that the following conditions
11124758Semax * are met:
12124758Semax * 1. Redistributions of source code must retain the above copyright
13124758Semax *    notice, this list of conditions and the following disclaimer.
14124758Semax * 2. Redistributions in binary form must reproduce the above copyright
15124758Semax *    notice, this list of conditions and the following disclaimer in the
16124758Semax *    documentation and/or other materials provided with the distribution.
17124758Semax *
18124758Semax * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19124758Semax * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20124758Semax * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21124758Semax * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22124758Semax * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23124758Semax * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24124758Semax * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25124758Semax * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26124758Semax * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27124758Semax * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28124758Semax * SUCH DAMAGE.
29124758Semax */
30124758Semax
31124758Semax#if !defined(__COLL_H__)
32124758Semax#define	__COLL_H__
33124758Semax
34124758Semax#include "bwstring.h"
35124758Semax#include "sort.h"
36124758Semax
37124758Semax/*
38124758Semax * Sort hint data for -n
39139721Semax */
40124758Semaxstruct n_hint
41124758Semax{
42124758Semax	unsigned long long	 n1;
43124758Semax	unsigned char		 si;
44124758Semax	bool			 empty;
45124758Semax	bool			 neg;
46124758Semax};
47344146Shselasky
48344146Shselasky/*
49344146Shselasky * Sort hint data for -g
50344146Shselasky */
51344146Shselaskystruct g_hint
52344146Shselasky{
53344146Shselasky	double			 d;
54344146Shselasky	bool			 nan;
55344146Shselasky	bool			 notnum;
56344146Shselasky};
57344146Shselasky
58344146Shselasky/*
59344146Shselasky * Sort hint data for -M
60344146Shselasky */
61344146Shselaskystruct M_hint
62344146Shselasky{
63344146Shselasky	int			 m;
64344146Shselasky};
65344146Shselasky
66344146Shselasky/*
67344146Shselasky * Sort hint data for -R
68344146Shselasky *
69344146Shselasky * This stores the first 12 bytes of the digest rather than the full output to
70344146Shselasky * avoid increasing the size of the 'key_hint' object via the 'v' union.
71344146Shselasky */
72344146Shselaskystruct R_hint
73344146Shselasky{
74344146Shselasky	unsigned char		 cached[12];
75344146Shselasky};
76344146Shselasky
77344146Shselasky/*
78344146Shselasky * Status of a sort hint object
79344146Shselasky */
80344146Shselaskytypedef enum
81344146Shselasky{
82344146Shselasky	HS_ERROR = -1, HS_UNINITIALIZED = 0, HS_INITIALIZED = 1
83344146Shselasky} hint_status;
84344146Shselasky
85344146Shselasky/*
86344146Shselasky * Sort hint object
87344146Shselasky */
88344146Shselaskystruct key_hint
89344146Shselasky{
90344146Shselasky	hint_status		status;
91344146Shselasky	union
92344146Shselasky	{
93344146Shselasky		struct n_hint		nh;
94344146Shselasky		struct g_hint		gh;
95344146Shselasky		struct M_hint		Mh;
96344146Shselasky		struct R_hint		Rh;
97344146Shselasky	}			v;
98344146Shselasky};
99344146Shselasky
100344146Shselasky/*
101344146Shselasky * Key value
102344146Shselasky */
103344146Shselaskystruct key_value
104344146Shselasky{
105344146Shselasky	struct bwstring		*k; /* key string */
106344146Shselasky	struct key_hint		 hint[0]; /* key sort hint */
107344146Shselasky} __packed;
108344146Shselasky
109344146Shselasky/*
110344146Shselasky * Set of keys container object.
111344146Shselasky */
112344146Shselaskystruct keys_array
113344146Shselasky{
114344146Shselasky	struct key_value	 key[0];
115344146Shselasky};
116344146Shselasky
117344146Shselasky/*
118344146Shselasky * Parsed -k option data
119344146Shselasky */
120344146Shselaskystruct key_specs
121344146Shselasky{
122344146Shselasky	struct sort_mods	 sm;
123344146Shselasky	size_t			 c1;
124344146Shselasky	size_t			 c2;
125344146Shselasky	size_t			 f1;
126344146Shselasky	size_t			 f2;
127344146Shselasky	bool			 pos1b;
128344146Shselasky	bool			 pos2b;
129344146Shselasky};
130344146Shselasky
131344146Shselasky/*
132344146Shselasky * Single entry in sort list.
133344146Shselasky */
134344146Shselaskystruct sort_list_item
135344146Shselasky{
136344146Shselasky	struct bwstring		*str;
137344146Shselasky	struct keys_array	 ka;
138344146Shselasky};
139344146Shselasky
140344146Shselasky/*
141344146Shselasky * Function type, used to compare two list objects
142344146Shselasky */
143344146Shselaskytypedef int (*listcoll_t)(struct sort_list_item **ss1, struct sort_list_item **ss2);
144344146Shselasky
145344146Shselaskyextern struct key_specs *keys;
146344146Shselaskyextern size_t keys_num;
147344146Shselasky
148344146Shselasky/*
149344146Shselasky * Main localised symbols. These must be wint_t as they may hold WEOF.
150344146Shselasky */
151344146Shselaskyextern wint_t symbol_decimal_point;
152344146Shselaskyextern wint_t symbol_thousands_sep;
153344146Shselaskyextern wint_t symbol_negative_sign;
154344146Shselaskyextern wint_t symbol_positive_sign;
155344146Shselasky
156344146Shselasky/* funcs */
157344146Shselasky
158344146Shselaskycmpcoll_t get_sort_func(struct sort_mods *sm);
159344146Shselasky
160344146Shselaskystruct keys_array *keys_array_alloc(void);
161344146Shselaskysize_t keys_array_size(void);
162344146Shselaskystruct key_value *get_key_from_keys_array(struct keys_array *ka, size_t ind);
163344146Shselaskyvoid set_key_on_keys_array(struct keys_array *ka, struct bwstring *s, size_t ind);
164344146Shselaskyvoid clean_keys_array(const struct bwstring *s, struct keys_array *ka);
165344146Shselasky
166344146Shselaskystruct sort_list_item *sort_list_item_alloc(void);
167344146Shselaskyvoid sort_list_item_set(struct sort_list_item *si, struct bwstring *str);
168344146Shselaskyvoid sort_list_item_clean(struct sort_list_item *si);
169344146Shselaskysize_t sort_list_item_size(struct sort_list_item *si);
170344146Shselasky
171344146Shselaskyint preproc(struct bwstring *s, struct keys_array *ka);
172124758Semaxint top_level_str_coll(const struct bwstring *, const struct bwstring *);
173124758Semaxint key_coll(struct keys_array *ks1, struct keys_array *ks2, size_t offset);
174124758Semaxint str_list_coll(struct bwstring *str1, struct sort_list_item **ss2);
175124758Semaxint list_coll_by_str_only(struct sort_list_item **ss1, struct sort_list_item **ss2);
176124758Semaxint list_coll(struct sort_list_item **ss1, struct sort_list_item **ss2);
177124758Semaxint list_coll_offset(struct sort_list_item **ss1, struct sort_list_item **ss2, size_t offset);
178124758Semax
179124758Semaxlistcoll_t get_list_call_func(size_t offset);
180124758Semax
181124758Semax#endif /* __COLL_H__ */
182124758Semax