source: MML/trunk/applications/m2html/private/doxysearch.m @ 4

Last change on this file since 4 was 4, checked in by zhangj, 10 years ago

Initial import--MML version from SOLEIL@2013

File size: 7.5 KB
Line 
1function result = doxysearch(query,filename)
2%DOXYSEARCH Search a query in a 'search.idx' file
3%  RESULT = DOXYSEARCH(QUERY,FILENAME) looks for request QUERY
4%  in FILENAME (Doxygen search.idx format) and returns a list of
5%  files responding to the request in RESULT.
6%
7%  See also DOXYREAD, DOXYWRITE
8
9%  Copyright (C) 2004 Guillaume Flandin <Guillaume@artefact.tk>
10%  $Revision: 1.1 $Date: 2004/05/05 14:33:55 $
11
12%  This program is free software; you can redistribute it and/or
13%  modify it under the terms of the GNU General Public License
14%  as published by the Free Software Foundation; either version 2
15%  of the License, or any later version.
16%
17%  This program is distributed in the hope that it will be useful,
18%  but WITHOUT ANY WARRANTY; without even the implied warranty of
19%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20%  GNU General Public License for more details.
21%
22%  You should have received a copy of the GNU General Public License
23%  along with this program; if not, write to the Free Software
24%  Foundation Inc, 59 Temple Pl. - Suite 330, Boston, MA 02111-1307, USA.
25
26%  Suggestions for improvement and fixes are always welcome, although no
27%  guarantee is made whether and when they will be implemented.
28%  Send requests to <Guillaume@artefact.tk>
29
30%  See <http://www.doxygen.org/> for more details.
31
32error(nargchk(1,2,nargin));
33if nargin == 1,
34        filename = 'search.idx';
35end
36
37%- Open the search index file
38[fid, errmsg] = fopen(filename,'r','ieee-be');
39if fid == -1, error(errmsg); end
40
41%- 4 byte header (DOXS)
42header = char(fread(fid,4,'uchar'))';
43if ~all(header == 'DOXS')
44    error('[doxysearch] Header of index file is invalid!');
45end
46
47%- many thanks to <doxyread.m> and <doxysearch.php>
48r = query;
49requiredWords  = {};
50forbiddenWords = {};
51foundWords     = {};
52res            = {};
53while 1
54    % extract each word of the query
55    [t,r] = strtok(r);
56    if isempty(t), break, end;
57    if t(1) == '+'
58        t = t(2:end); requiredWords{end+1} = t;
59    elseif t(1) == '-'
60        t = t(2:end); forbiddenWords{end+1} = t;
61    end
62    if ~ismember(t,foundWords)
63        foundWords{end+1} = t;
64        res = searchAgain(fid,t,res);
65    end
66end
67
68%- Filter and sort results
69docs = combineResults(res);
70filtdocs = filterResults(docs,requiredWords,forbiddenWords);
71filtdocs = normalizeResults(filtdocs);
72res = sortResults(filtdocs);
73
74%-
75if nargout
76    result = res;
77else
78    for i=1:size(res,1)
79        fprintf('   %d. %s - %s\n      ',i,res{i,1},res{i,2});
80        for j=1:size(res{i,4},1)
81            fprintf('%s ',res{i,4}{j,1});
82        end
83        fprintf('\n');
84    end
85end
86
87%- Close the search index file
88fclose(fid);
89
90%===========================================================================
91function res = searchAgain(fid, word,res)
92
93        i = computeIndex(word);
94        if i > 0
95       
96        fseek(fid,i*4+4,'bof'); % 4 bytes per entry, skip header
97        start = size(res,1);
98        idx = readInt(fid);
99       
100        if idx > 0
101           
102            fseek(fid,idx,'bof');
103            statw = readString(fid);
104                    while ~isempty(statw)
105                            statidx  = readInt(fid);
106                if length(statw) >= length(word) & ...
107                    strcmp(statw(1:length(word)),word)
108                                res{end+1,1} = statw;   % word
109                    res{end,2}   = word;    % match
110                                res{end,3}   = statidx; % index
111                    res{end,4}   = (length(statw) == length(word)); % full
112                    res{end,5}   = {};      % doc
113                end
114                            statw = readString(fid);
115                end
116       
117            totalfreq = 0;
118            for j=start+1:size(res,1)
119                fseek(fid,res{j,3},'bof');
120                numdoc = readInt(fid);
121                docinfo = {};
122                for m=1:numdoc
123                                docinfo{m,1} = readInt(fid); % idx
124                                docinfo{m,2} = readInt(fid); % freq
125                    docinfo{m,3} = 0;            % rank
126                    totalfreq = totalfreq + docinfo{m,2};
127                    if res{j,2},
128                        totalfreq = totalfreq + docinfo{m,2};
129                    end;
130                        end
131                        for m=1:numdoc
132                                fseek(fid, docinfo{m,1}, 'bof');
133                                docinfo{m,4} = readString(fid); % name
134                                docinfo{m,5} = readString(fid); % url
135                        end
136                res{j,5} = docinfo;
137            end
138       
139            for j=start+1:size(res,1)
140                for m=1:size(res{j,5},1)
141                    res{j,5}{m,3} = res{j,5}{m,2} / totalfreq;
142                end
143            end
144           
145        end % if idx > 0
146       
147        end % if i > 0
148
149%===========================================================================
150function docs = combineResults(result)
151
152        docs = {};
153        for i=1:size(result,1)
154        for j=1:size(result{i,5},1)
155            key = result{i,5}{j,5};
156            rank = result{i,5}{j,3};
157            if ~isempty(docs) & ismember(key,{docs{:,1}})
158                l = find(ismember({docs{:,1}},key));
159                docs{l,3} = docs{l,3} + rank;
160                docs{l,3} = 2 * docs{l,3};
161            else
162                l = size(docs,1)+1;
163                docs{l,1} = key; % key
164                docs{l,2} = result{i,5}{j,4}; % name
165                docs{l,3} = rank; % rank
166                docs{l,4} = {}; %words
167            end
168            n = size(docs{l,4},1);
169            docs{l,4}{n+1,1} = result{i,1}; % word
170            docs{l,4}{n+1,2} = result{i,2}; % match
171            docs{l,4}{n+1,3} = result{i,5}{j,2}; % freq
172        end
173        end
174
175%===========================================================================
176function filtdocs = filterResults(docs,requiredWords,forbiddenWords)
177
178        filtdocs = {};
179        for i=1:size(docs,1)
180        words = docs{i,4};
181        c = 1;
182        j = size(words,1);
183        % check required
184        if ~isempty(requiredWords)
185            found = 0;
186            for k=1:j
187                if ismember(words{k,1},requiredWords)
188                    found = 1;
189                    break; 
190                end
191            end
192            if ~found, c = 0; end
193        end
194        % check forbidden
195        if ~isempty(forbiddenWords)
196            for k=1:j
197                if ismember(words{k,1},forbiddenWords)
198                    c = 0;
199                    break;
200                end
201            end
202        end
203        % keep it or not
204        if c,
205            l = size(filtdocs,1)+1;
206            filtdocs{l,1} = docs{i,1};
207            filtdocs{l,2} = docs{i,2};
208            filtdocs{l,3} = docs{i,3};
209            filtdocs{l,4} = docs{i,4};
210        end;
211        end
212
213%===========================================================================
214function docs = normalizeResults(docs);
215
216    m = max([docs{:,3}]);
217    for i=1:size(docs,1)
218        docs{i,3} = 100 * docs{i,3} / m;
219    end
220
221%===========================================================================
222function result = sortResults(docs);
223
224    [y, ind] = sort([docs{:,3}]);
225    result = {};
226    ind = fliplr(ind);
227    for i=1:size(docs,1)
228        result{i,1} = docs{ind(i),1};
229        result{i,2} = docs{ind(i),2};
230        result{i,3} = docs{ind(i),3};
231        result{i,4} = docs{ind(i),4};
232    end
233
234%===========================================================================
235function i = computeIndex(word)
236
237    if length(word) < 2,
238       i = -1;
239    else
240        i = double(word(1)) * 256 + double(word(2));
241    end
242   
243%===========================================================================
244function s = readString(fid)
245
246        s = '';
247        while 1
248                w = fread(fid,1,'uchar');
249                if w == 0, break; end
250                s(end+1) = char(w);
251        end
252
253%===========================================================================
254function i = readInt(fid)
255
256        i = fread(fid,1,'uint32');
Note: See TracBrowser for help on using the repository browser.