📄 input.c
字号:
/*Copyright (c) 1990 Massachusetts Institute of Technology, Cambridge, MA.All rights reserved.This Agreement gives you, the LICENSEE, certain rights and obligations.By using the software, you indicate that you have read, understood, andwill comply with the terms.Permission to use, copy and modify for internal, noncommercial purposesis hereby granted. Any distribution of this program or any part thereofis strictly prohibited without prior written consent of M.I.T.Title to copyright to this software and to any associated documentationshall at all times remain with M.I.T. and LICENSEE agrees to preservesame. LICENSEE agrees not to make any copies except for LICENSEE'Sinternal noncommercial use, or to use separately any portion of thissoftware without prior written consent of M.I.T. LICENSEE agrees toplace the appropriate copyright notice on any such copies.Nothing in this Agreement shall be construed as conferring rights to usein advertising, publicity or otherwise any trademark or the name of"Massachusetts Institute of Technology" or "M.I.T."M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. Byway of example, but not limitation, M.I.T. MAKES NO REPRESENTATIONS ORWARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE ORTHAT THE USE OF THE LICENSED SOFTWARE COMPONENTS OR DOCUMENTATION WILLNOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.M.I.T. shall not be held liable for any liability nor for any direct,indirect or consequential damages with respect to any claim by LICENSEEor any third party on account of or arising from this Agreement or useof this software.*/#include "mulGlobal.h"#include "zbufGlobal.h"#if SINGLE_FILE_INPUT == ON/* * Modified 2/22/01 Steve Whiteley, stevew@wrcad.com, Whiteley Research Inc. * * This allows all input to go into a single list file. The format is as * follows: * (regular list file) * End * File <the_first_file> * (contents of <the_first_file>) * End * File <the_second_file> * (contents of <the_second_file>) * End * ... * * The characters following 'E' in "End" and following 'F' in "File" are * optional. Like the other keys, 'E' and 'F' are case-insensitive, and * must be in the first text column. The files are those referenced in * the list file, and can be appended in any order. The "End" after a * neutral file is optional. *//* struct to keep a list of file offsets to point to data */struct f_offset{ char *filename; unsigned long offset; struct f_offset *next;};static struct f_offset *list_file_offsets;/* name of list file, contains all input */static char *list_file_name;/* Function to generate a list of offsets into the list file to the data * "files". This is called if an 'E' line appears in the list file. */voidsetup_file_offsets(FILE *fp){ char buf[1024]; while (fgets(buf, 1024, fp) != NULL) { if (buf[0] == 'F' || buf[0] == 'f') { char *s = buf+1, *t; while (*s && !isspace(*s)) s++; while (isspace(*s)) s++; t = s; while (*t && !isspace(*t)) t++; if (t > s) { struct f_offset *f = (struct f_offset*) malloc(sizeof(struct f_offset)); if (!f) { fprintf(stderr, "Out of memory.\n"); exit(1); } f->filename = (char*)malloc(t - s + 1); if (!f->filename) { fprintf(stderr, "Out of memory.\n"); exit(1); } strncpy(f->filename, s, t-s); f->filename[t-s] = 0; f->offset = ftell(fp); f->next = list_file_offsets; list_file_offsets = f; } } }}/* This fopen() replaces the standard fopen() when opening subsidiary * input files. If the name is found in the offset list, the list file * is opened, with the file pointer set to point at that "file". */FILE *fc_fopen(char *filename, char *mode){ if (list_file_name) { struct f_offset *f; for (f = list_file_offsets; f; f = f->next) { if (!strcmp(filename, f->filename)) { FILE *fp = fopen(list_file_name, mode); if (!fp) break; fseek(fp, f->offset, 0); return (fp); } } } return (fopen(filename, mode));}#endif/* reads an input file list file (a list of dielectric i/f and conductor surface files with permittivities) returns linked list of file pointers and permittivities in surface structs surface list file is specified on the command line with `-l<filename>' each line in the list file specifies a surface filename and its permittivites if a list file line has the filename string `stdin' then stdin will be read (note that more than one `stdin' is not allowed) list file line formats conductor surface: C <filename> <outer rel permittivity> <tx> <ty> <tz> [+] dielectric surface: D <file> <outer rel perm> <inner rel perm> <tx> <ty> <tz> <rx> <ry> <rz> [-] thin conductor on dielectric boundary (B => "both"): B <file> <outer rel perm> <inner rel perm> <tx> <ty> <tz> <rx> <ry> <rz> [+-] group name specification line: G <group name> comment line: * <comment line> the <tx> <ty> <tz> are 3 components of a translation vector that is applied to all the panels in the file the <rx> <ry> <rz> specify a reference point on the outside of the interface surface (all surface normals should point towards the point) the optional `-' indicates that the reference point is inside the surface (all surface normals should point away from the point) the reference point is used to figure which permittivity is on which side for type B surfaces, there must be no space between the `+' and `-' if both are used - note that D surfaces must never have a `+' since the reference point must be on one side, each file must contain a convex surface (ie any surface must be broken into such subsurfaces) the optional `+' indicates that the panels in the next conductor line file should be grouped together for the purposes of renumbering - if two files have two distinct conductors but both sets of panels are numbered `1' inside the two files then use something like C first_file 1.5 <tx> <ty> <tz> C second_file 1.5 <tx> <ty> <tz> - on the other hand, if parts of the same conductor are split into two files (say because the second part borders a different dielectric) then use something like C first_file 1.5 <tx> <ty> <tz> + C second_file 2.0 <tx> <ty> <tz> in this case it is up to the user to make sure first_file's panels and second_file's panels all have the same conductor number - to disable the renumbering entirely, use the `+' on all the conductor lines: C first_file 3.0 <tx> <ty> <tz> + C second_file 4.0 <tx> <ty> <tz> + C last_file 3.0 <tx> <ty> <tz> + - files grouped together with the + option have their conductor names appended with the string ` (GROUP<number>)' - for example, the conductor name `BIT_LINE' shows up as `BIT_LINE (GROUP3)' if it is in the third group - a string other than `GROUP<number>' may be specified for the group name using G line `G <group name>' just before the group to be renamed; this is helpful when idenifying conductors to omit from capacitance calculations using the -k option*/void read_list_file(surf_list, num_surf, list_file, read_from_stdin)int *num_surf, read_from_stdin;char *list_file;surface **surf_list;{ int linecnt, end_of_chain, ref_pnt_is_inside, group_cnt; FILE *fp, *fopen(); char tline[BUFSIZ], file_name[BUFSIZ], plus[BUFSIZ], group_name[BUFSIZ]; double outer_perm, inner_perm, tx, ty, tz, rx, ry, rz; surface *cur_surf; /* find the end of the current surface list */ if(*surf_list != NULL) { for(cur_surf = *surf_list; cur_surf->next != NULL; cur_surf = cur_surf->next); } /* attempt to open file list file */#if SINGLE_FILE_INPUT == ON if((fp = fc_fopen(list_file, "r")) == NULL) {#else if((fp = fopen(list_file, "r")) == NULL) {#endif fprintf(stderr, "read_list_file: can't open list file\n `%s'\nto read\n", list_file); exit(1); } /* read file names and permittivities, build linked list */ linecnt = 0; group_cnt = read_from_stdin + 1; sprintf(group_name, "GROUP%d", group_cnt); while(fgets(tline, sizeof(tline), fp) != NULL) { linecnt++; if(tline[0] == 'C' || tline[0] == 'c') { if(sscanf(&(tline[1]), "%s %lf %lf %lf %lf", file_name, &outer_perm, &tx, &ty, &tz) != 5) { fprintf(stderr, "read_list_file: bad conductor surface format, tline %d:\n%s\n", linecnt, tline); exit(1); } /* check if end of chain of surfaces with same conductor numbers */ end_of_chain = TRUE; if(sscanf(&(tline[1]), "%s %lf %lf %lf %lf %s", file_name, &outer_perm, &tx, &ty, &tz, plus) == 6) { if(!strcmp(plus, "+")) end_of_chain = FALSE; } /* allocate and load surface struct */ if(*surf_list == NULL) { CALLOC(*surf_list, 1, surface, ON, AMSC); cur_surf = *surf_list; } else { CALLOC(cur_surf->next, 1, surface, ON, AMSC); cur_surf->next->prev = cur_surf; cur_surf = cur_surf->next; } cur_surf->type = CONDTR; cur_surf->trans[0] = tx; cur_surf->trans[1] = ty; cur_surf->trans[2] = tz; cur_surf->end_of_chain = end_of_chain; CALLOC(cur_surf->name, strlen(file_name)+1, char, ON, AMSC); strcpy(cur_surf->name, file_name); cur_surf->outer_perm = outer_perm; /* set up group name */ CALLOC(cur_surf->group_name, strlen(group_name)+1, char, ON, AMSC); strcpy(cur_surf->group_name, group_name); /* update group name if end of chain */ if(end_of_chain) { sprintf(group_name, "GROUP%d", ++group_cnt); } (*num_surf)++; } else if(tline[0] == 'B' || tline[0] == 'b') { if(sscanf(&(tline[1]), "%s %lf %lf %lf %lf %lf %lf %lf %lf", file_name, &outer_perm, &inner_perm, &tx, &ty, &tz, &rx, &ry, &rz) != 9) { fprintf(stderr, "read_list_file: bad thin conductor on dielectric interface surface format, line %d:\n%s\n", linecnt, tline); exit(1); } /* check if end of chain of surfaces with same conductor numbers */ end_of_chain = TRUE; ref_pnt_is_inside = FALSE; if(sscanf(&(tline[1]), "%s %lf %lf %lf %lf %lf %lf %lf %lf %s", file_name, &outer_perm, &inner_perm, &tx, &ty, &tz, &rx, &ry, &rz, plus) == 10) { if(!strcmp(plus, "+")) end_of_chain = FALSE; if(!strcmp(plus, "+-") || !strcmp(plus, "-+")) { end_of_chain = FALSE; ref_pnt_is_inside = TRUE; } if(!strcmp(plus, "-")) ref_pnt_is_inside = TRUE; } /* allocate and load surface struct */ if(*surf_list == NULL) { CALLOC(*surf_list, 1, surface, ON, AMSC); cur_surf = *surf_list; } else { CALLOC(cur_surf->next, 1, surface, ON, AMSC); cur_surf->next->prev = cur_surf; cur_surf = cur_surf->next; } cur_surf->type = BOTH; cur_surf->trans[0] = tx; cur_surf->trans[1] = ty; cur_surf->trans[2] = tz; cur_surf->ref[0] = rx; cur_surf->ref[1] = ry; cur_surf->ref[2] = rz; cur_surf->ref_inside = ref_pnt_is_inside; cur_surf->end_of_chain = end_of_chain; CALLOC(cur_surf->name, strlen(file_name)+1, char, ON, AMSC); strcpy(cur_surf->name, file_name); cur_surf->outer_perm = outer_perm; cur_surf->inner_perm = inner_perm; /* set up group name */ CALLOC(cur_surf->group_name, strlen(group_name)+1, char, ON, AMSC); strcpy(cur_surf->group_name, group_name); /* update group name if end of chain */ if(end_of_chain) { sprintf(group_name, "GROUP%d", ++group_cnt); } (*num_surf)++; } else if(tline[0] == 'D' || tline[0] == 'd') { if(sscanf(&(tline[1]), "%s %lf %lf %lf %lf %lf %lf %lf %lf", file_name, &outer_perm, &inner_perm, &tx, &ty, &tz, &rx, &ry, &rz) != 9) { fprintf(stderr, "read_list_file: bad dielectric interface surface format, line %d:\n%s\n", linecnt, tline); exit(1); } /* check to see if reference point is negative side of surface */ ref_pnt_is_inside = FALSE; if(sscanf(&(tline[1]), "%s %lf %lf %lf %lf %lf %lf %lf %lf %s", file_name, &outer_perm, &inner_perm, &tx, &ty, &tz, &rx, &ry, &rz, plus) == 10) { if(!strcmp(plus, "-")) ref_pnt_is_inside = TRUE; } /* allocate and load surface struct */ if(*surf_list == NULL) { CALLOC(*surf_list, 1, surface, ON, AMSC); cur_surf = *surf_list; } else { CALLOC(cur_surf->next, 1, surface, ON, AMSC); cur_surf->next->prev = cur_surf; cur_surf = cur_surf->next; } cur_surf->type = DIELEC; cur_surf->trans[0] = tx; cur_surf->trans[1] = ty; cur_surf->trans[2] = tz; cur_surf->ref[0] = rx; cur_surf->ref[1] = ry; cur_surf->ref[2] = rz; cur_surf->ref_inside = ref_pnt_is_inside; cur_surf->end_of_chain = TRUE; CALLOC(cur_surf->name, strlen(file_name)+1, char, ON, AMSC); strcpy(cur_surf->name, file_name); cur_surf->outer_perm = outer_perm; cur_surf->inner_perm = inner_perm; /* set up group name */ CALLOC(cur_surf->group_name, strlen(group_name)+1, char, ON, AMSC); strcpy(cur_surf->group_name, group_name); /* update group name (DIELEC surface is always end of chain) */ sprintf(group_name, "GROUP%d", ++group_cnt); (*num_surf)++; } else if(tline[0] == 'G' || tline[0] == 'g') { if(sscanf(&(tline[1]), "%s", group_name) != 1) { fprintf(stderr,"read_list_file: bad group name format, line %d:\n%s\n", linecnt, tline); exit(1); } } else if(tline[0] == '%' || tline[0] == '*' || tline[0] == '#'); /* ignore comments */#if SINGLE_FILE_INPUT == ON else if (tline[0] == 'E' || tline[0] == 'e') { list_file_name = (char*)malloc(strlen(list_file) + 1); if (!list_file_name) { fprintf(stderr, "Out of memory.\n"); exit(1); } strcpy(list_file_name, list_file); setup_file_offsets(fp); break; }#endif else { /* SRW -- ignore lines with all white space */ if (isspace(tline[0])) { char *t = tline + 1; while (isspace(*t)) t++; if (!*t) continue; } fprintf(stderr, "read_list_file: bad line format, line %d:\n%s\n", linecnt, tline);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -