/* Copyright (C) 1993 Bell-Northern Research This file is part of vsplit. Vmkr is distributed in the hope that it will be useful, but without any warranty. No author or distributor accepts responsibility to anyone for the consequences of using it or for whether it serves any particular purpose or works at all, unless he says so in writing. Everyone is granted permission to copy, modify and redistribute vsplit, but only under the conditions described in the document "vsplit copying permission notice". An exact copy of the document is supposed to have been given to you along with vsplit so that you can know how you may redistribute it all. It should be in a file named COPYING. Among other things, the copyright notice and this notice must be preserved on all copies. */ #include "typedef.h" #include extern struct names *hashtab[BASE]; extern struct names *fname_tab[BASE]; extern int return_code; extern int verbose; extern char dir_name[MAXTOKEN]; /* holds the directory name */ int arch_count; int ent_count; int pkg_count; int pkg_body_count; int config_count; /* * subprogram to parse a file, and return a pointer that points * to a linked list of tokens, their variables, and keywords. */ struct token_holder *get_tokens(fname, copy) char *fname; int copy; { char token[MAXTOKEN]; char tt[MAXTOKEN], last_prefix[MAXTOKEN]; char line[MAXLINE]; int nottoken, found_token; int hashval; struct names *np, *lookup(); char *next_token(); int state; int begin_count; char keywrd[MAXTOKEN], var1[MAXTOKEN], var2[MAXTOKEN]; int last_state; struct token_holder *newtokens; struct token_holder *head; struct token_holder *current_head; FILE *fp, *fopen(); /* * added these variables for Vsplit to the +++...'s */ int tot_units; FILE *fp_out; long unit_start, unit_stop, last_end; int last_type; int last_was_ent; /* +++++++++++++++++++++ */ nottoken = FALSE; found_token = FALSE; tot_units = 0; last_end = 0; unit_start = 0; unit_stop = 0; last_type = 0; arch_count = 0; ent_count = 0; pkg_count = 0; pkg_body_count = 0; config_count = 0; head = NULL; /* * The initial state is 1. */ state = 1; last_state = 1; /* * Now, open the file, and start to parse it. */ /*----printf("opening file fp '%s' for parsing\n", fname); fflush(NULL);*/ if ((fp = fopen(fname, "r")) == NULL) { /*++++printf("about to return a null... name does not exist\n");*/ return (NULL); } strcpy(token, next_token(fp)); while(stringcmp(token, "") != 0) { /*----printf("state %d token '%s'\n", state, token); fflush(NULL);*/ hashval = hash(token); np = lookup(token, hashtab); if (state == 1) { last_state = state; if (np != NULL) { found_token = TRUE; strcpy(keywrd, token); if ( stringcmp(token, "ARCHITECTURE") == 0 ) { state = 2; arch_count++; } else if ( stringcmp(token, "END") == 0 ) { state = 5; } else if ( (stringcmp(token, "ENTITY") == 0) || (stringcmp(token, "PORT") == 0) || (stringcmp(token, "FOR") == 0) ) { state = 6; if (stringcmp(token, "ENTITY") == 0) { ent_count++; last_was_ent = TRUE; } else last_was_ent = FALSE; } else if ( stringcmp(token, "PACKAGE") == 0 ) { state = 7; pkg_count++; } else if ( stringcmp(token, "USE") == 0 ) { state = 9; } else if ( stringcmp(token, "CONFIGURATION") == 0 ) { state = 13; config_count++; } else if ( stringcmp(token, "ATTRIBUTE") == 0 ) { state = 40; } else { printf("illegal token :%s: found in state 1\n",token); } if ( (state == 2) || (state == 7) || (state == 6) || (state == 9) || (state == 13) ) { /* * If we have encountered a keyword that we are looking for, then * get a new token_holder structure and initialize the * keyword and next fields. */ if (head == NULL) { head = MALLOC(token_holder); current_head = head; newtokens = head; } else { newtokens = MALLOC(token_holder); /* * assign the current pointer to this new token. */ current_head->next = newtokens; current_head = newtokens; } newtokens->keywrd = NMALLOC(strlen(token)+1, char); strcpy(newtokens->keywrd, token); newtokens->var1 = NULL; newtokens->var2 = NULL; newtokens->token = NULL; newtokens->next = NULL; /*----printf("note, just installed keyword %s\n",newtokens->keywrd);*/ } /* * if we have found the beginning of a primary or secondary unit, * then we must copy from the last position to the current position * to the output file. */ if ( (state == 2) || ((state == 6) && (stringcmp(token, "ENTITY") == 0)) || (state == 7) || (state == 13) ) { tot_units++; if (tot_units == 1) { /* * if this is the first unit found, then just mark the beginning and * end pointers, as there may just be one primary unit in the whole file. */ unit_start = 0; last_type = state; } else { /* * if this was not the first unit found, then copy the last unit found * to the output, and set up this unit for copying the next time around. */ unit_stop = last_end; copy_unit(fname,last_type,unit_start, unit_stop,last_prefix,copy); last_type = state; strcpy(last_prefix, ""); unit_start = last_end+1; } } } } else if (state == 2) { last_state = state; newtokens->var1 = NMALLOC(strlen(token)+1, char); strcpy(newtokens->var1, token); state = 3; /* * copy the architecture name to last_prefix */ sprintf(last_prefix, "%s",token); } else if (state == 3) { /* * If, for the ARCHITECTURE keyword, we don't detect "OF" after we * detect the name (state 2), then we don't have an architecture, and * must ingnore this token. */ last_state = state; if (stringcmp(token, "OF") == 0) state = 4; else state = 1; } else if (state == 4) { last_state = state; newtokens->var2 = NMALLOC(strlen("")+1, char); strcpy(newtokens->var2, ""); newtokens->token = NMALLOC(strlen(token)+1, char); strcpy(newtokens->token, token); state = 1; /* * now, copy the entity name to last_prefix * such that we have ent_arch.vhd */ sprintf(tt, "%s_%s",token,last_prefix); strcpy(last_prefix, tt); } else if (state == 5) { last_end = ftell(fp); last_state = state; state = 1; } else if (state == 6) { last_state = state; newtokens->var1 = NMALLOC(strlen("")+1, char); strcpy(newtokens->var1, ""); newtokens->var2 = NMALLOC(strlen("")+1, char); strcpy(newtokens->var2, ""); newtokens->token = NMALLOC(strlen(token)+1, char); strcpy(newtokens->token, token); state = 1; /* * if the last token was an entity token, then we can set * up last_prefix to be entname_.vhd */ if (last_was_ent) sprintf(last_prefix, "%s_", token); } else if (state == 7) { last_state = state; if ( stringcmp(token, "BODY") == 0 ) { strcpy(var1, token); newtokens->var1 = NMALLOC(strlen(token)+1, char); strcpy(newtokens->var1, token); state = 8; /* * note that if we have a package body, update counters to reflect this, * as well as change last_prefix so that this unit is written to the * correct file. */ pkg_count--; pkg_body_count++; if (pkg_body_count > 1) sprintf(tt, "pkg_body%d_", pkg_count); else sprintf(tt, "pkg_body_"); strcpy(last_prefix, tt); } else { newtokens->var1 = NMALLOC(strlen("")+1, char); strcpy(newtokens->var1, ""); newtokens->var2 = NMALLOC(strlen("")+1, char); strcpy(newtokens->var2, ""); newtokens->token = NMALLOC(strlen(token)+1, char); strcpy(newtokens->token, token); state = 1; /* * we have a package, and thus can set last_prefix to be pname_ */ sprintf(last_prefix, "%s_",token); } } else if (state == 8) { last_state = state; newtokens->var2 = NMALLOC(strlen("")+1, char); strcpy(newtokens->var2, ""); newtokens->token = NMALLOC(strlen(token)+1, char); strcpy(newtokens->token, token); state = 1; /* * the file that the package body will reside in is called * pname.vhd */ sprintf(last_prefix, "%s", token); } else if (state == 9) { last_state = state; strcpy(var1, token); if ( stringcmp(token, "ENTITY") == 0 ) { newtokens->var1 = NMALLOC(strlen(token)+1, char); strcpy(newtokens->var1, token); state = 10; } else if ( stringcmp(token, "CONFIGURATION") == 0 ) { newtokens->var1 = NMALLOC(strlen(token)+1, char); strcpy(newtokens->var1, token); state = 11; } else { newtokens->var1 = NMALLOC(strlen("")+1, char); strcpy(newtokens->var1, ""); newtokens->var2 = NMALLOC(strlen("")+1, char); strcpy(newtokens->var2, ""); newtokens->token = NMALLOC(strlen(token)+1, char); strcpy(newtokens->token, token); state = 16; } /*++++printf("note that the use token is %s\n",token);*/ /*++++printf("and going from state 9 to state %d\n",state);*/ } else if (state == 10) { last_state = state; strcpy(var2, token); newtokens->var2 = NMALLOC(strlen(token)+1, char); strcpy(newtokens->var2, token); state = 12; } else if (state == 11) { last_state = state; newtokens->var2 = NMALLOC(strlen("")+1, char); strcpy(newtokens->var2, ""); newtokens->token = NMALLOC(strlen(token)+1, char); strcpy(newtokens->token, token); state = 1; } else if (state == 12) { last_state = state; newtokens->token = NMALLOC(strlen(token)+1, char); strcpy(newtokens->token, token); state = 1; } else if (state == 13) { last_state = state; /* * Got a CONFIGURATION token, and this token is assigned * to var1, and represents the configuration name. */ newtokens->var1 = NMALLOC(strlen(token)+1, char); strcpy(newtokens->var1, token); newtokens->var2 = NMALLOC(strlen("")+1, char); strcpy(newtokens->var2, ""); state = 14; /* * copy the configuration name to last_prefix. The * format for this will be cnfg_ent.vhd */ sprintf(last_prefix, "%s", token); } else if (state == 14) { /* * used to swallow token "OF" */ last_state = state; state = 15; } else if (state == 15) { /* * copy the entity name to token field. */ last_state = state; newtokens->token = NMALLOC(strlen(token)+1, char); strcpy(newtokens->token, token); state = 1; sprintf(tt, "%s_%s", last_prefix, token); strcpy(last_prefix, tt); } else if (state == 16) { if ( stringcmp(token, ";") != 0 ) { newtokens = MALLOC(token_holder); current_head->next = newtokens; current_head = newtokens; sprintf(tt, "USE"); newtokens->keywrd = NMALLOC(strlen(tt)+1, char); strcpy(newtokens->keywrd, tt); newtokens->var1 = NULL; newtokens->var2 = NULL; newtokens->token = NULL; newtokens->next = NULL; newtokens->var1 = NMALLOC(strlen("")+1, char); strcpy(newtokens->var1, ""); newtokens->var2 = NMALLOC(strlen("")+1, char); strcpy(newtokens->var2, ""); newtokens->token = NMALLOC(strlen(token)+1, char); strcpy(newtokens->token, token); state = 16; } else { state = 1; } } else if (state == 40) { /* * if we got ATTRIBUTE... get rid of all tokens till the * semicolon */ if ( stringcmp(token, ";") == 0 ) { state = 1; } } sprintf(token,""); nottoken = FALSE; strcpy(token, next_token(fp)); } /* * Now, when we reach the end of the file, copy the last unit. */ unit_stop = last_end; copy_unit(fname, last_type, unit_start, unit_stop, last_prefix, copy); /* * remember to close the files. */ /*----printf("closing file fp '%s'\n", fname); fflush(NULL);*/ fclose(fp); return (head); } hash(token) char *token; { int a; int hashindex; int hashval; for (hashval = 0; *token != '\0';) { a = *token++; if(isupper(a)) a=tolower(a); hashval += a; } /* printf("hashindex = %d and hashval = %d ",hashindex,hashval); */ return ( hashindex = (hashval) % BASE) ; } create_database() { int hashval; char token[MAXTOKEN]; sprintf(token, "ARCHITECTURE"); install(token, hashtab); sprintf(token, "ATTRIBUTE"); install(token, hashtab); sprintf(token, "CONFIGURATION");install(token, hashtab); sprintf(token, "END"); install(token, hashtab); sprintf(token, "ENTITY"); install(token, hashtab); sprintf(token, "FOR"); install(token, hashtab); sprintf(token, "PACKAGE"); install(token, hashtab); sprintf(token, "PORT"); install(token, hashtab); sprintf(token, "USE"); install(token, hashtab); /* sprintf(token, "ABS"); install(token, hashtab); sprintf(token, "ACCESS"); install(token, hashtab); sprintf(token, "AFTER"); install(token, hashtab); sprintf(token, "ALIAS"); install(token, hashtab); sprintf(token, "ALL"); install(token, hashtab); sprintf(token, "AND"); install(token, hashtab); sprintf(token, "ARRAY"); install(token, hashtab); sprintf(token, "ASSERT"); install(token, hashtab); sprintf(token, "BEGIN"); install(token, hashtab); sprintf(token, "BLOCK"); install(token, hashtab); sprintf(token, "BODY"); install(token, hashtab); sprintf(token, "BUFFER"); install(token, hashtab); sprintf(token, "BUS"); install(token, hashtab); sprintf(token, "CASE"); install(token, hashtab); sprintf(token, "COMPONENT"); install(token, hashtab); sprintf(token, "CONSTANT"); install(token, hashtab); sprintf(token, "DISCONNECT"); install(token, hashtab); sprintf(token, "DOWNTO"); install(token, hashtab); sprintf(token, "ELSE"); install(token, hashtab); sprintf(token, "ELSIF"); install(token, hashtab); sprintf(token, "EXIT"); install(token, hashtab); sprintf(token, "FILE"); install(token, hashtab); sprintf(token, "FUNCTION"); install(token, hashtab); sprintf(token, "GENERATE"); install(token, hashtab); sprintf(token, "GENERIC"); install(token, hashtab); sprintf(token, "GUARDED"); install(token, hashtab); sprintf(token, "IF"); install(token, hashtab); sprintf(token, "IN"); install(token, hashtab); sprintf(token, "INOUT"); install(token, hashtab); sprintf(token, "IS"); install(token, hashtab); sprintf(token, "LABEL"); install(token, hashtab); sprintf(token, "LIBRARY"); install(token, hashtab); sprintf(token, "LINKAGE"); install(token, hashtab); sprintf(token, "LOOP"); install(token, hashtab); sprintf(token, "MAP"); install(token, hashtab); sprintf(token, "MOD"); install(token, hashtab); sprintf(token, "NAND"); install(token, hashtab); sprintf(token, "NEW"); install(token, hashtab); sprintf(token, "NEXT"); install(token, hashtab); sprintf(token, "NOR"); install(token, hashtab); sprintf(token, "NOT"); install(token, hashtab); sprintf(token, "NULL"); install(token, hashtab); sprintf(token, "OF"); install(token, hashtab); sprintf(token, "ON"); install(token, hashtab); sprintf(token, "OPEN"); install(token, hashtab); sprintf(token, "OR"); install(token, hashtab); sprintf(token, "OTHERS"); install(token, hashtab); sprintf(token, "OUT"); install(token, hashtab); sprintf(token, "PROCEDURE"); install(token, hashtab); sprintf(token, "PROCESS"); install(token, hashtab); sprintf(token, "RANGE"); install(token, hashtab); sprintf(token, "RECORD"); install(token, hashtab); sprintf(token, "REGISTER"); install(token, hashtab); sprintf(token, "REM"); install(token, hashtab); sprintf(token, "REPORT"); install(token, hashtab); sprintf(token, "RETURN"); install(token, hashtab); sprintf(token, "SELECT"); install(token, hashtab); sprintf(token, "SEVERITY"); install(token, hashtab); sprintf(token, "SIGNAL"); install(token, hashtab); sprintf(token, "SUBTYPE"); install(token, hashtab); sprintf(token, "THEN"); install(token, hashtab); sprintf(token, "TO"); install(token, hashtab); sprintf(token, "TRANSPORT"); install(token, hashtab); sprintf(token, "TYPE"); install(token, hashtab); sprintf(token, "UNITS"); install(token, hashtab); sprintf(token, "UNTIL"); install(token, hashtab); sprintf(token, "VARIABLE"); install(token, hashtab); sprintf(token, "WAIT"); install(token, hashtab); sprintf(token, "WHEN"); install(token, hashtab); sprintf(token, "WHILE"); install(token, hashtab); sprintf(token, "WITH"); install(token, hashtab); sprintf(token, "XOR"); install(token, hashtab); */ } struct names *lookup(s, hashtab) char *s; struct names *hashtab[]; { struct names *np; /* * first get a hash value of token, and assign np to the * pointer in the hash table corresponding to it. * Then, go thru the database until a match is found for * the token. If a match is found, return the pointer to * the name. If no match is found, return NULL. */ for (np = hashtab[hash(s)]; np != NULL; np = np->next) { if (stringcmp(s,np->name) == 0) { return(np); } } return(NULL); } install(name, hashtab) char *name; struct names *hashtab[]; { struct names *np, *newnp, *oldnp, *lookup(), *p; char *strsave(); int hashval; np = lookup(name, hashtab); if (np == NULL) { /* * get a new element of type np, and assign the * name field. */ newnp = MALLOC(names); newnp->name = NMALLOC(strlen(name)+1, char); strcpy(newnp->name, name); /* * get the hashtable pointer indicated by the hashing of the name. */ hashval = hash(name); np = hashtab[hashval]; if (np == NULL) /* * if the table entry is null, update that entry to point to * the new element. */ { hashtab[hashval] = newnp; } else { /* * else, until this pointer is null, search thru the data. */ while (np != NULL) { oldnp = np; np = np->next; } /* * now, update the data so that the old end of data points to * the new element, which is now the end of data. */ oldnp->next = newnp; } } } /*--------------------------------------------------------------------------*/ char *next_token(fp) FILE *fp; { int x; int found; int state; char token[MAXTOKEN]; x = fgetc(fp); state = 0; found = FALSE; sprintf(token, ""); while ( (x != EOF) && (!found) ) { if (state == 0) { /* * first, check to see if we have encountered a terminating character that * is also a token. */ if (x == ';') { state = 0; found = TRUE; sprintf(token,"%c",x); } /* * now check to see if we have encountered a character that is a terminating * character, but doesn't become part of a token. */ else if ( (x == ' ') || (x == '[') || (x == ']') || (x == '(') || (x == ')') || (x == '+') || (x == ':') || (x == '|') || (x == '#') || (x == '^') || (x == '*') || (x == ',') || (x == '<') || (x == '>') || (x == '/') || (x == 9) || (x == 10) ) { state = 2; } else if (x == '-') { /* * '-' is a terminating token, but could also be part of '--' which implies a comment * for the rest of the line. */ state = 3; } else if (x == '"') { /* * we must swallow everything between quotes. */ state = 4; } else { /* * otherwise, we have part of a token... */ sprintf(token,"%c",x); state = 1; } } else if (state == 1) { /* * if we are composing a token... */ if ( (x == ';') || (x == '-') || (x == '"') ) { /* * if we get a terminating character that we need info on next time into * this sub program, return that character to the stream. */ state = 0; ungetc(x, fp); found = TRUE; } /* * now check to see if we have encountered a character that is a terminating * character, but doesn't become part of a token. */ else if ( (x == ' ') || (x == '[') || (x == ']') || (x == '(') || (x == ')') || (x == '+') || (x == ':') || (x == '|') || (x == '#') || (x == '^') || (x == '*') || (x == ',') || (x == '<') || (x == '>') || (x == '/') || (x == 9) || (x == 10) ) { state = 0; found = TRUE; } else { sprintf(token, "%s%c", token, x); } } else if (state == 2) { /* * else, if we are eating up terminating characters... */ if (x == ';') { sprintf(token, "%c", x); found = TRUE; state = 0; } else if (x == '-') { state = 3; } else if (x == '"') { state = 4; } else if ( (x == ' ') || (x == '[') || (x == ']') || (x == '(') || (x == ')') || (x == '+') || (x == ':') || (x == '|') || (x == '#') || (x == '^') || (x == '*') || (x == ',') || (x == '<') || (x == '>') || (x == '/') || (x == 9) || (x == 10) ) { } else { sprintf(token, "%c", x); state = 1; } } else if (state == 3) { if (x == ';') { sprintf(token, "%c", x); found = TRUE; state = 0; } else if (x == '-') { state = 5; } else if (x == '"') { state = 4; } else if ( (x == ' ') || (x == '[') || (x == ']') || (x == '(') || (x == ')') || (x == '+') || (x == ':') || (x == '|') || (x == '#') || (x == '^') || (x == '*') || (x == ',') || (x == '<') || (x == '>') || (x == '/') || (x == 9) || (x == 10) ) { state = 2; } else { sprintf(token, "%c", x); state = 1; } } else if (state == 4) { if ( (x == '"') || (x == 10) ) { /* * If we find the matching ", or we reach the end of the line (assume that * the user forgot the other ")... */ state = 0; } } else if (state == 5) { /* * we have encountered two '-' in a row... thus whatever follows, to the end of the * line is a comment, and to be ignored. */ if (x == 10) { state = 0; } } else { printf("ERROR : illegal state '%d' encountered while in next_token()\n"); } if (!found) x = fgetc(fp); } return (token); } /* * the following procedure lexically compares two strings and tests * to see if a is less, equal, or greater than b, lexically, without * begin case sensitive. */ stringcmp(a, b) char *a, *b; { int i; int different; int end; int aa, bb; i = 0; different = 0; end = FALSE; while ( (different == 0) && (!end) ) { aa = a[i]; bb = b[i]; if isupper(aa) aa = tolower(aa); if isupper(bb) bb = tolower(bb); if ( (aa == '\0') && (bb != '\0') ) /* if a ends before b, then a is less than b */ different = -1; else if ( (bb == '\0') && (aa != '\0') ) /* if b ends before a, then a is greater than b */ different = 1; else if ( (aa == '\0') && (bb == '\0') ) /* if a and b end at the same time, then they are equal */ end = TRUE; /* * now if the strings haven't ended, check to see if the next * character is less than, greater than, or equal. */ else if (aa < bb) different = -1; else if (aa > bb) different = 1; else i++; } return (different); } /* * now, the procedure to copy a unit to a new file. */ copy_unit(file_name, last_type, unit_start, unit_stop, pfix, copy) char *file_name; int last_type; long unit_start; long unit_stop; char *pfix; int copy; { FILE *fp_in, *fp_out, *fopen(); char name_fp_out[MAXTOKEN]; char token[MAXTOKEN]; char prefix[MAXTOKEN]; char *m2l(); int x; struct names *np, *lookup(); int count; int accessible; count = 0; strcpy(prefix, m2l(pfix)); /*---- printf("call to copy unit... variables are :\n"); printf("\tfile_name '%s'\n",file_name); printf("\tunit_start '%d'\n",unit_start); printf("\tunit_stop '%d'\n",unit_stop); printf("\tprefix '%s'\n",prefix); printf("\tdir_name is '%s'\n",dir_name); if (copy == 1) printf("\tcopy is TRUE\n"); else printf("\tcopy is FALSE\n"); fflush(NULL); ----*/ if (stringcmp(prefix, "") == 0) { printf("ERROR : prefix is empty, in copy_unit()!\n"); return (NULL); } /* * First, open the source file. */ /*----printf("opening file fp_in '%s' ... source for copying\n", file_name); fflush(NULL);*/ if ( ((fp_in = fopen(file_name, "r")) == NULL) && (copy) ) { printf("ERROR : could not open source file '%s', in copy_unit()\n", file_name); return (NULL); } /* * position the start of where to copy from */ if (copy) fseek(fp_in, unit_start, SEEK_SET); if (stringcmp(dir_name, "") == 0) sprintf(name_fp_out, "%s.vhd", prefix); else { sprintf(name_fp_out, "%s/%s.vhd", dir_name, prefix); } /* * now, check to see if the file has already been used. */ /*----printf("opening file fp_out '%s'... potentital op, to see if exists\n", name_fp_out); fflush(NULL);*/ while ((fp_out = fopen(name_fp_out, "r")) != NULL) { if (copy) printf("WARNING : file '%s' already exists!\n",name_fp_out); fclose(fp_out); count++; if (stringcmp(dir_name, "") == 0) { sprintf(token, "%s%d.vhd",prefix,count); } else { sprintf(token, "%s/%s%d.vhd",dir_name,prefix,count); } strcpy(name_fp_out, token); if (copy) printf("\t...new name is '%s'\n",name_fp_out); } /* * now, open the destination (output) file. */ if (copy) { /*----printf("opening file fp_out '%s'... as dest\n", name_fp_out); fflush(NULL);*/ if ((fp_out = fopen(name_fp_out, "w")) == NULL) { printf("ERROR : in procedure copy_unit... can't open output file "); printf("%s\n",name_fp_out); return (NULL); } } if (!copy) { if (last_type == 2) printf("architecture unit "); else if (last_type == 6) printf("entity unit "); else if (last_type == 7) printf("package unit "); else if (last_type == 13) printf("configuration unit "); printf("'%s'\n",name_fp_out); } /* * now, while we don't go past the stop pointer, copy the source * to the target. */ if (verbose && copy) printf("copying from '%s' to '%s'\n",file_name, name_fp_out); while ( (ftell(fp_in) <= unit_stop) && (copy) ) { x = fgetc(fp_in); fputc(x, fp_out); } /* * add an extra newline at the end of the file. */ if (copy) { x = 10; fputc(x, fp_out); fputc(x, fp_out); } /* * close the source and destination files. */ if (fp_in != NULL) { fclose(fp_in); } if (fp_out != NULL) { fclose(fp_out); } } char *m2l(s) char *s; { /* * This function takes as input a string, terminated by the null * character(same as what the string functions require), and return * the lowercase conversion of that string. */ int i; char result[MAXTOKEN]; i = 0; while (s[i] != '\0') { if (isupper(s[i])) { result[i] = tolower(s[i]); } else { result[i] = s[i]; } i++; } /* * copy the terminating null. */ result[i] = s[i]; return (result); }