/**
* trigraph.cc - ISO Trigraph Converter.
* 
* Author: Satoru SATOH <ss&#64;gnome.gr.jp>
* License: Public Domain
* Usage:
*   $ g++ -Wall -g -O2 -I/usr/include/boost -lboost_regex trigraph.cc -o trigraph
*   $ ./trigraph trigraph.cc
*
* Note: I wrote this just to learn how to use boost::regex*. There are many
* other much-easier way to do the same thing. For exmaple, you can simply
* trigraph foo.txt like this,
*
*  bash-3.1$ cat foo.txt | sed -e "
*  s/\#/??=/g
*  s,\\\,??\/,g
*  s/\\^/??\'/g
*  s/\\[/??\(/g
*  s/\\]/??\)/g
*  s/|/??\!/g
*  s/{/??</g
*  s/}/??>/g
*  s/~/??-/g
*  "
* 
* @see ISO Trigraph [http://en.wikipedia.org/wiki/C_trigraph]:
*/

#include <iostream>
#include <fstream>
#include <string>
#include <boost/regex.hpp>	// boost::regex, boost::regex_replace

int
main (int argc, char * argv[]) {
  if (argc < 2) {
    std::cerr << "Usage: " << argv[0] << " FILE" << std::endl;
    return 1;
  }

  std::ifstream ifs(argv[1]);
  if (! ifs.is_open()) {
    std::cerr << "Could not open: " << argv[1] << std::endl;
    return -1;
  }

  try {
    std::string si, so;
    const boost::regex reg("(#)|(\\\\)|(\\^)|(\\[)|(\\])|(\\|)|(\\{)|(\\})|(~)");
    const std::string trigraph("\?\?(?1=)(?2/)(?3')(?4\\()(?5\\))(?6!)(?7<)(?8>)(?9-)");

    while (! ifs.eof()) {
      getline(ifs, si);
      so = boost::regex_replace(si, reg, trigraph, boost::format_all);
      std::cout << so << std::endl;
    }
  } catch (...) {
    return -1;
  }
  return 0;
}

// EOF

