#!/bin/sh # # This is a shell archive. To extract its contents, # execute this file with /bin/sh to create the file(s): # # infmx_tidy.c # # This shell archive created: Wed Aug 21 09:13:06 EDT 1996 # echo "Extracting file infmx_tidy.c" sed -e 's/^X//' <<\SHAR_EOF > infmx_tidy.c X/* X Title : infmx_tidy.c X Author : Paul Redman X Date : 12th Sept 1995 X Description : Informix code beautifier X X Copyright (c) 1995 - Paul Redman - 75052.1341@compuserve.com X X=========================================================================== X This program is freely given away to be used and modified as required. It X is not perfect so if you find bugs or enhance it why not send me a copy at X the above email address. The only restriction on modification is that you X leave the copyright line above and this comment in the source code. X X No warranties implied. It does not break or remove source code, contains no X deliberate bugs and hopefully will prove useful....BUT on no account can you X sue me if it doesn't work or causes you problems. X X You should be able to compile it with : cc -o infmx_tidy infmx_tidy.c X You can run it with : infmx_tidy X=========================================================================== X X*/ X X#include X#include X X#define ERR_FATAL 0x01 X#define ERR_NONFATAL 0x02 X#define BUFSIZE 256 X Xvoid process(); Xvoid errfunc(); Xvoid doline(); Xvoid copy_line(); X X Xstatic char errbuf[255]; X X X/*----------------------------------------------------------------------- X main - entry function X RETURNS: Nothing X-----------------------------------------------------------------------*/ Xint main(argc, argv) Xint argc; Xchar *argv[]; X{ X X if (argc != 3) X { X sprintf(errbuf, "Usage: go "); X errfunc(ERR_FATAL, errbuf); X } X X /* call main routine */ X process(argv[1], argv[2]); X X /* say goodbye */ X printf("\n\n\n\n (c) Copyright 1995 - Paul Redman "); X printf("\n Thankyou for using infmx_tidy\n\n"); X fflush(stdout); X X X return(0); X} X X/*----------------------------------------------------------------------- X errfunc - error routine X RETURNS: Nothing X-----------------------------------------------------------------------*/ Xvoid errfunc(errtype, buf) Xint errtype; Xchar *buf; X{ X fprintf(stderr, "\n\n%s\n\n", buf); X fflush(stderr); X if (errtype == ERR_FATAL) X exit(1); X} X X/*----------------------------------------------------------------------- X process - main routine X RETURNS: Nothing X-----------------------------------------------------------------------*/ Xvoid process(infile, outfile) Xchar *infile; Xchar *outfile; X{ X FILE *ifp, X *ofp, X *fopen(); X char *ibuf, X *obuf; X int cnt; X X X ifp = fopen(infile, "r"); X if (ifp == (FILE *) NULL) X { X sprintf(errbuf,"Input file %s could not be opened for reading", infile); X errfunc(ERR_FATAL, errbuf); X } X X ofp = fopen(outfile, "w"); X if (ofp == (FILE *) NULL) X { X sprintf(errbuf, "Output file %s could not be opened for writing", outfile); X errfunc(ERR_FATAL, errbuf); X } X X ibuf = (char *) malloc(BUFSIZE * sizeof(char)); X if (ibuf == (char *) NULL) X { X fclose(ofp); X fclose(ifp); X errfunc(ERR_FATAL, "Out of memory allcating inbuf variable"); X } X memset(ibuf, 0x00, BUFSIZE); X X obuf = (char *) malloc(BUFSIZE * sizeof(char)); X if (obuf == (char *) NULL) X { X fclose(ofp); X fclose(ifp); X errfunc(ERR_FATAL, "Out of memory allcating outbuf variable"); X } X memset(obuf, 0x00, BUFSIZE); X X X for (cnt = 0; feof(ifp) == 0; cnt++) X { X fgets(ibuf, (BUFSIZE - 1), ifp); X if (feof(ifp)) X break; X X doline(ibuf, obuf); X fprintf(ofp, "%s", obuf); X fflush(ofp); X } X X fflush(ofp); X fclose(ofp); X fclose(ifp); X X free(obuf); X free(ibuf); X} X X X/*----------------------------------------------------------------------- X doline - process 1 line between in and out buffers X RETURNS: Nothing X-----------------------------------------------------------------------*/ Xvoid doline(ibuf, obuf) Xchar *ibuf; /* main input buffer */ Xchar *obuf; /* main output buffer */ X{ X char *ip, *op; /* ptrs to main buffers */ X int n; /* temp variable (loops) */ X char c; /* temp variable */ X char *p; /* temp ptr variable */ X char *token; /* buffer to hold first token in the line */ X char *tok; /* ptr to token buffer */ X static int curly_set = 0; /* set after a {, reset on a } */ X static int spaces = 0; /* no. of spaces to indent output buffer */ X static int line_no = 0; /* Count of lines processed */ X X ip = ibuf; X op = obuf; X X line_no++; X X /* copy blank lines as is */ X for (; *ip == ' ' || *ip == '\t' || *ip == '\n' ; ip++); X if (*ip == '\0') X { X ip = ibuf; X copy_line(ip,op); X return; X } X X X /* Check for end of a multi line comment - note we reject the whole line X when we find a } so we cannot process chars after the } */ X if (curly_set) X { X if (close_curly(ip)) X curly_set = 0; X X /* copy whole line if part of a comment OR end of a comment */ X copy_line(ip, op); X return; X } X X /* Check for a single line comment - if found kick out the identical line */ X if (is_a_hash(ip)) X { X ip = ibuf; X copy_line(ip, op); X return; X } X X X /* Check for a multi line comment - if found kick out all lines between X curly brackets 'as is' by setting curly flag */ X if (is_a_curly(ip)) X { X curly_set = 1; X X /* Check if comment is closed on same line */ X if (close_curly(ip)) X curly_set = 0; X ip = ibuf; X copy_line(ip, op); X return; X } X X X /* Not a comment - must be a real line */ X X X /* strip leading spaces */ X if (*ip == ' ' || *ip == '\t') X for (; *ip == ' ' || *ip == '\t'; ip++); X X /* store this address for use further down */ X p = ip; X X /* build first token in the inbuf */ X token = (char *) malloc(BUFSIZE * sizeof(char)); X memset(token, 0x00, BUFSIZE); X tok = token; X for(; *ip != ' ' && *ip != '\t' && *ip != '\n' && *ip != '\0'; ip++) X *tok++ = toupper(*ip); X *tok = '\0'; X X X /* No. of spaces are adjusted before outptting the current line if it X contains statements like END IF, ELSE, END WHILE etc. */ X spaces = calc_before_spaces(spaces, token, ibuf); X X /* be user friendly */ X printf("\nLine No. %05d, Token=|%s|, spaces=%d", line_no, token, spaces); X fflush(stdout); X X X /* if token is "LABEL xx" ignore spaces (labels always go on 1st char) else X output no. of spaces to outbuf (decided by previous token) */ X X if (strcmp(token, "LABEL", 5) != 0) X for (n=0; n < spaces; n++) X *op++ = ' '; X X /* default routine to copy whole line as is */ X ip = p; X while ((c = *ip++) != '\0') X *op++ = c; X *op='\0'; X X /* calculate number of spaces for next line using this token. This affects X IF, WHEN, MAIN, FUNCTION, DEFINE etc. keywords that push the next line X forward 4 chars */ X spaces = calc_after_spaces(spaces, token, ibuf); X free(token); X} X X/*----------------------------------------------------------------------- X copy_line - copy an entire line 'as is' X RETURNS: Nothing X-----------------------------------------------------------------------*/ Xvoid copy_line(ip, op) Xchar *ip, *op; X{ X while (*ip != '\0') X *op++ = *ip++; X *op='\0'; X} X X/*----------------------------------------------------------------------- X is_a_hash - looks for a single line comment X RETURNS: 0 if not a comment, 1 if is a comment X-----------------------------------------------------------------------*/ Xint is_a_hash(ip) Xchar *ip; X{ X if (*ip == '#' ) X return(1); X X for (; *ip == ' ' || *ip == '\t'; ip++); X X if (*ip == '#' ) X return(1); X else X return(0); X} X X/*----------------------------------------------------------------------- X is_a_curly - looks for a multi line comment X RETURNS: 0 if not a comment, 1 if is a comment X-----------------------------------------------------------------------*/ Xint is_a_curly(ip) Xchar *ip; X{ X if (*ip == '{') X return(1); X X for (; *ip == ' ' || *ip == '\t'; ip++); X X if (*ip == '{') X return(1); X else X return(0); X} X X/*----------------------------------------------------------------------- X close_curly - look for the } character X RETURNS: 0 if not found, 1 if found X-----------------------------------------------------------------------*/ Xint close_curly(ip) Xchar *ip; X{ X while (*ip != '}' && *ip != '\0') X *ip++; X X return( (*ip) ? 1 : 0); X} X X/*----------------------------------------------------------------------- X calc_after_spaces - calculate number of spaces based on token and how X it affects the next line X RETURNS: no. of spaces to indent next line X-----------------------------------------------------------------------*/ Xint calc_after_spaces(spaces, tok, ibuf) Xint spaces; Xchar *tok; /* first token in input buffer */ Xchar *ibuf; /* original input buffer */ X{ X if (strncmp(tok, "MAIN", 4) == 0) X spaces += 4; X X X /* the problem with indenting after a DEFINE is that I don't know when to X un-indent again. Note we have the same problem with the OPTION stmt. */ X /* if (strncmp(tok, "DEFINE", 6) == 0) X spaces += 4; X */ X X if (strncmp(tok, "IF", 2) == 0) X if (no_endif(ibuf)) X spaces += 4; X X if (strncmp(tok, "ELSE", 4) == 0) X spaces += 4; X X if (strncmp(tok, "CASE", 4) == 0) X spaces += 4; X X /* don't let WHEN and WHENEVER get mixed up */ X if (strlen(tok) == 4 && strncmp(tok, "WHEN", 4) == 0) X spaces += 4; X X if (strncmp(tok, "FOR", 3) == 0) X spaces += 4; X X if (strncmp(tok, "FUNCTION", 8) == 0) X spaces += 4; X X if (strncmp(tok, "WHILE", 5) == 0) X spaces += 4; X X return ((spaces >= 0) ? spaces : 0); X} X/*----------------------------------------------------------------------- X calc_before_spaces - calculate number of spaces based on token for X current line X RETURNS: no. of spaces to indent next line X-----------------------------------------------------------------------*/ Xint calc_before_spaces(spaces, tok, ibuf) Xint spaces; Xchar *tok; /* first token in input buffer */ Xchar *ibuf; /* original input buffer */ X{ X if (strncmp(tok, "ELSE", 2) == 0) X spaces -= 4; X X if (strncmp(tok, "END", 3) == 0) X spaces -= 4; X X if (strncmp(tok, "MAIN", 4) == 0) X spaces = 0; X X if (strncmp(tok, "FUNCTION", 8) == 0) X spaces = 0; X X if (strncmp(tok, "RECORD", 6) == 0) X spaces = 0; X X /* don't let WHEN and WHENEVER get mixed up */ X if (strlen(tok) == 4 && strncmp(tok, "WHEN", 4) == 0) X spaces -= 4; X X return ((spaces >= 0) ? spaces : 0); X} X X/*----------------------------------------------------------------------- X no_endif - checks for presence of END IF on this line X RETURNS: TRUE (=1) if END IF does not exist, else FALSE (=0) X-----------------------------------------------------------------------*/ Xint no_endif(ibuf) Xchar *ibuf; /* original input buffer */ X{ X char *token, *tok, *ip; X int rc = 1; X X ip = ibuf; X X /* build first token in the inbuf */ X token = (char *) malloc(BUFSIZE * sizeof(char)); X X while (1) X { X memset(token, 0x00, BUFSIZE); X tok = token; X X /* remove whitespace */ X for (; *ip == ' ' || *ip == '\t';) X ip++; X X for(; *ip != ' ' && *ip != '\t' && *ip != '\n' && *ip != '\0'; ip++) X *tok++ = toupper(*ip); X *tok = '\0'; X X /* note - tok would stop on '\n' so now value *ip = '\O' */ X if (*ip == '\n' || *ip == '\0') X break; X X if (strncmp(token, "END", 3) == 0) X { X X memset(token, 0x00, BUFSIZE); X tok = token; X X /* remove whitespace */ X for (; *ip == ' ' || *ip == '\t';) X ip++; X X for(; *ip != ' ' && *ip != '\t' && *ip != '\n' && *ip != '\0'; ip++) X *tok++ = toupper(*ip); X *tok = '\0'; X X if (strncmp(token, "IF", 2) == 0) X { X rc = 0; X break; X } X } X X } /* end while(1) */ X X return(rc); X} SHAR_EOF if [ `wc -c < infmx_tidy.c` -ne 12614 ] then echo "Lengths do not match -- Bad Copy of infmx_tidy.c" fi echo "Done." exit 0