aboutsummaryrefslogtreecommitdiffstats
path: root/support/lib/Support/StringExtras.cpp
blob: 2229df049ac5ef3c4b19882e9a02f0d5222196e7 (plain)
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


#include "llvm/Support/StringExtras.h"
#include "llvm/ConstPoolVals.h"
#include "llvm/DerivedTypes.h"

// Can we treat the specified array as a string?  Only if it is an array of
// ubytes or non-negative sbytes.
//
bool isStringCompatible(ConstPoolArray *CPA) {
  const Type *ETy = cast<ArrayType>(CPA->getType())->getElementType();
  if (ETy == Type::UByteTy) return true;
  if (ETy != Type::SByteTy) return false;

  for (unsigned i = 0; i < CPA->getNumOperands(); ++i)
    if (cast<ConstPoolSInt>(CPA->getOperand(i))->getValue() < 0)
      return false;

  return true;
}

// toOctal - Convert the low order bits of X into an octal letter
static inline char toOctal(int X) {
  return (X&7)+'0';
}

// getAsCString - Return the specified array as a C compatible string, only if
// the predicate isStringCompatible is true.
//
string getAsCString(ConstPoolArray *CPA) {
  if (isStringCompatible(CPA)) {
    string Result;
    const Type *ETy = cast<ArrayType>(CPA->getType())->getElementType();
    Result = "\"";
    for (unsigned i = 0; i < CPA->getNumOperands(); ++i) {
      unsigned char C = (ETy == Type::SByteTy) ?
        (unsigned char)cast<ConstPoolSInt>(CPA->getOperand(i))->getValue() :
        (unsigned char)cast<ConstPoolUInt>(CPA->getOperand(i))->getValue();

      if (isprint(C)) {
        Result += C;
      } else {
        switch(C) {
        case '\a': Result += "\\a"; break;
        case '\b': Result += "\\b"; break;
        case '\f': Result += "\\f"; break;
        case '\n': Result += "\\n"; break;
        case '\r': Result += "\\r"; break;
        case '\t': Result += "\\t"; break;
        case '\v': Result += "\\v"; break;
        default:
          Result += '\\';
          Result += toOctal(C >> 6);
          Result += toOctal(C >> 3);
          Result += toOctal(C >> 0);
          break;
        }
      }
    }
    Result += "\"";

    return Result;
  } else {
    return CPA->getStrValue();
  }
}