1af0dd31fSDavid Chisnall /*- 2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 31de7b4b8SPedro F. Giffuni * 4af0dd31fSDavid Chisnall * Copyright (c) 2013 David Chisnall 5af0dd31fSDavid Chisnall * All rights reserved. 6af0dd31fSDavid Chisnall * 7af0dd31fSDavid Chisnall * This software was developed by SRI International and the University of 8af0dd31fSDavid Chisnall * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) 9af0dd31fSDavid Chisnall * ("CTSRD"), as part of the DARPA CRASH research programme. 10af0dd31fSDavid Chisnall * 11af0dd31fSDavid Chisnall * Redistribution and use in source and binary forms, with or without 12af0dd31fSDavid Chisnall * modification, are permitted provided that the following conditions 13af0dd31fSDavid Chisnall * are met: 14af0dd31fSDavid Chisnall * 1. Redistributions of source code must retain the above copyright 15af0dd31fSDavid Chisnall * notice, this list of conditions and the following disclaimer. 16af0dd31fSDavid Chisnall * 2. Redistributions in binary form must reproduce the above copyright 17af0dd31fSDavid Chisnall * notice, this list of conditions and the following disclaimer in the 18af0dd31fSDavid Chisnall * documentation and/or other materials provided with the distribution. 19af0dd31fSDavid Chisnall * 20af0dd31fSDavid Chisnall * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21af0dd31fSDavid Chisnall * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22af0dd31fSDavid Chisnall * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23af0dd31fSDavid Chisnall * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24af0dd31fSDavid Chisnall * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25af0dd31fSDavid Chisnall * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26af0dd31fSDavid Chisnall * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27af0dd31fSDavid Chisnall * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28af0dd31fSDavid Chisnall * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29af0dd31fSDavid Chisnall * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30af0dd31fSDavid Chisnall * SUCH DAMAGE. 31af0dd31fSDavid Chisnall * 32af0dd31fSDavid Chisnall * $FreeBSD$ 33af0dd31fSDavid Chisnall */ 34af0dd31fSDavid Chisnall 35bbe31b70SEd Maste #include <string> 3621d5d37bSEd Maste #include <functional> 37bbe31b70SEd Maste #include <cstdio> 38bbe31b70SEd Maste #include <cstdlib> 3967b60a1bSKyle Evans #include <cstring> 40009f7b42SDavid Chisnall #include <ctype.h> 41bbe31b70SEd Maste #include <libgen.h> 42af0dd31fSDavid Chisnall 43bbe31b70SEd Maste #include "util.hh" 44af0dd31fSDavid Chisnall 45bbe31b70SEd Maste using std::string; 46af0dd31fSDavid Chisnall 47af0dd31fSDavid Chisnall namespace dtc 48af0dd31fSDavid Chisnall { 49af0dd31fSDavid Chisnall 50af0dd31fSDavid Chisnall void 51bbe31b70SEd Maste push_string(byte_buffer &buffer, const string &s, bool escapes) 52af0dd31fSDavid Chisnall { 53bbe31b70SEd Maste size_t length = s.size(); 54bbe31b70SEd Maste for (size_t i=0 ; i<length ; ++i) 55af0dd31fSDavid Chisnall { 56bbe31b70SEd Maste uint8_t c = s[i]; 57af0dd31fSDavid Chisnall if (escapes && c == '\\' && i+1 < length) 58af0dd31fSDavid Chisnall { 59bbe31b70SEd Maste c = s[++i]; 60af0dd31fSDavid Chisnall switch (c) 61af0dd31fSDavid Chisnall { 62af0dd31fSDavid Chisnall // For now, we just ignore invalid escape sequences. 63af0dd31fSDavid Chisnall default: 64af0dd31fSDavid Chisnall case '"': 65af0dd31fSDavid Chisnall case '\'': 66af0dd31fSDavid Chisnall case '\\': 67af0dd31fSDavid Chisnall break; 68af0dd31fSDavid Chisnall case 'a': 69af0dd31fSDavid Chisnall c = '\a'; 70af0dd31fSDavid Chisnall break; 71af0dd31fSDavid Chisnall case 'b': 72af0dd31fSDavid Chisnall c = '\b'; 73af0dd31fSDavid Chisnall break; 74af0dd31fSDavid Chisnall case 't': 75af0dd31fSDavid Chisnall c = '\t'; 76af0dd31fSDavid Chisnall break; 77af0dd31fSDavid Chisnall case 'n': 78af0dd31fSDavid Chisnall c = '\n'; 79af0dd31fSDavid Chisnall break; 80af0dd31fSDavid Chisnall case 'v': 81af0dd31fSDavid Chisnall c = '\v'; 82af0dd31fSDavid Chisnall break; 83af0dd31fSDavid Chisnall case 'f': 84af0dd31fSDavid Chisnall c = '\f'; 85af0dd31fSDavid Chisnall break; 86af0dd31fSDavid Chisnall case 'r': 87af0dd31fSDavid Chisnall c = '\r'; 88af0dd31fSDavid Chisnall break; 89af0dd31fSDavid Chisnall case '0'...'7': 90af0dd31fSDavid Chisnall { 91af0dd31fSDavid Chisnall int v = digittoint(c); 92bbe31b70SEd Maste if (i+1 < length && s[i+1] <= '7' && s[i+1] >= '0') 93af0dd31fSDavid Chisnall { 94af0dd31fSDavid Chisnall v <<= 3; 95bbe31b70SEd Maste v |= digittoint(s[i+1]); 96af0dd31fSDavid Chisnall i++; 97bbe31b70SEd Maste if (i+1 < length && s[i+1] <= '7' && s[i+1] >= '0') 98af0dd31fSDavid Chisnall { 99af0dd31fSDavid Chisnall v <<= 3; 100bbe31b70SEd Maste v |= digittoint(s[i+1]); 101af0dd31fSDavid Chisnall } 102af0dd31fSDavid Chisnall } 103af0dd31fSDavid Chisnall c = (uint8_t)v; 104af0dd31fSDavid Chisnall break; 105af0dd31fSDavid Chisnall } 106af0dd31fSDavid Chisnall case 'x': 107af0dd31fSDavid Chisnall { 108af0dd31fSDavid Chisnall ++i; 109af0dd31fSDavid Chisnall if (i >= length) 110af0dd31fSDavid Chisnall { 111af0dd31fSDavid Chisnall break; 112af0dd31fSDavid Chisnall } 113bbe31b70SEd Maste int v = digittoint(s[i]); 114bbe31b70SEd Maste if (i+1 < length && ishexdigit(s[i+1])) 115af0dd31fSDavid Chisnall { 116af0dd31fSDavid Chisnall v <<= 4; 117bbe31b70SEd Maste v |= digittoint(s[++i]); 118af0dd31fSDavid Chisnall } 119af0dd31fSDavid Chisnall c = (uint8_t)v; 120af0dd31fSDavid Chisnall break; 121af0dd31fSDavid Chisnall } 122af0dd31fSDavid Chisnall } 123af0dd31fSDavid Chisnall } 124af0dd31fSDavid Chisnall buffer.push_back(c); 125af0dd31fSDavid Chisnall } 126af0dd31fSDavid Chisnall } 127af0dd31fSDavid Chisnall 12821d5d37bSEd Maste namespace { 12921d5d37bSEd Maste string 13021d5d37bSEd Maste dirbasename(std::function<char*(char*)> fn, const string &s) 131af0dd31fSDavid Chisnall { 132bbe31b70SEd Maste if (s == string()) 133bbe31b70SEd Maste { 134bbe31b70SEd Maste return string(); 135bbe31b70SEd Maste } 13621d5d37bSEd Maste std::unique_ptr<char, decltype(free)*> str = {strdup(s.c_str()), free}; 13721d5d37bSEd Maste string dn(fn(str.get())); 138bbe31b70SEd Maste return dn; 139af0dd31fSDavid Chisnall } 140af0dd31fSDavid Chisnall } 14121d5d37bSEd Maste 14221d5d37bSEd Maste string dirname(const string &s) 14321d5d37bSEd Maste { 14421d5d37bSEd Maste return dirbasename(::dirname, s); 14521d5d37bSEd Maste } 14621d5d37bSEd Maste 14721d5d37bSEd Maste string basename(const string &s) 14821d5d37bSEd Maste { 14921d5d37bSEd Maste return dirbasename(::basename, s); 150bbe31b70SEd Maste } 151af0dd31fSDavid Chisnall } // namespace dtc 152af0dd31fSDavid Chisnall 153