Parsing “lines”

00001: #define BUFFER_SIZE 1<<16
00002: #define ARR_SIZE 1<<16
00003: 
00004: void parse_args(char *buffer, char** args, 
00005:                 size_t args_size, size_t *nargs)
00006: {
00007:     char *buf_args[args_size]; /* You need C99 */
00008:     char **cp;
00009:     char *wbuf;
00010:     size_t i, j;
00011:     
00012:     wbuf=buffer;
00013:     buf_args[0]=buffer; 
00014:     args[0] =buffer;
00015:     
00016:     for(cp=buf_args; (*cp=strsep(&wbuf, " \n\t")) != NULL ;){
00017:         if ((*cp != '') && (++cp >= &buf_args[args_size]))
00018:             break;
00019:     }
00020:     
00021:     for (j=i=0; buf_args[i]!=NULL; i++){
00022:         if(strlen(buf_args[i])>0)
00023:             args[j++]=buf_args[i];
00024:     }
00025:     
00026:     *nargs=j;
00027:     args[j]=NULL;
00028: }

To understand how it works, I suggest to take a look at the man page of strsep. As you can see this is a lot of code to perform a very simple task.
Compare with

        argv = cmd.split()

The C++ version is a bit longer (because I split some lines) than the C version, but there is less “magic”. In fact if you read the code it is very easy to understand how it works. Moreovere there is no hassle with memory allocation.

00001: #include <iostream>
00002: #include <string>
00003: #include <vector>
00004: #include <algorithm>
00005: #include <iterator>
00006: #include <cstdlib>
00007: #include <cerrno>
00008: #include <exception>
00009: #include <unistd.h>
00010: 
00011: using std::string;
00012: 
00013: void 
00014: split_string(const std::string s, 
00015:              const std::string sep, 
00016:              std::vector<std::string> &components)
00017: {
00018:     typedef std::pair<size_t, size_t> Range;
00019:     size_t pos, old_pos;
00020:     Range trange;
00021:     std::vector<Range> ranges;
00022:     trange.first = 0;
00023:     trange.second = s.find(sep, trange.first);
00024:     if (trange.second == string::npos){
00025:         trange.second = s.length();
00026:     }        
00027:     ranges.push_back(trange);
00028:     while(trange.second < s.length()){
00029:         trange.first = trange.second + 1;
00030:         trange.second = s.find(sep, trange.first);
00031:         if (trange.second == string::npos){
00032:             trange.second = s.length();
00033:         }
00034:         ranges.push_back(trange);
00035:     }
00036:     
00037:     for (int i = 0; i < ranges.size() ; ++i){
00038:        components.push_back(s.substr(ranges[i].first, 
00039:                 ranges[i].second - ranges[i].first) );
00040:     }
00041: }
00042: 
00043: class InvalidCommandLine : public std::exception {
00044: 
00045: };
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: