Читаем Thinking In C++. Volume 2: Practical Programming полностью

      << part[INCLUDE] << endl;

  } else { // Already exists; verify it

    stringstream cppfile;

    ostringstream newcpp;

    cppfile << existcpp.rdbuf();

    // Check that first two lines conform:

    bool changed = false;

    string s;

    cppfile.seekg(0);

    getline(cppfile, s);

    bool lineUsed = false;

    for (int line = CPPLINE1;

         cppfile.good() && line <= INCLUDE;

         ++line) {

      if(startsWith(s, part[line])) {

        newcpp << s << endl;

        lineUsed = true;

        if (getline(cppfile, s))

          lineUsed = false;

      } else {

        newcpp << part[line] << endl;

        changed = true;

        lineUsed = false;

      }

    }

    // Copy rest of file

    if (!lineUsed)

      newcpp << s << endl;

    newcpp << cppfile.rdbuf();

    // If there were changes, overwrite file:

    if(changed){

      existcpp.close();

      ofstream newCPP(part[IMPLEMENT].c_str());

      assure(newCPP, part[IMPLEMENT].c_str());

      newCPP << "//@//\n"  // Change marker

        << newcpp.str();

    }

  }

}

int main(int argc, char* argv[]) {

  if(argc > 1)

    cppCheck(argv[1]);

  else

    cppCheck("cppCheckTest.h");

} ///:~

First notice the useful function startsWith( ), which does just what its name says—it returns true if the first string argument starts with the second argument. This is used when looking for the expected comments and include-related statements. Having the array of strings, part, allows for easy looping through the series of expected statements in source code. If the source file doesn’t exist, we merely write the statements to a new file of the given name. If the file does exist, we search a line at a time, verifying that the expected lines occur. If they are not present, they are inserted. Special care has to be taken to make sure we don’t drop existing lines (see where we use the Boolean variable lineUsed). Notice that we use a stringstream for an existing file, so we can first write the contents of the file to it and then read from it and search it.

The names in the enumeration are BASE, the capitalized base file name without extension; HEADER, the header file name; IMPLEMENT, the implementation file (cpp) name; HLINE1, the skeleton first line of the header file; GUARD1, GUARD2, and GUARD3, the "guard" lines in the header file (to prevent multiple inclusion); CPPLINE1, the skeleton first line of the cpp file; and INCLUDE, the line in the cpp file that includes the header file.

If you run this program without any arguments, the following two files are created:

// CPPCHECKTEST.h

#ifndef CPPCHECKTEST_H

#define CPPCHECKTEST_H

#endif // CPPCHECKTEST_H

// CPPCHECKTEST.cpp

#include "CPPCHECKTEST.h"

(We removed the colon after the double-slash in the first comment lines so as not to confuse the book’s code extractor. It will appear in the actual output produced by cppCheck.)

You can experiment by removing selected lines from these files and re-running the program. Each time you will see that the correct lines are added back in. When a file is modified, the string "//@//" is placed as the first line of the file to bring the change to your attention. You will need to remove this line before you process the file again (otherwise cppcheck will assume the initial comment line is missing).

<p>Detecting compiler errors</p>

All the code in this book is designed to compile as shown without errors. Any line of code that should generate a compile-time error is commented out with the special comment sequence "//!". The following program will remove these special comments and append a numbered comment to the line. When you run your compiler, it should generate error messages, and you will see all the numbers appear when you compile all the files. This program also appends the modified line to a special file so that you can easily locate any lines that don’t generate errors.

//: C04:Showerr.cpp

// Un-comment error generators

#include

#include

#include

#include

#include

#include

#include

#include "../require.h"

using namespace std;

const string usage =

  "usage: showerr filename chapnum\n"

  "where filename is a C++ source file\n"

  "and chapnum is the chapter name it's in.\n"

  "Finds lines commented with //! and removes\n"

  "comment, appending //(#) where # is unique\n"

  "across all files, so you can determine\n"

  "if your compiler finds the error.\n"

  "showerr /r\n"

  "resets the unique counter.";

class Showerr {

  const int CHAP;

  const string MARKER, FNAME;

  // File containing error number counter:

  const string ERRNUM;

  // File containing error lines:

  const string ERRFILE;

  stringstream edited; // Edited file

  int counter;

public:

  Showerr(const string& f, const string& en,

    const string& ef, int c) : FNAME(f), MARKER("//!"),

    ERRNUM(en), ERRFILE(ef), CHAP(c) { counter = 0; }

  void replaceErrors() {

    ifstream infile(FNAME.c_str());

    assure(infile, FNAME.c_str());

    ifstream count(ERRNUM.c_str());

    if(count) count >> counter;

    int linecount = 1;

    string buf;

    ofstream errlines(ERRFILE.c_str(), ios::app);

    assure(errlines, ERRFILE.c_str());

    while(getline(infile, buf)) {

      // Find marker at start of line:

      size_t pos = buf.find(MARKER);

      if(pos != string::npos) {

        // Erase marker:

        buf.erase(pos, MARKER.size() + 1);

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных