Update dg_olc.c (#143)
Better auto-formatting of dg_scripts. Thanks to haloway13 for the patch.
This commit is contained in:
73
src/dg_olc.c
73
src/dg_olc.c
@@ -1091,59 +1091,74 @@ int format_script(struct descriptor_data *d)
|
|||||||
char nsc[MAX_CMD_LENGTH], *t, line[READ_SIZE];
|
char nsc[MAX_CMD_LENGTH], *t, line[READ_SIZE];
|
||||||
char *sc;
|
char *sc;
|
||||||
size_t len = 0, nlen = 0, llen = 0;
|
size_t len = 0, nlen = 0, llen = 0;
|
||||||
int indent = 0, indent_next = FALSE, found_case = FALSE, i, line_num = 0, ret;
|
int indent = 0, indent_next = FALSE, line_num = 0, ret, i; // Declare i here
|
||||||
|
int block_stack[READ_SIZE]; // Stack to track block types
|
||||||
|
int stack_top = -1; // Initialize stack as empty
|
||||||
|
int switch_indent[READ_SIZE]; // Array to track switch indent levels
|
||||||
|
int switch_top = -1; // Index for switch_indent array
|
||||||
|
int case_indent = 0; // Track indent for case blocks
|
||||||
|
int in_switch = 0; // Flag to indicate if we're inside a switch block
|
||||||
|
|
||||||
if (!d->str || !*d->str)
|
if (!d->str || !*d->str)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
sc = strdup(*d->str); /* we work on a copy, because of strtok() */
|
sc = strdup(*d->str); // Work on a copy
|
||||||
t = strtok(sc, "\n\r");
|
t = strtok(sc, "\n\r");
|
||||||
*nsc = '\0';
|
*nsc = '\0';
|
||||||
|
|
||||||
while (t) {
|
while (t) {
|
||||||
line_num++;
|
line_num++;
|
||||||
skip_spaces(&t);
|
skip_spaces(&t);
|
||||||
if (!strn_cmp(t, "if ", 3) ||
|
|
||||||
!strn_cmp(t, "switch ", 7)) {
|
if (!strn_cmp(t, "switch ", 7)) {
|
||||||
indent_next = TRUE;
|
indent_next = TRUE;
|
||||||
} else if (!strn_cmp(t, "while ", 6)) {
|
stack_top++;
|
||||||
found_case = TRUE; /* so you can 'break' a loop without complains */
|
block_stack[stack_top] = 's'; // 's' for switch
|
||||||
|
switch_top++;
|
||||||
|
switch_indent[switch_top] = indent; // Save current indent level for switch
|
||||||
|
in_switch++; // We're entering a switch block
|
||||||
|
} else if (!strn_cmp(t, "case", 4) || !strn_cmp(t, "default", 7)) {
|
||||||
|
if (in_switch > 0) { // If we're inside a switch
|
||||||
|
indent = switch_indent[switch_top] + 1; // Indent cases one level under switch
|
||||||
|
indent_next = TRUE; // Indent the next line after case
|
||||||
|
case_indent = indent; // Save indent for case block
|
||||||
|
}
|
||||||
|
} else if (!strn_cmp(t, "if ", 3) || !strn_cmp(t, "while ", 6)) {
|
||||||
indent_next = TRUE;
|
indent_next = TRUE;
|
||||||
} else if (!strn_cmp(t, "end", 3) ||
|
stack_top++;
|
||||||
!strn_cmp(t, "done", 4)) {
|
block_stack[stack_top] = 'l'; // 'l' for loop or conditional
|
||||||
if (!indent) {
|
} else if (!strn_cmp(t, "end", 3) || !strn_cmp(t, "done", 4)) {
|
||||||
|
if (stack_top < 0) {
|
||||||
write_to_output(d, "Unmatched 'end' or 'done' (line %d)!\r\n", line_num);
|
write_to_output(d, "Unmatched 'end' or 'done' (line %d)!\r\n", line_num);
|
||||||
free(sc);
|
free(sc);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
indent--;
|
if (block_stack[stack_top] == 's') {
|
||||||
indent_next = FALSE;
|
indent = switch_indent[switch_top]; // Reset to the exact indent level where switch was declared
|
||||||
|
switch_top--; // Decrease switch stack if ending a switch
|
||||||
|
case_indent = 0; // Reset case indent since we're leaving the switch
|
||||||
|
in_switch--; // We're leaving a switch block
|
||||||
|
} else {
|
||||||
|
indent--; // For other blocks like while
|
||||||
|
}
|
||||||
|
stack_top--;
|
||||||
|
indent_next = FALSE; // Reset for next line
|
||||||
} else if (!strn_cmp(t, "else", 4)) {
|
} else if (!strn_cmp(t, "else", 4)) {
|
||||||
if (!indent) {
|
if (stack_top < 0 || block_stack[stack_top] != 'l') {
|
||||||
write_to_output(d, "Unmatched 'else' (line %d)!\r\n", line_num);
|
write_to_output(d, "Unmatched 'else' (line %d)!\r\n", line_num);
|
||||||
free(sc);
|
free(sc);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
indent--;
|
indent--; // Reduce indent for else, then increment for next statement
|
||||||
indent_next = TRUE;
|
indent_next = TRUE;
|
||||||
} else if (!strn_cmp(t, "case", 4) ||
|
|
||||||
!strn_cmp(t, "default", 7)) {
|
|
||||||
if (!indent) {
|
|
||||||
write_to_output(d, "Case/default outside switch (line %d)!\r\n", line_num);
|
|
||||||
free(sc);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (!found_case) /* so we don't indent multiple case statements without a break */
|
|
||||||
indent_next = TRUE;
|
|
||||||
found_case = TRUE;
|
|
||||||
} else if (!strn_cmp(t, "break", 5)) {
|
} else if (!strn_cmp(t, "break", 5)) {
|
||||||
if (!found_case || !indent ) {
|
if (stack_top < 0 || (block_stack[stack_top] != 's' && block_stack[stack_top] != 'l')) {
|
||||||
write_to_output(d, "Break not in case (line %d)!\r\n", line_num);
|
write_to_output(d, "Break not in case or loop (line %d)!\r\n", line_num);
|
||||||
free(sc);
|
free(sc);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
found_case = FALSE;
|
indent = case_indent + 1; // Indent break one level deeper than case
|
||||||
indent--;
|
indent_next = FALSE; // Ensure no automatic increase for next line after break
|
||||||
}
|
}
|
||||||
|
|
||||||
*line = '\0';
|
*line = '\0';
|
||||||
@@ -1169,8 +1184,8 @@ int format_script(struct descriptor_data *d)
|
|||||||
t = strtok(NULL, "\n\r");
|
t = strtok(NULL, "\n\r");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (indent)
|
if (stack_top >= 0)
|
||||||
write_to_output(d, "Unmatched if, while or switch ignored.\r\n");
|
write_to_output(d, "Unmatched block statements ignored.\r\n");
|
||||||
|
|
||||||
free(*d->str);
|
free(*d->str);
|
||||||
*d->str = strdup(nsc);
|
*d->str = strdup(nsc);
|
||||||
|
|||||||
Reference in New Issue
Block a user