1af0dd31fSDavid Chisnall /*- 2*1de7b4b8SPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*1de7b4b8SPedro 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> 39009f7b42SDavid Chisnall #include <ctype.h> 40bbe31b70SEd Maste #include <libgen.h> 41af0dd31fSDavid Chisnall 42bbe31b70SEd Maste #include "util.hh" 43af0dd31fSDavid Chisnall 44bbe31b70SEd Maste using std::string; 45af0dd31fSDavid Chisnall 46af0dd31fSDavid Chisnall namespace dtc 47af0dd31fSDavid Chisnall { 48af0dd31fSDavid Chisnall 49af0dd31fSDavid Chisnall void 50bbe31b70SEd Maste push_string(byte_buffer &buffer, const string &s, bool escapes) 51af0dd31fSDavid Chisnall { 52bbe31b70SEd Maste size_t length = s.size(); 53bbe31b70SEd Maste for (size_t i=0 ; i<length ; ++i) 54af0dd31fSDavid Chisnall { 55bbe31b70SEd Maste uint8_t c = s[i]; 56af0dd31fSDavid Chisnall if (escapes && c == '\\' && i+1 < length) 57af0dd31fSDavid Chisnall { 58bbe31b70SEd Maste c = s[++i]; 59af0dd31fSDavid Chisnall switch (c) 60af0dd31fSDavid Chisnall { 61af0dd31fSDavid Chisnall // For now, we just ignore invalid escape sequences. 62af0dd31fSDavid Chisnall default: 63af0dd31fSDavid Chisnall case '"': 64af0dd31fSDavid Chisnall case '\'': 65af0dd31fSDavid Chisnall case '\\': 66af0dd31fSDavid Chisnall break; 67af0dd31fSDavid Chisnall case 'a': 68af0dd31fSDavid Chisnall c = '\a'; 69af0dd31fSDavid Chisnall break; 70af0dd31fSDavid Chisnall case 'b': 71af0dd31fSDavid Chisnall c = '\b'; 72af0dd31fSDavid Chisnall break; 73af0dd31fSDavid Chisnall case 't': 74af0dd31fSDavid Chisnall c = '\t'; 75af0dd31fSDavid Chisnall break; 76af0dd31fSDavid Chisnall case 'n': 77af0dd31fSDavid Chisnall c = '\n'; 78af0dd31fSDavid Chisnall break; 79af0dd31fSDavid Chisnall case 'v': 80af0dd31fSDavid Chisnall c = '\v'; 81af0dd31fSDavid Chisnall break; 82af0dd31fSDavid Chisnall case 'f': 83af0dd31fSDavid Chisnall c = '\f'; 84af0dd31fSDavid Chisnall break; 85af0dd31fSDavid Chisnall case 'r': 86af0dd31fSDavid Chisnall c = '\r'; 87af0dd31fSDavid Chisnall break; 88af0dd31fSDavid Chisnall case '0'...'7': 89af0dd31fSDavid Chisnall { 90af0dd31fSDavid Chisnall int v = digittoint(c); 91bbe31b70SEd Maste if (i+1 < length && s[i+1] <= '7' && s[i+1] >= '0') 92af0dd31fSDavid Chisnall { 93af0dd31fSDavid Chisnall v <<= 3; 94bbe31b70SEd Maste v |= digittoint(s[i+1]); 95af0dd31fSDavid Chisnall i++; 96bbe31b70SEd Maste if (i+1 < length && s[i+1] <= '7' && s[i+1] >= '0') 97af0dd31fSDavid Chisnall { 98af0dd31fSDavid Chisnall v <<= 3; 99bbe31b70SEd Maste v |= digittoint(s[i+1]); 100af0dd31fSDavid Chisnall } 101af0dd31fSDavid Chisnall } 102af0dd31fSDavid Chisnall c = (uint8_t)v; 103af0dd31fSDavid Chisnall break; 104af0dd31fSDavid Chisnall } 105af0dd31fSDavid Chisnall case 'x': 106af0dd31fSDavid Chisnall { 107af0dd31fSDavid Chisnall ++i; 108af0dd31fSDavid Chisnall if (i >= length) 109af0dd31fSDavid Chisnall { 110af0dd31fSDavid Chisnall break; 111af0dd31fSDavid Chisnall } 112bbe31b70SEd Maste int v = digittoint(s[i]); 113bbe31b70SEd Maste if (i+1 < length && ishexdigit(s[i+1])) 114af0dd31fSDavid Chisnall { 115af0dd31fSDavid Chisnall v <<= 4; 116bbe31b70SEd Maste v |= digittoint(s[++i]); 117af0dd31fSDavid Chisnall } 118af0dd31fSDavid Chisnall c = (uint8_t)v; 119af0dd31fSDavid Chisnall break; 120af0dd31fSDavid Chisnall } 121af0dd31fSDavid Chisnall } 122af0dd31fSDavid Chisnall } 123af0dd31fSDavid Chisnall buffer.push_back(c); 124af0dd31fSDavid Chisnall } 125af0dd31fSDavid Chisnall } 126af0dd31fSDavid Chisnall 12721d5d37bSEd Maste namespace { 12821d5d37bSEd Maste string 12921d5d37bSEd Maste dirbasename(std::function<char*(char*)> fn, const string &s) 130af0dd31fSDavid Chisnall { 131bbe31b70SEd Maste if (s == string()) 132bbe31b70SEd Maste { 133bbe31b70SEd Maste return string(); 134bbe31b70SEd Maste } 13521d5d37bSEd Maste std::unique_ptr<char, decltype(free)*> str = {strdup(s.c_str()), free}; 13621d5d37bSEd Maste string dn(fn(str.get())); 137bbe31b70SEd Maste return dn; 138af0dd31fSDavid Chisnall } 139af0dd31fSDavid Chisnall } 14021d5d37bSEd Maste 14121d5d37bSEd Maste string dirname(const string &s) 14221d5d37bSEd Maste { 14321d5d37bSEd Maste return dirbasename(::dirname, s); 14421d5d37bSEd Maste } 14521d5d37bSEd Maste 14621d5d37bSEd Maste string basename(const string &s) 14721d5d37bSEd Maste { 14821d5d37bSEd Maste return dirbasename(::basename, s); 149bbe31b70SEd Maste } 150af0dd31fSDavid Chisnall } // namespace dtc 151af0dd31fSDavid Chisnall 152