00001
00002 #include "idep_filedepiter.h"
00003
00004 #include <ctype.h>
00005 #include <cstring>
00006 #include <memory>
00007 #include <iostream>
00008 #include <fstream>
00009 #include <cassert>
00010
00011
00012
00013 enum { MAX_LINE_LENGTH = 2048 };
00014
00015
00016
00017
00018 static int loadBuf(std::istream& in, char *buf, int bufSize)
00019 {
00020 enum { END_OF_INPUT = -1, SUCCESS = 0, OVERFLOWN = 1 };
00021
00022
00023
00024
00025
00026
00027
00028 int nearEnd = bufSize - 1;
00029
00030 buf[nearEnd] = '\n';
00031
00032 if (in.getline(buf, bufSize).fail()) {
00033 return END_OF_INPUT;
00034 }
00035
00036 if ('\0' == buf[nearEnd]) {
00037 char c;
00038 while (in && !in.get(c).eof() && c != '\n') {
00039
00040 }
00041 return OVERFLOWN;
00042 }
00043
00044 return SUCCESS;
00045 }
00046
00047 const char *extractDependency(char *buffer)
00048 {
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 if ('#' != buffer[0]) {
00068 return 0;
00069 }
00070
00071 char *p = buffer;
00072 while (isspace(*++p)) {
00073 }
00074
00075 if ('i' != *p) {
00076 return 0;
00077 }
00078
00079 static char KEY[] = "include";
00080 if (0 != strncmp(p, "include", sizeof KEY - 1)) {
00081 return 0;
00082 }
00083 p += sizeof KEY - 1;
00084
00085 while (isspace(*p)) {
00086 ++p;
00087 }
00088
00089 if ('<' != *p && '"' != *p) {
00090 return 0;
00091 }
00092 ++p;
00093
00094 while (isspace(*p)) {
00095 ++p;
00096 }
00097
00098
00099
00100
00101 int length = strcspn(p, " \t\">");
00102 p[length] = 0;
00103
00104 return p;
00105 }
00106
00107
00108
00109 struct idep_FileDepIter_i {
00110 std::ifstream d_file;
00111 char d_buf[MAX_LINE_LENGTH];
00112 const char *d_header_p;
00113 int d_isValidFile;
00114
00115 idep_FileDepIter_i(const char *fileName);
00116 };
00117
00118 idep_FileDepIter_i::idep_FileDepIter_i(const char *fileName)
00119 : d_file(fileName)
00120 , d_header_p(d_buf)
00121 {
00122 d_isValidFile = !!d_file;
00123 }
00124
00125
00126
00127 idep_FileDepIter::idep_FileDepIter(const char *fileName)
00128 : d_this(new idep_FileDepIter_i(fileName))
00129 {
00130 if (!isValidFile()) {
00131 d_this->d_header_p = 0;
00132 }
00133 ++*this;
00134 }
00135
00136 idep_FileDepIter::~idep_FileDepIter()
00137 {
00138 delete d_this;
00139 }
00140
00141 void idep_FileDepIter::reset()
00142 {
00143 if (isValidFile()) {
00144 d_this->d_file.seekg(std::ios::beg);
00145 d_this->d_file.clear(d_this->d_file.rdstate() & std::ios::badbit);
00146 d_this->d_header_p = d_this->d_buf;
00147 }
00148 ++*this;
00149 }
00150
00151 void idep_FileDepIter::operator++()
00152 {
00153 d_this->d_header_p = 0;
00154 while (loadBuf(d_this->d_file, d_this->d_buf, sizeof d_this->d_buf) >= 0) {
00155 if ((d_this->d_header_p = extractDependency(d_this->d_buf))) {
00156 break;
00157 }
00158 };
00159 }
00160
00161 int idep_FileDepIter::isValidFile() const
00162 {
00163 return d_this->d_isValidFile;
00164 }
00165
00166 idep_FileDepIter::operator const void *() const
00167 {
00168 return d_this->d_header_p ? this : 0;
00169 }
00170
00171 const char *idep_FileDepIter::operator ()() const
00172 {
00173 return d_this->d_header_p;
00174 }