summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/scanners/c/pleac.expected.raydebug518
-rw-r--r--test/scanners/c/pleac.in.c518
2 files changed, 1036 insertions, 0 deletions
diff --git a/test/scanners/c/pleac.expected.raydebug b/test/scanners/c/pleac.expected.raydebug
new file mode 100644
index 0000000..c4dbb9a
--- /dev/null
+++ b/test/scanners/c/pleac.expected.raydebug
@@ -0,0 +1,518 @@
+comment(// -*- c++ -*-)
+
+comment(// @@PLEAC@@_NAME)
+comment(// @@SKIP@@ C++/STL/Boost)
+
+
+comment(// @@PLEAC@@_WEB)
+comment(// @@SKIP@@ http://www.research.att.com/~bs/C++.html)
+comment(// @@SKIP@@ http://www.boost.org/)
+
+
+comment(// @@PLEAC@@_1.0)
+comment(// In C++, one can use the builtin 'char *' type or the 'string' type)
+comment(// to represent strings. In this section, we will work with the C++)
+comment(// library 'string' class.)
+
+comment(// Characteristics of 'string' types:)
+comment(// - may be of any length)
+comment(// - are defined within the std namespace)
+comment(// - can be converted to a 'const char *' using std::string::c_str(\))
+comment(// - can be subscripted to access individual characters (e.g., str[3])
+comment(// returns the 4th character of the string)
+comment(// - memory associated with strings is reclaimed automatically as strings)
+comment(// go out of scope)
+comment(// - strings cannot be used as true/false values (i.e., the following is not)
+comment(// allowed: string s; if (s\) {}\))
+
+comment(//-----------------------------)
+comment(// Before using strings, you must include the <string> header file)
+preprocessor(#include) include(<string>)
+
+comment(//-----------------------------)
+comment(// To create a literal strings, you must use double quotes ("\). You cannot)
+comment(// use single quotes. )
+
+comment(//-----------------------------)
+comment(// String variables must be declared -- if no value is given it's)
+comment(// value is the empty string (""\). )
+ident(std)operator(::)ident(string) ident(s)operator(;)
+
+comment(//-----------------------------)
+comment(// To insert special characters, quote the character with \\
+std::string s1 = "\\\\n"; // Two characters, \\ and n)
+ident(std)operator(::)ident(string) ident(s2) operator(=) string<delimiter(")content(Jon )char(\\")content(Maddog)char(\\")content( Orwant)delimiter(")>operator(;) comment(// Literal double quotes)
+
+comment(//-----------------------------)
+comment(// Strings can be declared in one of two ways)
+ident(std)operator(::)ident(string) ident(s1) operator(=) string<delimiter(")content(assignment syntax)delimiter(")>operator(;)
+ident(std)operator(::)ident(string) ident(s2)operator(()string<delimiter(")content(constructor syntax)delimiter(")>operator(\);)
+
+comment(//-----------------------------)
+comment(// Multi-line strings.)
+comment(// There is no equivalent to perl's "here" documents in c++)
+ident(std)operator(::)ident(string) ident(s1) operator(=) string<delimiter(")>error()
+ident(This) ident(is) ident(a) ident(multiline) ident(string) ident(started) ident(and) ident(finished) ident(with) pre_type(double)
+ident(quotes) ident(that) ident(spans) integer(4) ident(lines) operator(()ident(it) ident(contains) integer(3) ident(newline) ident(characters)operator(\))operator(.)
+string<delimiter(")content(;)>error()
+
+ident(std)operator(::)ident(string) ident(s2) operator(=) string<delimiter(")content(This is a multiline string started and finished with double )>error()
+ident(quotes) ident(that) ident(spans) integer(2) ident(lines) operator(()ident(it) ident(contains) integer(1) ident(newline) ident(character)operator(\))operator(.)string<delimiter(")content(;)>error()
+comment(//-----------------------------)
+
+
+comment(// @@PLEAC@@_1.1)
+ident(std)operator(::)ident(string) ident(s) operator(=) string<delimiter(")content(some string)delimiter(")>operator(;)
+
+comment(//-----------------------------)
+ident(std)operator(::)ident(string) ident(value1) operator(=) ident(s)operator(.)ident(substr)operator(()ident(offset)operator(,) ident(length)operator(\);)
+ident(std)operator(::)ident(string) ident(value2) operator(=) ident(s)operator(.)ident(substr)operator(()ident(offset)operator(\);)
+
+comment(// Unlike perl, the substr function returns a copy of the substring)
+comment(// rather than a reference to the existing substring, thus using substr)
+comment(// on the left hand side of an assignment statement will not modify )
+comment(// the original string. To get this functionality, you can use the)
+comment(// std::string::replace function.)
+
+comment(// Using offsets and lengths)
+ident(s)operator(.)ident(replace)operator(()ident(offset)operator(,) ident(length)operator(,) ident(newstring)operator(\);)
+ident(s)operator(.)ident(replace)operator(()ident(offset)operator(,) ident(s)operator(.)ident(size)operator((\)-)ident(offset)operator(,) ident(newtail)operator(\);)
+
+comment(//-----------------------------)
+comment(// The C++ string class doesn't have anything equivalent to perl's unpack.)
+comment(// Instead, one can use C structures to import/export binary data)
+
+comment(//-----------------------------)
+preprocessor(#include) include(<string>)
+ident(string) ident(s) operator(=) string<delimiter(")content(This is what you have)delimiter(")>operator(;)
+
+ident(std)operator(::)ident(string) ident(first) operator(=) ident(s)operator(.)ident(substr)operator(()integer(0)operator(,) integer(1)operator(\);) comment(// "T")
+ident(std)operator(::)ident(string) ident(second) operator(=) ident(s)operator(.)ident(substr)operator(()integer(5)operator(,) integer(2)operator(\);) comment(// "is")
+ident(std)operator(::)ident(string) ident(rest) operator(=) ident(s)operator(.)ident(substr)operator(()integer(13)operator(\);) comment(// "you have")
+
+comment(// C++ strings do not support backwards indexing as perl does but )
+comment(// you can fake it out by subtracting the negative index from the)
+comment(// string length)
+ident(std)operator(::)ident(string) ident(last) operator(=) ident(s)operator(.)ident(substr)operator(()ident(s)operator(.)ident(size)operator((\)-)integer(1)operator(\);) comment(// "e")
+ident(std)operator(::)ident(string) ident(end) operator(=) ident(s)operator(.)ident(substr)operator(()ident(s)operator(.)ident(size)operator((\)-)integer(4)operator(\);) comment(// "have")
+ident(std)operator(::)ident(string) ident(piece) operator(=) ident(s)operator(.)ident(substr)operator(()ident(s)operator(.)ident(size)operator((\)-)integer(8)operator(,) integer(3)operator(\);) comment(// "you")
+
+comment(//-----------------------------)
+preprocessor(#include) include(<string>)
+preprocessor(#include) include(<iostream>)
+
+ident(string) ident(s)operator(()string<delimiter(")content(This is what you have)delimiter(")>operator(\);)
+ident(std)operator(::)ident(cout) operator(<<) ident(s) operator(<<) ident(std)operator(::)ident(endl)operator(;)
+comment(// This is what you have)
+
+ident(s)operator(.)ident(replace)operator(()integer(5)operator(,)integer(2)operator(,)string<delimiter(")content(wasn't)delimiter(")>operator(\);) comment(// change "is to "wasn't")
+comment(// This wasn't what you have)
+
+ident(s)operator(.)ident(replace)operator(()ident(s)operator(.)ident(size)operator((\)-)integer(12)operator(,) integer(12)operator(,) string<delimiter(")content(ondrous)delimiter(")>operator(\);) comment(// "This wasn't wondrous")
+comment(// This wasn't wonderous)
+
+ident(s)operator(.)ident(replace)operator(()integer(0)operator(,) integer(1)operator(,) string<delimiter(")delimiter(")>operator(\);) comment(// delete first character)
+comment(// his wasn't wondrous)
+
+ident(s)operator(.)ident(replace)operator(()ident(s)operator(.)ident(size)operator((\)-)integer(10)operator(,) integer(10)operator(,) string<delimiter(")delimiter(")>operator(\);) comment(// delete last 10 characters)
+comment(// his wasn')
+
+comment(//-----------------------------)
+comment(// C++ does not have built-in support for the perl s///, m//, and tr/// )
+comment(// operators; however, similar results can be achieved in at least )
+comment(// two ways:)
+comment(// - string operations such as string::find, string::rfind, etc.)
+comment(// - the boost regular expression library (regex++\) supports perl)
+comment(// regular expression syntax.)
+comment(// TODO: Add examples of each.)
+
+comment(// MISSING: if (substr($string, -10\) =~ /pattern/\) {)
+comment(// print "Pattern matches in last 10 characters\\n";)
+comment(// })
+
+comment(// MISSING: substr($string, 0, 5\) =~ s/is/at/g;)
+
+comment(//-----------------------------)
+comment(// exchange the first and last letters in a string using substr and replace)
+ident(string) ident(a) operator(=) string<delimiter(")content(make a hat)delimiter(")>operator(;)
+
+ident(std)operator(::)ident(string) ident(first) operator(=) ident(a)operator(.)ident(substr)operator(()integer(0)operator(,)integer(1)operator(\);)
+ident(std)operator(::)ident(string) ident(last) operator(=) ident(a)operator(.)ident(substr)operator(()ident(a)operator(.)ident(size)operator((\)-)integer(1)operator(\);)
+
+ident(a)operator(.)ident(replace)operator(()integer(0)operator(,)integer(1)operator(,) ident(last)operator(\);)
+ident(a)operator(.)ident(replace)operator(()ident(a)operator(.)ident(size)operator((\)-)integer(1)operator(,) integer(1)operator(,) ident(first)operator(\);)
+
+comment(// exchange the first and last letters in a string using indexing and swap)
+preprocessor(#include) include(<algorithm>)
+ident(std)operator(::)ident(swap)operator(()ident(a)operator([)integer(0)operator(],) ident(a)operator([)ident(a)operator(.)ident(size)operator((\)-)integer(1)operator(]\);)
+comment(//-----------------------------)
+
+
+comment(// @@PLEAC@@_1.2)
+comment(//-----------------------------)
+comment(// C++ doesn't have functionality equivalent to the || and ||=. )
+comment(// If statements and trigraphs can be used instead.)
+comment(//-----------------------------)
+comment(// C++ doesn't have anything equivalent "defined". C++ variables)
+comment(// cannot be used at all if they have not previously been defined.)
+
+comment(//-----------------------------)
+comment(// Use b if b is not empty, else c)
+ident(a) operator(=) ident(b)operator(.)ident(size)operator((\)) operator(?) ident(b) operator(:) ident(c)operator(;)
+
+comment(// Set x to y unless x is not empty)
+reserved(if) operator(()ident(x)operator(.)ident(is_empty)operator((\)\)) ident(x) operator(=) ident(y)operator(;)
+
+comment(//-----------------------------)
+ident(foo) operator(=) operator((!)ident(bar)operator(.)ident(is_empty)operator((\)\)) operator(?) ident(bar) operator(:) string<delimiter(")content(DEFAULT VALUE)delimiter(")>operator(;)
+
+comment(//-----------------------------)
+comment(// NOTE: argv is declared as char *argv[] in C/C++. We assume)
+comment(// the following code surrounds the following examples that deal)
+comment(// with argv. Also, arguments to a program start at argv[1] -- argv[0])
+comment(// is the name of the executable that's running.)
+preprocessor(#include) include(<string.h>)
+pre_type(int) ident(main)operator(()pre_type(int) ident(argc)operator(,) pre_type(char) operator(*)ident(argv)operator([]\)) operator({)
+ pre_type(char) operator(**)ident(args) operator(=) ident(argv)operator(+)integer(1)operator(;) comment(// +1 skips argv[0], the name of the executable)
+ comment(// examples)
+operator(})
+
+comment(//-----------------------------)
+ident(std)operator(::)ident(string) ident(dir) operator(=) operator((*)ident(args)operator(\)) operator(?) operator(*)ident(argv)operator(++) operator(:) string<delimiter(")content(/tmp)delimiter(")>operator(;)
+
+comment(//-----------------------------)
+ident(std)operator(::)ident(string) ident(dir) operator(=) ident(argv)operator([)integer(1)operator(]) operator(?) ident(argv)operator([)integer(1)operator(]) operator(:) string<delimiter(")content(/tmp)delimiter(")>operator(;)
+
+comment(//-----------------------------)
+ident(std)operator(::)ident(string) ident(dir) operator(=) operator(()ident(argc)operator(-)integer(1)operator(\)) operator(?) ident(argv)operator([)integer(1)operator(]) operator(:) string<delimiter(")content(/tmp)delimiter(")>operator(;)
+
+comment(//-----------------------------)
+preprocessor(#include) include(<map>)
+ident(std)operator(::)ident(map)operator(<)ident(std)operator(::)ident(string)operator(,)pre_type(int)operator(>) ident(count)operator(;)
+
+ident(count)operator([)ident(shell)operator(.)ident(size)operator((\)) operator(?) ident(shell) operator(:) string<delimiter(")content(/bin/sh)delimiter(")>operator(]++;)
+
+comment(//-----------------------------)
+comment(// find the user name on Unix systems)
+comment(// TODO: Simplify. This is too ugly and complex)
+preprocessor(#include) include(<sys/types.h>)
+preprocessor(#include) include(<unistd.h>)
+preprocessor(#include) include(<pwd.h>)
+preprocessor(#include) include("boost/lexical_cast.hpp")
+
+ident(std)operator(::)ident(string) ident(user)operator(;)
+pre_type(char) operator(*)ident(msg) operator(=) integer(0)operator(;)
+ident(passwd) operator(*)ident(pwd) operator(=) integer(0)operator(;)
+
+reserved(if) operator(() operator(()ident(msg) operator(=) ident(getenv)operator(()string<delimiter(")content(USER)delimiter(")>operator(\)\)) operator(||)
+ operator(()ident(msg) operator(=) ident(getenv)operator(()string<delimiter(")content(LOGNAME)delimiter(")>operator(\)\)) operator(||)
+ operator(()ident(msg) operator(=) ident(getlogin)operator((\)\)) operator(\))
+ ident(user) operator(=) ident(msg)operator(;)
+reserved(else) reserved(if) operator(()ident(pwd) operator(=) ident(getpwuid)operator(()ident(getuid)operator((\)\)\))
+ ident(user) operator(=) ident(pwd)operator(->)ident(pw_name)operator(;)
+reserved(else)
+ ident(user) operator(=) string<delimiter(")content(Unknown uid number )delimiter(")> operator(+) ident(boost)operator(::)ident(lexical_cast)operator(<)ident(std)operator(::)ident(string)operator(>()ident(getuid)operator((\)\);)
+
+comment(//-----------------------------)
+reserved(if) operator(()ident(starting_point)operator(.)ident(is_empty)operator((\)\)) ident(starting_point) operator(=) string<delimiter(")content(Greenwich)delimiter(")>operator(;)
+
+comment(//-----------------------------)
+comment(// Example using list. Other C++ STL containers work similarly.)
+preprocessor(#include) include(<list>)
+ident(list)operator(<)pre_type(int)operator(>) ident(a)operator(,) ident(b)operator(;)
+reserved(if) operator(()ident(a)operator(.)ident(is_empty)operator((\)\)) ident(a) operator(=) ident(b)operator(;) comment(// copy only if a is empty)
+ident(a) operator(=) operator((!)ident(b)operator(.)ident(is_empty)operator((\)\)) operator(?) ident(b) operator(:) ident(c)operator(;) comment(// asign b if b nonempty, else c)
+comment(//-----------------------------)
+
+
+comment(// @@PLEAC@@_1.3)
+comment(//-----------------------------)
+preprocessor(#include) include(<algorithm>)
+ident(std)operator(::)ident(swap)operator(()ident(a)operator(,) ident(b)operator(\);)
+
+comment(//-----------------------------)
+ident(temp) operator(=) ident(a)operator(;)
+ident(a) operator(=) ident(b)operator(;)
+ident(b) operator(=) ident(temp)operator(;)
+
+comment(//-----------------------------)
+ident(std)operator(::)ident(string) ident(a)operator(()string<delimiter(")content(alpha)delimiter(")>operator(\);)
+ident(std)operator(::)ident(string) ident(b)operator(()string<delimiter(")content(omega)delimiter(")>operator(\);)
+ident(std)operator(::)ident(swap)operator(()ident(a)operator(,)ident(b)operator(\);)
+
+comment(//-----------------------------)
+comment(// The ability to exchange more than two variables at once is not )
+comment(// built into the C++ language or C++ standard libraries. However, you)
+comment(// can use the boost tuple library to accomplish this.)
+preprocessor(#include) include(<boost/tuple/tuple.hpp>)
+
+ident(boost)operator(::)ident(tie)operator(()ident(alpha)operator(,)ident(beta)operator(,)ident(production)operator(\))
+ operator(=) ident(boost)operator(::)ident(make_tuple)operator(()string<delimiter(")content(January)delimiter(")>operator(,) string<delimiter(")content(March)delimiter(")>operator(,) string<delimiter(")content(August)delimiter(")>operator(\);)
+comment(// move beta to alpha,)
+comment(// move production to beta,)
+comment(// move alpha to production)
+ident(boost)operator(::)ident(tie)operator(()ident(alpha)operator(,) ident(beta)operator(,) ident(production)operator(\))
+ operator(=) ident(boost)operator(::)ident(make_tuple)operator(()ident(beta)operator(,) ident(production)operator(,) ident(alpha)operator(\);)
+comment(//-----------------------------)
+
+
+comment(// @@PLEAC@@_1.4)
+comment(//-----------------------------)
+comment(// There are several ways to convert between characters)
+comment(// and integers. The examples assume the following declarations:)
+pre_type(char) ident(ch)operator(;)
+pre_type(int) ident(num)operator(;)
+
+comment(//-----------------------------)
+comment(// Using implicit conversion)
+ident(num) operator(=) ident(ch)operator(;)
+ident(ch) operator(=) ident(num)operator(;)
+
+comment(//-----------------------------)
+comment(// New-style C++ casts)
+ident(ch) operator(=) ident(static_cast)operator(<)pre_type(char)operator(>()ident(num)operator(\);)
+ident(num) operator(=) ident(static_cast)operator(<)pre_type(int)operator(>()ident(ch)operator(\);)
+
+comment(//-----------------------------)
+comment(// Old-style C casts)
+ident(ch) operator(=) operator(()pre_type(char)operator(\))ident(num)operator(;)
+ident(num) operator(=) operator(()pre_type(int)operator(\))ident(ch)operator(;)
+
+comment(//-----------------------------)
+comment(// Using the C++ stringstream class)
+preprocessor(#include) include(<sstream>) comment(// On some older compilers, use <strstream>)
+ident(std)operator(::)ident(stringstream) ident(a)operator(;) comment(// On some older compilers, use std::strstream)
+
+ident(a) operator(<<) ident(ch)operator(;) comment(// Append character to a string)
+ident(a) operator(>>) ident(num)operator(;) comment(// Output character as a number)
+
+ident(a) operator(<<) ident(num)operator(;) comment(// Append number to a string)
+ident(a) operator(>>) ident(ch)operator(;) comment(// Output number as a character)
+
+comment(//-----------------------------)
+comment(// Using sprintf, printf)
+pre_type(char) ident(str)operator([)integer(2)operator(];) comment(// Has to be length 2 to have room for NULL character)
+ident(sprintf)operator(()ident(str)operator(,) string<delimiter(")content(%c)delimiter(")>operator(,) ident(num)operator(\);)
+ident(printf)operator(()string<delimiter(")content(Number %d is character %c)char(\\n)delimiter(")>operator(,) ident(num)operator(,) ident(num)operator(\);)
+
+comment(//-----------------------------)
+pre_type(int) ident(ascii_value) operator(=) char('e')operator(;) comment(// now 101)
+pre_type(char) ident(character) operator(=) integer(101)operator(;) comment(// now 'e')
+
+comment(//-----------------------------)
+ident(printf)operator(()string<delimiter(")content(Number %d is character %c)char(\\n)delimiter(")>operator(,) integer(101)operator(,) integer(101)operator(\);)
+
+comment(//-----------------------------)
+comment(// Convert from HAL to IBM, character by character)
+preprocessor(#include) include(<string>)
+preprocessor(#include) include(<iostream>)
+
+ident(std)operator(::)ident(string) ident(ibm)operator(,) ident(hal) operator(=) string<delimiter(")content(HAL)delimiter(")>operator(;)
+reserved(for) operator(()pre_type(unsigned) pre_type(int) ident(i)operator(=)integer(0)operator(;) ident(i)operator(<)ident(hal)operator(.)ident(size)operator((\);) operator(++)ident(i)operator(\))
+ ident(ibm) operator(+=) ident(hal)operator([)ident(i)operator(]+)integer(1)operator(;) comment(// Add one to each ascii value)
+ident(std)operator(::)ident(cout) operator(<<) ident(ibm) operator(<<) ident(std)operator(::)ident(endl)operator(;) comment(// prints "IBM")
+
+comment(//-----------------------------)
+comment(// Convert hal from HAL to IBM)
+preprocessor(#include) include(<string>)
+preprocessor(#include) include(<iostream>)
+preprocessor(#include) include(<functional>) comment(// For bind1st and plus<>)
+preprocessor(#include) include(<algorithm>) comment(// For transform )
+
+ident(std)operator(::)ident(string) ident(hal) operator(=) string<delimiter(")content(HAL)delimiter(")>operator(;)
+ident(transform)operator(()ident(hal)operator(.)ident(begin)operator((\),) ident(hal)operator(.)ident(end)operator((\),) ident(hal)operator(.)ident(begin)operator((\),)
+ ident(bind1st)operator(()ident(plus)operator(<)pre_type(char)operator(>(\),)integer(1)operator(\)\);)
+ident(std)operator(::)ident(cout) operator(<<) ident(hal) operator(<<) ident(std)operator(::)ident(endl)operator(;) comment(// prints "IBM")
+comment(//-----------------------------)
+
+
+comment(// @@PLEAC@@_1.5)
+comment(//-----------------------------)
+comment(// Since C++ strings can be accessed one character at a time,)
+comment(// there's no need to do any processing on the string to convert)
+comment(// it into an array of characters. )
+preprocessor(#include) include(<string>)
+ident(std)operator(::)ident(string) ident(s)operator(;)
+
+comment(// Accessing characters using for loop and integer offsets)
+reserved(for) operator(()pre_type(unsigned) pre_type(int) ident(i)operator(=)integer(0)operator(;) ident(i)operator(<)ident(s)operator(.)ident(size)operator((\);) operator(++)ident(i)operator(\)) operator({)
+ comment(// do something with s[i])
+operator(})
+
+comment(// Accessing characters using iterators)
+reserved(for) operator(()ident(std)operator(::)ident(string)operator(::)ident(iterator) ident(i)operator(=)ident(s)operator(.)ident(begin)operator((\);) ident(i)operator(!=)ident(s)operator(.)ident(end)operator((\);) operator(++)ident(i)operator(\)) operator({)
+ comment(// do something with *i)
+operator(})
+
+comment(//-----------------------------)
+ident(std)operator(::)ident(string) ident(str) operator(=) string<delimiter(")content(an apple a day)delimiter(")>operator(;)
+ident(std)operator(::)ident(map)operator(<)pre_type(char)operator(,)pre_type(int)operator(>) ident(seen)operator(;)
+
+reserved(for) operator(()ident(std)operator(::)ident(string)operator(::)ident(iterator) ident(i)operator(=)ident(str)operator(.)ident(begin)operator((\);) ident(i)operator(!=)ident(str)operator(.)ident(end)operator((\);) operator(++)ident(i)operator(\))
+ ident(seen)operator([*)ident(i)operator(]++;)
+
+ident(std)operator(::)ident(cout) operator(<<) string<delimiter(")content(unique chars are: )delimiter(")>operator(;)
+reserved(for) operator(()ident(std)operator(::)ident(map)operator(<)pre_type(char)operator(,)pre_type(int)operator(>::)ident(iterator) ident(i)operator(=)ident(seen)operator(.)ident(begin)operator((\);) ident(i)operator(!=)ident(seen)operator(.)ident(end)operator((\);) operator(++)ident(i)operator(\))
+ ident(std)operator(::)ident(cout) operator(<<) ident(i)operator(->)ident(first)operator(;)
+ident(std)operator(::)ident(cout) operator(<<) ident(std)operator(::)ident(endl)operator(;)
+comment(// unique chars are: adelnpy)
+
+comment(//-----------------------------)
+pre_type(int) ident(sum) operator(=) integer(0)operator(;)
+reserved(for) operator(()ident(std)operator(::)ident(string)operator(::)ident(iterator) ident(i)operator(=)ident(str)operator(.)ident(begin)operator((\);) ident(i)operator(!=)ident(str)operator(.)ident(end)operator((\);) operator(++)ident(i)operator(\))
+ ident(sum) operator(+=) operator(*)ident(i)operator(;)
+ident(std)operator(::)ident(cout) operator(<<) string<delimiter(")content(sum is )delimiter(")> operator(<<) ident(sum) operator(<<) ident(std)operator(::)ident(endl)operator(;)
+comment(// prints "sum is 1248" if str was "an appla a day")
+
+
+comment(//-----------------------------)
+comment(// MISSING: sysv-like checksum program)
+
+comment(//-----------------------------)
+comment(// slowcat, emulate a slow line printer)
+preprocessor(#include) include(<sys/time.h>)
+preprocessor(#include) include(<iostream>)
+preprocessor(#include) include(<fstream>)
+
+pre_type(int) ident(main)operator(()pre_type(int) ident(argc)operator(,) pre_type(char) operator(*)ident(argv)operator([]\)) operator({)
+ ident(timeval) ident(delay) operator(=) operator({) integer(0)operator(,) integer(50000) operator(};) comment(// Delay in { seconds, nanoseconds })
+ pre_type(char) operator(**)ident(arg) operator(=) ident(argv)operator(+)integer(1)operator(;)
+ reserved(while) operator((*)ident(arg)operator(\)) operator({) comment(// For each file)
+ ident(std)operator(::)ident(ifstream) ident(file)operator((*)ident(arg)operator(++\);)
+ pre_type(char) ident(c)operator(;)
+ reserved(while) operator(()ident(file)operator(.)ident(get)operator(()ident(c)operator(\)\)) operator({)
+ ident(std)operator(::)ident(cout)operator(.)ident(put)operator(()ident(c)operator(\);)
+ ident(std)operator(::)ident(cout)operator(.)ident(flush)operator((\);)
+ ident(select)operator(()integer(0)operator(,) integer(0)operator(,) integer(0)operator(,) integer(0)operator(,) operator(&)ident(delay)operator(\);)
+ operator(})
+ operator(})
+operator(})
+comment(//-----------------------------)
+
+
+comment(// @@PLEAC@@_1.6)
+comment(//-----------------------------)
+preprocessor(#include) include(<string>)
+preprocessor(#include) include(<algorithm>) comment(// For reverse)
+ident(std)operator(::)ident(string) ident(s)operator(;)
+
+ident(reverse)operator(()ident(s)operator(.)ident(begin)operator((\),) ident(s)operator(.)ident(end)operator((\)\);)
+
+comment(//-----------------------------)
+preprocessor(#include) include(<vector>) comment(// For std::vector)
+preprocessor(#include) include(<sstream>) comment(// On older compilers, use <strstream>)
+preprocessor(#include) include("boost/regex.hpp") comment(// For boost::regex_split)
+
+ident(std)operator(::)ident(string) ident(str)operator(;)
+ident(std)operator(::)ident(vector)operator(<)ident(std)operator(::)ident(string)operator(>) ident(words)operator(;)
+ident(boost)operator(::)ident(regex_split)operator(()ident(std)operator(::)ident(back_inserter)operator(()ident(words)operator(\),) ident(str)operator(\);)
+ident(reverse)operator(()ident(words)operator(.)ident(begin)operator((\),) ident(words)operator(.)ident(end)operator((\)\);) comment(// Reverse the order of the words)
+
+ident(std)operator(::)ident(stringstream) ident(revwords)operator(;) comment(// On older compilers, use strstream)
+ident(copy)operator(()ident(words)operator(.)ident(begin)operator((\),) ident(words)operator(.)ident(end)operator((\),) ident(ostream_inserter)operator(<)ident(string)operator(>()ident(revwords)operator(,)string<delimiter(")content( )delimiter(")>operator(\);)
+ident(std)operator(::)ident(cout) operator(<<) ident(revwards)operator(.)ident(str)operator((\)) operator(<<) ident(std)operator(::)ident(endl)operator(;)
+
+comment(//-----------------------------)
+ident(std)operator(::)ident(string) ident(rts) operator(=) ident(str)operator(;)
+ident(reverse)operator(()ident(rts)operator(.)ident(begin)operator((\),) ident(rts)operator(.)ident(end)operator((\)\);) comment(// Reverses letters in rts)
+
+comment(//-----------------------------)
+ident(std)operator(::)ident(vector)operator(<)ident(string)operator(>) ident(words)operator(;)
+ident(reverse)operator(()ident(words)operator(.)ident(begin)operator((\),) ident(words)operator(.)ident(end)operator((\)\);) comment(// Reverses words in container)
+
+comment(//-----------------------------)
+comment(// Reverse word order)
+ident(std)operator(::)ident(string) ident(s) operator(=) string<delimiter(")content(Yoda said, 'can you see this?')delimiter(")>operator(;)
+
+ident(std)operator(::)ident(vector)operator(<)ident(std)operator(::)ident(string)operator(>) ident(allwords)operator(;)
+ident(boost)operator(::)ident(regex_split)operator(()ident(std)operator(::)ident(back_inserter)operator(()ident(allwords)operator(\),) ident(s)operator(\);)
+
+ident(reverse)operator(()ident(allwords)operator(.)ident(begin)operator((\),) ident(allwords)operator(.)ident(end)operator((\)\);)
+
+ident(std)operator(::)ident(stringstream) ident(revwords)operator(;) comment(// On older compilers, use strstream)
+ident(copy)operator(()ident(allwords)operator(.)ident(begin)operator((\),) ident(allwords)operator(.)ident(end)operator((\),) ident(ostream_inserter)operator(<)ident(string)operator(>()ident(revwords)operator(,)string<delimiter(")content( )delimiter(")>operator(\)\);)
+ident(std)operator(::)ident(cout) operator(<<) ident(revwards)operator(.)ident(str)operator((\)) operator(<<) ident(std)operator(::)ident(endl)operator(;)
+comment(// this?' see you 'can said, Yoda)
+
+comment(//-----------------------------)
+ident(std)operator(::)ident(string) ident(word) operator(=) string<delimiter(")content(reviver)delimiter(")>operator(;)
+pre_type(bool) ident(is_palindrome) operator(=) ident(equal)operator(()ident(word)operator(.)ident(begin)operator((\),) ident(word)operator(.)ident(end)operator((\),) ident(word)operator(.)ident(rbegin)operator((\)\);)
+
+comment(//-----------------------------)
+preprocessor(#include) include(<ifstream>)
+
+ident(std)operator(::)ident(ifstream) ident(dict)operator(()string<delimiter(")content(/usr/dict/words)delimiter(")>operator(\);)
+ident(std)operator(::)ident(string) ident(word)operator(;)
+reserved(while)operator(()ident(getline)operator(()ident(dict)operator(,)ident(word)operator(\)\)) operator({)
+ reserved(if) operator(()ident(equal)operator(()ident(word)operator(.)ident(begin)operator((\),) ident(word)operator(.)ident(end)operator((\),) ident(word)operator(.)ident(rbegin)operator((\)\)) operator(&&)
+ ident(word)operator(.)ident(size)operator((\)) operator(>) integer(5)operator(\))
+ ident(std)operator(::)ident(cout) operator(<<) ident(word) operator(<<) ident(std)operator(::)ident(endl)operator(;)
+operator(})
+comment(//-----------------------------)
+
+
+comment(// @@PLEAC@@_1.7)
+comment(//-----------------------------)
+preprocessor(#include) include(<string>)
+
+ident(std)operator(::)ident(string)operator(::)ident(size_type) ident(pos)operator(;)
+reserved(while) operator((()ident(pos) operator(=) ident(str)operator(.)ident(find)operator(()string<delimiter(")char(\\t)delimiter(")>operator(\)\)) operator(!=) ident(std)operator(::)ident(string)operator(::)ident(npos)operator(\))
+ ident(str)operator(.)ident(replace)operator(()ident(pos)operator(,) integer(1)operator(,) ident(string)operator(()char(' ')operator(,)integer(8)operator(-)ident(pos)operator(%)integer(8)operator(\)\);)
+comment(//-----------------------------)
+
+
+comment(// @@PLEAC@@_1.8)
+comment(//-----------------------------)
+comment(// Not applicable to C++)
+comment(//-----------------------------)
+
+
+comment(// @@PLEAC@@_1.9)
+comment(//-----------------------------)
+comment(// TODO: Fix to be more like cookbook)
+comment(// TODO: Modify/add code to do this with locales)
+preprocessor(#include) include(<string>)
+preprocessor(#include) include(<algorithm>)
+
+ident(std)operator(::)ident(string) ident(phrase) operator(=) string<delimiter(")content(bo peep)delimiter(")>operator(;)
+ident(transform)operator(()ident(phrase)operator(.)ident(begin)operator((\),) ident(phrase)operator(.)ident(end)operator((\),) ident(phrase)operator(.)ident(begin)operator((\),) ident(toupper)operator(\);)
+comment(// "BO PEEP")
+ident(transform)operator(()ident(phrase)operator(.)ident(begin)operator((\),) ident(phrase)operator(.)ident(end)operator((\),) ident(phrase)operator(.)ident(begin)operator((\),) ident(tolower)operator(\);)
+comment(// "bo peep")
+comment(//-----------------------------)
+
+
+comment(// @@PLEAC@@_1.10)
+comment(//-----------------------------)
+comment(// C++ does not provide support for perl-like in-string interpolation,)
+comment(// concatenation must be used instead.)
+
+preprocessor(#include) include(<string>)
+
+ident(std)operator(::)ident(string) ident(var1)operator(,) ident(var2)operator(;)
+ident(std)operator(::)ident(string) ident(answer) operator(=) ident(var1) operator(+) ident(func)operator((\)) operator(+) ident(var2)operator(;) comment(// func returns string or char *)
+
+comment(//-----------------------------)
+preprocessor(#include) include("boost/lexical_cast.hpp")
+
+pre_type(int) ident(n) operator(=) integer(4)operator(;)
+ident(std)operator(::)ident(string) ident(phrase) operator(=) string<delimiter(")content(I have )delimiter(")> operator(+) ident(boost)operator(::)ident(lexical_cast)operator(<)ident(string)operator(>()ident(n)operator(+)integer(1)operator(\)) operator(+) string<delimiter(")content( guanacos.)delimiter(")>operator(;)
+
+comment(//-----------------------------)
+ident(std)operator(::)ident(cout) operator(<<) string<delimiter(")content(I have )delimiter(")> operator(+) ident(boost)operator(::)ident(lexical_cast)operator(<)ident(string)operator(>()ident(n)operator(+)integer(1)operator(\)) operator(+) string<delimiter(")content( guanacos.)delimiter(")> operator(<<) ident(std)operator(::)ident(endl)operator(;)
+
+
+comment(// @@PLEAC@@_1.11)
+comment(//-----------------------------)
+comment(// C++ does not have "here documents".)
+comment(// TODO: Lots more.)
+preprocessor(#include) include(<string>)
+preprocessor(#include) include("boost/regex.hpp")
+
+ident(std)operator(::)ident(string) ident(var) operator(=) string<delimiter(")>error()
+ ident(your) ident(text)
+ ident(goes) ident(here)operator(.)
+string<delimiter(")content(;)>error()
+
+ident(boost)operator(::)ident(regex) ident(ex)operator(()string<delimiter(")content(^)char(\\\\)content(s+)delimiter(")>operator(\);)
+ident(var) operator(=) ident(boost)operator(::)ident(regex_merge)operator(()ident(var)operator(,) ident(ex)operator(,) string<delimiter(")delimiter(")>operator(\);) \ No newline at end of file
diff --git a/test/scanners/c/pleac.in.c b/test/scanners/c/pleac.in.c
new file mode 100644
index 0000000..2f84217
--- /dev/null
+++ b/test/scanners/c/pleac.in.c
@@ -0,0 +1,518 @@
+// -*- c++ -*-
+
+// @@PLEAC@@_NAME
+// @@SKIP@@ C++/STL/Boost
+
+
+// @@PLEAC@@_WEB
+// @@SKIP@@ http://www.research.att.com/~bs/C++.html
+// @@SKIP@@ http://www.boost.org/
+
+
+// @@PLEAC@@_1.0
+// In C++, one can use the builtin 'char *' type or the 'string' type
+// to represent strings. In this section, we will work with the C++
+// library 'string' class.
+
+// Characteristics of 'string' types:
+// - may be of any length
+// - are defined within the std namespace
+// - can be converted to a 'const char *' using std::string::c_str()
+// - can be subscripted to access individual characters (e.g., str[3]
+// returns the 4th character of the string
+// - memory associated with strings is reclaimed automatically as strings
+// go out of scope
+// - strings cannot be used as true/false values (i.e., the following is not
+// allowed: string s; if (s) {})
+
+//-----------------------------
+// Before using strings, you must include the <string> header file
+#include <string>
+
+//-----------------------------
+// To create a literal strings, you must use double quotes ("). You cannot
+// use single quotes.
+
+//-----------------------------
+// String variables must be declared -- if no value is given it's
+// value is the empty string ("").
+std::string s;
+
+//-----------------------------
+// To insert special characters, quote the character with \
+std::string s1 = "\\n"; // Two characters, \ and n
+std::string s2 = "Jon \"Maddog\" Orwant"; // Literal double quotes
+
+//-----------------------------
+// Strings can be declared in one of two ways
+std::string s1 = "assignment syntax";
+std::string s2("constructor syntax");
+
+//-----------------------------
+// Multi-line strings.
+// There is no equivalent to perl's "here" documents in c++
+std::string s1 = "
+This is a multiline string started and finished with double
+quotes that spans 4 lines (it contains 3 newline characters).
+";
+
+std::string s2 = "This is a multiline string started and finished with double
+quotes that spans 2 lines (it contains 1 newline character).";
+//-----------------------------
+
+
+// @@PLEAC@@_1.1
+std::string s = "some string";
+
+//-----------------------------
+std::string value1 = s.substr(offset, length);
+std::string value2 = s.substr(offset);
+
+// Unlike perl, the substr function returns a copy of the substring
+// rather than a reference to the existing substring, thus using substr
+// on the left hand side of an assignment statement will not modify
+// the original string. To get this functionality, you can use the
+// std::string::replace function.
+
+// Using offsets and lengths
+s.replace(offset, length, newstring);
+s.replace(offset, s.size()-offset, newtail);
+
+//-----------------------------
+// The C++ string class doesn't have anything equivalent to perl's unpack.
+// Instead, one can use C structures to import/export binary data
+
+//-----------------------------
+#include <string>
+string s = "This is what you have";
+
+std::string first = s.substr(0, 1); // "T"
+std::string second = s.substr(5, 2); // "is"
+std::string rest = s.substr(13); // "you have"
+
+// C++ strings do not support backwards indexing as perl does but
+// you can fake it out by subtracting the negative index from the
+// string length
+std::string last = s.substr(s.size()-1); // "e"
+std::string end = s.substr(s.size()-4); // "have"
+std::string piece = s.substr(s.size()-8, 3); // "you"
+
+//-----------------------------
+#include <string>
+#include <iostream>
+
+string s("This is what you have");
+std::cout << s << std::endl;
+// This is what you have
+
+s.replace(5,2,"wasn't"); // change "is to "wasn't"
+// This wasn't what you have
+
+s.replace(s.size()-12, 12, "ondrous"); // "This wasn't wondrous"
+// This wasn't wonderous
+
+s.replace(0, 1, ""); // delete first character
+// his wasn't wondrous
+
+s.replace(s.size()-10, 10, ""); // delete last 10 characters
+// his wasn'
+
+//-----------------------------
+// C++ does not have built-in support for the perl s///, m//, and tr///
+// operators; however, similar results can be achieved in at least
+// two ways:
+// - string operations such as string::find, string::rfind, etc.
+// - the boost regular expression library (regex++) supports perl
+// regular expression syntax.
+// TODO: Add examples of each.
+
+// MISSING: if (substr($string, -10) =~ /pattern/) {
+// print "Pattern matches in last 10 characters\n";
+// }
+
+// MISSING: substr($string, 0, 5) =~ s/is/at/g;
+
+//-----------------------------
+// exchange the first and last letters in a string using substr and replace
+string a = "make a hat";
+
+std::string first = a.substr(0,1);
+std::string last = a.substr(a.size()-1);
+
+a.replace(0,1, last);
+a.replace(a.size()-1, 1, first);
+
+// exchange the first and last letters in a string using indexing and swap
+#include <algorithm>
+std::swap(a[0], a[a.size()-1]);
+//-----------------------------
+
+
+// @@PLEAC@@_1.2
+//-----------------------------
+// C++ doesn't have functionality equivalent to the || and ||=.
+// If statements and trigraphs can be used instead.
+//-----------------------------
+// C++ doesn't have anything equivalent "defined". C++ variables
+// cannot be used at all if they have not previously been defined.
+
+//-----------------------------
+// Use b if b is not empty, else c
+a = b.size() ? b : c;
+
+// Set x to y unless x is not empty
+if (x.is_empty()) x = y;
+
+//-----------------------------
+foo = (!bar.is_empty()) ? bar : "DEFAULT VALUE";
+
+//-----------------------------
+// NOTE: argv is declared as char *argv[] in C/C++. We assume
+// the following code surrounds the following examples that deal
+// with argv. Also, arguments to a program start at argv[1] -- argv[0]
+// is the name of the executable that's running.
+#include <string.h>
+int main(int argc, char *argv[]) {
+ char **args = argv+1; // +1 skips argv[0], the name of the executable
+ // examples
+}
+
+//-----------------------------
+std::string dir = (*args) ? *argv++ : "/tmp";
+
+//-----------------------------
+std::string dir = argv[1] ? argv[1] : "/tmp";
+
+//-----------------------------
+std::string dir = (argc-1) ? argv[1] : "/tmp";
+
+//-----------------------------
+#include <map>
+std::map<std::string,int> count;
+
+count[shell.size() ? shell : "/bin/sh"]++;
+
+//-----------------------------
+// find the user name on Unix systems
+// TODO: Simplify. This is too ugly and complex
+#include <sys/types.h>
+#include <unistd.h>
+#include <pwd.h>
+#include "boost/lexical_cast.hpp"
+
+std::string user;
+char *msg = 0;
+passwd *pwd = 0;
+
+if ( (msg = getenv("USER")) ||
+ (msg = getenv("LOGNAME")) ||
+ (msg = getlogin()) )
+ user = msg;
+else if (pwd = getpwuid(getuid()))
+ user = pwd->pw_name;
+else
+ user = "Unknown uid number " + boost::lexical_cast<std::string>(getuid());
+
+//-----------------------------
+if (starting_point.is_empty()) starting_point = "Greenwich";
+
+//-----------------------------
+// Example using list. Other C++ STL containers work similarly.
+#include <list>
+list<int> a, b;
+if (a.is_empty()) a = b; // copy only if a is empty
+a = (!b.is_empty()) ? b : c; // asign b if b nonempty, else c
+//-----------------------------
+
+
+// @@PLEAC@@_1.3
+//-----------------------------
+#include <algorithm>
+std::swap(a, b);
+
+//-----------------------------
+temp = a;
+a = b;
+b = temp;
+
+//-----------------------------
+std::string a("alpha");
+std::string b("omega");
+std::swap(a,b);
+
+//-----------------------------
+// The ability to exchange more than two variables at once is not
+// built into the C++ language or C++ standard libraries. However, you
+// can use the boost tuple library to accomplish this.
+#include <boost/tuple/tuple.hpp>
+
+boost::tie(alpha,beta,production)
+ = boost::make_tuple("January", "March", "August");
+// move beta to alpha,
+// move production to beta,
+// move alpha to production
+boost::tie(alpha, beta, production)
+ = boost::make_tuple(beta, production, alpha);
+//-----------------------------
+
+
+// @@PLEAC@@_1.4
+//-----------------------------
+// There are several ways to convert between characters
+// and integers. The examples assume the following declarations:
+char ch;
+int num;
+
+//-----------------------------
+// Using implicit conversion
+num = ch;
+ch = num;
+
+//-----------------------------
+// New-style C++ casts
+ch = static_cast<char>(num);
+num = static_cast<int>(ch);
+
+//-----------------------------
+// Old-style C casts
+ch = (char)num;
+num = (int)ch;
+
+//-----------------------------
+// Using the C++ stringstream class
+#include <sstream> // On some older compilers, use <strstream>
+std::stringstream a; // On some older compilers, use std::strstream
+
+a << ch; // Append character to a string
+a >> num; // Output character as a number
+
+a << num; // Append number to a string
+a >> ch; // Output number as a character
+
+//-----------------------------
+// Using sprintf, printf
+char str[2]; // Has to be length 2 to have room for NULL character
+sprintf(str, "%c", num);
+printf("Number %d is character %c\n", num, num);
+
+//-----------------------------
+int ascii_value = 'e'; // now 101
+char character = 101; // now 'e'
+
+//-----------------------------
+printf("Number %d is character %c\n", 101, 101);
+
+//-----------------------------
+// Convert from HAL to IBM, character by character
+#include <string>
+#include <iostream>
+
+std::string ibm, hal = "HAL";
+for (unsigned int i=0; i<hal.size(); ++i)
+ ibm += hal[i]+1; // Add one to each ascii value
+std::cout << ibm << std::endl; // prints "IBM"
+
+//-----------------------------
+// Convert hal from HAL to IBM
+#include <string>
+#include <iostream>
+#include <functional> // For bind1st and plus<>
+#include <algorithm> // For transform
+
+std::string hal = "HAL";
+transform(hal.begin(), hal.end(), hal.begin(),
+ bind1st(plus<char>(),1));
+std::cout << hal << std::endl; // prints "IBM"
+//-----------------------------
+
+
+// @@PLEAC@@_1.5
+//-----------------------------
+// Since C++ strings can be accessed one character at a time,
+// there's no need to do any processing on the string to convert
+// it into an array of characters.
+#include <string>
+std::string s;
+
+// Accessing characters using for loop and integer offsets
+for (unsigned int i=0; i<s.size(); ++i) {
+ // do something with s[i]
+}
+
+// Accessing characters using iterators
+for (std::string::iterator i=s.begin(); i!=s.end(); ++i) {
+ // do something with *i
+}
+
+//-----------------------------
+std::string str = "an apple a day";
+std::map<char,int> seen;
+
+for (std::string::iterator i=str.begin(); i!=str.end(); ++i)
+ seen[*i]++;
+
+std::cout << "unique chars are: ";
+for (std::map<char,int>::iterator i=seen.begin(); i!=seen.end(); ++i)
+ std::cout << i->first;
+std::cout << std::endl;
+// unique chars are: adelnpy
+
+//-----------------------------
+int sum = 0;
+for (std::string::iterator i=str.begin(); i!=str.end(); ++i)
+ sum += *i;
+std::cout << "sum is " << sum << std::endl;
+// prints "sum is 1248" if str was "an appla a day"
+
+
+//-----------------------------
+// MISSING: sysv-like checksum program
+
+//-----------------------------
+// slowcat, emulate a slow line printer
+#include <sys/time.h>
+#include <iostream>
+#include <fstream>
+
+int main(int argc, char *argv[]) {
+ timeval delay = { 0, 50000 }; // Delay in { seconds, nanoseconds }
+ char **arg = argv+1;
+ while (*arg) { // For each file
+ std::ifstream file(*arg++);
+ char c;
+ while (file.get(c)) {
+ std::cout.put(c);
+ std::cout.flush();
+ select(0, 0, 0, 0, &delay);
+ }
+ }
+}
+//-----------------------------
+
+
+// @@PLEAC@@_1.6
+//-----------------------------
+#include <string>
+#include <algorithm> // For reverse
+std::string s;
+
+reverse(s.begin(), s.end());
+
+//-----------------------------
+#include <vector> // For std::vector
+#include <sstream> // On older compilers, use <strstream>
+#include "boost/regex.hpp" // For boost::regex_split
+
+std::string str;
+std::vector<std::string> words;
+boost::regex_split(std::back_inserter(words), str);
+reverse(words.begin(), words.end()); // Reverse the order of the words
+
+std::stringstream revwords; // On older compilers, use strstream
+copy(words.begin(), words.end(), ostream_inserter<string>(revwords," ");
+std::cout << revwards.str() << std::endl;
+
+//-----------------------------
+std::string rts = str;
+reverse(rts.begin(), rts.end()); // Reverses letters in rts
+
+//-----------------------------
+std::vector<string> words;
+reverse(words.begin(), words.end()); // Reverses words in container
+
+//-----------------------------
+// Reverse word order
+std::string s = "Yoda said, 'can you see this?'";
+
+std::vector<std::string> allwords;
+boost::regex_split(std::back_inserter(allwords), s);
+
+reverse(allwords.begin(), allwords.end());
+
+std::stringstream revwords; // On older compilers, use strstream
+copy(allwords.begin(), allwords.end(), ostream_inserter<string>(revwords," "));
+std::cout << revwards.str() << std::endl;
+// this?' see you 'can said, Yoda
+
+//-----------------------------
+std::string word = "reviver";
+bool is_palindrome = equal(word.begin(), word.end(), word.rbegin());
+
+//-----------------------------
+#include <ifstream>
+
+std::ifstream dict("/usr/dict/words");
+std::string word;
+while(getline(dict,word)) {
+ if (equal(word.begin(), word.end(), word.rbegin()) &&
+ word.size() > 5)
+ std::cout << word << std::endl;
+}
+//-----------------------------
+
+
+// @@PLEAC@@_1.7
+//-----------------------------
+#include <string>
+
+std::string::size_type pos;
+while ((pos = str.find("\t")) != std::string::npos)
+ str.replace(pos, 1, string(' ',8-pos%8));
+//-----------------------------
+
+
+// @@PLEAC@@_1.8
+//-----------------------------
+// Not applicable to C++
+//-----------------------------
+
+
+// @@PLEAC@@_1.9
+//-----------------------------
+// TODO: Fix to be more like cookbook
+// TODO: Modify/add code to do this with locales
+#include <string>
+#include <algorithm>
+
+std::string phrase = "bo peep";
+transform(phrase.begin(), phrase.end(), phrase.begin(), toupper);
+// "BO PEEP"
+transform(phrase.begin(), phrase.end(), phrase.begin(), tolower);
+// "bo peep"
+//-----------------------------
+
+
+// @@PLEAC@@_1.10
+//-----------------------------
+// C++ does not provide support for perl-like in-string interpolation,
+// concatenation must be used instead.
+
+#include <string>
+
+std::string var1, var2;
+std::string answer = var1 + func() + var2; // func returns string or char *
+
+//-----------------------------
+#include "boost/lexical_cast.hpp"
+
+int n = 4;
+std::string phrase = "I have " + boost::lexical_cast<string>(n+1) + " guanacos.";
+
+//-----------------------------
+std::cout << "I have " + boost::lexical_cast<string>(n+1) + " guanacos." << std::endl;
+
+
+// @@PLEAC@@_1.11
+//-----------------------------
+// C++ does not have "here documents".
+// TODO: Lots more.
+#include <string>
+#include "boost/regex.hpp"
+
+std::string var = "
+ your text
+ goes here.
+";
+
+boost::regex ex("^\\s+");
+var = boost::regex_merge(var, ex, ""); \ No newline at end of file