Changeset View
Standalone View
args.c
Show First 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | |||||
/* profile specials for specials */ | /* profile specials for specials */ | ||||
#define IGN 1 /* ignore it */ | #define IGN 1 /* ignore it */ | ||||
#define CLI 2 /* case label indent (float) */ | #define CLI 2 /* case label indent (float) */ | ||||
#define STDIN 3 /* use stdin */ | #define STDIN 3 /* use stdin */ | ||||
#define KEY 4 /* type (keyword) */ | #define KEY 4 /* type (keyword) */ | ||||
static void scan_profile(FILE *); | static void scan_profile(FILE *); | ||||
#define KEY_FILE 5 /* only used for args */ | |||||
const char *option_source = "?"; | const char *option_source = "?"; | ||||
void add_typedefs_from_file(const char *str); | |||||
/* | /* | ||||
* N.B.: because of the way the table here is scanned, options whose names are | * N.B.: because of the way the table here is scanned, options whose names are | ||||
* substrings of other options must occur later; that is, with -lp vs -l, -lp | * substrings of other options must occur later; that is, with -lp vs -l, -lp | ||||
* must be first. Also, while (most) booleans occur more than once, the last | * must be first. Also, while (most) booleans occur more than once, the last | ||||
* default value is the one actually assigned. | * default value is the one actually assigned. | ||||
*/ | */ | ||||
struct pro { | struct pro { | ||||
const char *p_name; /* name, e.g. -bl, -cli */ | const char *p_name; /* name, e.g. -bl, -cli */ | ||||
int p_type; /* type (int, bool, special) */ | int p_type; /* type (int, bool, special) */ | ||||
int p_default; /* the default value (if int) */ | int p_default; /* the default value (if int) */ | ||||
int p_special; /* depends on type */ | int p_special; /* depends on type */ | ||||
int *p_obj; /* the associated variable */ | int *p_obj; /* the associated variable */ | ||||
} pro[] = { | } pro[] = { | ||||
{"T", PRO_SPECIAL, 0, KEY, 0}, | {"T", PRO_SPECIAL, 0, KEY, 0}, | ||||
{"U", PRO_SPECIAL, 0, KEY_FILE, 0}, | |||||
{"bacc", PRO_BOOL, false, ON, &blanklines_around_conditional_compilation}, | {"bacc", PRO_BOOL, false, ON, &blanklines_around_conditional_compilation}, | ||||
{"badp", PRO_BOOL, false, ON, &blanklines_after_declarations_at_proctop}, | {"badp", PRO_BOOL, false, ON, &blanklines_after_declarations_at_proctop}, | ||||
{"bad", PRO_BOOL, false, ON, &blanklines_after_declarations}, | {"bad", PRO_BOOL, false, ON, &blanklines_after_declarations}, | ||||
{"bap", PRO_BOOL, false, ON, &blanklines_after_procs}, | {"bap", PRO_BOOL, false, ON, &blanklines_after_procs}, | ||||
{"bbb", PRO_BOOL, false, ON, &blanklines_before_blockcomments}, | {"bbb", PRO_BOOL, false, ON, &blanklines_before_blockcomments}, | ||||
{"bc", PRO_BOOL, true, OFF, &ps.leave_comma}, | {"bc", PRO_BOOL, true, OFF, &ps.leave_comma}, | ||||
{"bl", PRO_BOOL, true, OFF, &btype_2}, | {"bl", PRO_BOOL, true, OFF, &btype_2}, | ||||
{"br", PRO_BOOL, true, ON, &btype_2}, | {"br", PRO_BOOL, true, ON, &btype_2}, | ||||
Show All 40 Lines | struct pro { | ||||
{"nfc1", PRO_BOOL, true, OFF, &format_col1_comments}, | {"nfc1", PRO_BOOL, true, OFF, &format_col1_comments}, | ||||
{"nfcb", PRO_BOOL, true, OFF, &format_block_comments}, | {"nfcb", PRO_BOOL, true, OFF, &format_block_comments}, | ||||
{"nip", PRO_BOOL, true, OFF, &ps.indent_parameters}, | {"nip", PRO_BOOL, true, OFF, &ps.indent_parameters}, | ||||
{"nlp", PRO_BOOL, true, OFF, &lineup_to_parens}, | {"nlp", PRO_BOOL, true, OFF, &lineup_to_parens}, | ||||
{"npcs", PRO_BOOL, false, OFF, &proc_calls_space}, | {"npcs", PRO_BOOL, false, OFF, &proc_calls_space}, | ||||
{"npro", PRO_SPECIAL, 0, IGN, 0}, | {"npro", PRO_SPECIAL, 0, IGN, 0}, | ||||
{"npsl", PRO_BOOL, true, OFF, &procnames_start_line}, | {"npsl", PRO_BOOL, true, OFF, &procnames_start_line}, | ||||
{"nps", PRO_BOOL, false, OFF, &pointer_as_binop}, | {"nps", PRO_BOOL, false, OFF, &pointer_as_binop}, | ||||
{"nsac", PRO_BOOL, false, OFF, &space_after_cast}, | |||||
{"nsc", PRO_BOOL, true, OFF, &star_comment_cont}, | {"nsc", PRO_BOOL, true, OFF, &star_comment_cont}, | ||||
{"nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines}, | {"nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines}, | ||||
{"nut", PRO_BOOL, true, OFF, &use_tabs}, | {"nut", PRO_BOOL, true, OFF, &use_tabs}, | ||||
{"nv", PRO_BOOL, false, OFF, &verbose}, | {"nv", PRO_BOOL, false, OFF, &verbose}, | ||||
{"pcs", PRO_BOOL, false, ON, &proc_calls_space}, | {"pcs", PRO_BOOL, false, ON, &proc_calls_space}, | ||||
{"psl", PRO_BOOL, true, ON, &procnames_start_line}, | {"psl", PRO_BOOL, true, ON, &procnames_start_line}, | ||||
{"ps", PRO_BOOL, false, ON, &pointer_as_binop}, | {"ps", PRO_BOOL, false, ON, &pointer_as_binop}, | ||||
{"sac", PRO_BOOL, false, ON, &space_after_cast}, | |||||
{"sc", PRO_BOOL, true, ON, &star_comment_cont}, | {"sc", PRO_BOOL, true, ON, &star_comment_cont}, | ||||
{"sob", PRO_BOOL, false, ON, &swallow_optional_blanklines}, | {"sob", PRO_BOOL, false, ON, &swallow_optional_blanklines}, | ||||
{"st", PRO_SPECIAL, 0, STDIN, 0}, | {"st", PRO_SPECIAL, 0, STDIN, 0}, | ||||
{"ta", PRO_BOOL, false, ON, &auto_typedefs}, | {"ta", PRO_BOOL, false, ON, &auto_typedefs}, | ||||
{"troff", PRO_BOOL, false, ON, &troff}, | {"troff", PRO_BOOL, false, ON, &troff}, | ||||
{"ut", PRO_BOOL, true, ON, &use_tabs}, | {"ut", PRO_BOOL, true, ON, &use_tabs}, | ||||
{"v", PRO_BOOL, false, ON, &verbose}, | {"v", PRO_BOOL, false, ON, &verbose}, | ||||
/* whew! */ | /* whew! */ | ||||
▲ Show 20 Lines • Show All 123 Lines • ▼ Show 20 Lines | found: | ||||
case KEY: | case KEY: | ||||
if (*param_start == 0) | if (*param_start == 0) | ||||
goto need_param; | goto need_param; | ||||
{ | { | ||||
char *str = strdup(param_start); | char *str = strdup(param_start); | ||||
if (str == NULL) | if (str == NULL) | ||||
err(1, NULL); | err(1, NULL); | ||||
addkey(str, 4); | add_typename(str); | ||||
} | } | ||||
break; | break; | ||||
case KEY_FILE: | |||||
if (*param_start == 0) | |||||
goto need_param; | |||||
add_typedefs_from_file(param_start); | |||||
break; | |||||
default: | default: | ||||
errx(1, "set_option: internal error: p_special %d", p->p_special); | errx(1, "set_option: internal error: p_special %d", p->p_special); | ||||
} | } | ||||
break; | break; | ||||
case PRO_BOOL: | case PRO_BOOL: | ||||
if (p->p_special == OFF) | if (p->p_special == OFF) | ||||
*p->p_obj = false; | *p->p_obj = false; | ||||
Show All 11 Lines | break; | ||||
case PRO_FONT: | case PRO_FONT: | ||||
parsefont((struct fstate *) p->p_obj, param_start); | parsefont((struct fstate *) p->p_obj, param_start); | ||||
break; | break; | ||||
default: | default: | ||||
errx(1, "set_option: internal error: p_type %d", p->p_type); | errx(1, "set_option: internal error: p_type %d", p->p_type); | ||||
} | } | ||||
} | |||||
void | |||||
add_typedefs_from_file(const char *str) | |||||
{ | |||||
FILE *file; | |||||
char line[BUFSIZ]; | |||||
char *copy; | |||||
if ((file = fopen(param_start, "r")) == NULL) { | |||||
fprintf(stderr, "indent: cannot open file %s\n", str); | |||||
exit(1); | |||||
} | |||||
while ((fgets(line, BUFSIZ, file)) != NULL) { | |||||
bapt: why not using getline(3) here to avoid having a limitation on the length of the line? which… | |||||
Not Done Inline ActionsNo specific reason, that's just the way it had been done for the Postgres fork and I didn't bother to improve it as you suggest. pstef: No specific reason, that's just the way it had been done for the Postgres fork and I didn't… | |||||
/* Remove trailing whitespace */ | |||||
line[strcspn(line, " \t\n\r")] = '\0'; | |||||
Not Done Inline Actionsfgets does not guarantee that there is trailing whitespace. In case there is no trailing whitespace at EOF, this will set line[0] = '\0'; lattera-gmail.com: fgets does not guarantee that there is trailing whitespace. In case there is no trailing… | |||||
Not Done Inline ActionsWhy would that be a problem? pstef: Why would that be a problem? | |||||
Not Done Inline ActionsIt'd be a problem because if: char *copy; char *line = "some data that should be parsed here but isn't due to no trailing whitespace"; size_t lastchar = 0; /* strcspn(line, " \t\n\r") will return 0 */ line[lastchar] = '\0'; copy = strdup(line); add_typename(copy); The copy variable ends up containing an empty string, even though there's data to be parsed. Since my comment was based on a glance, not on a full and careful review, it's likely that this piece of data is getting parsed for a reason. Why parse it if you don't care it's an empty string, even when it's not? lattera-gmail.com: It'd be a problem because if:
```
char *copy;
char *line = "some data that should be parsed… | |||||
Not Done Inline Actionsstrcspn("some data that should be parsed here but isn't due to no trailing whitespace", " \t\n\r") will return 4, not 0. 4 is the length of the segment of the first string which consists entirely of characters not from the second string. I argue that truncation here is not doing any harm, bacause typedef names cannot include any of the characters from the second string. pstef: strcspn("some data that should be parsed here but isn't due to no trailing whitespace", "… | |||||
Not Done Inline ActionsAfter re-reading the manpage for strcspn, it looks like I missed an important detail: "it computes the string array index of the first character of s which is also in charset, else the index of the first null character." So if that trailing whitespace isn't found, then it'll reduce it to line[strlen(line)], in which case, you'll be fine. So disregard this set of comments. lattera-gmail.com: After re-reading the manpage for strcspn, it looks like I missed an important detail: "it… | |||||
if ((copy = strdup(line)) == NULL) { | |||||
err(1, NULL); | |||||
} | |||||
add_typename(copy); | |||||
} | |||||
fclose(file); | |||||
} | } |
why not using getline(3) here to avoid having a limitation on the length of the line? which will also address the @lattera-gmail.com problem below