Commit | Line | Data |
---|---|---|
4d902e6f CY |
1 | ;;; srecode/cpp.el --- C++ specific handlers for Semantic Recoder |
2 | ||
114f9c96 | 3 | ;; Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc. |
4d902e6f CY |
4 | |
5 | ;; Author: Eric M. Ludlam <eric@siege-engine.com> | |
6 | ;; Jan Moringen <scymtym@users.sourceforge.net> | |
7 | ||
8 | ;; This file is part of GNU Emacs. | |
9 | ||
10 | ;; GNU Emacs is free software: you can redistribute it and/or modify | |
11 | ;; it under the terms of the GNU General Public License as published by | |
12 | ;; the Free Software Foundation, either version 3 of the License, or | |
13 | ;; (at your option) any later version. | |
14 | ||
15 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | ;; GNU General Public License for more details. | |
19 | ||
20 | ;; You should have received a copy of the GNU General Public License | |
21 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |
22 | ||
23 | ;;; Commentary: | |
24 | ;; | |
25 | ;; Supply some C++ specific dictionary fillers and helpers | |
26 | ||
27 | ;;; Code: | |
28 | ||
29 | ;;; :cpp ARGUMENT HANDLING | |
30 | ;; | |
31 | ;; When a :cpp argument is required, fill the dictionary with | |
32 | ;; information about the current C++ file. | |
33 | ;; | |
34 | ;; Error if not in a C++ mode. | |
35 | ||
36 | (require 'srecode) | |
37 | (require 'srecode/dictionary) | |
38 | (require 'srecode/semantic) | |
39 | ||
40 | ;;;###autoload | |
41 | (defun srecode-semantic-handle-:cpp (dict) | |
42 | "Add macros into the dictionary DICT based on the current c++ file. | |
43 | Adds the following: | |
44 | FILENAME_SYMBOL - filename converted into a C compat symbol. | |
45 | HEADER - Shown section if in a header file." | |
46 | ;; A symbol representing | |
47 | (let ((fsym (file-name-nondirectory (buffer-file-name))) | |
48 | (case-fold-search t)) | |
49 | ||
50 | ;; Are we in a header file? | |
51 | (if (string-match "\\.\\(h\\|hh\\|hpp\\|h\\+\\+\\)$" fsym) | |
52 | (srecode-dictionary-show-section dict "HEADER") | |
53 | (srecode-dictionary-show-section dict "NOTHEADER")) | |
54 | ||
55 | ;; Strip out bad characters | |
56 | (while (string-match "\\.\\| " fsym) | |
57 | (setq fsym (replace-match "_" t t fsym))) | |
58 | (srecode-dictionary-set-value dict "FILENAME_SYMBOL" fsym) | |
59 | ) | |
60 | ) | |
61 | ||
62 | (define-mode-local-override srecode-semantic-apply-tag-to-dict | |
63 | c++-mode (tag-wrapper dict) | |
64 | "Apply C++ specific features from TAG-WRAPPER into DICT. | |
65 | Calls `srecode-semantic-apply-tag-to-dict-default' first. Adds | |
66 | special behavior for tag of classes include, using and function." | |
67 | ||
68 | ;; Use default implementation to fill in the basic properties. | |
69 | (srecode-semantic-apply-tag-to-dict-default tag-wrapper dict) | |
70 | ||
71 | ;; Pull out the tag for the individual pieces. | |
72 | (let* ((tag (oref tag-wrapper :prime)) | |
73 | (class (semantic-tag-class tag))) | |
74 | ||
75 | ;; Add additional information based on the class of the tag. | |
76 | (cond | |
77 | ;; | |
78 | ;; INCLUDE | |
79 | ;; | |
80 | ((eq class 'include) | |
81 | ;; For include tags, we have to discriminate between system-wide | |
82 | ;; and local includes. | |
83 | (if (semantic-tag-include-system-p tag) | |
84 | (srecode-dictionary-show-section dict "SYSTEM") | |
85 | (srecode-dictionary-show-section dict "LOCAL"))) | |
86 | ||
87 | ;; | |
88 | ;; USING | |
89 | ;; | |
90 | ((eq class 'using) | |
91 | ;; Insert the subject (a tag) of the include statement as VALUE | |
92 | ;; entry into the dictionary. | |
93 | (let ((value-tag (semantic-tag-get-attribute tag :value)) | |
94 | (value-dict (srecode-dictionary-add-section-dictionary | |
95 | dict "VALUE"))) | |
96 | (srecode-semantic-apply-tag-to-dict | |
97 | (srecode-semantic-tag (semantic-tag-name value-tag) | |
98 | :prime value-tag) | |
99 | value-dict)) | |
100 | ;; Discriminate using statements referring to namespaces and | |
101 | ;; types. | |
102 | (when (eq (semantic-tag-get-attribute tag :kind) 'namespace) | |
103 | (srecode-dictionary-show-section dict "NAMESPACE"))) | |
104 | ||
105 | ;; | |
106 | ;; FUNCTION | |
107 | ;; | |
108 | ((eq class 'function) | |
109 | ;; @todo It would be nice to distinguish member functions from | |
110 | ;; free functions and only apply the const and pure modifiers, | |
111 | ;; when they make sense. My best bet would be | |
112 | ;; (semantic-tag-function-parent tag), but it is not there, when | |
113 | ;; the function is defined in the scope of a class. | |
114 | (let ((member 't) | |
115 | (modifiers (semantic-tag-modifiers tag))) | |
116 | ||
117 | ;; Add modifiers into the dictionary | |
118 | (dolist (modifier modifiers) | |
119 | (let ((modifier-dict (srecode-dictionary-add-section-dictionary | |
120 | dict "MODIFIERS"))) | |
121 | (srecode-dictionary-set-value modifier-dict "NAME" modifier))) | |
122 | ||
123 | ;; When the function is a member function, it can have | |
124 | ;; additional modifiers. | |
125 | (when member | |
126 | ||
127 | ;; For member functions, constness is called | |
128 | ;; 'methodconst-flag'. | |
129 | (when (semantic-tag-get-attribute tag :methodconst-flag) | |
130 | (srecode-dictionary-show-section dict "CONST")) | |
131 | ||
132 | ;; If the member function is pure virtual, add a dictionary | |
133 | ;; entry. | |
134 | (when (semantic-tag-get-attribute tag :pure-virtual-flag) | |
135 | (srecode-dictionary-show-section dict "PURE")) | |
136 | ) | |
137 | )) | |
138 | )) | |
139 | ) | |
140 | ||
141 | (provide 'srecode/cpp) | |
142 | ||
143 | ;; Local variables: | |
144 | ;; generated-autoload-file: "loaddefs.el" | |
4d902e6f CY |
145 | ;; generated-autoload-load-name: "srecode/cpp" |
146 | ;; End: | |
147 | ||
3999968a | 148 | ;; arch-tag: 4659755c-88b4-405e-818f-bb1f776a8e82 |
4d902e6f | 149 | ;;; srecode/cpp.el ends here |