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