4gl- reformatting TEXT-Blobs located in memory
Posted in 1993
Topics: Connectivity: ESQL/C, 4GL & Embedded SQL, Jobs, Consulting & Announcements
Often we want to reformat a text which is stored in a BLOB and print it out in a 4gl-report. The following function tx_fill is based on a PD-program fill (by Chad Larson). Usage: call tx_fill(blob, just, left, right) blob = name of blob just = " " no justifieing "j" justify right margin "s" no reformatting, only shifting of text left = left margin = first column of text right = right margin = last column of text Attention: when you use this function in a foreach-loop, you must free and locate the blob before every select. Please excuse my bad english and some german comments in the code. tx_fill.d: ------------------------------------------------------------------------ #include <stdio.h> #include <string.h> #include <memory.h> #undef DEBUG /* fill - Simple text formatter - 2.7 */ /* Aenderungen zum Aufruf als Unterprogramm ** Fill is a simple text formatter meant to be used from within ** your editor to provide the same functionality as the ^B command ** in WordStar. This presumes your editor can pipe an object through ** a filter. In vi, you would do something like "!}fill" to word wrap ** a paragraph. Of course, you may, in the spirit of Unix, find other ** uses for it. For example, fill has the side-effect of de-tabifying ** lines passed to it. ** Usage: fill [-b] [-c | -j] [-d] [-l n] [-r n] [-p n] Aufruf fill(text, justify, left, right) justify = leer Kein Einruecken j Rechtsbuendig s nur schieben - nicht formatieren left = linker Rand = erste Textstelle right = rechter Rand = letzte Textstelle ** -b box the output (replying to news) ** -c center the lines ** -d the block is left delimited ("** comment block") ** -j justify the right margin ** -l n set left margin to "n", defaults to 1 ** -r n set right margin to "n", defaults to 72 ** -p n sets a "paragraph" indent. */ /* ** Author: ** Chad R. Larson This program is placed in the ** DCF, Inc. Public Domain. You may do with ** 14623 North 49th Place it as you please. ** Scottsdale, AZ 85254 */ /* maximum length of a word */ #define WORD_MAX 128 /* forward references */ void j_line(); /* justify a line */ char *append(); char *malloc(); void ausgabe(); /* global flags */ #define FALSE 0 #define TRUE ~FALSE int nl_flag; /* new line has been processed */ char *d_adro, *d_adroz; /* Adresse Ausgabefeld z=akt-Zeiger */ char *d_adri, *d_adriz; /* Adresse Eingabefeld z=akt-Zeiger */ char *d_adr_end; /* Ende Adresse Eingabefeld */ int nlc, cc, oln; char * txfill(p_text, p_justify, p_left, p_right) char *p_text; char *p_justify; int p_left, p_right; { int c; /* a generic character */ int justify; /* justify right margin flag */ int shiftonly; /* only shift of text, no formatation */ int w_length; /* length of current word */ int l_length; /* length of current line */ int l_margin; /* left margin */ int r_margin; /* right margin */ int wrap_point; /* max chars allowed on a line */ char *margin; /* points to left margin string */ char *out_line; /* points to the output line */ char word[WORD_MAX]; /* the current word */ char *bp; /* a buffer pointer */ justify = FALSE; shiftonly = FALSE; l_length = 0; if (*p_justify == 'j') justify = TRUE; if (*p_justify == 's') shiftonly = TRUE; r_margin = p_right; l_margin = p_left; /* Laenge des Textes berechnen */ d_adriz = p_text; nlc = 0; cc = 0; while (*d_adriz) { if (*d_adriz == '\\n') nlc++; cc++; d_adriz++; } nlc++; oln = (cc + nlc * l_margin + nlc) * 1.5; #ifdef DEBUG printf ("Text: %x, Textlaenge: %d, Anzahl Zeilen: %d, alloc: %d\\n", p_text, cc, nlc, oln); printf ("Text: %s\\n", p_text); #endif /* Bereich fuer Ausgabetext */ if ( (d_adro = malloc( (unsigned)oln) ) == NULL ) return("++++ Textspeicher kann nicht allokiert werden\\n"); d_adri = p_text; d_adriz = p_text; d_adroz = d_adro; #ifdef DEBUG printf ("l_margin: %d, r_margin: %d\\n", l_margin, r_margin); #endif if (l_margin >= r_margin || l_margin < 1) l_margin = 1; if (r_margin <= l_margin) r_margin = l_margin + 60; /* create the left margin string */ if ( (margin = malloc( (unsigned)l_margin) ) == NULL ) { ausgabe("Unable to allocate space for margin.\\n"); return(d_adro); } (void)memset(margin, ' ', l_margin - 1); margin[l_margin - 1] = '\\0'; /* create the output line buffer */ wrap_point = r_margin - l_margin + 1; if ((out_line = malloc( (unsigned)wrap_point + 3) ) == NULL) { ausgabe("Unable to allocate space for line buffer.\\n"); return (d_adro); } /* move words from the input to the output */ bp = out_line; while ( (w_length = get_word(word, shiftonly)) != 0 ) { if (w_length == 1 && *word == '\\n') { if (l_length > 0) { if (justify) j_line(out_line, wrap_point); ausgabe(margin); /* set any offset */ ausgabe(out_line); /* put the line to stdout */ } *out_line = '\\0'; /* reset the output line */ ausgabe("\\n"); l_length = 0; bp = out_line; #ifdef DEBUG printf (" neue Zeile\\n"); #endif } else { if ( (l_length + w_length) > wrap_point ) { /* line wrap? */ while (out_line[l_length - 1] == ' ') /* trailing space strip */ l_length--; out_line[l_length] = '\\0'; if (justify) /* justify the line? */ j_line(out_line, wrap_point); ausgabe(margin); /* set any offset */ ausgabe(out_line); /* put the line to stdout */ ausgabe("\\n"); *out_line = '\\0'; /* reset the output line */ l_length = 0; bp = out_line; } bp = append(bp, word); bp = append(bp, " "); l_length += w_length + 1; } } /* clean up and exit */ if (l_length) { /* residual to flush */ while (out_line[l_length - 1] == ' ') l_length--; out_line[l_length] = '\\0'; ausgabe(margin); ausgabe(out_line); ausgabe("\\n"); } return(d_adro); } /* ** get_word - a routine to return the next word aus dem Eingabefeld ** Copies the next word from the input stream to the location pointed to ** by its argument. The word will be null terminated. A word is any ** string of characters delimited by whitespace. Returns the length ** of the word. */ int get_word(Word, shiftonly) char *Word; int shiftonly; { register int c; /* generic character */