1 /*
2 *
3 * Copyright (c) 2000-2001, Darren Hiebert
4 *
5 * This source code is released for free distribution under the terms of the
6 * GNU General Public License version 2 or (at your option) any later version.
7 *
8 * This module contains functions for generating tags for diff files (based on Sh parser).
9 */
10
11 /*
12 * INCLUDE FILES
13 */
14 #include "general.h" /* must always come first */
15
16 #include <ctype.h>
17 #include <string.h>
18
19 #include "parse.h"
20 #include "routines.h"
21 #include "read.h"
22 #include "vstring.h"
23
24 /*
25 * DATA DEFINITIONS
26 */
27 typedef enum {
28 K_FUNCTION
29 } diffKind;
30
31 static kindDefinition DiffKinds [] = {
32 { true, 'f', "function", "functions"}
33 };
34
35 enum {
36 DIFF_DELIM_MINUS = 0,
37 DIFF_DELIM_PLUS
38 };
39
40 static const char *DiffDelims[2] = {
41 "--- ",
42 "+++ "
43 };
44
45 /*
46 * FUNCTION DEFINITIONS
47 */
48
stripAbsolute(const unsigned char * filename)49 static const unsigned char *stripAbsolute (const unsigned char *filename)
50 {
51 const unsigned char *tmp;
52
53 /* strip any absolute path */
54 if (*filename == '/' || *filename == '\\')
55 {
56 bool skipSlash = true;
57
58 tmp = (const unsigned char*) strrchr ((const char*) filename, '/');
59 if (tmp == NULL)
60 { /* if no / is contained try \ in case of a Windows filename */
61 tmp = (const unsigned char*) strrchr ((const char*) filename, '\\');
62 if (tmp == NULL)
63 { /* last fallback, probably the filename doesn't contain a path, so take it */
64 tmp = filename;
65 skipSlash = false;
66 }
67 }
68
69 /* skip the leading slash or backslash */
70 if (skipSlash)
71 tmp++;
72 }
73 else
74 tmp = filename;
75
76 return tmp;
77 }
78
findDiffTags(void)79 static void findDiffTags (void)
80 {
81 vString *filename = vStringNew ();
82 const unsigned char *line, *tmp;
83 int delim = DIFF_DELIM_MINUS;
84
85 while ((line = readLineFromInputFile ()) != NULL)
86 {
87 const unsigned char* cp = line;
88
89 if (strncmp ((const char*) cp, DiffDelims[delim], 4u) == 0)
90 {
91 cp += 4;
92 if (isspace ((int) *cp)) continue;
93 /* when original filename is /dev/null use the new one instead */
94 if (delim == DIFF_DELIM_MINUS &&
95 strncmp ((const char*) cp, "/dev/null", 9u) == 0 &&
96 (cp[9] == 0 || isspace (cp[9])))
97 {
98 delim = DIFF_DELIM_PLUS;
99 continue;
100 }
101
102 tmp = stripAbsolute (cp);
103
104 if (tmp != NULL)
105 {
106 while (! isspace(*tmp) && *tmp != '\0')
107 {
108 vStringPut(filename, *tmp);
109 tmp++;
110 }
111
112 makeSimpleTag (filename, K_FUNCTION);
113 vStringClear (filename);
114 }
115
116 /* restore default delim */
117 delim = DIFF_DELIM_MINUS;
118 }
119 }
120 vStringDelete (filename);
121 }
122
DiffParser(void)123 extern parserDefinition* DiffParser (void)
124 {
125 static const char *const patterns [] = { "*.diff", "*.patch", NULL };
126 static const char *const extensions [] = { "diff", NULL };
127 parserDefinition* const def = parserNew ("Diff");
128 def->kindTable = DiffKinds;
129 def->kindCount = ARRAY_SIZE (DiffKinds);
130 def->patterns = patterns;
131 def->extensions = extensions;
132 def->parser = findDiffTags;
133 return def;
134 }
135