//#define BUFFERSIZE 4096
#define BUFFERSIZE 256
+#define TABSIZE 2
+
+/* type definition */
+
+typedef enum {
+ e_unknown = 0,
+ e_ansi,
+ e_kr
+} cmode_t;
/* gobal variables */
/* indent function */
-int indent (FILE *fin, FILE *fout) {
- char buffer[BUFFERSIZE + 1] = {0};
+int indent (FILE *fin, FILE *fout, cmode_t cmode) {
+ char bufin[BUFFERSIZE + 1] = {0};
+ char bufout[BUFFERSIZE * TABSIZE + 1] = {0};
+ size_t i, nb;
+ size_t nbindent = 0;
+ int begin = 1;
+ int parent = 0;
+ int comment = 0;
+ int newline = 0;
+ int string = 0;
+ int character = 0;
+ int special = 0;
+ int space = 0;
- char *pt = buffer;
while (!feof (fin)) {
- int nb = fread (pt, 1, BUFFERSIZE - (pt - buffer), fin);
- VERBOSE (DEBUG, fprintf (stdout, "buffer: %d\n", nb));
- pt = buffer;
- int i = 0;
- while (pt[i] != '\0') {
- if (pt[i++] == '\n') {
- pt[i - 1] = 0;
-
- /* process line */
- char *line = pt;
- VERBOSE (DEBUG, fprintf (stdout, "line: %d\n", strlen (line)));
- VERBOSE (DEBUG, fprintf (stdout, "out: %s\n", line));
- int k = 0;
- int begin = 0;
- while (line[k] != '\0') {
- switch (line[k]) {
- case ' ':
- case '\t':
- if (begin) trailing++;
+ memset (bufin, 0, sizeof (bufin));
+ memset (bufout, 0, sizeof (bufout));
+
+ /* read file */
+ nb = fread (bufin, 1, BUFFERSIZE, fin);
+ VERBOSE (DEBUG, fprintf (stdout, "buffer in: %d\n", nb));
+ if (errno != 0) {
+ VERBOSE (ERROR, fprintf (stderr, "can't read file (%d)\n", errno));
+ exit (1);
+ }
+
+ /* process line */
+ char *ptin = bufin;
+ char *ptout = bufout;
+ while (*ptin != '\0') {
+ VERBOSE (DEBUG, fprintf (stdout, "caracter: %c\n", *ptin));
+
+ /* manage comment */
+ if (comment > 0) {
+ if (((comment == 1) && (*ptin == '\n')) ||
+ ((comment == 2) && ((*ptin == '*') && (ptin[1] == '/')))) {
+ comment = 0;
+ }
+ special = 0;
+ *ptout++ = *ptin++;
+ continue;
+ }
+
+ /* manage indent */
+ switch (*ptin) {
+ case '/':
+ comment = (ptin[1] == '/') ? 1 : (ptin[1] == '*') ? 2 : 0;
+ if (begin) {
+ for (i = 0; i < nbindent * TABSIZE; i++) {
+ *ptout++ = ' ';
+ }
+ begin = 0;
+ }
+ *ptout++ = *ptin;
+ break;
+ case ' ':
+ case '\t':
+ if (begin == 0) {
+ if ((string) || (!space)) {
+ *ptout++ = *ptin;
+ }
+ }
+ break;
+ case '{':
+ *ptout++ = '\n';
+ for (i = 0; i < nbindent * TABSIZE; i++) {
+ *ptout++ = ' ';
+ }
+ *ptout++ = *ptin;
+ *ptout++ = '\n';
+ nbindent++;
+ newline = 1;
+ begin = 1;
+ break;
+ case '}':
+ *ptout++ = '\n';
+ nbindent--;
+ for (i = 0; i < nbindent * TABSIZE; i++) {
+ *ptout++ = ' ';
+ }
+ *ptout++ = *ptin;
+ if (ptin[1] != ';') {
+ *ptout++ = '\n';
+ }
+ newline = 1;
+ begin = 1;
+ break;
+ case ';':
+ *ptout++ = *ptin;
+ if (parent) {
break;
- default:
+ }
+ *ptout++ = '\n';
+ newline = 1;
+ begin = 1;
+ break;
+ case '\n':
+ if (newline == 1) {
+ newline = 0;
+ } else {
+ *ptout++ = '\n';
+ }
+ begin = 1;
+ break;
+ case '\r':
+ break;
+ default:
+ if ((*ptin == '"') && (!character) && (!special)) {
+ string ^= 1;
+ }
+ if ((*ptin == '\'') && (!string) && (!special)) {
+ character ^= 1;
+ }
+ if (begin) {
+ for (i = 0; i < nbindent * TABSIZE; i++) {
+ *ptout++ = ' ';
+ }
begin = 0;
-
- pt += i;
- i = 0;
+ }
+ *ptout++ = *ptin;
}
+ space = ((*ptin == ' ') || (*ptin == '\t'));
+ special = (*ptin == '\\');
+ parent += (*ptin == '(') ? +1 : (*ptin == ')') ? -1 : 0;
+ ptin++;
}
- /* copy end buffer */
- int j = 0;
- if (pt - buffer < BUFFERSIZE) {
- for (i = pt - buffer; i < BUFFERSIZE; i++) {
- buffer[j++] = *pt++;
+ ptout = '\0';
+
+ /* write file */
+ VERBOSE (DEBUG, fprintf (stdout, "buffer out: %d\n", strlen (bufout)));
+ ptout = bufout;
+ while ((nb = fwrite (ptout, 1, strlen (ptout), fout)) != strlen (ptout)) {
+ VERBOSE (DEBUG, fprintf (stdout, "buffer out: %d/%d\n", nb, strlen (ptout)));
+ if (errno != 0) {
+ VERBOSE (ERROR, fprintf (stderr, "can't write file (%d)\n", errno));
+ exit (1);
}
- }
- pt = buffer + j;
+ ptout += nb;
+ }
}
/* close all */
int main (int argc, char *argv[])
{
+ cmode_t cmode = e_unknown;
char *input = NULL;
char *mode = "ansi";
char *output = NULL;
/* check output */
FILE *fout = NULL;
if (output) {
- fout = fopen (input, "wb");
+ fout = fopen (output, "wb");
if (!fout) {
VERBOSE (ERROR, fprintf (stderr, "error: can't open file '%s'\n", output));
fclose (fin);
fout = stdout;
}
- return indent (fin, fout);
+ /* check mode */
+ if (strcmp (mode, "ansi") == 0) {
+ cmode = e_ansi;
+ } else if (strcmp (mode, "k&r") == 0) {
+ cmode = e_kr;
+ } else {
+ VERBOSE (ERROR, fprintf (stderr, "error: mode '%s' unknown\n", mode));
+ }
+
+ return indent (fin, fout, cmode);
}
// test: indent.exe -h