1 /*
2 ** Copyright (C) 2008-2020 by Carnegie Mellon University.
3 **
4 ** @OPENSOURCE_LICENSE_START@
5 ** See license information in ../../LICENSE.txt
6 ** @OPENSOURCE_LICENSE_END@
7 */
8
9 /*
10 ** skoptions-notes.c
11 **
12 ** Provide support for the --note-add, --note-file-add, and
13 ** --note-strip switches.
14 **
15 */
16
17
18 #include <silk/silk.h>
19
20 RCSIDENT("$SiLK: skoptions-notes.c ef14e54179be 2020-04-14 21:57:45Z mthomas $");
21
22 #include <silk/utils.h>
23 #include <silk/skstream.h>
24 #include <silk/skvector.h>
25
26
27 /* LOCAL DEFINES AND TYPEDEFS */
28
29 typedef enum {
30 OPT_NOTE_STRIP,
31 OPT_NOTE_ADD,
32 OPT_NOTE_FILE_ADD
33 } noteopt_type_t;
34
35 typedef struct noteopt_arg_st {
36 noteopt_type_t type;
37 const char *arg;
38 } noteopt_arg_t;
39
40
41 /* LOCAL VARIABLE DEFINITIONS */
42
43 /* a vector of noteopt_arg_t that is filled in by the user's use of
44 * the --note-add and --note-file-add switches. */
45 static sk_vector_t *noteopt_vec = NULL;
46
47 /* whether the application wants to ignore the --note-strip option */
48 static int noteopt_strip_ignored = 0;
49
50
51
52 /* OPTIONS SETUP */
53
54 static struct option noteopt_options[] = {
55 {"note-strip", NO_ARG, 0, OPT_NOTE_STRIP},
56 {"note-add", REQUIRED_ARG, 0, OPT_NOTE_ADD},
57 {"note-file-add", REQUIRED_ARG, 0, OPT_NOTE_FILE_ADD},
58 {0,0,0,0} /* sentinel */
59 };
60
61 static const char *noteopt_help[] = {
62 "Do not copy notes from the input files to the output file",
63 ("Store the textual argument in the output SiLK file's header\n"
64 "\tas an annotation. Switch may be repeated to add multiple annotations"),
65 ("Store the content of the named text file in the output\n"
66 "\tSiLK file's header as an annotation. Switch may be repeated."),
67 (char*)NULL
68 };
69
70
71 /* FUNCTION DEFINITIONS */
72
73
74 static int
noteopt_handler(clientData cData,int opt_index,char * opt_arg)75 noteopt_handler(
76 clientData cData,
77 int opt_index,
78 char *opt_arg)
79 {
80 int *note_strip = (int*)cData;
81 noteopt_arg_t note;
82
83 switch ((noteopt_type_t)opt_index) {
84 case OPT_NOTE_ADD:
85 case OPT_NOTE_FILE_ADD:
86 note.type = (noteopt_type_t)opt_index;
87 note.arg = opt_arg;
88 if (noteopt_vec == NULL) {
89 noteopt_vec = skVectorNew(sizeof(noteopt_arg_t));
90 if (noteopt_vec == NULL) {
91 skAppPrintOutOfMemory(NULL);
92 return 1;
93 }
94 }
95 if (skVectorAppendValue(noteopt_vec, ¬e)) {
96 skAppPrintOutOfMemory(NULL);
97 return 1;
98 }
99 break;
100
101 case OPT_NOTE_STRIP:
102 assert(noteopt_strip_ignored == 0);
103 *note_strip = 1;
104 break;
105
106 }
107
108 return 0;
109 }
110
111
112 int
skOptionsNotesRegister(int * note_strip)113 skOptionsNotesRegister(
114 int *note_strip)
115 {
116 if (note_strip == NULL) {
117 noteopt_strip_ignored = 1;
118 }
119
120 assert((sizeof(noteopt_options)/sizeof(struct option))
121 == (sizeof(noteopt_help)/sizeof(char*)));
122
123 return skOptionsRegister(¬eopt_options[noteopt_strip_ignored],
124 ¬eopt_handler, (clientData)note_strip);
125 }
126
127
128 void
skOptionsNotesTeardown(void)129 skOptionsNotesTeardown(
130 void)
131 {
132 if (noteopt_vec) {
133 skVectorDestroy(noteopt_vec);
134 }
135 noteopt_vec = NULL;
136 }
137
138
139 void
skOptionsNotesUsage(FILE * fh)140 skOptionsNotesUsage(
141 FILE *fh)
142 {
143 int i;
144
145 for (i = noteopt_strip_ignored; noteopt_options[i].name; ++i) {
146 fprintf(fh, "--%s %s. %s\n", noteopt_options[i].name,
147 SK_OPTION_HAS_ARG(noteopt_options[i]), noteopt_help[i]);
148 }
149 }
150
151
152 int
skOptionsNotesAddToStream(skstream_t * stream)153 skOptionsNotesAddToStream(
154 skstream_t *stream)
155 {
156 sk_file_header_t *hdr = skStreamGetSilkHeader(stream);
157 noteopt_arg_t *note;
158 size_t i;
159 int rv = 0;
160
161 if (noteopt_vec) {
162 for (i = 0;
163 ((note = (noteopt_arg_t*)skVectorGetValuePointer(noteopt_vec, i))
164 != NULL);
165 ++i)
166 {
167 if (note->type == OPT_NOTE_ADD) {
168 rv = skHeaderAddAnnotation(hdr, note->arg);
169 } else {
170 rv = skHeaderAddAnnotationFromFile(hdr, note->arg);
171 }
172 if (rv) {
173 return rv;
174 }
175 }
176 }
177
178 return rv;
179 }
180
181
182 /*
183 ** Local Variables:
184 ** mode:c
185 ** indent-tabs-mode:nil
186 ** c-basic-offset:4
187 ** End:
188 */
189