Added 'date' element type accepting YYYYMMDD
[pazpar2-moved-to-github.git] / src / normalize7bit.c
1 /* $Id: normalize7bit.c,v 1.5 2007-10-31 05:29:08 quinn Exp $
2    Copyright (c) 2006-2007, Index Data.
3
4    This file is part of Pazpar2.
5
6    Pazpar2 is free software; you can redistribute it and/or modify it under
7    the terms of the GNU General Public License as published by the Free
8    Software Foundation; either version 2, or (at your option) any later
9    version.
10
11    Pazpar2 is distributed in the hope that it will be useful, but WITHOUT ANY
12    WARRANTY; without even the implied warranty of MERCHANTABILITY or
13    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14    for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with Pazpar2; see the file LICENSE.  If not, write to the
18    Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19    02111-1307, USA.
20 */
21
22 /** \file normalize7bit.c
23     \brief char and string normalization for 7bit ascii only
24 */
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <ctype.h>
29
30 #if HAVE_CONFIG_H
31 #include "cconfig.h"
32 #endif
33
34 #include "normalize7bit.h"
35
36
37 /** \brief removes leading whitespace.. Removes suffix cahrs in rm_chars */
38 char * normalize7bit_generic(char * str, const char * rm_chars)
39 {
40     char *p, *pe;
41     for (p = str; *p && isspace(*p); p++)
42         ;
43     for (pe = p + strlen(p) - 1;
44          pe > p && strchr(rm_chars, *pe); pe--)
45         *pe = '\0';
46     return p;
47 }
48
49
50
51 char * normalize7bit_mergekey(char *buf, int skiparticle)
52 {
53     char *p = buf, *pout = buf;
54
55     if (skiparticle)
56     {
57         char firstword[64];
58         char articles[] = "the den der die des an a "; // must end in space
59
60         while (*p && !isalnum(*p))
61             p++;
62         pout = firstword;
63         while (*p && *p != ' ' && pout - firstword < 62)
64             *(pout++) = tolower(*(p++));
65         *(pout++) = ' ';
66         *(pout++) = '\0';
67         if (!strstr(articles, firstword))
68             p = buf;
69         pout = buf;
70     }
71
72     while (*p)
73     {
74         while (*p && !isalnum(*p))
75             p++;
76         while (isalnum(*p))
77             *(pout++) = tolower(*(p++));
78         if (*p)
79             *(pout++) = ' ';
80         while (*p && !isalnum(*p))
81             p++;
82     }
83     if (buf != pout)
84         do {
85             *(pout--) = '\0';
86         }
87         while (pout > buf && *pout == ' ');
88     
89     return buf;
90 }
91
92 // Extract what appears to be years from buf, storing highest and
93 // lowest values.
94 // longdate==1, look for YYYYMMDD, longdate=0 look only for YYYY
95 int extract7bit_dates(const char *buf, int *first, int *last, int longdate)
96 {
97     *first = -1;
98     *last = -1;
99     while (*buf)
100     {
101         const char *e;
102         int len;
103
104         while (*buf && !isdigit(*buf))
105             buf++;
106         len = 0;
107         for (e = buf; *e && isdigit(*e); e++)
108             len++;
109         if ((len == 4 && !longdate) || (longdate && len >= 4 && len <= 8))
110         {
111             int value = atoi(buf);
112             if (longdate && len == 4)
113                 value *= 10000; //  should really suffix 0101?
114             if (*first < 0 || value < *first)
115                 *first = value;
116             if (*last < 0 || value > *last)
117                 *last = value;
118         }
119         buf = e;
120     }
121     return *first;
122 }
123
124
125
126 /*
127  * Local variables:
128  * c-basic-offset: 4
129  * indent-tabs-mode: nil
130  * End:
131  * vim: shiftwidth=4 tabstop=8 expandtab
132  */