nis-util
1.0.D108
|
00001 // 00002 // nis-util - NIS Administration Utilities 00003 // Copyright (C) 2012 Peter Miller 00004 // 00005 // This program is free software; you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation; either version 2 of the License, or (at 00008 // your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License along 00016 // with this program. If not, see <http://www.gnu.org/licenses/>. 00017 // 00018 00019 #include <lib/ac/string.h> 00020 00021 #include <lib/input/remove_hash_comments.h> 00022 00023 00024 input_remove_hash_comments::~input_remove_hash_comments() 00025 { 00026 } 00027 00028 00029 input_remove_hash_comments::input_remove_hash_comments( 00030 const input::pointer &a_deeper 00031 ) : 00032 deeper(a_deeper), 00033 state(state_start_of_line) 00034 { 00035 } 00036 00037 00038 input_remove_hash_comments::pointer 00039 input_remove_hash_comments::create(const input::pointer &a_deeper) 00040 { 00041 return pointer(new input_remove_hash_comments(a_deeper)); 00042 } 00043 00044 00045 size_t 00046 input_remove_hash_comments::read_inner(source_location &data_locn, void *vdata, 00047 size_t data_size) 00048 { 00049 data_locn = deeper->get_source_location(); 00050 unsigned char *data = (unsigned char *)vdata; 00051 unsigned char *cp = data; 00052 unsigned char *end = data + data_size; 00053 while (cp < end) 00054 { 00055 int ic = deeper->get(); 00056 if (ic == input::eof) 00057 break; 00058 unsigned char c = ic; 00059 switch (state) 00060 { 00061 case state_start_of_line: 00062 switch (c) 00063 { 00064 case ' ': 00065 case '\t': 00066 whitespace.clear(); 00067 whitespace.push_back(c); 00068 state = state_white_space; 00069 break; 00070 00071 case '\n': 00072 *cp++ = '\n'; 00073 state = state_start_of_line; 00074 goto end_of_line; 00075 00076 case '#': 00077 state = state_discarding; 00078 break; 00079 00080 default: 00081 *cp++ = c; 00082 state = state_content; 00083 break; 00084 } 00085 break; 00086 00087 case state_discarding: 00088 if (c == '\n') 00089 { 00090 *cp++ = '\n'; 00091 state = state_start_of_line; 00092 goto end_of_line; 00093 } 00094 break; 00095 00096 case state_white_space: 00097 switch (c) 00098 { 00099 case ' ': 00100 case '\t': 00101 whitespace.push_back(c); 00102 state = state_white_space; 00103 break; 00104 00105 case '\n': 00106 *cp++ = '\n'; 00107 state = state_start_of_line; 00108 goto end_of_line; 00109 00110 case '#': 00111 whitespace.clear(); 00112 state = state_discarding; 00113 break; 00114 00115 default: 00116 // what if whitespace doesn't fit? 00117 // (the "or equal" is because we need room for 'c' as well) 00118 if (cp + whitespace.size() >= end) 00119 { 00120 deeper->unget(c); 00121 size_t nbytes = end - cp; 00122 assert(nbytes <= whitespace.size()); 00123 memcpy(cp, whitespace.get_data(), nbytes); 00124 cp += nbytes; 00125 whitespace.pop_front(nbytes); 00126 state = state_white_space; 00127 } 00128 else 00129 { 00130 memcpy(cp, whitespace.get_data(), whitespace.size()); 00131 cp += whitespace.size(); 00132 whitespace.clear(); 00133 *cp++ = c; 00134 state = state_content; 00135 } 00136 break; 00137 } 00138 break; 00139 00140 case state_content: 00141 switch (c) 00142 { 00143 case ' ': 00144 case '\t': 00145 whitespace.clear(); 00146 whitespace.push_back(c); 00147 state = state_white_space; 00148 break; 00149 00150 case '\n': 00151 *cp++ = c; 00152 state = state_start_of_line; 00153 goto end_of_line; 00154 00155 case '#': 00156 // Note: a@b#c does not contain the start of a comment 00157 default: 00158 *cp++ = c; 00159 state = state_content; 00160 break; 00161 } 00162 break; 00163 } 00164 } 00165 end_of_line: 00166 return (cp - data); 00167 } 00168 00169 00170 // vim: set ts=8 sw=4 et :