C. Construct a simple configuration file reading library and a configuration file reading library.

Source: Internet
Author: User
Tags php definition

C. Construct a simple configuration file reading library and a configuration file reading library.

Preface

I recently saw this article,

Json engine performance comparison report http://www.oschina.net/news/61942/cpp-json-compare? Utm_source = tuicool

I feel that there are a lot of technical difficulties and a lot of mountains are revealed.

Json standard definition http://www.json.org/json-zh.html

I have written a general json parser. The comparison between lines 1000 and the above is really weak. Later I saw a few of the source code blowing out of it. I feel deeply touched upon it.

I am not enough. I have been researching some downloads and found that using and designing and developing are two different things.

The main foundation of json design is in the structure design and Syntax Parsing. The encapsulation of a framework lies in the routines. If the routines are clear, the design can be combined.

Together. No matter what you do, it will always be optimized as long as you learn it. Below we will share a relatively simple article, but we will also configure the C framework in terms of structure design and Syntax Parsing.

Read capability.

 

Body

1. parsing file description

  The following figure shows the configuration file: test. php

<? php

// Here is a simple test php variable resolution

$ abc = "123456";

$ str = "1231212121212121212
21222222222
2121212 \ "
";
We only need to parse the above data, save it in the global area and call it next time. For example

The running result is as above. For the above configuration, there are the following rules

a. $ followed by the variable name

b. Use in the middle = split

c. Variable contents are wrapped with "", need to use "Use \"

The above is the configuration grammar rules. Below we gradually explain the content of grammar analysis

 

2. Simple core code, grammar analysis test

 The specific scanning algorithm is as follows

a. Skip the leading blank character and find the $ character

b. If $ is followed by a blank character, then read this line directly

c. Scan to = character, otherwise read this line

d Scan to "character

e Scan to the last "character, the previous character must not be \, otherwise the reading of this line is completed.

The above is the algorithm idea for processing, which is easier to understand. The specific test code is as follows

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>


#define _STR_PATH "test.php"

/ *
 * Process the file content here and output the parsed file content
 * /
int main (int argc, char * argv [])
{
    int c, n;
    char str [1024];
    int idx;
    FILE * txt = fopen (_STR_PATH, "rb");
    if (NULL == txt) {
        puts ("fopen is error!");
        exit (EXIT_FAILURE);
    }

    // Handle the reading problem here
    while ((c = fgetc (txt))! = EOF) {
        //1.0 Skip white space characters first
        while (c! = EOF && isspace (c))
            c = fgetc (txt);
        //2.0 if the first character encountered is not '$'
        if (c! = '$') {// Read this line
            while (c! = EOF && c! = '\ n')
                c = fgetc (txt);
            continue;
        }
        //2.1 The first character is a $ legal character, the beginning cannot be a space, otherwise it is also read
        if ((c = fgetc (txt))! = EOF && isspace (c)) {
            while (c! = EOF && c! = '\ n')
                c = fgetc (txt);
            continue;
        }
        // Start recording
        idx = 0;

        //3.0 find the first equal sign
        while (c! = EOF && c! = '=')
            str [idx ++] = c, c = fgetc (txt);
        if (c! = '=') // Invalid analysis ends directly
            break;


        //4.0 find the first "
        while (c! = EOF && c! = '\ "')
            str [idx ++] = c, c = fgetc (txt);
        if (c! = '\ "') // Invalid analysis ends directly
            break;

        //4.1 Find the second equal sign
        do {
            n = str [idx ++] = c;
            c = fgetc (txt);
        } while (c! = EOF && c! = '\ "' && n! = '\\');
        if (c! = '\ "') // Invalid analysis ends directly
            break;

        str [idx] = '\ 0';
        puts (str);

        // Last read to the end of the line
        while (c! = EOF && c! = '\ n')
            c = fgetc (txt);
        if (c! = '\ n')
            break;
    }

    fclose (txt);

    system ("pause");
    return 0;
}
The output of the above code is the above. The algorithm is straightforward and easy to understand. Writing a small function here is still very fulfilling. Especially looking at those famous open source code libraries, it is particularly cool.

The above code can be practiced by yourself, it is very interesting, there is no difficulty here. The code will be optimized from the previous framework.

 

3. The finalized interface description

Here we will apply the above ideas to actual combat, first look at the contents of the scconf.h interface as follows

#ifndef _H_SCCONF
#define _H_SCCONF

/ **
 * Here is the configuration file reading interface,
 * Write configuration, read configuration, need to point to the start of the configuration path _STR_SCPATH
 * /
#define _STR_SCCONF_PATH "module / schead / config / config.ini"

/ *
 * Start the configuration reading function, or restart
 * /
extern void sc_start (void);

/ *
 * Get the value of the corresponding key configuration, through the key
 * key: name in configuration
 *: Return the corresponding key value, if not return NULL, and print the log
 * /
extern const char * sc_get (const char * key);

#endif //! _H_SCCONF
There are only two interfaces. Enable this configuration to read the library and get the content of the specified key. The file directory structure is as follows

The above interface is also very simple to use

sc_start ();
puts (sc_get ("heoo"));
The config.ini configuration content is as follows

/ *
 * This is equivalent to the form of php definition variable, definition
 * The configuration file can be read later. Sc_get ("heoo") => "Hello!"
 * /

$ heoo = "Hello World \ n";

$ yexu = "\" How are you \ ",
I am fine, thanks!";

$ end = "coding future 123 runing,";
The specific implementation content is directly introduced later.

 

4. Specific implementation in the current development library

 First look at the code implemented by scconf.c

#include <scconf.h>
#include <scatom.h>
#include <tree.h>
#include <tstring.h>
#include <sclog.h>

// Simple binary tree structure
struct dict {
    _TREE_HEAD;
    char * key;
    char * value;
};

// Function creation function, kv is a structure like [abc \ 012345]
static void * __dict_new (tstring tstr)
{
    char * ptr; // Temporary variables
    struct dict * nd = malloc (sizeof (struct dict) + sizeof (char) * (tstr-> len + 1));
    if (NULL == nd) {
        SL_NOTICE ("malloc struct dict is error!");
        exit (EXIT_FAILURE);
    }

    nd-> __ tn.lc = NULL;
    nd-> __ tn.rc = NULL;
    // Read more books, the rest is sad, 1%, not me,
    nd-> key = ptr = (char *) nd + sizeof (struct dict);
    memcpy (ptr, tstr-> str, tstr-> len + 1);
    while (* ptr ++)
        ;
    nd-> value = ptr;

    return nd;
}

// Start adding
static inline int __dict_acmp (tstring tstr, struct dict * rnode)
{
    return strcmp (tstr-> str, rnode-> key);
}
// Find and delete
static inline int __dict_gdcmp (const char * lstr, struct dict * rnode)
{
    return strcmp (lstr, rnode-> key);
}

// Delete method
static inline void __dict_del (void * arg)
{
    free (arg);
}

// The foreplay is too long, it's not over yet.
static tree_t __tds; // Save dictionary The default value is NULL
// The default __tds destruction function
static inline void __tds_destroy (void)
{
    tree_destroy (& __ tds);
}

static int __lock; // For locking, the default value is 0

static void __analysis_start (FILE * txt, tree_t * proot)
{
    char c, n;
    TSTRING_CREATE (tstr);

    // Handle the reading problem here
    while ((c = fgetc (txt))! = EOF) {
        //1.0 Skip white space characters first
        while (c! = EOF && isspace (c))
            c = fgetc (txt);
        //2.0 if the first character encountered is not '$'
        if (c! = '$') {// Read this line
            while (c! = EOF && c! = '\ n')
                c = fgetc (txt);
            continue;
        }
        //2.1 The first character is a $ legal character, the beginning cannot be a space, otherwise it is also read
        if ((c = fgetc (txt))! = EOF && isspace (c)) {
            while (c! = EOF && c! = '\ n')
                c = fgetc (txt);
            continue;
        }
        // Start recording
        tstr.len = 0;

        //3.0 find the first equal sign
        while (c! = EOF && c! = '=') {
            if (! isspace (c))
                tstring_append (& tstr, c);
            c = fgetc (txt);
        }
        if (c! = '=') // Invalid analysis ends directly break;

        c = '\ 0';
        //4.0 find the first "
        while (c! = EOF && c! = '\ "') {
            if (! isspace (c))
                tstring_append (& tstr, c);
            c = fgetc (txt);
        }
        if (c! = '\ "') // Invalid analysis ends directly
            break;

        //4.1 Find the second equal sign
        for (n = c; (c = fgetc (txt))! = EOF; n = c) {
            if (c == '\ "' && n! = '\\')
                break;
            tstring_append (& tstr, c);
        }
        if (c! = '\ "') // Invalid analysis ends directly
            break;

        // This is the legal character, and the detection is started,
        tree_add (proot, & tstr);

        // Last read to the end of the line
        while (c! = EOF && c! = '\ n')
            c = fgetc (txt);
        if (c! = '\ n')
            break;
    }

    TSTRING_DESTROY (tstr);
}

/ *
* Start the configuration reading function, or restart
* /
void
sc_start (void)
{
    FILE * txt = fopen (_STR_SCCONF_PATH, "r");
    if (NULL == txt) {
        SL_NOTICE ("fopen" _STR_SCCONF_PATH "r is error!");
        return;
    }

    ATOM_LOCK (__ lock);
    // First release this __tds, this __tds memory is the same as the program cycle
    __tds_destroy ();
    // This underlying library, the lack of memory is directly exited
    __tds = tree_create (__ dict_new, __dict_acmp, __dict_gdcmp, __dict_del);

    // The following is the analysis and reading content
    __analysis_start (txt, & __ tds);

    ATOM_UNLOCK (__ lock);

    fclose (txt);
}

/ *
* Get the value of the corresponding key configuration, through the key
* key: name in configuration
*: Return the corresponding key value, if not return NULL, and print the log
* /
inline const char *
sc_get (const char * key)
{
    struct dict * kv;
    if ((! key) || (! * key) ||! (kv = tree_get (__ tds, key, NULL)))
        return NULL;

    return kv-> value;
}
The data structure uses the general tree.h binary search tree structure. The lock uses the scatom.h atomic lock, and the storage content uses tstring.h string memory management

Grammatical analysis is to parse characters according to the above reading ideas

static void __analysis_start (FILE * txt, tree_t * proot);
The data structure is

// Simple binary tree structure
struct dict {
    _TREE_HEAD;
    char * key;
    char * value;
};
Simple binary tree structure with key.

 

5. Use display

Let's test the above library, first test the code as follows test_scconf.c

#include <schead.h>
#include <scconf.h>

// After writing, what can I do, alone
int main (int argc, char * argv [])
{
    const char * value;
    sc_start ();

    // Simple test configuration read content
    value = sc_get ("heoo");
    puts (value);

    value = sc_get ("heoo2");
    if (value)
        puts (value);
    else
        puts ("heoo2 does not exist");

    value = sc_get ("yexu");
    puts (value);

    value = sc_get ("end");
    puts (value);

    system ("pause");
    return 0;
}
The results are as follows


For the configuration, see the config.ini above. Here we have completed the simple configuration file function. I want to rip a bit. I have used more languages or libraries. I still feel that the advanced VS + .Net library development is the best.

Building blocks is the most enjoyable, all functions are used, and the code design is also very beautiful. The only pity is that the speed is a bit slow and a little bloated. Personally feel that the development of C # library is the top bluff of the window C ++, C # is not promoted

Going out and dying of the C ++ programmers on the window, all moved to the ranks of Linux C / C ++ development. What is more interesting is that C # is not red because of Microsoft's dad, but because of the father of Unity 3D.

C # + VS is really beautiful to write, but if you do n’t need VS, let me say it another way. The test of a window programmer is to let him leave vs. whether it starts to be so ecstatic.

It is recommended to learn more as a programmer, because they are all languages, and it is convenient to communicate after learning more. What do you think?

 

Afterword

       Mistakes are inevitable, corrections are welcome, as I grow older, I feel that I am still very watery. I need to learn a lot of things, and I also need to abandon many things. For the unknown,

It's a record of all the chaos. Looking at the source code of the open source project is still very cool. Next time I have the opportunity to share the handwriting and an efficient cjson engine.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.