Share a C + + written to imitate awk framework class cawkdoc

Time:2021-6-13

I wrote this many years ago, imitating awk.
We are all familiar with awk, using awk to process files, read files, split fields these work, awk help you achieve.
Programmers only need to write business logic code, and awk also provides many commonly used string operation functions, which can be easily called, so it is very convenient to use.
But awk script is not suitable for developing complex logic after all, and the library functions it provides are also limited. Unlike C + +, there are many third-party libraries that can be called.
So I thought of writing a framework class to realize the basic functions of reading files by line and dividing fields, leaving only the business logic for developers to freely implement


The policy mode is used here. The programmer encapsulates the business logic into a policy class (realizing iawkonedualititr interface) and passes it to cawkdoc to enjoy the file reading function provided by cawkdoc.
At first, I thought about using the template method, but I was worried that the programmers who inherited cawkdoc would cover its implementation, so I thought the strategy method was better.


This is a small tool I used to implement with cawkdoc: code generator( https://github.com/kingstarer/kingstarer/tree/master/c%2B%2B/feepacker )
At that time, this tool reduced a lot of workload for the project team, and my colleagues liked it at that time.
It’s a pity that the project has been cold for a long time, otherwise this tool might still be in use:)
Although the tool has not been used for a long time, I still like the idea of this code generator (code template replacement). Some time ago, I started a java project and wrote a curd code generator. I still applied this method and used the idea of code template.


Share the main code of cawkdoc

AwkBase.h

#pragma once
#include "AwkFunc.h"

class CAwkDoc;
class IAwkOneDualItr
{
public:
    virtual int dualBegin(CAwkDoc &Doc) = 0;
    //Return 0 means normal, continue to process the next one, return 1 means exit text processing directly to the end stage, return - 1 means error processing, exit directly  
    virtual int dualOneLine(CAwkDoc &Doc) = 0;
    virtual int dualEnd(CAwkDoc &Doc) = 0;
};

class CAwkOneDualItrBase:public IAwkOneDualItr
{
public:
    virtual int dualBegin(CAwkDoc& Doc)
    {
        return 0;
    }

    virtual int dualEnd(CAwkDoc& Doc)
    {
        return 0;
    }
};

class CAwkDoc
{
public:
    typedef map AwkMapType;
    typedef vector AwkVecType;

public:
    CAwkDoc(void);
    CAwkDoc(IAwkOneDualItr* lineopr, const string& filepath);
    virtual ~CAwkDoc(void);
    virtual bool run();

    void setFileName(const string& filepath) 
    { 
        m_filename = filepath; 
    }

    void setDelimer(const string delimer) 
    { 
        m_delimer = delimer; 
    }

    vector& Parts()
    {
        return m_vecParts;
    }

    void setStrParam(const string& paramname, const string& paramvalue);
    string& getStrParam(const string& paramname);

    AwkVecType& getVecParam(const string& paramname);
    AwkMapType& getMapParam(const string& paramname);

public:

    int m_nf;
    int m_nr;
    string m_filename;
    string m_line;
    string m_delimer;
    vector m_vecParts;


    map m_strParams;
    map< string, AwkMapType > m_mpParams;
    map< string, AwkVecType > m_vecParams;

public:

    IAwkOneDualItr *m_lineopr;
};

AwkBase.cpp

#include "stdafx.h"
#include "AwkBase.h"

CAwkDoc::CAwkDoc(void)
{
    m_delimer = " ";
    m_nf = m_nr = 0;
    m_lineopr = NULL;
}

CAwkDoc::CAwkDoc(IAwkOneDualItr* lineopr, const string& filepath):
m_lineopr(lineopr), m_filename(filepath)
{
    m_nf = m_nr = 0; 
    m_delimer = " ";
}

CAwkDoc::~CAwkDoc(void)
{
}


bool CAwkDoc::run()
{
    //Read file
    string inparamStr = FileToString(m_filename);


    //Separate the document into branches
    vector vecLines;
    SplitStr(inparamStr, "\n", vecLines);

    if (vecLines.size() == 0)
    {
        Cerr < "err: file (" < m_ "File name <") is empty or does not exist! "<< endl;
        return false;
    }

    assert(m_lineopr != NULL);
    m_lineopr->dualBegin(*this);

    for (size_t i = 0; i < vecLines.size(); i++)
    {
        m_line = vecLines[i];
        if (m_line == "")
        {
            continue;
        }


        //Remove extra space (to prepare for later segmentation)
        string theline = m_line;
        //constrictSpace(theline);

        m_nr++;
        m_nf = SplitStr(theline, m_delimer, m_vecParts);

        if (m_vecParts.size() < 20)
        {
            m_vecParts.resize(20);
        }

        int ret = m_lineopr->dualOneLine(*this);

        //1 is normal end - 1 is abnormal end
        if ( ret == 1 )
        {
            break;
        }
        else if ( ret == -1 )
        {
            return false;
        }
    }

    m_lineopr->dualEnd(*this);

    return true;
}

void CAwkDoc::setStrParam(const string& paramname, const string& paramvalue)
{
    m_strParams[paramname] = paramvalue;
}

string& CAwkDoc::getStrParam(const string& paramname)
{
    return m_strParams[paramname];
}