cc-guess.el 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. ;;; cc-guess.el --- guess indentation values by scanning existing code
  2. ;; Copyright (C) 1985, 1987, 1992-2006, 2011-2012
  3. ;; Free Software Foundation, Inc.
  4. ;; Author: 1994-1995 Barry A. Warsaw
  5. ;; 2011- Masatake YAMATO
  6. ;; Maintainer: bug-cc-mode@gnu.org
  7. ;; Created: August 1994, split from cc-mode.el
  8. ;; Version: See cc-mode.el
  9. ;; Keywords: c languages oop
  10. ;; This file is part of GNU Emacs.
  11. ;; GNU Emacs is free software: you can redistribute it and/or modify
  12. ;; it under the terms of the GNU General Public License as published by
  13. ;; the Free Software Foundation, either version 3 of the License, or
  14. ;; (at your option) any later version.
  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. ;; You should have received a copy of the GNU General Public License
  20. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  21. ;;; Commentary:
  22. ;;
  23. ;; This file contains routines that help guess the cc-mode style in a
  24. ;; particular region/buffer. Here style means `c-offsets-alist' and
  25. ;; `c-basic-offset'.
  26. ;;
  27. ;; The main entry point of this program is `c-guess' command but there
  28. ;; are some variants.
  29. ;;
  30. ;; Suppose the major mode for the current buffer is one of the modes
  31. ;; provided by cc-mode. `c-guess' guesses the indentation style by
  32. ;; examining the indentation in the region between beginning of buffer
  33. ;; and `c-guess-region-max'.
  34. ;; and installs the guessed style. The name for installed style is given
  35. ;; by `c-guess-style-name'.
  36. ;;
  37. ;; `c-guess-buffer' does the same but in the whole buffer.
  38. ;; `c-guess-region' does the same but in the region between the point
  39. ;; and the mark. `c-guess-no-install', `c-guess-buffer-no-install'
  40. ;; and `c-guess-region-no-install' guess the indentation style but
  41. ;; don't install it. You can review a guessed style with `c-guess-view'.
  42. ;; After reviewing, use `c-guess-install' to install the style
  43. ;; if you prefer it.
  44. ;;
  45. ;; If you want to reuse the guessed style in another buffer,
  46. ;; run `c-set-style' command with the name of the guessed style:
  47. ;; "*c-guess*:<name-of-file-which-examined-when-guessing>".
  48. ;; Once the guessed style is installed explicitly with `c-guess-install'
  49. ;; or implicitly with `c-guess', `c-guess-buffer', or `c-guess-region',
  50. ;; a style name is given by `c-guess-style-name' with the above form.
  51. ;;
  52. ;; If you want to reuse the guessed style in future emacs sessions,
  53. ;; you may want to put it to your .emacs. `c-guess-view' is for
  54. ;; you. It emits emacs lisp code which defines the last guessed
  55. ;; style, in a temporary buffer. You can put the emitted code into
  56. ;; your .emacs. This command was suggested by Alan Mackenzie.
  57. ;;; Code:
  58. (eval-when-compile
  59. (let ((load-path
  60. (if (and (boundp 'byte-compile-dest-file)
  61. (stringp byte-compile-dest-file))
  62. (cons (file-name-directory byte-compile-dest-file) load-path)
  63. load-path)))
  64. (load "cc-bytecomp" nil t)))
  65. (cc-require 'cc-defs)
  66. (cc-require 'cc-engine)
  67. (cc-require 'cc-styles)
  68. (defcustom c-guess-offset-threshold 10
  69. "Threshold of acceptable offsets when examining indent information.
  70. Discard an examined offset if its absolute value is greater than this.
  71. The offset of a line included in the indent information returned by
  72. `c-guess-basic-syntax'."
  73. :version "24.1"
  74. :type 'integer
  75. :group 'c)
  76. (defcustom c-guess-region-max 50000
  77. "The maximum region size for examining indent information with `c-guess'.
  78. It takes a long time to examine indent information from a large region;
  79. this option helps you limit that time. `nil' means no limit."
  80. :version "24.1"
  81. :type 'integer
  82. :group 'c)
  83. ;;;###autoload
  84. (defvar c-guess-guessed-offsets-alist nil
  85. "Currently guessed offsets-alist.")
  86. ;;;###autoload
  87. (defvar c-guess-guessed-basic-offset nil
  88. "Currently guessed basic-offset.")
  89. (defvar c-guess-accumulator nil)
  90. ;; Accumulated examined indent information. Information is represented
  91. ;; in a list. Each element in it has following structure:
  92. ;;
  93. ;; (syntactic-symbol ((indentation-offset1 . number-of-times1)
  94. ;; (indentation-offset2 . number-of-times2)
  95. ;; ...))
  96. ;;
  97. ;; This structure is built by `c-guess-accumulate-offset'.
  98. ;;
  99. ;; Here we call the pair (indentation-offset1 . number-of-times1) a
  100. ;; counter. `c-guess-sort-accumulator' sorts the order of
  101. ;; counters by number-of-times.
  102. ;; Use `c-guess-dump-accumulator' to see the value.
  103. (defconst c-guess-conversions
  104. '((c . c-lineup-C-comments)
  105. (inher-cont . c-lineup-multi-inher)
  106. (string . -1000)
  107. (comment-intro . c-lineup-comment)
  108. (arglist-cont-nonempty . c-lineup-arglist)
  109. (arglist-close . c-lineup-close-paren)
  110. (cpp-macro . -1000)))
  111. ;;;###autoload
  112. (defun c-guess (&optional accumulate)
  113. "Guess the style in the region up to `c-guess-region-max', and install it.
  114. The style is given a name based on the file's absolute file name.
  115. If given a prefix argument (or if the optional argument ACCUMULATE is
  116. non-nil) then the previous guess is extended, otherwise a new guess is
  117. made from scratch."
  118. (interactive "P")
  119. (c-guess-region (point-min)
  120. (min (point-max) (or c-guess-region-max
  121. (point-max)))
  122. accumulate))
  123. ;;;###autoload
  124. (defun c-guess-no-install (&optional accumulate)
  125. "Guess the style in the region up to `c-guess-region-max'; don't install it.
  126. If given a prefix argument (or if the optional argument ACCUMULATE is
  127. non-nil) then the previous guess is extended, otherwise a new guess is
  128. made from scratch."
  129. (interactive "P")
  130. (c-guess-region-no-install (point-min)
  131. (min (point-max) (or c-guess-region-max
  132. (point-max)))
  133. accumulate))
  134. ;;;###autoload
  135. (defun c-guess-buffer (&optional accumulate)
  136. "Guess the style on the whole current buffer, and install it.
  137. The style is given a name based on the file's absolute file name.
  138. If given a prefix argument (or if the optional argument ACCUMULATE is
  139. non-nil) then the previous guess is extended, otherwise a new guess is
  140. made from scratch."
  141. (interactive "P")
  142. (c-guess-region (point-min)
  143. (point-max)
  144. accumulate))
  145. ;;;###autoload
  146. (defun c-guess-buffer-no-install (&optional accumulate)
  147. "Guess the style on the whole current buffer; don't install it.
  148. If given a prefix argument (or if the optional argument ACCUMULATE is
  149. non-nil) then the previous guess is extended, otherwise a new guess is
  150. made from scratch."
  151. (interactive "P")
  152. (c-guess-region-no-install (point-min)
  153. (point-max)
  154. accumulate))
  155. ;;;###autoload
  156. (defun c-guess-region (start end &optional accumulate)
  157. "Guess the style on the region and install it.
  158. The style is given a name based on the file's absolute file name.
  159. If given a prefix argument (or if the optional argument ACCUMULATE is
  160. non-nil) then the previous guess is extended, otherwise a new guess is
  161. made from scratch."
  162. (interactive "r\nP")
  163. (c-guess-region-no-install start end accumulate)
  164. (c-guess-install))
  165. (defsubst c-guess-empty-line-p ()
  166. (eq (line-beginning-position)
  167. (line-end-position)))
  168. ;;;###autoload
  169. (defun c-guess-region-no-install (start end &optional accumulate)
  170. "Guess the style on the region; don't install it.
  171. Every line of code in the region is examined and values for the following two
  172. variables are guessed:
  173. * `c-basic-offset', and
  174. * the indentation values of the various syntactic symbols in
  175. `c-offsets-alist'.
  176. The guessed values are put into `c-guess-guessed-basic-offset' and
  177. `c-guess-guessed-offsets-alist'.
  178. Frequencies of use are taken into account when guessing, so minor
  179. inconsistencies in the indentation style shouldn't produce wrong guesses.
  180. If given a prefix argument (or if the optional argument ACCUMULATE is
  181. non-nil) then the previous examination is extended, otherwise a new
  182. guess is made from scratch.
  183. Note that the larger the region to guess in, the slower the guessing.
  184. So you can limit the region with `c-guess-region-max'."
  185. (interactive "r\nP")
  186. (let ((accumulator (when accumulate c-guess-accumulator)))
  187. (setq c-guess-accumulator (c-guess-examine start end accumulator))
  188. (let ((pair (c-guess-guess c-guess-accumulator)))
  189. (setq c-guess-guessed-basic-offset (car pair)
  190. c-guess-guessed-offsets-alist (cdr pair)))))
  191. (defun c-guess-examine (start end accumulator)
  192. (let ((reporter (when (fboundp 'make-progress-reporter)
  193. (make-progress-reporter "Examining Indentation "
  194. start
  195. end))))
  196. (save-excursion
  197. (goto-char start)
  198. (while (< (point) end)
  199. (unless (c-guess-empty-line-p)
  200. (mapc (lambda (s)
  201. (setq accumulator (or (c-guess-accumulate accumulator s)
  202. accumulator)))
  203. (c-save-buffer-state () (c-guess-basic-syntax))))
  204. (when reporter (progress-reporter-update reporter (point)))
  205. (forward-line 1)))
  206. (when reporter (progress-reporter-done reporter)))
  207. (c-guess-sort-accumulator accumulator))
  208. (defun c-guess-guess (accumulator)
  209. ;; Guess basic-offset and offsets-alist from ACCUMULATOR,
  210. ;; then return them as a cons: (basic-offset . offsets-alist).
  211. ;; See the comments at `c-guess-accumulator' about the format
  212. ;; ACCUMULATOR.
  213. (let* ((basic-offset (c-guess-make-basic-offset accumulator))
  214. (typical-offsets-alist (c-guess-make-offsets-alist
  215. accumulator))
  216. (symbolic-offsets-alist (c-guess-symbolize-offsets-alist
  217. typical-offsets-alist
  218. basic-offset))
  219. (merged-offsets-alist (c-guess-merge-offsets-alists
  220. (copy-tree c-guess-conversions)
  221. symbolic-offsets-alist)))
  222. (cons basic-offset merged-offsets-alist)))
  223. (defun c-guess-current-offset (relpos)
  224. ;; Calculate relative indentation (point) to RELPOS.
  225. (- (progn (back-to-indentation)
  226. (current-column))
  227. (save-excursion
  228. (goto-char relpos)
  229. (current-column))))
  230. (defun c-guess-accumulate (accumulator syntax-element)
  231. ;; Add SYNTAX-ELEMENT to ACCUMULATOR.
  232. (let ((symbol (car syntax-element))
  233. (relpos (cadr syntax-element)))
  234. (when (numberp relpos)
  235. (let ((offset (c-guess-current-offset relpos)))
  236. (when (< (abs offset) c-guess-offset-threshold)
  237. (c-guess-accumulate-offset accumulator
  238. symbol
  239. offset))))))
  240. (defun c-guess-accumulate-offset (accumulator symbol offset)
  241. ;; Added SYMBOL and OFFSET to ACCUMULATOR. See
  242. ;; `c-guess-accumulator' about the structure of ACCUMULATOR.
  243. (let* ((entry (assoc symbol accumulator))
  244. (counters (cdr entry))
  245. counter)
  246. (if entry
  247. (progn
  248. (setq counter (assoc offset counters))
  249. (if counter
  250. (setcdr counter (1+ (cdr counter)))
  251. (setq counters (cons (cons offset 1) counters))
  252. (setcdr entry counters))
  253. accumulator)
  254. (cons (cons symbol (cons (cons offset 1) nil)) accumulator))))
  255. (defun c-guess-sort-accumulator (accumulator)
  256. ;; Sort each element of ACCUMULATOR by the number-of-times. See
  257. ;; `c-guess-accumulator' for more details.
  258. (mapcar
  259. (lambda (entry)
  260. (let ((symbol (car entry))
  261. (counters (cdr entry)))
  262. (cons symbol (sort counters
  263. (lambda (a b)
  264. (if (> (cdr a) (cdr b))
  265. t
  266. (and
  267. (eq (cdr a) (cdr b))
  268. (< (car a) (car b)))))))))
  269. accumulator))
  270. (defun c-guess-make-offsets-alist (accumulator)
  271. ;; Throw away the rare cases in accumulator and make an offsets-alist structure.
  272. (mapcar
  273. (lambda (entry)
  274. (cons (car entry)
  275. (car (car (cdr entry)))))
  276. accumulator))
  277. (defun c-guess-merge-offsets-alists (strong weak)
  278. ;; Merge two offsets-alists into one.
  279. ;; When two offsets-alists have the same symbol
  280. ;; entry, give STRONG priority over WEAK.
  281. (mapc
  282. (lambda (weak-elt)
  283. (unless (assoc (car weak-elt) strong)
  284. (setq strong (cons weak-elt strong))))
  285. weak)
  286. strong)
  287. (defun c-guess-make-basic-offset (accumulator)
  288. ;; As candidate for `c-basic-offset', find the most frequently appearing
  289. ;; indentation-offset in ACCUMULATOR.
  290. (let* (;; Drop the value related to `c' syntactic-symbol.
  291. ;; (`c': Inside a multiline C style block comment.)
  292. ;; The impact for values of `c' is too large for guessing
  293. ;; `basic-offset' if the target source file is small and its license
  294. ;; notice is at top of the file.
  295. (accumulator (assq-delete-all 'c (copy-tree accumulator)))
  296. ;; Drop syntactic-symbols from ACCUMULATOR.
  297. (alist (apply #'append (mapcar (lambda (elts)
  298. (mapcar (lambda (elt)
  299. (cons (abs (car elt))
  300. (cdr elt)))
  301. (cdr elts)))
  302. accumulator)))
  303. ;; Gather all indentation-offsets other than 0.
  304. ;; 0 is meaningless as `basic-offset'.
  305. (offset-list (delete 0
  306. (delete-dups (mapcar
  307. (lambda (elt) (car elt))
  308. alist))))
  309. ;; Sum of number-of-times for offset:
  310. ;; (offset . sum)
  311. (summed (mapcar (lambda (offset)
  312. (cons offset
  313. (apply #'+
  314. (mapcar (lambda (a)
  315. (if (eq (car a) offset)
  316. (cdr a)
  317. 0))
  318. alist))))
  319. offset-list)))
  320. ;;
  321. ;; Find the majority.
  322. ;;
  323. (let ((majority '(nil . 0)))
  324. (while summed
  325. (when (< (cdr majority) (cdr (car summed)))
  326. (setq majority (car summed)))
  327. (setq summed (cdr summed)))
  328. (car majority))))
  329. (defun c-guess-symbolize-offsets-alist (offsets-alist basic-offset)
  330. ;; Convert the representation of OFFSETS-ALIST to an alist using
  331. ;; `+', `-', `++', `--', `*', or `/'. These symbols represent
  332. ;; a value relative to BASIC-OFFSET. Their meaning can be found
  333. ;; in the CC Mode manual.
  334. (mapcar
  335. (lambda (elt)
  336. (let ((s (car elt))
  337. (v (cdr elt)))
  338. (cond
  339. ((integerp v)
  340. (cons s (c-guess-symbolize-integer v
  341. basic-offset)))
  342. (t elt))))
  343. offsets-alist))
  344. (defun c-guess-symbolize-integer (int basic-offset)
  345. (let ((aint (abs int)))
  346. (cond
  347. ((eq int basic-offset) '+)
  348. ((eq aint basic-offset) '-)
  349. ((eq int (* 2 basic-offset)) '++)
  350. ((eq aint (* 2 basic-offset)) '--)
  351. ((eq (* 2 int) basic-offset) '*)
  352. ((eq (* 2 aint) basic-offset) '-)
  353. (t int))))
  354. (defun c-guess-style-name ()
  355. ;; Make a style name for the guessed style.
  356. (format "*c-guess*:%s" (buffer-file-name)))
  357. (defun c-guess-make-style (basic-offset offsets-alist)
  358. (when basic-offset
  359. ;; Make a style from guessed values.
  360. (let* ((offsets-alist (c-guess-merge-offsets-alists
  361. offsets-alist
  362. c-offsets-alist)))
  363. `((c-basic-offset . ,basic-offset)
  364. (c-offsets-alist . ,offsets-alist)))))
  365. ;;;###autoload
  366. (defun c-guess-install (&optional style-name)
  367. "Install the latest guessed style into the current buffer.
  368. \(This guessed style is a combination of `c-guess-guessed-basic-offset',
  369. `c-guess-guessed-offsets-alist' and `c-offsets-alist'.)
  370. The style is entered into CC Mode's style system by
  371. `c-add-style'. Its name is either STYLE-NAME, or a name based on
  372. the absolute file name of the file if STYLE-NAME is nil."
  373. (interactive "sNew style name (empty for default name): ")
  374. (let* ((style (c-guess-make-style c-guess-guessed-basic-offset
  375. c-guess-guessed-offsets-alist)))
  376. (if style
  377. (let ((style-name (or (if (equal style-name "")
  378. nil
  379. style-name)
  380. (c-guess-style-name))))
  381. (c-add-style style-name style t)
  382. (message "Style \"%s\" is installed" style-name))
  383. (error "Not yet guessed"))))
  384. (defun c-guess-dump-accumulator ()
  385. "Show `c-guess-accumulator'."
  386. (interactive)
  387. (with-output-to-temp-buffer "*Accumulated Examined Indent Information*"
  388. (pp c-guess-accumulator)))
  389. (defun c-guess-reset-accumulator ()
  390. "Reset `c-guess-accumulator'."
  391. (interactive)
  392. (setq c-guess-accumulator nil))
  393. (defun c-guess-dump-guessed-values ()
  394. "Show `c-guess-guessed-basic-offset' and `c-guess-guessed-offsets-alist'."
  395. (interactive)
  396. (with-output-to-temp-buffer "*Guessed Values*"
  397. (princ "basic-offset: \n\t")
  398. (pp c-guess-guessed-basic-offset)
  399. (princ "\n\n")
  400. (princ "offsets-alist: \n")
  401. (pp c-guess-guessed-offsets-alist)
  402. ))
  403. (defun c-guess-dump-guessed-style (&optional printer)
  404. "Show the guessed style.
  405. `pp' is used to print the style but if PRINTER is given,
  406. PRINTER is used instead. If PRINTER is not `nil', it
  407. is called with one argument, the guessed style."
  408. (interactive)
  409. (let ((style (c-guess-make-style c-guess-guessed-basic-offset
  410. c-guess-guessed-offsets-alist)))
  411. (if style
  412. (with-output-to-temp-buffer "*Guessed Style*"
  413. (funcall (if printer printer 'pp) style))
  414. (error "Not yet guessed"))))
  415. (defun c-guess-guessed-syntactic-symbols ()
  416. ;; Return syntactic symbols in c-guess-guessed-offsets-alist
  417. ;; but not in c-guess-conversions.
  418. (let ((alist c-guess-guessed-offsets-alist)
  419. elt
  420. (symbols nil))
  421. (while alist
  422. (setq elt (car alist)
  423. alist (cdr alist))
  424. (unless (assq (car elt) c-guess-conversions)
  425. (setq symbols (cons (car elt)
  426. symbols))))
  427. symbols))
  428. (defun c-guess-view-reorder-offsets-alist-in-style (style guessed-syntactic-symbols)
  429. ;; Reorder the `c-offsets-alist' field of STYLE.
  430. ;; If an entry in `c-offsets-alist' holds a guessed value, move it to
  431. ;; front in the field. In addition alphabetical sort by entry name is done.
  432. (setq style (copy-tree style))
  433. (let ((offsets-alist-cell (assq 'c-offsets-alist style))
  434. (guessed-syntactic-symbols (c-guess-guessed-syntactic-symbols)))
  435. (setcdr offsets-alist-cell
  436. (sort (cdr offsets-alist-cell)
  437. (lambda (a b)
  438. (let ((a-guessed? (memq (car a) guessed-syntactic-symbols))
  439. (b-guessed? (memq (car b) guessed-syntactic-symbols)))
  440. (cond
  441. ((or (and a-guessed? b-guessed?)
  442. (not (or a-guessed? b-guessed?)))
  443. (string-lessp (symbol-name (car a))
  444. (symbol-name (car b))))
  445. (a-guessed? t)
  446. (b-guessed? nil)))))))
  447. style)
  448. (defun c-guess-view-mark-guessed-entries (guessed-syntactic-symbols)
  449. ;; Put " ; Guess value" markers on all entries which hold
  450. ;; guessed values.
  451. ;; `c-basic-offset' is always considered as holding a guessed value.
  452. (let ((needs-markers (cons 'c-basic-offset
  453. guessed-syntactic-symbols)))
  454. (while needs-markers
  455. (goto-char (point-min))
  456. (when (search-forward (concat "("
  457. (symbol-name (car needs-markers))
  458. " ") nil t)
  459. (move-end-of-line 1)
  460. (comment-dwim nil)
  461. (insert " Guessed value"))
  462. (setq needs-markers
  463. (cdr needs-markers)))))
  464. (defun c-guess-view (&optional with-name)
  465. "Emit emacs lisp code which defines the last guessed style.
  466. So you can put the code into .emacs if you prefer the
  467. guessed code.
  468. \"STYLE NAME HERE\" is used as the name for the style in the
  469. emitted code. If WITH-NAME is given, it is used instead.
  470. WITH-NAME is expected as a string but if this function
  471. called interactively with prefix argument, the value for
  472. WITH-NAME is asked to the user."
  473. (interactive "P")
  474. (let* ((temporary-style-name (cond
  475. ((stringp with-name) with-name)
  476. (with-name (read-from-minibuffer
  477. "New style name: "))
  478. (t
  479. "STYLE NAME HERE")))
  480. (guessed-style-name (c-guess-style-name))
  481. (current-style-name c-indentation-style)
  482. (parent-style-name (if (string-equal guessed-style-name
  483. current-style-name)
  484. ;; The guessed style is already installed.
  485. ;; It cannot be used as the parent style.
  486. ;; Use the default style for the current
  487. ;; major mode as the parent style.
  488. (cc-choose-style-for-mode
  489. major-mode
  490. c-default-style)
  491. ;; The guessed style is not installed yet.
  492. current-style-name)))
  493. (c-guess-dump-guessed-style
  494. (lambda (style)
  495. (let ((guessed-syntactic-symbols (c-guess-guessed-syntactic-symbols)))
  496. (pp `(c-add-style ,temporary-style-name
  497. ',(cons parent-style-name
  498. (c-guess-view-reorder-offsets-alist-in-style
  499. style
  500. guessed-syntactic-symbols))))
  501. (with-current-buffer standard-output
  502. (lisp-interaction-mode)
  503. (c-guess-view-mark-guessed-entries
  504. guessed-syntactic-symbols)
  505. (buffer-enable-undo)))))))
  506. (cc-provide 'cc-guess)
  507. ;;; cc-guess.el ends here