blob: 71db9677540e397ce99cde57aad0e1199a1befba [file] [log] [blame]
Miroslav Zagorac70230c62020-12-09 16:54:31 +01001/***
2 * Copyright 2020 HAProxy Technologies
3 *
4 * This file is part of the HAProxy OpenTracing filter.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20#include "include.h"
21
22
23/***
24 * NAME
25 * flt_ot_conf_hdr_init -
26 *
27 * ARGUMENTS
28 * size -
29 * id -
30 * linenum -
31 * head -
32 * err -
33 *
34 * DESCRIPTION
35 * -
36 *
37 * RETURN VALUE
38 * -
39 */
40static void *flt_ot_conf_hdr_init(size_t size, const char *id, int linenum, struct list *head, char **err)
41{
42 struct flt_ot_conf_hdr *retptr = NULL, *ptr;
43
44 FLT_OT_FUNC("%zu, \"%s\", %d, %p, %p:%p", size, id, linenum, head, FLT_OT_DPTR_ARGS(err));
45
46 if (head != NULL)
47 list_for_each_entry(ptr, head, list)
48 if (strcmp(ptr->id, id) == 0) {
49 FLT_OT_ERR("'%s' : already defined", id);
50
51 FLT_OT_RETURN(retptr);
52 }
53
54 retptr = FLT_OT_CALLOC(1, size);
55 if (retptr != NULL) {
56 retptr->id_len = strlen(id);
57 if (retptr->id_len >= FLT_OT_ID_MAXLEN)
58 FLT_OT_ERR("'%s' : name too long", id);
59 else
60 retptr->id = FLT_OT_STRDUP(id);
61
62 if (retptr->id == NULL)
63 FLT_OT_FREE_CLEAR(retptr);
64 }
65
66 if (retptr != NULL) {
67 retptr->cfg_line = linenum;
68
69 if (head != NULL)
Willy Tarreau2b718102021-04-21 07:32:39 +020070 LIST_APPEND(head, &(retptr->list));
Miroslav Zagorac70230c62020-12-09 16:54:31 +010071 } else {
72 FLT_OT_ERR("out of memory");
73 }
74
75 FLT_OT_RETURN(retptr);
76}
77
78
79/***
80 * NAME
81 * flt_ot_conf_ph_init -
82 *
83 * ARGUMENTS
84 * id -
85 * linenum -
86 * head -
87 * err -
88 *
89 * DESCRIPTION
90 * -
91 *
92 * RETURN VALUE
93 * -
94 */
95struct flt_ot_conf_ph *flt_ot_conf_ph_init(const char *id, int linenum, struct list *head, char **err)
96{
97 struct flt_ot_conf_ph *retptr;
98
99 FLT_OT_FUNC("\"%s\", %d, %p, %p:%p", id, linenum, head, FLT_OT_DPTR_ARGS(err));
100
101 retptr = flt_ot_conf_hdr_init(sizeof(*retptr), id, linenum, head, err);
102 if (retptr != NULL)
103 FLT_OT_DBG_CONF_PH("- init ", retptr);
104
105 FLT_OT_RETURN(retptr);
106}
107
108
109/***
110 * NAME
111 * flt_ot_conf_ph_free -
112 *
113 * ARGUMENTS
114 * ptr -
115 *
116 * DESCRIPTION
117 * -
118 *
119 * RETURN VALUE
120 * This function does not return a value.
121 */
122void flt_ot_conf_ph_free(struct flt_ot_conf_ph **ptr)
123{
124 FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr));
125
126 if ((ptr == NULL) || (*ptr == NULL))
127 FLT_OT_RETURN();
128
129 FLT_OT_DBG_CONF_PH("- free ", *ptr);
130
131 FLT_OT_FREE((*ptr)->id);
132 FLT_OT_LIST_DEL(&((*ptr)->list));
133 FLT_OT_FREE_CLEAR(*ptr);
134
135 FLT_OT_RETURN();
136}
137
138
139/***
140 * NAME
141 * flt_ot_conf_sample_expr_init -
142 *
143 * ARGUMENTS
144 * id -
145 * linenum -
146 * head -
147 * err -
148 *
149 * DESCRIPTION
150 * -
151 *
152 * RETURN VALUE
153 * -
154 */
155struct flt_ot_conf_sample_expr *flt_ot_conf_sample_expr_init(const char *id, int linenum, struct list *head, char **err)
156{
157 struct flt_ot_conf_sample_expr *retptr;
158
159 FLT_OT_FUNC("\"%s\", %d, %p, %p:%p", id, linenum, head, FLT_OT_DPTR_ARGS(err));
160
161 retptr = flt_ot_conf_hdr_init(sizeof(*retptr), id, linenum, head, err);
162 if (retptr != NULL)
163 FLT_OT_DBG_CONF_SAMPLE_EXPR("- init ", retptr);
164
165 FLT_OT_RETURN(retptr);
166}
167
168
169/***
170 * NAME
171 * flt_ot_conf_sample_expr_free -
172 *
173 * ARGUMENTS
174 * ptr -
175 *
176 * DESCRIPTION
177 * -
178 *
179 * RETURN VALUE
180 * This function does not return a value.
181 */
182void flt_ot_conf_sample_expr_free(struct flt_ot_conf_sample_expr **ptr)
183{
184 FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr));
185
186 if ((ptr == NULL) || (*ptr == NULL))
187 FLT_OT_RETURN();
188
189 FLT_OT_DBG_CONF_SAMPLE_EXPR("- free ", *ptr);
190
191 FLT_OT_FREE((*ptr)->value);
192 release_sample_expr((*ptr)->expr);
193 FLT_OT_LIST_DEL(&((*ptr)->list));
194 FLT_OT_FREE_CLEAR(*ptr);
195
196 FLT_OT_RETURN();
197}
198
199
200/***
201 * NAME
202 * flt_ot_conf_sample_init -
203 *
204 * ARGUMENTS
205 * args -
206 * linenum -
207 * head -
208 * err -
209 *
210 * DESCRIPTION
211 * -
212 *
213 * RETURN VALUE
214 * -
215 */
216struct flt_ot_conf_sample *flt_ot_conf_sample_init(char **args, int linenum, struct list *head, char **err)
217{
218 struct flt_ot_conf_sample *retptr;
219
220 FLT_OT_FUNC("%p, %d, %p, %p:%p", args, linenum, head, FLT_OT_DPTR_ARGS(err));
221
222 retptr = flt_ot_conf_hdr_init(sizeof(*retptr), args[1], linenum, head, err);
223 if (retptr == NULL)
224 FLT_OT_RETURN(retptr);
225
226 flt_ot_args_to_str(args, 2, &(retptr->value));
227 if (retptr->value == NULL) {
228 FLT_OT_FREE_CLEAR(retptr);
229
230 FLT_OT_RETURN(retptr);
231 }
232
233 retptr->num_exprs = flt_ot_args_count(args) - 2;
234 LIST_INIT(&(retptr->exprs));
235
236 FLT_OT_DBG_CONF_SAMPLE("- init ", retptr);
237
238 FLT_OT_RETURN(retptr);
239}
240
241
242/***
243 * NAME
244 * flt_ot_conf_sample_free -
245 *
246 * ARGUMENTS
247 * ptr -
248 *
249 * DESCRIPTION
250 * -
251 *
252 * RETURN VALUE
253 * This function does not return a value.
254 */
255void flt_ot_conf_sample_free(struct flt_ot_conf_sample **ptr)
256{
257 FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr));
258
259 if ((ptr == NULL) || (*ptr == NULL))
260 FLT_OT_RETURN();
261
262 FLT_OT_DBG_CONF_SAMPLE("- free ", *ptr);
263
264 FLT_OT_FREE((*ptr)->key);
265 FLT_OT_FREE((*ptr)->value);
266 FLT_OT_LIST_DESTROY(sample_expr, &((*ptr)->exprs));
267 FLT_OT_LIST_DEL(&((*ptr)->list));
268 FLT_OT_FREE_CLEAR(*ptr);
269
270 FLT_OT_RETURN();
271}
272
273
274/***
275 * NAME
276 * flt_ot_conf_str_init -
277 *
278 * ARGUMENTS
279 * id -
280 * linenum -
281 * head -
282 * err -
283 *
284 * DESCRIPTION
285 * -
286 *
287 * RETURN VALUE
288 * -
289 */
290struct flt_ot_conf_str *flt_ot_conf_str_init(const char *id, int linenum, struct list *head, char **err)
291{
292 struct flt_ot_conf_str *retptr;
293
294 FLT_OT_FUNC("\"%s\", %d, %p, %p:%p", id, linenum, head, FLT_OT_DPTR_ARGS(err));
295
296 retptr = flt_ot_conf_hdr_init(sizeof(*retptr), id, linenum, head, err);
297 if (retptr != NULL)
298 FLT_OT_DBG_CONF_STR("- init ", retptr);
299
300 FLT_OT_RETURN(retptr);
301}
302
303
304/***
305 * NAME
306 * flt_ot_conf_str_free -
307 *
308 * ARGUMENTS
309 * ptr -
310 *
311 * DESCRIPTION
312 * -
313 *
314 * RETURN VALUE
315 * This function does not return a value.
316 */
317void flt_ot_conf_str_free(struct flt_ot_conf_str **ptr)
318{
319 FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr));
320
321 if ((ptr == NULL) || (*ptr == NULL))
322 FLT_OT_RETURN();
323
324 FLT_OT_DBG_CONF_STR("- free ", *ptr);
325
326 FLT_OT_FREE((*ptr)->str);
327 FLT_OT_LIST_DEL(&((*ptr)->list));
328 FLT_OT_FREE_CLEAR(*ptr);
329
330 FLT_OT_RETURN();
331}
332
333
334/***
335 * NAME
336 * flt_ot_conf_context_init -
337 *
338 * ARGUMENTS
339 * id -
340 * linenum -
341 * head -
342 * err -
343 *
344 * DESCRIPTION
345 * -
346 *
347 * RETURN VALUE
348 * -
349 */
350struct flt_ot_conf_context *flt_ot_conf_context_init(const char *id, int linenum, struct list *head, char **err)
351{
352 struct flt_ot_conf_context *retptr;
353
354 FLT_OT_FUNC("\"%s\", %d, %p, %p:%p", id, linenum, head, FLT_OT_DPTR_ARGS(err));
355
356 retptr = flt_ot_conf_hdr_init(sizeof(*retptr), id, linenum, head, err);
357 if (retptr != NULL)
358 FLT_OT_DBG_CONF_CONTEXT("- init ", retptr);
359
360 FLT_OT_RETURN(retptr);
361}
362
363
364/***
365 * NAME
366 * flt_ot_conf_context_free -
367 *
368 * ARGUMENTS
369 * ptr -
370 *
371 * DESCRIPTION
372 * -
373 *
374 * RETURN VALUE
375 * This function does not return a value.
376 */
377void flt_ot_conf_context_free(struct flt_ot_conf_context **ptr)
378{
379 FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr));
380
381 if ((ptr == NULL) || (*ptr == NULL))
382 FLT_OT_RETURN();
383
384 FLT_OT_DBG_CONF_CONTEXT("- free ", *ptr);
385
386 FLT_OT_FREE((*ptr)->id);
387 FLT_OT_LIST_DEL(&((*ptr)->list));
388 FLT_OT_FREE_CLEAR(*ptr);
389
390 FLT_OT_RETURN();
391}
392
393
394/***
395 * NAME
396 * flt_ot_conf_span_init -
397 *
398 * ARGUMENTS
399 * id -
400 * linenum -
401 * head -
402 * err -
403 *
404 * DESCRIPTION
405 * -
406 *
407 * RETURN VALUE
408 * -
409 */
410struct flt_ot_conf_span *flt_ot_conf_span_init(const char *id, int linenum, struct list *head, char **err)
411{
412 struct flt_ot_conf_span *retptr;
413
414 FLT_OT_FUNC("\"%s\", %d, %p, %p:%p", id, linenum, head, FLT_OT_DPTR_ARGS(err));
415
416 retptr = flt_ot_conf_hdr_init(sizeof(*retptr), id, linenum, head, err);
417 if (retptr == NULL)
418 FLT_OT_RETURN(retptr);
419
420 LIST_INIT(&(retptr->tags));
421 LIST_INIT(&(retptr->logs));
422 LIST_INIT(&(retptr->baggages));
423
424 FLT_OT_DBG_CONF_SPAN("- init ", retptr);
425
426 FLT_OT_RETURN(retptr);
427}
428
429
430/***
431 * NAME
432 * flt_ot_conf_span_free -
433 *
434 * ARGUMENTS
435 * ptr -
436 *
437 * DESCRIPTION
438 * -
439 *
440 * RETURN VALUE
441 * This function does not return a value.
442 */
443void flt_ot_conf_span_free(struct flt_ot_conf_span **ptr)
444{
445 FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr));
446
447 if ((ptr == NULL) || (*ptr == NULL))
448 FLT_OT_RETURN();
449
450 FLT_OT_DBG_CONF_SPAN("- free ", *ptr);
451
452 FLT_OT_FREE((*ptr)->id);
453 FLT_OT_FREE((*ptr)->ref_id);
454 FLT_OT_FREE((*ptr)->ctx_id);
455 FLT_OT_LIST_DESTROY(sample, &((*ptr)->tags));
456 FLT_OT_LIST_DESTROY(sample, &((*ptr)->logs));
457 FLT_OT_LIST_DESTROY(sample, &((*ptr)->baggages));
458 FLT_OT_LIST_DEL(&((*ptr)->list));
459 FLT_OT_FREE_CLEAR(*ptr);
460
461 FLT_OT_RETURN();
462}
463
464
465/***
466 * NAME
467 * flt_ot_conf_scope_init -
468 *
469 * ARGUMENTS
470 * id -
471 * linenum -
472 * head -
473 * err -
474 *
475 * DESCRIPTION
476 * -
477 *
478 * RETURN VALUE
479 * -
480 */
481struct flt_ot_conf_scope *flt_ot_conf_scope_init(const char *id, int linenum, struct list *head, char **err)
482{
483 struct flt_ot_conf_scope *retptr = NULL;
484
485 FLT_OT_FUNC("\"%s\", %d, %p, %p:%p", id, linenum, head, FLT_OT_DPTR_ARGS(err));
486
487 retptr = flt_ot_conf_hdr_init(sizeof(*retptr), id, linenum, head, err);
488 if (retptr == NULL)
489 FLT_OT_RETURN(retptr);
490
491 LIST_INIT(&(retptr->acls));
492 LIST_INIT(&(retptr->contexts));
493 LIST_INIT(&(retptr->spans));
494 LIST_INIT(&(retptr->finish));
495
496 FLT_OT_DBG_CONF_SCOPE("- init ", retptr);
497
498 FLT_OT_RETURN(retptr);
499}
500
501/***
502 * NAME
503 * flt_ot_conf_scope_free -
504 *
505 * ARGUMENTS
506 * ptr -
507 *
508 * DESCRIPTION
509 * -
510 *
511 * RETURN VALUE
512 * This function does not return a value.
513 */
514void flt_ot_conf_scope_free(struct flt_ot_conf_scope **ptr)
515{
516 struct acl *acl, *aclback;
517
518 FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr));
519
520 if ((ptr == NULL) || (*ptr == NULL))
521 FLT_OT_RETURN();
522
523 FLT_OT_DBG_CONF_SCOPE("- free ", *ptr);
524
525 FLT_OT_FREE((*ptr)->id);
526 list_for_each_entry_safe(acl, aclback, &((*ptr)->acls), list) {
527 prune_acl(acl);
528 FLT_OT_LIST_DEL(&(acl->list));
529 FLT_OT_FREE(acl);
530 }
531 if ((*ptr)->cond != NULL) {
532 prune_acl_cond((*ptr)->cond);
533 FLT_OT_FREE((*ptr)->cond);
534 }
535 FLT_OT_LIST_DESTROY(context, &((*ptr)->contexts));
536 FLT_OT_LIST_DESTROY(span, &((*ptr)->spans));
537 FLT_OT_LIST_DESTROY(str, &((*ptr)->finish));
538 FLT_OT_LIST_DEL(&((*ptr)->list));
539 FLT_OT_FREE_CLEAR(*ptr);
540
541 FLT_OT_RETURN();
542}
543
544
545/***
546 * NAME
547 * flt_ot_conf_group_init -
548 *
549 * ARGUMENTS
550 * id -
551 * linenum -
552 * head -
553 * err -
554 *
555 * DESCRIPTION
556 * -
557 *
558 * RETURN VALUE
559 * -
560 */
561struct flt_ot_conf_group *flt_ot_conf_group_init(const char *id, int linenum, struct list *head, char **err)
562{
563 struct flt_ot_conf_group *retptr;
564
565 FLT_OT_FUNC("\"%s\", %d, %p, %p:%p", id, linenum, head, FLT_OT_DPTR_ARGS(err));
566
567 retptr = flt_ot_conf_hdr_init(sizeof(*retptr), id, linenum, head, err);
568 if (retptr == NULL)
569 FLT_OT_RETURN(retptr);
570
571 LIST_INIT(&(retptr->ph_scopes));
572
573 FLT_OT_DBG_CONF_GROUP("- init ", retptr);
574
575 FLT_OT_RETURN(retptr);
576}
577
578
579/***
580 * NAME
581 * flt_ot_conf_group_free -
582 *
583 * ARGUMENTS
584 * ptr -
585 *
586 * DESCRIPTION
587 * -
588 *
589 * RETURN VALUE
590 * This function does not return a value.
591 */
592void flt_ot_conf_group_free(struct flt_ot_conf_group **ptr)
593{
594 FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr));
595
596 if ((ptr == NULL) || (*ptr == NULL))
597 FLT_OT_RETURN();
598
599 FLT_OT_DBG_CONF_GROUP("- free ", *ptr);
600
601 FLT_OT_FREE((*ptr)->id);
602 FLT_OT_LIST_DESTROY(ph_scope, &((*ptr)->ph_scopes));
603 FLT_OT_LIST_DEL(&((*ptr)->list));
604 FLT_OT_FREE_CLEAR(*ptr);
605
606 FLT_OT_RETURN();
607}
608
609
610/***
611 * NAME
612 * flt_ot_conf_tracer_init -
613 *
614 * ARGUMENTS
615 * id -
616 * linenum -
617 * err -
618 *
619 * DESCRIPTION
620 * -
621 *
622 * RETURN VALUE
623 * -
624 */
625struct flt_ot_conf_tracer *flt_ot_conf_tracer_init(const char *id, int linenum, char **err)
626{
627 struct flt_ot_conf_tracer *retptr;
628
629 FLT_OT_FUNC("\"%s\", %d, %p:%p", id, linenum, FLT_OT_DPTR_ARGS(err));
630
631 retptr = flt_ot_conf_hdr_init(sizeof(*retptr), id, linenum, NULL, err);
632 if (retptr == NULL)
633 FLT_OT_RETURN(retptr);
634
635 retptr->rate_limit = FLT_OT_FLOAT_U32(FLT_OT_RATE_LIMIT_MAX, FLT_OT_RATE_LIMIT_MAX);
636 init_new_proxy(&(retptr->proxy_log));
637 LIST_INIT(&(retptr->acls));
638 LIST_INIT(&(retptr->ph_groups));
639 LIST_INIT(&(retptr->ph_scopes));
640
641 FLT_OT_DBG_CONF_TRACER("- init ", retptr);
642
643 FLT_OT_RETURN(retptr);
644}
645
646
647/***
648 * NAME
649 * flt_ot_conf_tracer_free -
650 *
651 * ARGUMENTS
652 * ptr -
653 *
654 * DESCRIPTION
655 * -
656 *
657 * RETURN VALUE
658 * This function does not return a value.
659 */
660void flt_ot_conf_tracer_free(struct flt_ot_conf_tracer **ptr)
661{
662 struct acl *acl, *aclback;
663 struct logsrv *logsrv, *logsrvback;
664
665 FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr));
666
667 if ((ptr == NULL) || (*ptr == NULL))
668 FLT_OT_RETURN();
669
670 FLT_OT_DBG_CONF_TRACER("- free ", *ptr);
671
672 FLT_OT_FREE((*ptr)->id);
673 FLT_OT_FREE((*ptr)->config);
674 FLT_OT_FREE((*ptr)->plugin);
675 FLT_OT_DBG(2, "- deleting acls list %s", flt_ot_list_debug(&((*ptr)->acls)));
676 list_for_each_entry_safe(acl, aclback, &((*ptr)->acls), list) {
677 prune_acl(acl);
678 FLT_OT_LIST_DEL(&(acl->list));
679 FLT_OT_FREE(acl);
680 }
681 FLT_OT_DBG(2, "- deleting proxy_log.logsrvs list %s", flt_ot_list_debug(&((*ptr)->proxy_log.logsrvs)));
682 list_for_each_entry_safe(logsrv, logsrvback, &((*ptr)->proxy_log.logsrvs), list) {
Willy Tarreau2b718102021-04-21 07:32:39 +0200683 LIST_DELETE(&(logsrv->list));
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100684 FLT_OT_FREE(logsrv);
685 }
686 FLT_OT_LIST_DESTROY(ph_group, &((*ptr)->ph_groups));
687 FLT_OT_LIST_DESTROY(ph_scope, &((*ptr)->ph_scopes));
688 FLT_OT_FREE_CLEAR(*ptr);
689
690 FLT_OT_RETURN();
691}
692
693
694/***
695 * NAME
696 * flt_ot_conf_init -
697 *
698 * ARGUMENTS
699 * px -
700 *
701 * DESCRIPTION
702 * -
703 *
704 * RETURN VALUE
705 * -
706 */
707struct flt_ot_conf *flt_ot_conf_init(struct proxy *px)
708{
709 struct flt_ot_conf *retptr;
710
711 FLT_OT_FUNC("%p", px);
712
713 retptr = FLT_OT_CALLOC(1, sizeof(*retptr));
714 if (retptr == NULL)
715 FLT_OT_RETURN(retptr);
716
717 retptr->proxy = px;
718 LIST_INIT(&(retptr->groups));
719 LIST_INIT(&(retptr->scopes));
720
721 FLT_OT_DBG_CONF("- init ", retptr);
722
723 FLT_OT_RETURN(retptr);
724}
725
726
727/***
728 * NAME
729 * flt_ot_conf_free -
730 *
731 * ARGUMENTS
732 * ptr -
733 *
734 * DESCRIPTION
735 * -
736 *
737 * RETURN VALUE
738 * This function does not return a value.
739 */
740void flt_ot_conf_free(struct flt_ot_conf **ptr)
741{
742 FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr));
743
744 if ((ptr == NULL) || (*ptr == NULL))
745 FLT_OT_RETURN();
746
747 FLT_OT_DBG_CONF("- free ", *ptr);
748
749 FLT_OT_FREE((*ptr)->id);
750 FLT_OT_FREE((*ptr)->cfg_file);
751 flt_ot_conf_tracer_free(&((*ptr)->tracer));
752 FLT_OT_LIST_DESTROY(group, &((*ptr)->groups));
753 FLT_OT_LIST_DESTROY(scope, &((*ptr)->scopes));
754 FLT_OT_FREE_CLEAR(*ptr);
755
756 FLT_OT_RETURN();
757}
758
759/*
760 * Local variables:
761 * c-indent-level: 8
762 * c-basic-offset: 8
763 * End:
764 *
765 * vi: noexpandtab shiftwidth=8 tabstop=8
766 */