xref: /Universal-ctags/main/flags.c (revision 4b5f2b4154ebc8e2bb8cb3f31b20ef6f70ad8fcb)
1 /*
2 *
3 *   Copyright (c) 2000-2003, 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 to process command line options.
9 */
10 
11 /*
12 *   INCLUDE FILES
13 */
14 #include "general.h"  /* must always come first */
15 
16 #include <string.h>
17 #include <stdio.h>
18 
19 #include "ctags.h"
20 #include "flags_p.h"
21 #include "vstring.h"
22 #include "routines.h"
23 
flagsEval(const char * flags_original,flagDefinition * defs,unsigned int ndefs,void * data)24 extern const char *flagsEval (const char* flags_original, flagDefinition* defs, unsigned int ndefs, void* data)
25 {
26 	unsigned int i, j;
27 	char *flags;
28 	const char *optscript = NULL;
29 
30 	if (!flags_original)
31 		return NULL;
32 
33 	flags = eStrdup (flags_original);
34 	for (i = 0 ; flags [i] != '\0' ; ++i)
35 	{
36 		if (flags [i] == LONG_FLAGS_OPEN && flags [i + 1] == LONG_FLAGS_OPEN)
37 		{
38 			optscript = flags_original + i;
39 			break;
40 		}
41 		else if (flags [i] == LONG_FLAGS_OPEN)
42 		{
43 			const char* aflag = flags + i + 1;
44 			char* needle_close_paren = strchr(aflag, LONG_FLAGS_CLOSE);
45 			const char* param;
46 			char* needle_equal;
47 
48 			if (needle_close_paren == NULL)
49 			{
50 				error (WARNING, "long flags specifier opened with `%c' is not closed `%c': \"%s\"",
51 				       LONG_FLAGS_OPEN, LONG_FLAGS_CLOSE, flags_original);
52 				break;
53 			}
54 
55 			*needle_close_paren = '\0';
56 			needle_equal = strchr(aflag, '=');
57 			if ((needle_equal == NULL || (needle_equal >= needle_close_paren)))
58 			{
59 				needle_equal = NULL;
60 				param = NULL;
61 			}
62 			else
63 			{
64 				param = needle_equal + 1;
65 				*needle_equal = '\0';
66 			}
67 
68 			for ( j = 0 ; j < ndefs ; ++j )
69 				if (defs[j].longStr && (strcmp(aflag, defs[j].longStr) == 0))
70 					defs[j].longProc(aflag, param, data);
71 
72 			if (needle_equal)
73 				*needle_equal = '=';
74 			*needle_close_paren = LONG_FLAGS_CLOSE;
75 
76 			i = needle_close_paren - flags;
77 		}
78 		else for (j = 0 ; j < ndefs ; ++j)
79 			if (flags[i] == defs[j].shortChar)
80 				defs[j].shortProc(flags[i], data);
81 	}
82 	eFree (flags);
83 	return optscript;
84 }
85 
flagsColprintTableNew(void)86 extern struct colprintTable * flagsColprintTableNew (void)
87 {
88 	return colprintTableNew ("L:LETTER", "L:NAME", "L:DESCRIPTION", NULL);
89 }
90 
flagsColprintAddDefinitions(struct colprintTable * table,flagDefinition * def,unsigned int ndefs)91 extern void flagsColprintAddDefinitions (struct colprintTable *table, flagDefinition* def,
92 										 unsigned int ndefs)
93 {
94 	vString *longName = vStringNew ();
95 
96 	for (unsigned int i = 0; i < ndefs; i++)
97 	{
98 		struct colprintLine * line;
99 		char shortChar;
100 		const char *paramName;
101 		const char *description;
102 
103 
104 		line = colprintTableGetNewLine(table);
105 
106 		shortChar = def[i].shortChar;
107 		if (shortChar == '\0')
108 			shortChar = '-';
109 		colprintLineAppendColumnChar (line, shortChar);
110 
111 		vStringCopyS (longName, def[i].longStr? def[i].longStr: RSV_NONE);
112 		paramName = def[i].paramName;
113 		if (paramName)
114 		{
115 			vStringPut (longName, '=');
116 			vStringCatS (longName, paramName);
117 		}
118 		colprintLineAppendColumnVString (line, longName);
119 		vStringClear(longName);
120 
121 		description = def[i].description? def[i].description: "";
122 		colprintLineAppendColumnCString (line, description);
123 	}
124 
125 	vStringDelete(longName);
126 }
127 
flagsColprintCompareLines(struct colprintLine * a,struct colprintLine * b)128 static int flagsColprintCompareLines(struct colprintLine *a , struct colprintLine *b)
129 {
130 	const char *a_letter = colprintLineGetColumn (a, 0);
131 	const char *b_letter = colprintLineGetColumn (b, 0);
132 
133 	if (a_letter[0] != '-' && b_letter[0] == '-')
134 		return -1;
135 	else if (a_letter[0] == '-' && b_letter[0] != '-')
136 		return 1;
137 	else if (a_letter[0] != '-' && b_letter[0] != '-')
138 		return strcmp(a_letter, b_letter);
139 
140 
141 	const char *a_name = colprintLineGetColumn (a, 1);
142 	const char *b_name = colprintLineGetColumn (b, 1);
143 
144 	if (a_name[0] != '_' && b_name[0] == '_')
145 		return -1;
146 	else if (a_name[0] == '_' && b_name[0] != '_')
147 		return 1;
148 
149 	return strcmp(a_name, b_name);
150 }
151 
flagsColprintTablePrint(struct colprintTable * table,bool withListHeader,bool machinable,FILE * fp)152 extern void flagsColprintTablePrint (struct colprintTable *table,
153 									 bool withListHeader, bool machinable, FILE *fp)
154 {
155 	colprintTableSort (table, flagsColprintCompareLines);
156 	colprintTablePrint (table, 0, withListHeader, machinable, fp);
157 }
158