Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief Utility functions for comment metakeys
5 : *
6 : * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
7 : *
8 : */
9 :
10 : #include "keymetaformatting.h"
11 :
12 : #include <ctype.h>
13 : #include <kdbease.h>
14 : #include <kdbhelper.h>
15 : #include <kdbproposal.h>
16 : #include <string.h>
17 :
18 69 : static void elektraAddCommentInfo (KeySet * comments, Key * commentBase, size_t spaces, const char * commentStart, const char * comment)
19 : {
20 69 : keySetString (commentBase, comment);
21 :
22 69 : if (commentStart)
23 : {
24 : /* this comment contains actual comment data */
25 10 : Key * commentStartKey = keyDup (commentBase);
26 10 : keyAddBaseName (commentStartKey, "start");
27 10 : keySetString (commentStartKey, commentStart);
28 10 : ksAppendKey (comments, commentStartKey);
29 : }
30 :
31 69 : ksAppendKey (comments, commentBase);
32 :
33 : /* a space comment key is created for each common comment key
34 : * and for each line that contains more than one space
35 : */
36 69 : if (commentStart || spaces > 0)
37 : {
38 14 : Key * commentSpaceKey = keyDup (commentBase);
39 14 : keyAddBaseName (commentSpaceKey, "space");
40 14 : keySetStringF (commentSpaceKey, "%d", spaces);
41 14 : ksAppendKey (comments, commentSpaceKey);
42 : }
43 69 : }
44 :
45 :
46 : /**
47 : * Adds a line comment to the supplied comment keyset.
48 : * The created comment key will always have an array index
49 : * >= 1. This is because #0 is reserved for inline comments
50 : *
51 : * The following rules apply to the comment subkeys (i.e. space, start)
52 : * - a space key is only omitted for newline comments that do not contain spaces
53 : * each other line comment will have a space key (probably with the value 0)
54 : * - the start key is only present if the comment start sequence is not NULL
55 : *
56 : * @param comments the keyset that should hold the created keys
57 : * @param spaces the number of spaces in the comment
58 : * @param commentStart the used comment start sequence
59 : * @param comment the comment data (i.e. the actual comment)
60 : */
61 20 : void elektraAddLineComment (KeySet * comments, size_t spaces, const char * commentStart, const char * comment)
62 : {
63 : Key * lineComment;
64 :
65 : /* initialize the comment key */
66 20 : if (ksGetSize (comments) == 0)
67 : {
68 10 : lineComment = keyNew ("comment/#", KEY_META_NAME, KEY_END);
69 10 : elektraArrayIncName (lineComment);
70 10 : ksAppendKey (comments, lineComment);
71 10 : lineComment = elektraArrayGetNextKey (comments);
72 : }
73 : else
74 : {
75 : // TODO: doing all this every time is very inefficient. Arrayhandling
76 : // definitely needs to be improved
77 10 : Key * arrayBase = keyNew ("comment", KEY_META_NAME, KEY_END);
78 10 : KeySet * array = elektraArrayGet (arrayBase, comments);
79 10 : lineComment = elektraArrayGetNextKey (array);
80 10 : keyDel (arrayBase);
81 10 : ksDel (array);
82 : }
83 :
84 20 : elektraAddCommentInfo (comments, lineComment, spaces, commentStart, comment);
85 20 : }
86 :
87 : /**
88 : * Adds an inline comment to the supplied comment keyset.
89 : * The inline comment will always have the index #0. If an
90 : * inline comment is already present in the supplied comment keyset
91 : * it will be replaced.
92 : *
93 : * @param comments the keyset that should hold the created keys
94 : * @param spaces the number of spaces in the comment
95 : * @param commentStart the used comment start sequence
96 : * @param comment the comment data (i.e. the actual comment)
97 : */
98 49 : void elektraAddInlineComment (KeySet * comments, size_t spaces, const char * commentStart, const char * comment)
99 : {
100 49 : Key * inlineComment = keyNew ("comment/#", KEY_META_NAME, KEY_END);
101 49 : elektraArrayIncName (inlineComment);
102 :
103 49 : elektraAddCommentInfo (comments, inlineComment, spaces, commentStart, comment);
104 49 : }
105 :
106 : /**
107 : * Counts the number of spaces at the beginning of a string.
108 : * The function continues until the first non blank character is detected.
109 : * This means that tabs are counted as normal spaces.
110 : *
111 : * @param line the string in which spaces are counted
112 : * @return the number of spaces before the first non blank character
113 : */
114 156 : size_t elektraCountStartSpaces (const char * line)
115 : {
116 : /* count the number of whitespace characters before the comment */
117 156 : size_t spaces = 0;
118 156 : size_t lineLen = strlen (line);
119 204 : for (size_t i = 0; i < lineLen; i++)
120 : {
121 200 : if (isblank (line[i]))
122 : {
123 48 : spaces++;
124 : }
125 : else
126 : {
127 : break;
128 : }
129 : }
130 156 : return spaces;
131 : }
|