File: utility.c

package info (click to toggle)
httpry 0.1.8-5
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 436 kB
  • sloc: ansic: 1,358; perl: 1,336; sh: 155; makefile: 62
file content (130 lines) | stat: -rw-r--r-- 3,312 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*

  ----------------------------------------------------
  httpry - HTTP logging and information retrieval tool
  ----------------------------------------------------

  Copyright (c) 2005-2014 Jason Bittel <jason.bittel@gmail.com>

*/

#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "error.h"

/* Strip leading and trailing spaces from parameter string, modifying
   the string in place and returning a pointer to the (potentially)
   new starting point */
char *str_strip_whitespace(char *str) {
        size_t len = strlen(str);

#ifdef DEBUG
        ASSERT(str);
        ASSERT(strlen(str) > 0);
#endif

        while (isspace(*str)) str++;
        while (len && isspace(*(str + len - 1)))
                *(str + (len--) - 1) = '\0';

        return str;
}

/* Convert the paramter string to lowercase */
char *str_tolower(char *str) {
        char *c;

#ifdef DEBUG
        ASSERT(str);
        ASSERT(strlen(str) > 0);
#endif

        for (c = str; *c != '\0'; c++) {
                *c = tolower(*c);
        }

        return str;
}

/* Compare two strings, ignoring the case of str1 and
   assuming str2 is lowercase. Break if we find a string
   terminator in str2 and consider it a match as str1
   will not always have a string terminator. */
int str_compare(const char *str1, const char *str2) {

#ifdef DEBUG
        ASSERT(str2);
        ASSERT(strlen(str2) > 0);
        ASSERT(str1 != str2);
#endif

        while (tolower(*str1) == *str2) {
                str1++;
                str2++;
                if (*str2 == '\0') return 0;
        }

        return tolower(*str1) - *str2;
}

/* Copy at most len characters from src to dest, guaranteeing
   dest will be properly terminated. Returns the total number of
   characters copied, not including the string terminator. */
int str_copy(char *dest, const char *src, size_t len) {
        const char *start = dest;

        if (len > 0) {
                while ((*src != '\0') && --len) {
                        *dest++ = *src++;
                }
                *dest = '\0';
        }

        return dest - start;
}

/* Wrapper function around str_copy() that first allocates
   memory for the destination string and then copies the
   parameter string into it. */
char *str_duplicate(const char *str) {
        char *new;
        size_t len = strlen(str);

        if ((new = malloc(len + 1)) == NULL)
                return NULL;

#ifdef DEBUG
        ASSERT(str_copy(new, str, len + 1) <= (len + 1));
#else
        str_copy(new, str, len + 1);
#endif

        return new;
}

/* Implementation of Jenkins's One-at-a-Time hash, as described on
   this page: http://www.burtleburtle.net/bob/hash/doobs.html */
unsigned int hash_str(char *str, unsigned int hashsize) {
        unsigned long int hash;

#ifdef DEBUG
        ASSERT(str);
        ASSERT(strlen(str) > 0);
#endif

        for (hash = 0; *str != '\0'; str++) {
                hash += tolower(*str);
                hash += (hash << 10);
                hash ^= (hash >> 6);
        }

        hash += (hash << 3);
        hash ^= (hash >> 11);
        hash += (hash << 15);

        /* Restrict hash value to a maximum of hashsize;
           hashsize must be a power of 2 */
        return (unsigned int) (hash & (hashsize - 1));
}