/* HTM_LINK This program is a link-editor for HTML. It is provided with a "make file," and uses the information in that file to generate modified copies of the HTML files listed therein, which are located in the same directory as the make file, and puts them in a subdirectory amed "htm_lnk" The program also generates a table of contents, likewise stored in "htm_lnk," and all of these files are linked together. The format of the make file is as follows: ---------------------------------------------------- The first record of the make file is: BOOK#t_c_fn_ext#author#,book_title# The second record is: HOME#home_url_str# There are one or more chapter records following, which take the form: CHAP#chap_fn_ext#chap_title#chap_num#chap_mode# where chap_mode is formed from the following characters: use either, both, or none: f = first in link sequence l = last in link sequence chose one of: h = make edited copy of html original d = create dummy chapter 0 = generate nothing optional: n = named chapter, eg. preface, instead of number REM# gets ignored, but it must not be in the first two positions ---------------------------------------------------------------- Andrew D. Todd 1249 Pineview Dr., Apt 4 Morgantown, WV 26505 adtodd@mail.wvnet.edu http://rowboats-sd-ca.com/ --------------------------------------------------------------- usage: htm_link make_file where make_file is the filespec for the make file ---------------------------------------------------------------- environment: MS-DOS, using MIX Power C compiler (superset of Microsoft C, Borland Turbo C), however, should be extremely portable. ----------------------------------------------------------------- This program is in the public domain, and may be used for any purpose whatsover, without permission or notification, but it is offered "as-is" without any warrentee, express or implied. ----------------------------------------------------------------- */ /*=================================================================*/ #include #include #include #include #include #define FN_EXT_LEN 13 #define FILE_SPEC_LEN 256 /*------------------------------------------------------------------*/ /*==================================================================*/ const int seq_before = 1; const int seq_after = 2; const int rec_ch_fn_ext = 1; const int rec_ch_title = 2; const int rec_ch_num = 3; const int rec_ch_mode = 4; /*=================================================================*/ /* The Chapter List Object-- an array of records with prescribed access methods */ /*-----------------------------------------------------------------*/ struct chap_descriptor { char chap_fn_ext[FN_EXT_LEN]; char chap_title[80]; char chap_num[20]; /* either a chapter number or equivallent like preface */ char chap_mode[10]; /* use either, both, or none: f = first in link sequence l = last in link sequence chose one of: h = make edited copy of html original d = create dummy chapter 0 = generate nothing optional: n = named chapter, eg. preface, instead of number */ }; struct chap_descriptor chap_list[100]; /* declared global */ /*--------------------------------------------------------------*/ void set_chap_list( int chap_count, char *fn_ext_str, char *title_str, char *num_str, char *mode_str ) { strcpy(chap_list[chap_count].chap_fn_ext, fn_ext_str); strcpy(chap_list[chap_count].chap_title, title_str); strcpy(chap_list[chap_count].chap_num, num_str); strcpy(chap_list[chap_count].chap_mode, mode_str); } /* Set the fields of the record referenced by CHAP_COUNT to the string arguments. */ /*-------------------------------------------------------------------*/ char *get_chap_list(int record_field, int chap_count) { if(record_field == rec_ch_fn_ext) return(chap_list[chap_count].chap_fn_ext); else if(record_field == rec_ch_title) return(chap_list[chap_count].chap_title); else if(record_field == rec_ch_num) return(chap_list[chap_count].chap_num); else if(record_field == rec_ch_mode) return(chap_list[chap_count].chap_mode); } /* function to get specified field. */ /*===================================================================*/ /* the make file lives in the source directory the first record is: BOOK#t_c_fn_ext#author#,book_title# the second record is: HOME#home_url_str# all of these text strings being as defined in function main. There are one or more chapter records following, which take the form: CHAP#chap_fn_ext#chap_title#chap_num#chap_mode# REM# gets ignored, but it must not be in the first two positions */ /*==================================================================*/ main(int argc, char *argv[]) { char src_path[FILE_SPEC_LEN], home_url_str[256], mk_fspec[FILE_SPEC_LEN]; int num_chaps; char t_c_fn_ext[FN_EXT_LEN]; char author[80], book_title[80]; /* start with a file spec for the make file */ if(argc == 2) strcpy(mk_fspec, argv[1]); else { perror( "there should be one argument-- \n\ a filespec for the make file" ); exit(8); } /* extract its path */ path_of_fspec(src_path, mk_fspec); /* build the chapter list from the make file */ build_chap_list(mk_fspec, home_url_str, &num_chaps, t_c_fn_ext, author, book_title ); /* and proceed to assemble the book */ mk_book_fr_chap_list(home_url_str, num_chaps, t_c_fn_ext, author, book_title, src_path, "htm_lnk"); } /*==================================================================*/ char *path_of_fspec(char *f_path, char *fspec) { int flags, disk_num; char p_drive[FN_EXT_LEN], p_path[FILE_SPEC_LEN], c_drive[FN_EXT_LEN], c_path[FILE_SPEC_LEN], c_f_path[FILE_SPEC_LEN], p_fn[FN_EXT_LEN], f_extension[FN_EXT_LEN]; /* get the current drive and path */ getcwd(c_f_path, FILE_SPEC_LEN); fnsplit(c_f_path, c_drive, c_path, p_fn, f_extension); /* and now the drive and path from the filespec */ flags = fnsplit(fspec, p_drive, p_path, p_fn, f_extension); /* select the default drive and its default directory if appropriate */ if((flags & DRIVE) == 0) { strcpy(p_drive, c_drive); if((flags & DIRECTORY) == 0) strcpy(p_path, c_path); } else if((flags & DIRECTORY) == 0) /* if the drive is present but the directory is not, get a default directory for the specified drive */ { p_path[0] = '\\'; getcurdir(drv_nam_to_int(p_drive), &p_path[1]); } /* now assemble drive and directory into a path */ x_strcpy(f_path, p_drive, p_path, NULL); return(f_path); } /*-------------------------------------------------------------------------*/ int drv_nam_to_int(char *str) { char c; c=str[0]; c=toupper(c); c=c-'A'+1; return(c); } /* converts a name string into a drive number acceptable to MS-DOS */ /*==================================================================*/ int build_chap_list( char *mk_fspec, char *home_url_str, int *num_chaps, char *t_c_fn_ext, char *author, char *book_title ) { FILE *fp; fp=fopen(mk_fspec, "r"); /* read BOOK record */ if( get_book_rec_fr_fp(fp, t_c_fn_ext, author, book_title) == 0 ) return(0); /* read HOME record */ else if( get_home_rec_fr_fp(fp, home_url_str) == 0 ) return(0); /*read all CHAP and REM records */ else if( (*num_chaps = get_other_records_fr_fp(fp)) == 0 ) return(0); else fclose(fp); return(1); } /* build a chapter list, and set all the parameters except the first */ /*==================================================================*/ int get_book_rec_fr_fp( FILE *fp, char *t_c_fn_ext, char *author, char *book_title ) { const int t_c_fn_ext_fld = 1, author_fld = 2, book_title_fld = 3; /*BOOK record*/ int result; char array_data_str[128]; char *control_ary[4]; result=get_tok_ary_fr_fp(fp, array_data_str, "#", control_ary, 4, sizeof(array_data_str)); if( fits_tok_ary_rec(result, control_ary, 4, "BOOK") ) { strcpy(t_c_fn_ext, control_ary[t_c_fn_ext_fld]); strcpy(author, control_ary[author_fld]); strcpy(book_title, control_ary[book_title_fld]); return(1); } else { perror( "line is not in the format expected\n\ the first line of the file must have four fields\n\ the first field must be BOOK" ); return(0); } } /*=================================================================*/ int get_home_rec_fr_fp(FILE *fp, char *home_url_str) { const int home_url_str_fld = 1; /*HOME record*/ int result; char array_data_str[128]; char *control_ary[2]; result=get_tok_ary_fr_fp(fp, array_data_str, "#", control_ary, 2, sizeof(array_data_str)); if( fits_tok_ary_rec(result, control_ary, 2, "HOME") ) { strcpy(home_url_str, control_ary[home_url_str_fld]); return(1); } else { perror( "line has is not in the format expected\n\ the second line of the file must have two fields\n\ the first field must be HOME" ); return(0); } } /*==================================================================*/ int get_other_records_fr_fp(FILE *fp) { const int record_type_fld = 0, /*CHAP record*/ chap_fn_ext_fld = 1, chap_title_fld = 2, chap_num_fld = 3, chap_mode_fld = 4; char array_data_str[128]; char *control_ary[5]; int result; int chap_count = 0; for(;;) { result=get_tok_ary_fr_fp(fp, array_data_str, "#", control_ary, 5, sizeof(array_data_str)); /* test for end of file */ if(result == -2) return(chap_count); /* test for REM record and skip if found */ else if( fits_tok_ary_rec(result, control_ary, 1, "REM") ) continue; /* test for CHAP record and enter its data into the table if found */ else if( fits_tok_ary_rec(result, control_ary, 5, "CHAP") ) { set_chap_list( chap_count, control_ary[chap_fn_ext_fld], control_ary[chap_title_fld], control_ary[chap_num_fld], control_ary[chap_mode_fld] ); chap_count++; } else { perror( "the line is not in a valid format\n\ lines after the first two can be either REM lines\n\ or CHAP lines with five fields\n\ the first field must be CHAP or REM" ); return(0); } } } /* returns the number of chapters found */ /*==================================================================*/ fits_tok_ary_rec( int result, char *control_ary[], int rec_fields, char *match_str ) { const int record_type_fld = 0; if( (result >= rec_fields) && (strcmp(control_ary[record_type_fld], match_str) == 0) ) return(1); else return(0); } /* returns 1 for true, and 0 for false */ /*==================================================================*/ int get_tok_ary_fr_fp( FILE *fp, char *array_data_str, char *delimiters, char *control_ary[], int max_size, int max_length ) { int return_code; if( fgets(array_data_str, max_length, fp) == NULL ) return(-2); else { puts(array_data_str); return_code = tok_str_to_pt_ary( array_data_str, delimiters, control_ary, max_size); return(return_code); } } /* read a line with uniform delimiters from the file into an array of pointers to strings. print raw line to stdout for debugging indication. Returns the number of array elements, or -2 to indicate end of file */ /*==================================================================*/ int tok_str_to_pt_ary( char *tok_str, char *delimiters, char *control_ary[], int max_size ) { int curr_element; char *curr_tok; curr_tok=strtok(tok_str, delimiters); for(curr_element=0; curr_element < max_size; curr_element++) { if(curr_tok == NULL) break; else { control_ary[curr_element] = curr_tok; curr_tok = strtok(NULL, delimiters); } } return(curr_element); } /* use strtok to convert a token string with uniform delimiters into an array of pointers to strings. returns the number of array elements. */ /*==================================================================*/ mk_book_fr_chap_list( char *home_url_str, int num_chaps, char *t_c_fn_ext, char *author, char *book_title, char *src_path, char *sdir_name, ) { char dst_path[FILE_SPEC_LEN], fspec_t_c[FILE_SPEC_LEN]; int fd_t_c, i; char nav_bar_title[256]; /* create a place to put the output */ mk_sdir_w_path(dst_path, src_path, sdir_name); /*open the table of contents */ x_strcpy(fspec_t_c, dst_path, t_c_fn_ext, NULL); fd_t_c = open(fspec_t_c, O_WRONLY|O_CREAT|O_EXCL|O_BINARY, S_IREAD|S_IWRITE); x_strcpy(nav_bar_title, author, " -- ", book_title, NULL); /* make the beginning of the table of contents */ wr_tab_cont_start(fd_t_c, book_title, author); /* process every chapter */ for(i = 0; i <= num_chaps ;i++) mk_chap_fr_table( i, src_path, dst_path, t_c_fn_ext, home_url_str, nav_bar_title, fd_t_c); /* finish up the table of contents */ wr_tab_cont_end(fd_t_c, home_url_str); close(fd_t_c); } /*==============================================================*/ char *mk_sdir_w_path( char *dst_sdir_path, char *src_path, char *sdir_name ) { x_strcpy(dst_sdir_path, src_path, sdir_name, NULL); mkdir(dst_sdir_path); strcat(dst_sdir_path, "\\"); return(dst_sdir_path); } /* make a directory in a path, and return a new path pointing to this directory */ /*==================================================================*/ void wr_tab_cont_start( int fd, char *book_title, char *author ) { char build_str[1000]; x_strcpy( build_str, "\r\n\r\n", "\r\n
\r\n", book_title, "\r\n
\r\n

by\r\n

", author, "\r\n
\r\n


", NULL ); write_s(fd, build_str); } /* writes the start of a table of contents html page to an open file descriptor, plugging in "book_title" and "author" strings */ /*==================================================================*/ void wr_tab_cont_end(int fd, char *home_url_str) { char lnk_tag[512], build_str[640]; x_strcpy( build_str, "\r\n", build_lnk_tag(lnk_tag, home_url_str, "Home Page"), "\r\n", NULL ); write_s(fd, build_str); } /* writes the end of a table of contents html page to an open file descriptor, plugging in the "home_url_str" strings for the Home link */ /*==================================================================*/ void mk_chap_fr_table( int i, char *src_path, char *dst_path, char *t_c_fn_ext, char *home_url_str, char *nav_bar_title, int fd_t_c ) { char prev_fn_ext[FN_EXT_LEN], next_fn_ext[FN_EXT_LEN], *curr_mode; int is_num_chap, is_chap_generated, is_chap_stub; /* computed from table entry */ curr_mode = get_chap_list(rec_ch_mode, i); /*----- look up the following optional parameters -------*/ /*------------------------------ try f = first in link sequence */ if_not_match_contains_char_str_cpy( curr_mode, 'f', prev_fn_ext, get_chap_list(rec_ch_fn_ext, i-1)); /*------------------------------ try l = last in link sequence */ if_not_match_contains_char_str_cpy( curr_mode, 'l', next_fn_ext, get_chap_list(rec_ch_fn_ext, i+1)); /*-------- try n = named chapter, eg. preface, instead of number */ if( match_contains_char(curr_mode, 'n') ) is_num_chap = 0; else is_num_chap = 1; /*-- Now choose one of the following -----------------------------*/ /*--------------------- try h = make edited copy of html original */ if( match_contains_char(curr_mode, 'h') ) { is_chap_generated = 1; is_chap_stub = 0; } /*------------------------otherwise try d = create dummy chapter */ else if( match_contains_char(curr_mode, 'd') ) { is_chap_generated = 1; is_chap_stub = 1; } else /* default nothing-- 0 = generate nothing */ { is_chap_generated = 0; is_chap_stub = 0; } /*-- always do the following --------------------------------------*/ mk_chap_fr_file( src_path, dst_path, get_chap_list(rec_ch_fn_ext, i), t_c_fn_ext, prev_fn_ext, next_fn_ext, home_url_str, nav_bar_title, get_chap_list(rec_ch_title, i), get_chap_list(rec_ch_num, i), is_num_chap, is_chap_generated, is_chap_stub, fd_t_c ); } /* works out parameters from the table and feeds them to an interior function which acts on a particular file, as well as creating a table of contents entry. */ /*==================================================================*/ char *if_not_match_contains_char_str_cpy( char *match, char code, char *dst, char *poss_src ) { if( match_contains_char(match, code) ) strcpy(dst, ""); else strcpy(dst, poss_src); return(dst); } /* copy the possible source to the destination if the match string contains the code, otherwise make the destination an empty string */ /*==================================================================*/ int match_contains_char(char *match, char code) { if(strchr(match, code) != NULL ) return(1); else return(0); } /* true if the match string contains the code, otherwise false */ /*==================================================================*/ int mk_chap_fr_file( char *src_path, char *dst_path, char *curr_fn_ext, char *t_c_fn_ext, char *prev_fn_ext, char *next_fn_ext, char *home_url_str, char *nav_bar_title, char *ch_title, char *chap_num_txt, int is_num_chap, int is_chap_generated, int is_chap_stub, int fd_t_c ) { int fd_i, fd_o, result_code; char f_stub[2048], b_stub[2048], src_fspec[FILE_SPEC_LEN], dst_fspec[FILE_SPEC_LEN]; /*-- make an entry in the table of contents --*/ wr_t_c_line(fd_t_c, chap_num_txt, ch_title, curr_fn_ext); /*-- now see about creating the chapter file --*/ if(is_chap_generated) { /* open the chapter source and destination files */ x_strcpy(src_fspec, src_path, curr_fn_ext, NULL); x_strcpy(dst_fspec, dst_path, curr_fn_ext, NULL); open_filter(src_fspec, dst_fspec, &fd_i, &fd_o); /**/ mk_stubs( f_stub, b_stub, t_c_fn_ext, prev_fn_ext, next_fn_ext, home_url_str, nav_bar_title, ch_title, chap_num_txt, is_num_chap ); if(is_chap_stub) result_code= create_stub_chap( fd_o, f_stub, b_stub); else result_code= cpy_htm_ins_stub(fd_i, fd_o, f_stub, b_stub); close(fd_i); close(fd_o); } return(result_code); } /* Creates a table of contents entry, and chooses a method for creating the chapter, providing open file descriptors. Return 1 for success, 0 for failure */ /*==================================================================*/ int open_filter(char *fn_in, char *fn_out, int *fd_in, int *fd_out) { *fd_in = open(fn_in, O_RDONLY|O_BINARY); if(*fd_in == -1) { printf(" \nSource File %s Does Not Exist\n", fn_in); return(-1); } *fd_out = open(fn_out, O_WRONLY|O_CREAT|O_EXCL|O_BINARY, S_IREAD|S_IWRITE); if( *fd_out == -1) { printf("\nDestination File %s Invalid\n", fn_out); return(-1); } /* assuming success */ printf( "\nOpening Source File \n %s \n to copy to Dest. File %\n", fn_in, fn_out ); return(0); } /* opens a filter of fn_in, fn_out, and sets file descriptors *fd_i, fd_o. Returns 0 for sucess, -1 for failure. */ /*==================================================================*/ void mk_stubs( char *f_stub, char *b_stub, char *t_c_fn_ext, char *prev_fn_ext, char *next_fn_ext, char *home_url_str, char *nav_bar_title, char *ch_title, char *chap_num_txt, int is_num_chap ) { char nav_bar[2048]; mk_nav_bar( nav_bar, t_c_fn_ext, prev_fn_ext, next_fn_ext, home_url_str, nav_bar_title ); mk_f_stub( f_stub, nav_bar, ch_title, chap_num_txt, is_num_chap ); strcpy(b_stub, nav_bar); } /*==================================================================*/ /* write a link to the table of contents */ void wr_t_c_line( int fd_t_c, char *chap_num_txt, char *ch_title, char *curr_fn_ext ) { char t_c_line[512], t_c_lnk[512], t_c_lnk_txt[256]; x_strcpy( t_c_lnk_txt, chap_num_txt, ". ", ch_title, NULL ); build_lnk_tag(t_c_lnk, curr_fn_ext, t_c_lnk_txt); x_strcpy(t_c_line, "\r\n

\r\n ", t_c_lnk, "\r\n

\r\n", NULL); write_s(fd_t_c, t_c_line); } /* Writes a table of contents line, pointing to file curr_fn_ext, into the file referenced by descriptor fd_t_c, with the visible text: chap_num_txt[period-blanks]ch_title */ /*==================================================================*/ char *x_strcpy(char *dst, char *src_1, ...) { va_list argptr; char *src_next; if(src_1 != NULL) { strcpy(dst, src_1); va_start(argptr, src_1); src_next = va_arg(argptr, char *); while (src_next != NULL) { strcat(dst, src_next); src_next = va_arg(argptr, char *); } va_end(argptr); } else strcpy(dst, ""); return(dst); } /* concatenates a variable number of strings into a previously empty (or scratch) string. The argument list is terminated by NULL */ /*==================================================================*/ char *build_lnk_tag(char *dst_lnk_tag, char *url_str, char *lnk_txt) { if(url_str[0] != '\0') x_strcpy( dst_lnk_tag, "", lnk_txt, "", NULL ); else strcpy(dst_lnk_tag, url_str); return(dst_lnk_tag); } /* If url_str is not empty, copy it and link_txt into a ddynamic link in link_tag, otherwise make link_tag empty. Return whatever winds up in link_tag */ /*==================================================================*/ char *mk_nav_bar( char *dst_nav_bar, char *t_c_fn_ext, char *prev_fn_ext, char *next_fn_ext, char *home_url_str, char *nav_bar_title ) { char horizontal_ruler_tag[32]; char spacer[16]; char dmy_lnk_tag_t[128], dmy_lnk_tag_l[128], dmy_lnk_tag_n[128], dmy_lnk_tag_h[128]; strcpy(spacer,"  "); strcpy(horizontal_ruler_tag, "\r\n


\r\n"); /* start building the navigation bar */ x_strcpy( dst_nav_bar, horizontal_ruler_tag, "
", nav_bar_title, "
\r\n", build_lnk_tag(dmy_lnk_tag_t, t_c_fn_ext, "Table of Contents"), spacer, build_lnk_tag(dmy_lnk_tag_l, prev_fn_ext, "Last Chapter"), spacer, build_lnk_tag(dmy_lnk_tag_n, next_fn_ext, "Next Chapter"), spacer, build_lnk_tag(dmy_lnk_tag_h, home_url_str, "Home Page"), horizontal_ruler_tag, NULL ); return(dst_nav_bar); } /* Build a navigation bar from the file names tc_fn_ext, prev_fn_ext, next_fn_ext, home_url_str ignoring any that are empty, and title the navigation bar with nav_bar_title */ /*==================================================================*/ void mk_f_stub( char *dst_f_stub, char *nav_bar, char *ch_title, char *chap_num_txt, int is_num_chap ) { char ful_ch_n_txt[80]; if(is_num_chap) x_strcpy(ful_ch_n_txt, "Chapter ", chap_num_txt, NULL); else strcpy(ful_ch_n_txt, chap_num_txt); x_strcpy( dst_f_stub, nav_bar, "
 ", ful_ch_n_txt, "\r\n

", ch_title, "

\r\n", NULL ); } /*==================================================================*/ int create_stub_chap( int fd_o, char *f_stub, char *b_stub ) { write_s(fd_o, "\r\n\r\n\r\n"); write_s(fd_o, f_stub); write_s(fd_o, b_stub); write_s(fd_o, "\r\n"); return(1); } /* returns 1 for sucess, 0 for failure, faked */ /*==================================================================*/ /*------------------------------------------------------------------*/ /* Copy the HTML file, inserting the stubs */ /*------------------------------------------------------------------*/ int cpy_htm_ins_stub( int fd_i, int fd_o, char *f_stub, char *b_stub ) { if( cpy_match_insrt(fd_i, fd_o, "", seq_before, "") == 0) return(0); else if( cpy_match_insrt(fd_i, fd_o, "", seq_before, "") == 0) return(0); else if( cpy_match_insrt(fd_i, fd_o, "", seq_before, "") == 0) return(0); else if( cpy_match_insrt(fd_i, fd_o, f_stub, seq_after, "") == 0) return(0); else if( cpy_match_insrt(fd_i, fd_o, b_stub, seq_before, "") == 0) return(0); else if( cpy_match_insrt(fd_i, fd_o, "", seq_before, "") == 0) return(0); else return(1); } /* Parse through fd_i, writing to fd_o. Insert f_stub after and b_stub before . If tokens: are out of sequence, report failure. Returns 1 for sucess, 0 for failure */ /*==================================================================*/ int cpy_match_insrt( int fd_i, int fd_o, char *possible_stub, int before_or_after, char *match ) { if( cpy_to_match(fd_i, fd_o, match, 0) == 0) return(0); else { if (before_or_after == seq_before) { write_s(fd_o, possible_stub); write_s(fd_o, match); return(1); } else if(before_or_after == seq_after) { write_s(fd_o, match); write_s(fd_o, possible_stub); return(1); } else return(0); } } /* Copies up to a match, then inserts POSSIBLE STUB before or after the matched string. returns 1 for sucess, 0 for failure */ /*==================================================================*/ /*--------------------------------------------------------------------*/ /* Subfunction -- copy up to the next match */ /*--------------------------------------------------------------------*/ int cpy_to_match( int fd_i, int fd_o, char *target, int suppress_output /* 1 = suppress */ ) { int chars_in_tgt, chars_in_buff, chars_refilled, out_of_input_flg; char buffer[30]; chars_in_tgt = strlen(target); chars_in_buff = read(fd_i, buffer, chars_in_tgt); if( chars_in_buff != chars_in_tgt) { if(!suppress_output) write(fd_o, buffer, chars_in_buff); return(0); } out_of_input_flg = 0; while( strnicmp(buffer, target, chars_in_buff) != 0 ) { if(!suppress_output) write(fd_o, buffer, 1); chr_arr_lshift(buffer, chars_in_buff, 1); chars_refilled = read(fd_i, &(buffer[chars_in_buff-1]), 1); if(chars_refilled == 0) { if(!suppress_output) write(fd_o, buffer, (chars_in_buff-1)); out_of_input_flg = 1; break; } } if(out_of_input_flg == 1) return(0); else return(1); } /* does not copy the match string, returns 1 if found, 0 if failure */ /*==================================================================*/ int write_s(int fd, char *s) { int length, retcode; length = strlen(s); if(length != 0) retcode = write(fd, s, length); else retcode = 0; return( retcode ); } /* Writes the contents of the string s to the file descriptor fd. Returns number of bytes writen, or -1 for error */ /*===================================================================*/ chr_arr_lshift(char *buffer, int len_shift_area, int dist_shifted) { int i; for(i=0; i < (len_shift_area - dist_shifted); i++) buffer[i] = buffer[i+dist_shifted]; } /* left-shifts a byte-precision shift register of LEN_SHIFT_AREA bytes starting on BUFFER, for DIST_SHIFTED bytes */ /*===============================================================*/