#ifndef tu_blk_c #define tu_blk_c 1 /**** MODULE UNDER CONSTRUCTION (as off 2009/06/28) ****/ /*-------------------------*/ void Init_tu_blk (void) /*---------------------------------------------------------- | Init_tu_blk -- create some basic support vars, etc. +----------------------------------------------------------------*/ { char *Xd; int i; /** BEGIN **/ GG_block_xs = (char *) malloc(MAX_GG_BLOCK_XS_SIZE); if (GG_block_xs == NULL) { printf ("*** ERR: Out of memory. malloc (GG_block_xs). \n"); exit (-1); } Xd = GG_block_xs; for (i=0; i < MAX_GG_BLOCK_XS_SIZE ; i++) *Xd++ = ' '; Xd--; *Xd = '\0'; /* null terminate it */ *GG_block_xs = '\n'; /* make everything look like TEXT */ GG_scratch_block = Allocate_blk_struct ("GG_scratch_block", DEF_BLK_32000); if (GG_scratch_block == NULL) { printf ("*** ERR: Not enough memory in pgm: Tst-blk.c GG_scratch_block [ALOC=%d]\n", DEF_BLK_32000); PAUSE; return; /* not fatal, SYSTEM RETURN VALUE !!!! ***/ } } /* End: Init_tu_blk() */ /*------------------------------------------------------------------------*/ struct Blk_struct *Allocate_blk_struct (char *Block_name, int Size) /*---------------------------------------------------------------------- | Allocate_blk_struct (size) -- creates a char-blk of the | indicated size. On dos machines you are pretty much limited | to 32K bytes - prob should use a bit less (eg, 32k - 8). No | restriction for unix, natch. | | Also, note that this set of funcs() prob isn' robust enough to\ | *really* support hex data; sorry about that, Chief! +-----------------------------------------------------------------*/ { struct Blk_struct *Tptr; /* the retf */ char *Xs, *Xd; /* init with blanks and such */ int i; /* loop index */ /** BEGIN **/ Tptr = NULL; Tptr = (struct Blk_struct *) malloc (BLK_STRUCT_SIZE); if (Tptr == NULL) { printf ("*** ERR: Out of memory: malloc (Blk_struct (%d))\n", Size); PAUSE; return (struct Blk_struct *) NULL; } Tptr->Blk_name = NULL; Tptr->Blk_size = 0; Tptr->Blk_char_count = 0; Tptr->Blk_data = NULL; Tptr->Blk_start = NULL; Tptr->Blk_end = NULL; Tptr->Next_read = NULL; Tptr->Last_written = NULL; Tptr->Prev = NULL; Tptr->Next = NULL; /*------------------------ allocate and set INTERNAL vars of the BLK -----*/ /*----------------- alloc the MEM-BLK itself */ Xd = NULL; Xd = (char *) malloc (Size); Xs = (char *) malloc (strlen(Block_name)+1); if ((Xs == NULL) || (Xd == NULL)) { printf ("*** ERR: Out of memory: malloc (Blk_struct (Size=%d))\n", Size); PAUSE; return (struct Blk_struct *) 0; /* ansi lives; tedious isn't it? RETURN */ } strcpy (Xs, Block_name); Tptr->Blk_name = Xs; /* set viewable name of the block, et cetera.... */ Tptr->Blk_size = Size; Tptr->Blk_data = Xd; Tptr->Blk_start = Xd; for (i=0 ; i < Size ;i++) /* blank out the block */ *Xd++ = ' '; Xd--; /* back up one space and set it to null *. *Xd = '\0'; Tptr->Blk_end = Xd; Tptr->Blk_char_count = 0; /* no data stored yet */ Tptr->Next_read = Tptr->Blk_start; Tptr->Last_written = Tptr->Blk_start; /* there is no data yet; this is sort of bogus */ Tptr->Next = NULL; /* nothing linked in this version */ Tptr->Prev = NULL; /* linked list thingies */ if (GG_verbose != 0) { printf ("--- Allocated block: '%s' - Size=%d, [%X .. %X]\n", Tptr->Blk_name, Tptr->Blk_size, Tptr->Blk_start, Tptr->Blk_end); PAUSE; } return Tptr; /* A-ok, Houston! */ } /* End: Allocate_blk_struct() */ /*--------------------------------------------------------*/ short Deallocate_blk_struct (struct Blk_struct *Blk) /*--------------------------------------------------------------- | This routine is v. important (on some systems). THe prob | is that the block can contain ANY data (ie, 0x00 - 0xff) | and as we all know C is obsessed with null-terminated strings. | So, what we do is allocate the block and physically mark the | boundaries (start & end). Before we de-allocate it, we fill it | with blanks and one final null 0x00 that way the de-alloc | func will treat it like it's just a big text string and no | prob. This prob occurs on various compilers -- and drives | you nuts. You get a final "deference to null pointer" (or some | such cookie) hope this helps. -- Pizo. +----------------------------------------------------------------*/ { struct Blk_struct *Tptr; /* writeable pointer */ char *Xd; int i, Size; /** BEGIN **/ Tptr = Blk; /* Make it changeable */ Xd = Tptr->Blk_data; Size = Tptr->Blk_size; for (i=1 ; i < Size ;i++) /* Note the i=1 and NOT i=0 */ *Xd++ = ' '; *Xd = '\0'; /* set the last char in the block to 0x00 */ /*** NEED TO INSERT THE demalloc ?? or what-ever it is ***/ /** prob should check the mem as well. Note then you STILL ***/ /** have to SNIP out the LINK-LIST node pointed to by Blk !!!! ***/ return -1; /** STUB **/ /*** this func not working yet ***/ } /* End: Deallocate_blk_struct() */ /*---------------------------------------------------------*/ void Show_blk_struct (struct Blk_struct *Blk) /*------------------------------------------------------------------- | This is pretty much just a "dump" func that can be adapted | to something more elegant. Use it to debug with, etc. (enjoy) | Also, this pretty much ASSUMES that you have TEXT in the block; | that is, not binary (hex) data. | | See also: Show_hex_blk_struct () below. Share and enjoy. -- 42. +--------------------------------------------------------------------*/ { struct Blk_struct *Tptr; /* writeable pointer */ char *Xd, *End_of_blk; /** BEGIN **/ Tptr = Blk; /* Make it changeable */ Xd = Tptr->Blk_data; End_of_blk = Tptr->Blk_end; while ((*Xd != '\0') && (Xd != End_of_blk)) { printf ("%c", *Xd); if (*Xd == '\n') printf ("\r"); Xd++; } return; /* we are done. --PRAGMA: a "PAUSE;" could go here for debug */ } /* end: Show_blk_struct() */ /*---------------------------------------------------------*/ void Show_HEX_blk_struct (struct Blk_struct *Blk, char *Start_here, char *End_here) /*------------------------------------------------------------------- | This is pretty much just a "hex dump" func/ | | NOTE: THere is ABSOLUTELY NO CHECKING of the two boundaries | that you pass in (Start_here & End_here). I thought about | but decided it's way too complicated (actully just a loop -- | see comments below). So, i said forget it. YOu prob know what | you're doing, so if you find something in the block and SAVE | the pointers to it, then you can pass them in here. | | Note, i've decided to create an aux package: tu-blkx.c | which will provide some helper routines (mainly for text | editing and such). | | How the CHECKING code would look: | short Show_HEX_blk_struct_with_checking (Blk, Start_here, End_here) | returns SHORT (indicating a prob) | | char *Xj; -- temp var to scan the block Note: Ada-sytle comment! | short Start_is_ok, End_is_ok; | | BEGIN | | Start_is_ok = 0; -- assume the worst; ie, that they are OUT | End_is_ok = 0; -- OF BOUNDS !! | | for (Xj = Blk->Start ; Xj++ ; Xj <= Blk->End) | { | if (Start_here == Xj) Start_is_ok = 1; -- it's inside | if (End_here == Xj) End_is_ok = 1; | } | if ((Start_is_ok == 0) && (End_is_ok == 0)) | return BLOCK_BOUNDARY_START_AND_STOP_VALUES_OUT_OF_BOUNDS; | if (Start_is_ok == 0) | return BLOCK_BONDARY_START_VALUE_OUT_OF_BOUNDS; | if (End_is_ok == 0) | return BLOCK_BOUNDARY_END_VALUE_OUT_OF_BOUNDS; | | -- rest of func's code would go here -- | | then return BLOCK_BOUNDARY_VALUES_ARE_OK. | | See also: Show_blk_struct () above. Share and enjoy. -- 42. +--------------------------------------------------------------------*/ { int i; char *addr; char alpha [16]; /** BEGIN **/ for (i=0; i < 16 ; i++) alpha[0] = '.'; printf ("Hex dump : 0 1 2 3 4 5 6 7 8 9 A B C D E F\n"); i = 0; for (addr = Start_here; addr <= End_here; addr++) { if ((addr < Blk->Blk_start) || (addr > Blk->Blk_end)) { printf ("*** WARN: Hex-dump outside of bound!\n"); printf ("*** Request range: [%8x - %8x]\n", Start_here, End_here); printf ("*** Blk boundaries: [%8x - %8x]\n\n", Blk->Blk_start, Blk->Blk_end); PAUSE; } if (i==0) printf ("%8x : ", addr); printf ("%2x ", *addr); i++; if (i == 16) { printf ("%16c\n", alpha); for (i=0; i < 16 ; i++) alpha[i] = '.'; i = 0; } } return; } /* end: Show_HEX_blk_struct() */ /*----------------------------------------------------------*/ int Append_text_to_blk (struct Blk_struct *Blk, char *Xs) /*------------------------------------------------------------ | NOTE: Last_char is CHANGED by this routine. | | Note that in the case of an in-complete write, the strag data | is out there, but the pointers are not updated. | | In keeping with unix read() write() funcs, the value | returned is the number of bytes successfully written. +-------------------------------------------------------------------*/ { struct Blk_struct *Tptr; /* writeable pointer */ char *Xd, *End_of_blk; int Char_count; /** BEGIN **/ Tptr = Blk; /* Make it changeable */ Xd = Tptr->Last_written; /* usually points to a \n */ if (Tptr->Last_written != Tptr->Next_read) /* ie, block is empty */ Xd++; /* othersise, skip over /n */ Char_count = 0; while (*Xs != '\0') { Xd++; /* Must be able to append \0 */ if (Xd > Tptr->Blk_end) { printf ("*** ERR: E-of-BLOCK: '%s'. At char count #%d\n", Tptr->Blk_name, Char_count); return -Char_count; /** NOT WRITTEN -- RETURN (negative-value) **/ } Xd--; *Xd++ = *Xs++; /* WRITE and make ready to write again */ Char_count++; } Xd++; /* must be able to put \0 in */ if (Xd > Tptr->Blk_end) { printf ("*** ERR: E-of-BLOCK. (TEXT-MODE) At char count #%d\n", Char_count); return -Char_count; /** NOT WRITTEN **/ } Xd--; Tptr->Last_written = Xd; /* point to where the /n is going to be */ *Xd++ = '\n'; /* ok to append NEW-LINE */ Char_count++; *Xd = '\0'; /* mark the logical end of the block */ return Char_count; /* righty-oh!!! */ } /* End: Append_text_to_blk() *. /*------------------------------------------------------------*/ int Pull_line_from_text_block (struct Blk_struct *Blk) /*--------------------------------------------------------------------- | Using the value pointed to by Cur_char, it moves Cur_char | up one char (unless at the very begining of the BLK), and | then moves it to the end of the \n. | | NOTE: The buffer used for this is GG_block_xs (which is used | regardless of which BLK is read from. If you want this | intact, you will need to copy to a separate string. | | NOTE: Tptr->Cur_char will be changed (pointing to NEXT line). | | The retf (int) is the num chars read. If there are *more* chars | than will fit in GG_block_xs (based on MAX_GG_BLOCK_XS_SIZE), then | a NEGATIVE value is returne of the number read into the buffer. | | NOTE: In EITHER case, the value of Tptr->Cur_char *is* moved. +--------------------------------------------------------------------*/ { char *Xs, *Xd; int Count = 0; int Max_limit = 0; struct Blk_struct *Tptr; /* writeable pointer */ /** BEGIN **/ Tptr = Blk; /* Make it changeable */ Xs = Tptr->Next_read; Max_limit = MAX_GG_BLOCK_XS_SIZE -1; Xd = GG_block_xs; while ((Xs <= Tptr->Blk_end) && (*Xs != '\n') && (Count < Max_limit)) { Count++; *Xd++ = *Xs++; } *Xd = '\0'; /* terminate it */ if (Count >= MAX_GG_BLOCK_XS_SIZE) { Count = -Count; /* over flow! */ } return Count; } /* End: Pull_line_from_text_block () */ /*------------------------------------------------------------*/ void Show_lines_in_text_block (struct Blk_struct *Blk, int Nlines) /*---------------------------------------------------------------- | Using the value pointed to by Next_read, shows (without moving | Next_read) the next "Nlines". +--------------------------------------------------------------------*/ { char *Xs; int Count = 0; struct Blk_struct *Tptr; /* writeable pointer */ /** BEGIN **/ Tptr = Blk; /* Make it changeable */ Xs = Tptr->Next_read; while ((Xs != Tptr->Blk_end) && Count < Nlines) { if (*Xs == '\n') Count++; printf ("%c", *Xs); Xs++; } return; } /* End: Show_lines_text_block () */ /*------------------------------------------------------------------------*/ void Show_lines_starting_at_in_text_block (struct Blk_struct *Blk, char *Xs, int Nlines) /*------------------------------------------------------------------------- | Using the value pointed to by Xs, shows (without moving Cur_char) | the next "Nlines". +---------------------------------------------------------------------------*/ { int Count = 0; struct Blk_struct *Tptr; /* writeable pointer */ /** BEGIN **/ Tptr = Blk; /* Make it changeable */ if (Tptr->Blk_end == Tptr->Blk_start) return; /** the block is emtpy */ if (Tptr->Blk_char_count == 0) { printf ("*** WARN: Text-blk '%s' shows contents, but count = 0\n", Tptr->Blk_name); PAUSE; } if ((Xs < Tptr->Blk_start) || (Xs >= Tptr->Blk_end)) { printf ("*** ERR: Show_lines_starting_at_in_text_blk()\n); printf ("*** -- Blk string pointer NOT with-in BLOCK.\n"); printf ("*** Xs_requested = x'%X, Blk '%s' [%X .. %X]\n", Tptr->Blk_name, Tptr->Blk_start, Tptr->Blk_end); PAUSE; return; } while ((Xs != Tptr->Blk_end) && (Count < Nlines)) { if (*Xs == '\n') Count++; printf ("%c", *Xs); Xs++; } return; } /* End: Show_lines_starting_at_in_text_block () */ /*------------------------------------------------------*/ int Write_blk_to_outfile (struct Blk_struct *Blk) /*---------------------------------------------------------- | Writes RAW data of entire block (From Start to where-ever | the first null is +---------------------------------------------------------------*/ { char *Xs; struct Blk_struct *Tptr; /* writeable pointer */ /** BEGIN **/ Tptr = Blk; /* Make it changeable */ Xs = Tptr->Blk_start; while (Xs <= Tptr->Blk_end) { fprintf (Out_file, "%c", *Xs); Xs++; } return 0; } /* End: Write_blk_to_outfile() */ /*-------------------------------------------------------------*/ int Writeln_blk_to_outfile (struct Blk_struct *Blk, short Crlf_mode) /*-------------------------------------------------------------- | Note to use DEFINED value for Crlf_mode | CRLF_MODE_NL_ONLY | CRLF_MODE_CR_ONLY | CRLF_MODE_CR_LF +----------------------------------------------------------*/ { char *Xs; struct Blk_struct *Tptr; /** BEGIN **/ Tptr = Blk; /* Make it changeable */ Xs = Tptr->Blk_start; while (Xs <= Tptr->Blk_end) { if (*Xs != '\n') fprintf (Out_file, "%c", *Xs); else { if (Crlf_mode == CRLF_MODE_NL_ONLY) fprintf (Out_file, "\n"); if (Crlf_mode == CRLF_MODE_CR_ONLY) fprintf (Out_file, "\r"); if (Crlf_mode == CRLF_MODE_CR_LF) fprintf (Out_file, "\r\n"); } Xs++; } return 0; } /* End: Writeln_blk_to_outfile() */ #endif /* tu_blk_c */