There are 6 supporting dvi variations of the ‘CopyTo to-file op group’ dvi command:
The code
produces the string ‘ B1 B3 ’.
<..CopyTo files..>
{ <.CopyTo vars.>
eoln_ch = (int) ’x’;
while( eoln_ch != EOF ) {
status = scan_str("CopyTo: ", TRUE, lg_file);
status = scan_until_str(" ", 1, status, lg_file);
status = scan_until_str(" ", 2, status, lg_file);
status = scan_until_str(" ", 3, status, lg_file);
status = scan_until_str(" ", 4, status, lg_file);
status = scan_until_end_str("", 5, status, lg_file);
if( status ){
if( debug ){
(IGNORED) printf("...CopyTo: %s%s%s%s%s...\n",
match[1], match[2], match[3], match[4], match[5]);
}
rec_op = eq_str(match[2],"From ")? From_op :
( eq_str(match[2],"Until ")? Until_op :
( eq_str(match[2],"Skip ")? Skip_op :
( eq_str(match[2],"Cont ")? Cont_op : No_op )));
if( rec_op == No_op ){ <.try Addr and Set ops.> }
if( rec_op == No_op ){
(IGNORED) fprintf(stderr,"--- warning --- ");
(IGNORED) fprintf(stderr,"CopyTo: %s%s%s%s%s?\n",
match[1], match[2], match[3], match[4], match[5]);
} else {
<.find file records.>
<.find to-from record.>
<.find group record.>
<.enter op record.>
<.act on op.>
} } }
<.release CopyTo resources.>
}
-_-_-
<..try Addr and Set ops..>
ch = match[2];
if( (ch[0]==’S’) && (ch[1]==’e’) && (ch[2]==’t’) ){
ch += 3; rec_op = Set_op;
} else if( (ch[0]==’A’) && (ch[1]==’d’) && (ch[2]==’d’) && (ch[3]==’r’) ){
ch += 4; rec_op = Addr_op;
}
if( rec_op != No_op ){
addr = 0; while( (*ch>=’0’) && (*ch<=’9’) ){
addr = addr*10 + *ch - ’0’; ch++;
} }
-_-_-
<..release CopyTo resources..>
for( p = opened_files; p != (struct files_rec*) 0; ){
(IGNORED) fclose(p->file);
free((void *) p->name);
<.free to-from records.>
p1= p; p = p->right; free((void *) p1);
}
-_-_-
<..free to-from records..>
for( p1 = p->down; p1 != (struct files_rec*) 0; ){
<.free group records.>
p2 = p1; p1 = p1->right; free((void *) p2);
}
-_-_-
<..free group records..>
for( p2 = p1->down; p2 != (struct files_rec*) 0; ){
<.free op records.>
p3 = p2; p2 = p2->right; free((void *) p3);
}
-_-_-
<..free op records..>
for( p3 = p2->down; p3 != (struct files_rec*) 0; ){
p4 = p3; p3 = p3->down; free((void *) p4);
}
-_-_-
<..act on op..>
if( rec_op == Until_op ){
for( p = to_rec->down;
p != (struct files_rec*) 0; p = p->down ){
if( p->op == From_op ){ from_op = p; break; }
}
if( p == (struct files_rec*) 0 ){
<.missing From for CopyTo.>
} else {
<.perform ops.>
<.remove ops.>
}
}
-_-_-
<..perform ops..>
in_file = from_rec->file;
out_file = to_rec->file;
start_loc = from_op->loc;
write_on = TRUE;
(IGNORED) fseek(in_file, (long) start_loc, <.abs file addr.>);
for( p= from_op; p != to_rec; p = p->up ){
switch( p->op ){
case Until_op:{ <.Until op.> break; }
case Skip_op:{ <.Skip op.> break; }
case Cont_op:{ <.Cont op.> break; }
case Set_op:{ <.Set op.> break; }
default: { }
} }
-_-_-
<..Until op..>
if( write_on ){
end_loc = p->loc;
for(; start_loc<end_loc; start_loc++) {
(IGNORED) putc( getc(in_file), out_file );
} }
-_-_-
<..Skip op..>
if( write_on ){
end_loc = p->loc;
for(; start_loc<end_loc; start_loc++) {
(IGNORED) putc( getc(in_file), out_file );
}
}
write_on = FALSE;
-_-_-
<..Cont op..>
end_loc = p->loc;
if( write_on ){
for(; start_loc<end_loc; start_loc++) {
(IGNORED) putc( getc(in_file), out_file );
}
} else {
start_loc = end_loc;
(IGNORED) fseek(in_file, (long) end_loc, <.abs file addr.>);
}
write_on = TRUE;
-_-_-
<..Set op..>
addr = -1;
for( p1 = from_op->up; p1 != to_rec; p1 = p1->up ){
if( (p1->op == Addr_op) && (p1->label == p->label) ){
addr = p1->loc; break;
} }
if( addr != -1 ){ (p->up)->loc = addr; }
-_-_-
<..remove ops..>
to_rec->down = from_op->down;
if( from_op->down != (struct files_rec*) 0){
(from_op->down)->up = to_rec;
}
for( p = from_op; p != to_rec; ){
p1 = p; p = p->up; free((void *) p1);
}
if( to_rec->down == (struct files_rec*) 0){
if( to_rec->left == (struct files_rec*) 0 ){
(to_rec->up)->down = to_rec->right;
} else {
(to_rec->left)->right = to_rec->right;
}
if( to_rec->right != (struct files_rec*) 0 ){
(to_rec->right)->left = to_rec->left;
}
p1 = to_rec; to_rec = to_rec->up; free((void *) p1);
}
-_-_-
<..missing From for CopyTo..>
(IGNORED) fprintf(stderr,"%sMissing ‘CopyTo From’:\n", "--- warning --- ");
for( p = to_rec->down; p != (struct files_rec*) 0; p = p->down ){
(IGNORED) fprintf(stderr," %s %s%d %s\n", to_rec->name,
p->op == From_op ? "From " :
( p->op == Until_op ? "Until " :
( p->op == Skip_op ? "Skip " :
( p->op == Cont_op? "Cont " :
( p->op == Addr_op? "Addr " :
( p->op == Set_op? "Set " : "No_op " ))))),
p->loc, from_rec->name
);
}
-_-_-
<..enter op record..>
p = m_alloc(struct files_rec, 1);
p->down = to_rec->down; to_rec->down = p;
p->up = to_rec;
if( p->down != (struct files_rec*) 0 ){
(p->down)->up = p;
}
*(match[4] + (int) strlen((char *) match[4]) - 1) = ’\0’;
p->loc = (int) get_long_int(match[4]);
p->op = rec_op;
p->label = addr;
-_-_-
<..find group record..>
if( to_rec->down == (struct files_rec*) 0 ){
<.add first group record.>
} else {
to_rec = to_rec->down;
for( p = to_rec->right; p != (struct files_rec*) 0; p = p->right ){
if( eq_str(to_rec->group,match[3]) ){ break; }
to_rec = p;
}
if( !eq_str(to_rec->group,match[3]) ){
<.add next group record.>
} }
-_-_-
<..add first group record..>
to_rec->down = p = m_alloc(struct files_rec, 1);
p->up = to_rec;
p->right = p->left = p->down = (struct files_rec*) 0;
p->name = to_rec->name;
p->file = to_rec->file;
p->from_rec = from_rec;
p->loc = -1;
p->op = No_op;
p->group = m_alloc(char, (int) strlen((char *) match[3]) + 1);
(IGNORED) strcpy((char *) p->group, (char *) match[3] );
to_rec = p;
-_-_-
<..add next group record..>
to_rec->right = p = m_alloc(struct files_rec, 1);
p->left = to_rec;
p->right = p->down = (struct files_rec*) 0;
p->up = to_rec->up;
p->name = to_rec->name;
p->file = to_rec->file;
p->from_rec = from_rec;
p->loc = -1;
p->group = m_alloc(char, (int) strlen((char *) match[3]) + 1);
(IGNORED) strcpy((char *) p->group, (char *) match[3] );
to_rec = p;
-_-_-
<..find to-from record..>
if( to_rec->down == (struct files_rec*) 0 ){
<.add first to-from record.>
} else {
to_rec = to_rec->down;
for( p = to_rec->right; p != (struct files_rec*) 0; p = p->right ){
if( to_rec->from_rec == from_rec ){ break; }
to_rec = p;
}
if( to_rec->from_rec != from_rec ){
<.add next to-from record.>
} }
-_-_-
<..add first to-from record..>
to_rec->down = p = m_alloc(struct files_rec, 1);
p->up = to_rec;
p->right = p->left = p->down = (struct files_rec*) 0;
p->name = to_rec->name;
p->file = to_rec->file;
p->from_rec = from_rec;
p->loc = -1;
p->op = No_op;
to_rec = p;
-_-_-
<..add next to-from record..>
to_rec->right = p = m_alloc(struct files_rec, 1);
p->left = to_rec;
p->right = p->down = (struct files_rec*) 0;
p->up = to_rec->up;
p->name = to_rec->name;
p->file = to_rec->file;
p->from_rec = from_rec;
p->loc = -1;
to_rec = p;
-_-_-
<..find file records..>
file_name = match[1];
*(file_name + (int) strlen((char *) file_name) - 1) = ’\0’;
strcpy((char *) file_mode, WRITE_TEXT_FLAGS);
for(i=1; i<=2; i++){
<.search CopyTo file.>
file_name = match[5];
strcpy((char *) file_mode, <.CopyTo read flags.>);
}
-_-_-
<..search CopyTo file..>
for( p = opened_files; p != (struct files_rec*) 0; p = p->right ){
if( eq_str(file_name,p->name) ) { break; }
}
if( p == (struct files_rec*) 0 ){
p = m_alloc(struct files_rec, 1);
p->right = opened_files; opened_files = p;
p->down = (struct files_rec*) 0;
strcpy((char *) p->file_mode, (char *) file_mode);
p->name = m_alloc(char, (int) strlen((char *) file_name) + 1);
(IGNORED) strcpy((char *) p->name, (char *) file_name );
if( (p->file = fopen(file_name, file_mode)) == NULL )
{ (IGNORED) warn_i_str(5,file_name); }
}
to_rec = from_rec; from_rec = p;
-_-_-
<..defines..>+
struct files_rec{
FILE* file;
char *name, *group, op;
Q_CHAR file_mode[5];
int loc, label;
struct files_rec *from_rec, *right, *left, *down, *up;
};
#define No_op 0
#define From_op 1
#define Until_op 2
#define Skip_op 3
#define Cont_op 4
#define Addr_op 5
#define Set_op 6
-_-_-
<..CopyTo vars..>
Q_CHAR *file_name, file_mode[5];
int i, start_loc, end_loc, addr = 0;
char rec_op, *ch;
static struct files_rec *to_rec, *from_rec,
*opened_files = (struct files_rec *) 0,
*p, *p1, *p2, *p3, *p4, *from_op;
FILE *in_file, *out_file;
BOOL write_on;
-_-_-