xref: /NextBSD/usr.bin/dtc/string.hh (revision 84d351007654069f9643c8e4b4802a7f5f08ee42)
1 /*-
2  * Copyright (c) 2013 David Chisnall
3  * All rights reserved.
4  *
5  * This software was developed by SRI International and the University of
6  * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
7  * ("CTSRD"), as part of the DARPA CRASH research programme.
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  * $FreeBSD$
31  */
32 
33 #ifndef _STRING_HH_
34 #define _STRING_HH_
35 #include "input_buffer.hh"
36 #include <string>
37 #include <functional>
38 
39 namespace dtc
40 {
41 
42 /**
43  * String, referring to a place in the input file.  We don't bother copying
44  * strings until we write them to the final output.  These strings should be
45  * two words long: a start and a length.  They are intended to be cheap to copy
46  * and store in collections.  Copying the string object does not copy the
47  * underlying storage.
48  *
49  * Strings are not nul-terminated.
50  */
51 class string
52 {
53 	friend std::hash<string>;
54 	/** Start address.  Contained within the mmap()'d input file and not
55 	 * owned by this object. */
56 	const char *start;
57 	/** length of the string.  DTS strings are allowed to contain nuls */
58 	int length;
59 	/** Generic function for parsing strings matching the character set
60 	 * defined by the template argument.  */
61 	template<class T>
62 	static string parse(input_buffer &s);
63 	public:
64 	/**
65 	 * Constructs a string referring into another buffer.
66 	 */
string(const char * s,int l)67 	string(const char *s, int l) : start(s), length(l) {}
68 	/** Constructs a string from a C string.  */
string(const char * s)69 	string(const char *s) : start(s), length(strlen(s)) {}
70 	/** Default constructor, returns an empty string. */
string()71 	string() : start(0), length(0) {}
72 	/** Construct a from an input buffer, ending with a nul terminator. */
73 	string(input_buffer &s);
74 	/**
75 	 * Returns the longest string in the input buffer starting at the
76 	 * current cursor and composed entirely of characters that are valid in
77 	 * node names.
78 	 */
79 	static string parse_node_name(input_buffer &s);
80 	/**
81 	 * Returns the longest string in the input buffer starting at the
82 	 * current cursor and composed entirely of characters that are valid in
83 	 * property names.
84 	 */
85 	static string parse_property_name(input_buffer &s);
86 	/**
87 	 * Parses either a node or a property name.  If is_property is true on
88 	 * entry, then only property names are parsed.  If it is false, then it
89 	 * will be set, on return, to indicate whether the parsed name is only
90 	 * valid as a property.
91 	 */
92 	static string parse_node_or_property_name(input_buffer &s,
93 	                                          bool &is_property);
94 	/**
95 	 * Compares two strings for equality.  Strings are equal if they refer
96 	 * to identical byte sequences.
97 	 */
98 	bool operator==(const string& other) const;
99 	/**
100 	 * Compares a string against a C string.  The trailing nul in the C
101 	 * string is ignored for the purpose of comparison, so this will always
102 	 * fail if the string contains nul bytes.
103 	 */
104 	bool operator==(const char *other) const;
105 	/**
106 	 * Inequality operator, defined as the inverse of the equality
107 	 * operator.
108 	 */
109 	template <typename T>
operator !=(T other)110 	inline bool operator!=(T other)
111 	{
112 		return !(*this == other);
113 	}
114 	/**
115 	 * Comparison operator, defined to allow strings to be used as keys in
116 	 * maps.
117 	 */
118 	bool operator<(const string& other) const;
119 	/**
120 	 * Returns true if this is the empty string, false otherwise.
121 	 */
empty() const122 	inline bool empty() const
123 	{
124 		return length == 0;
125 	}
126 	/**
127 	 * Returns the size of the string, in bytes.
128 	 */
size()129 	inline size_t size()
130 	{
131 		return length;
132 	}
133 	/**
134 	 * Writes the string to the specified buffer.
135 	 */
136 	void push_to_buffer(byte_buffer &buffer, bool escapes=false);
137 	/**
138 	 * Prints the string to the specified output stream.
139 	 */
140 	void print(FILE *file);
141 	/**
142 	 * Dumps the string to the standard error stream.  Intended to be used
143 	 * for debugging.
144 	 */
145 	void dump();
146 };
147 
148 } // namespace dtc
149 namespace std
150 {
151 	template<>
152 	struct hash<dtc::string>
153 	{
operator ()std::hash154 		std::size_t operator()(dtc::string const& s) const
155 		{
156 			std::string str(s.start, s.length);
157 			std::hash<std::string> h;
158 			return h(str);
159 		}
160 	};
161 }
162 
163 
164 #endif // !_STRING_HH_
165