Skip to content

Commit a0143c3

Browse files
committed
Merge branch 'callbacks'
2 parents a7cb8a3 + 4dd60af commit a0143c3

File tree

7 files changed

+152
-45
lines changed

7 files changed

+152
-45
lines changed

lib/docurium.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def initialize(config_file, repo = nil)
2727
end
2828

2929
def init_data(version = 'HEAD')
30-
data = {:files => [], :functions => {}, :globals => {}, :types => {}, :prefix => ''}
30+
data = {:files => [], :functions => {}, :callbacks => {}, :globals => {}, :types => {}, :prefix => ''}
3131
data[:prefix] = option_version(version, 'input', '')
3232
data
3333
end
@@ -389,17 +389,17 @@ def update_globals!(data, recs)
389389

390390
# process this type of record
391391
case r[:type]
392-
when :function
393-
data[:functions][r[:name]] ||= {}
392+
when :function, :callback
393+
t = r[:type] == :function ? :functions : :callbacks
394+
data[t][r[:name]] ||= {}
394395
wanted[:functions].each do |k|
395396
next unless r.has_key? k
396-
conents = nil
397397
if k == :description || k == :comments
398398
contents = md.render r[k]
399399
else
400400
contents = r[k]
401401
end
402-
data[:functions][r[:name]][k] = contents
402+
data[t][r[:name]][k] = contents
403403
end
404404
file_map[r[:file]][:functions] << r[:name]
405405

lib/docurium/docparser.rb

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,15 @@ def extract_typedef(cursor)
111111
#puts "typed struct, #{cursor.spelling}"
112112
rec.merge! extract_struct(child)
113113
when :cursor_parm_decl
114-
#puts "have parm #{cursor.spelling}, #{cursor.display_name}"
115-
subject, desc = extract_subject_desc(cursor.comment)
116-
rec[:decl] = cursor.spelling
117-
rec[:description] = subject
118-
rec[:comments] = desc
114+
rec.merge! extract_function(cursor)
115+
rec[:type] = :callback
116+
# this is wasteful, but we don't get the array from outside
117+
cmt = extract_function_comment(cursor.comment)
118+
ret = {
119+
:type => extract_callback_result(rec[:underlying_type]),
120+
:comment => cmt[:return]
121+
}
122+
rec[:return] = ret
119123
else
120124
raise "No idea how to handle #{child.kind}"
121125
end
@@ -125,21 +129,14 @@ def extract_typedef(cursor)
125129
rec
126130
end
127131

128-
def extract_subject_desc(comment)
129-
subject = comment.child.text
130-
desc = (comment.find_all { |cmt| cmt.kind == :comment_paragraph }).drop(1).map(&:text).join("\n\n")
131-
return subject, desc
132+
def extract_callback_result(type)
133+
type[0..(type.index('(') - 1)].strip
132134
end
133135

134-
def extract_function(cursor)
135-
comment = cursor.comment
136-
137-
#puts "looking at function #{cursor.spelling}, #{cursor.display_name}"
138-
cmt = extract_function_comment(comment)
139-
136+
def extract_function_args(cursor, cmt)
140137
# We only want to look at parm_decl to avoid looking at a return
141138
# struct as a parameter
142-
args = children(cursor)
139+
children(cursor)
143140
.select {|c| c.kind == :cursor_parm_decl }
144141
.map do |arg|
145142
{
@@ -148,6 +145,20 @@ def extract_function(cursor)
148145
:comment => cmt[:args][arg.display_name],
149146
}
150147
end
148+
end
149+
150+
def extract_subject_desc(comment)
151+
subject = comment.child.text
152+
desc = (comment.find_all { |cmt| cmt.kind == :comment_paragraph }).drop(1).map(&:text).join("\n\n")
153+
return subject, desc
154+
end
155+
156+
def extract_function(cursor)
157+
comment = cursor.comment
158+
159+
#puts "looking at function #{cursor.spelling}, #{cursor.display_name}"
160+
cmt = extract_function_comment(comment)
161+
args = extract_function_args(cursor, cmt)
151162
#args = args.reject { |arg| arg[:comment].nil? }
152163

153164
ret = {

site/index.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ <h3>signature</h3>
138138
<code class="params"><%= sig %></code>
139139
</div>
140140
<!-- function history -->
141+
<% if (sigs) { %>
141142
<div class="signatures">
142143
<h3>versions</h3>
143144
<ul>
@@ -146,6 +147,7 @@ <h3>versions</h3>
146147
<% }) %>
147148
</ul>
148149
</div>
150+
<% } %> <!-- if we have version history -->
149151
<div class="fileLink">Defined in: <a href="<%= fileLink %>"> <%= data.file %></a></div>
150152
<% if (data.examples) { %>
151153
<div class="funcEx">Used in examples:
@@ -161,6 +163,7 @@ <h3>versions</h3>
161163
</ul>
162164
</div>
163165
<% } %> <!-- if we have examples -->
166+
<% if (alsoLinks) { %>
164167
<div class="also">
165168
Also in <a href="<%= alsoGroup %>"><%= groupName %></a> group: <br/>
166169
<% _.each(_.initial(alsoLinks), function(link) { %>
@@ -169,6 +172,7 @@ <h3>versions</h3>
169172
<% var link = _.last(alsoLinks) %>
170173
<a href="<%= link.url %>"><%= link.name %></a>
171174
</div>
175+
<% } %> <!-- if we have "also" links -->
172176
</script>
173177

174178
<!-- main page, list of groups and their functions -->

site/js/docurium.js

Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -213,42 +213,54 @@ $(function() {
213213
var fname = this.get('fname')
214214
var docurium = this.get('docurium')
215215

216+
var isCallback = gname === 'callback'
216217
var group = docurium.getGroup(gname)
217218

218219
var fdata = docurium.get('data')['functions']
219-
var functions = group[1]
220+
221+
var ldata = fdata
222+
if (isCallback) {
223+
var cdata = docurium.get('data')['callbacks']
224+
ldata = cdata
225+
} else {
226+
var functions = group[1]
227+
}
220228

221229
// Function Arguments
222-
var args = _.map(fdata[fname]['args'], function(arg) {
230+
var args = _.map(ldata[fname]['args'], function(arg) {
223231
return {link: this.hotLink(arg.type), name: arg.name, comment: arg.comment}
224232
}, docurium)
225233

226-
var data = fdata[fname]
234+
var data = ldata[fname]
227235
// function return value
228236
var ret = data['return']
229237
var returns = {link: docurium.hotLink(ret.type), comment: ret.comment}
230238
// function signature
231239
var sig = docurium.hotLink(ret.type) + ' ' + fname + '(' + data['argline'] + ');'
232240
// version history
233-
var sigHist = docurium.get('signatures')[fname]
234-
var version = docurium.get('version')
235-
var sigs = _.map(sigHist.exists, function(ver) {
236-
var klass = []
237-
if (sigHist.changes[ver])
238-
klass.push('changed')
239-
if (ver == version)
240-
klass.push('current')
241-
242-
return {url: '#' + functionLink(gname, fname, ver), name: ver, klass: klass.join(' ')}
243-
})
241+
if (!isCallback) {
242+
var sigHist = docurium.get('signatures')[fname]
243+
var version = docurium.get('version')
244+
var sigs = _.map(sigHist.exists, function(ver) {
245+
var klass = []
246+
if (sigHist.changes[ver])
247+
klass.push('changed')
248+
if (ver == version)
249+
klass.push('current')
250+
251+
return {url: '#' + functionLink(gname, fname, ver), name: ver, klass: klass.join(' ')}
252+
})
253+
}
244254
// GitHub link
245255
var fileLink = docurium.github_file(data.file, data.line, data.lineto)
246256
// link to the group
247-
var version = docurium.get('version')
248-
var alsoGroup = '#' + groupLink(group[0], version)
249-
var alsoLinks = _.map(functions, function(f) {
250-
return {url: '#' + functionLink(gname, f, version), name: f}
251-
})
257+
if (!isCallback) {
258+
var version = docurium.get('version')
259+
var alsoGroup = '#' + groupLink(group[0], version)
260+
var alsoLinks = _.map(functions, function(f) {
261+
return {url: '#' + functionLink(gname, f, version), name: f}
262+
})
263+
}
252264

253265
this.set('data', {name: fname, data: data, args: args, returns: returns, sig: sig,
254266
sigs: sigs, fileLink: fileLink, groupName: gname,
@@ -381,6 +393,7 @@ $(function() {
381393
var group = o.group
382394
var gname = group[0]
383395
var fdata = o.functions
396+
var cdata = o.callbacks
384397
var version = o.version
385398

386399
this.functions = _.map(group[1], function(name) {
@@ -471,6 +484,16 @@ $(function() {
471484
}
472485
})
473486

487+
// look for callbacks
488+
_.each(data.callbacks, function(f, name) {
489+
if (name.search(value) > -1) {
490+
var gl = functionLink('callback', name, version)
491+
var url = '#' + gl
492+
searchResults.push({url: url, name: name, match: 'callback', navigate: gl})
493+
return
494+
}
495+
})
496+
474497
this.reset(searchResults)
475498
},
476499
})
@@ -556,14 +579,23 @@ $(function() {
556579
hotLink: function(text) {
557580
types = this.get('data')['types']
558581
var version = this.get('version')
582+
559583
for(var i=0; i<types.length; i++) {
560584
type = types[i]
561585
typeName = type[0]
562586
typeData = type[1]
563-
re = new RegExp(typeName + ' ', 'gi');
587+
re = new RegExp(typeName + '\\s', 'gi');
564588
var link = $('<a>').attr('href', '#' + typeLink(typeName, version)).append(typeName)[0]
565589
text = text.replace(re, link.outerHTML + ' ')
566590
}
591+
592+
var callbacks = this.get('data')['callbacks']
593+
_.each(callbacks, function(cb, typeName) {
594+
re = new RegExp(typeName + '$', 'gi');
595+
var link = $('<a>').attr('href', '#' + functionLink('callback', typeName, version)).append(typeName)[0]
596+
text = text.replace(re, link.outerHTML + ' ')
597+
});
598+
567599
return text
568600
},
569601

@@ -624,8 +656,9 @@ $(function() {
624656
this.doc.setVersion(version)
625657
var group = this.doc.getGroup(gname)
626658
var fdata = this.doc.get('data')['functions']
659+
var cdata = this.doc.get('data')['callbacks']
627660
var version = this.doc.get('version')
628-
var view = new GroupView({group: group, functions: fdata, version: version})
661+
var view = new GroupView({group: group, functions: fdata, callbacks: cdata, version: version})
629662
this.mainView.setActive(view)
630663
},
631664

test/fixtures/git2/callback.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* This file is to create a function which takes a callback in order
3+
* to test that we detect it correctly and will write it out.
4+
*/
5+
6+
#include "common.h"
7+
8+
/**
9+
* Worker which does soemthing to its pointer
10+
*/
11+
typedef int (*git_callback_do_work)(int *foo);
12+
13+
/**
14+
* Schedule some work to happen for a particular function
15+
*/
16+
GIT_EXTERN(int) git_work_schedule(git_callback_do_work worker);

test/parser_test.rb

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,4 +406,41 @@ def test_type_reference
406406

407407
end
408408

409+
def test_callaback
410+
name = 'typeref.h'
411+
contents = <<EOF
412+
/**
413+
* This is a callback type
414+
*
415+
* @return whether to reschedule
416+
*/
417+
typedef int (*some_callback)(int *foo);
418+
EOF
419+
420+
actual = parse(name, contents)
421+
expected = [{
422+
:file => "typeref.h",
423+
:line => 6,
424+
:lineto => 6,
425+
:tdef => :typedef,
426+
:name => "some_callback",
427+
:underlying_type => "int (*)(int *)",
428+
:type => :callback,
429+
:body => ' some_callback(int *foo);',
430+
:description => ' This is a callback type',
431+
:comments => ' ',
432+
:sig => "int *",
433+
:args => [{:name => "foo",
434+
:type => "int *",
435+
:comment => nil,
436+
}],
437+
:return => {:type => 'int',
438+
:comment => " whether to reschedule"},
439+
:decl => ' some_callback(int *foo)',
440+
:argline => 'int *foo',
441+
}]
442+
443+
assert_equal actual, expected
444+
end
445+
409446
end

test/repo_test.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ def teardown
3939

4040
def test_can_parse_headers
4141
keys = @data.keys.map { |k| k.to_s }.sort
42-
assert_equal ['files', 'functions', 'globals', 'groups', 'prefix', 'types'], keys
43-
assert_equal 153, @data[:functions].size
42+
assert_equal ['callbacks', 'files', 'functions', 'globals', 'groups', 'prefix', 'types'], keys
43+
assert_equal 154, @data[:functions].size
4444
end
4545

4646
def test_can_extract_enum_from_define
@@ -114,7 +114,7 @@ def test_can_get_the_full_description_from_multi_liners
114114
end
115115

116116
def test_can_group_functions
117-
assert_equal 14, @data[:groups].size
117+
assert_equal 15, @data[:groups].size
118118
group, funcs = @data[:groups].first
119119
assert_equal 'blob', group
120120
assert_equal 6, funcs.size
@@ -127,4 +127,10 @@ def test_can_store_mutliple_enum_doc_sections
127127
assert_equal 2, idxentry[1][:sections].size
128128
end
129129

130+
def test_can_parse_callback
131+
cb = @data[:callbacks]['git_callback_do_work']
132+
# we can mostly assume that the rest works as it's the same as for the functions
133+
assert_equal 'int', cb[:return][:type]
134+
end
135+
130136
end

0 commit comments

Comments
 (0)