/* $Id: cextspec.c,v 1.17 1997/01/26 14:30:17 cim Exp $ */ /* Copyright (C) 1994, 1998 Sverre Hvammen Johansen, * Department of Informatics, University of Oslo. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Inn og utlesing av externe spesifikasjoner */ /* TBD: Innlesing av identifikatorer mm må gjøres mer robust. */ #include "const.h" #include "dekl.h" #include "filelist.h" #include "newstr.h" #include "cimcomp.h" #include "extspec.h" #include "name.h" #if STDC_HEADERS || HAVE_STRING_H #include #else /* not STDC_HEADERS and not HAVE_STRING_H */ #include #endif /* not STDC_HEADERS and not HAVE_STRING_H */ #ifdef TIME_WITH_SYS_TIME #include #include #else #ifdef HAVE_SYS_TIME_H #include #else #include #endif #endif #ifdef STDC_HEADERS #include #else double strtod (); #endif #include char *xmalloc(); void free(); #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free static struct obstack osExtspec; /* HUSK AT REKKEF\LGEN SKAL V[RE categ,type,kind * * Filen starter alltid med * * Deklarasjon av en klasse: * * <'!' | '&'> * * * * Deklarasjon og spesifisering av prosedyre: * * <(if (type==TREF)<'!'qualnavn>) | * (if (categ==CCPROC)'^') | '&'> * * * * Spesifisering av vanlige parametere og deklarasjon av variable: * * <(if (type==TREF)) * else if(type==TLABEL)) else tom> * <(if (categ==CCONST)) | tom> * * Spesifisering av et array: * * <(if (type==TREF)) | tom> * * * Spesifisering av EXTERNAL klasse eller prosedyre * * <&> * * * Alle filer slutter med en ekstra */ #define ENDOF_CLASS_PROC_FILE '\n' #define START_NEW_EXTERNAL_SPEC '&' #define PREFIKS_MARKER '!' #define CPROC_MARKER '^' #define NO_MARKER '$' #define inchar(f) getc(f) #define getval(f, i) { int tmp;fscanf(f,"%d",&tmp);i=tmp;} #define getconst(f, i) { fscanf(f,"%d",&i);} /****************************************************************************** INITEXTSPEC */ void initExtspec () { obstack_init (&osExtspec); } /****************************************************************************** GETNAME */ static char * getname (f) FILE *f; { int c; char *s, *sx; for (c= getc (f); c !=EOF && c != '\n' && c!= ' '; c= getc (f)) obstack_1grow (&osExtspec, c); obstack_1grow (&osExtspec, 0); s= obstack_finish (&osExtspec); sx= tag (s); obstack_free (&osExtspec, s); return sx; } /* fscanf leter frem til neste \n eller blank (eller til slutten) men lar * \n eller blank bli igjen. * Hvis \n er forste tegn n}r fscanf kalles s} kastes dette tegnet.Men * getc kalles etter fscanf s} vil denne returnere med \n.Derfor m} dette * tegnet leses av etter at hvert navn er lest inn * For å overføre filnavn id til deklarasjonslageret */ char *timestamp=""; /* Det globale tidsmerket */ char *directive_timestamp=""; struct stamp *first_stamp; static char timestampchars[63] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '_'}; /****************************************************************************** GETTIMESTAMP */ void gettimestamp () { #if GET_TIME_OF_DAY static struct timeval tp; static struct timezone tzp; #endif FILE *f; int t, th; if (strcmp (directive_timestamp, "")) timestamp= directive_timestamp; else if (option_reuse_timestamp && (f = searc_and_open_name_in_archlist (extcodename, TRUE)) != NULL) { if (option_verbose) fprintf (stderr, "Reading atr-file %s\n", extcodename); /* Leser identifikasjon , som alltid ligger f|rst p} filen */ { char r_buff[12]; r_buff[0] = '\0'; fscanf (f, "%11s\n", r_buff); if (strcmp (r_buff, "/*Cim_atr*/")) merror (5, extcodename); } timestamp= getname (f); fclose (f); } else { #if GET_TIME_OF_DAY gettimeofday (&tp, &tzp); t = tp.tv_sec; th = tp.tv_usec; #else t = time (NULL); th = 0; #endif th /= 252; obstack_1grow (&osExtspec, timestampchars[th - th / 63 * 63]); th /= 63; obstack_1grow (&osExtspec, timestampchars[th - th / 63 * 63]); while (t != 0) { obstack_1grow (&osExtspec, timestampchars[t - t / 63 * 63]); t /= 63; } obstack_1grow (&osExtspec, 0); timestamp= obstack_finish (&osExtspec); } } /****************************************************************************** GENATRFILENAMEFROMID */ static char * genatrfilenamefromid (ident) char *ident; { int i; char *s, *sx; obstack_grow (&osExtspec, ident, strlen (ident)); obstack_grow0 (&osExtspec, ".atr", 4); s= obstack_finish (&osExtspec); for (i = strlen (s) - 5; i >= 0; i--) if (s[i] >= 'A' && s[i] <= 'Z') s[i] += 32; /* LOWERCASE */ sx= tag (s); obstack_free (&osExtspec, s); return sx; } /****************************************************************************** GENATRFILENAMEFROMFILENAME */ static char * genatrfilenamefromfilename (filename) char *filename; { char *s, *sx; int len = strlen (filename); if (len >=4 && !strcmp (&filename[len - 4], ".atr")) return (tag (filename)); if (len >=4 && !(strcmp (&filename[len - 4], ".sim") && strcmp (&filename[len - 4], ".SIM") && strcmp (&filename[len - 4], ".cim") && strcmp (&filename[len - 4], ".CIM"))) obstack_grow (&osExtspec, filename, len - 4); else obstack_grow (&osExtspec, filename, len); obstack_grow0 (&osExtspec, ".atr", 4); s= obstack_finish (&osExtspec); sx= tag (s); obstack_free (&osExtspec, s); return sx; } /****************************************************************************** EXTERNAL_IS_IN */ static char external_is_in (ident, kind) char *ident; char kind; { struct DECL *rd; struct BLOCK *rb; rb = cblock; for (rd = rb->parloc; rd != NULL; rd = rd->next) if (rd->ident == ident && rd->kind == kind) return (TRUE); return (FALSE); } /****************************************************************************** NEXTDECL */ static char *lesinn (); static nextdecl (f, filename, timestamp) FILE *f; char *filename, *timestamp; { char type, kind, categ; char tegn; char *ident; char codeclass=0; char *rtname=NULL; categ = getc (f); if (categ == (char) EOF) merror (5, filename); if (categ == ENDOF_CLASS_PROC_FILE) return (FALSE); else if (categ == START_NEW_EXTERNAL_SPEC) { char *localTimestamp; char *localFilename; type = getc (f); kind = getc (f); ident = getname (f); /* Leser navnet */ localTimestamp= getname (f); /* tidsmerket */ localFilename= getname (f); /* filnavnet */ if (!external_is_in (ident, kind)) { if (localTimestamp != lesinn (localFilename)) merror (4, filename); } return (TRUE); } type = getc (f); kind = getc (f); ident = getname (f); switch (kind) { case KPROC: case KCLASS: tegn = getc (f); if (tegn == PREFIKS_MARKER) { prefquantident = getname (f); tegn = getc (f); if (tegn == CPROC_MARKER) { rtname = getname (f); if (categ != CCPROC) codeclass = getc (f) - '0'; else codeclass = CCCPROC; } else ungetc (tegn, f); } else { prefquantident = 0; if (tegn == CPROC_MARKER) { rtname = getname (f); if (categ != CCPROC) codeclass = getc (f) - '0'; else codeclass = CCCPROC; } } regDecl (ident, type, kind, categ); beginBlock (kind); cblock->timestamp= timestamp; cblock->filename= filename; if (kind == KCLASS) { getval (f, cblock->fornest); getval (f, cblock->connest); } getval (f, cblock->ptypno); if (getc (f) == '%') cblock->blno = cblock->ptypno; getval (f, cblock->ent); /* Les inn parametere, virtuelle, hidden, protected og deklarasjoner */ while (nextdecl (f, filename, timestamp)); endBlock (rtname, codeclass); break; default: if (type == TREF) { prefquantident = getname (f); } switch (categ) { case CCONST: regDecl (ident, type, kind, categ); if (type == TTEXT) { int i; getval (f, i); getc (f); cblock->lastparloc->value.tval.txt= getname (f); } else if (type == TREAL) { char *s; s= getname (f); cblock->lastparloc->value.rval= strtod (s, NULL); } else { getconst (f, cblock->lastparloc->value.ival); getc (f); } break; default: regDecl (ident, type, kind, categ); if (type == TLABEL) getconst (f, cprevdecl->plev); break; } if (kind == KARRAY) getval (f, cblock->lastparloc->dim); } return (TRUE); } /****************************************************************************** LESINN */ static char *lesinn (filename) char *filename; { struct stamp *st; char *timestamp; FILE *f; f = searc_and_open_name_in_archlist (filename, TRUE); if (f == NULL) return (NULL); if (option_verbose) fprintf (stderr, "Reading atr-file %s\n", filename); /* Leser identifikasjon , som alltid ligger f|rst p} filen */ { char r_buff[12]; r_buff[0] = '\0'; fscanf (f, "%11s\n", r_buff); if (strcmp (r_buff, "/*Cim_atr*/")) merror (5, filename); } /* Leser tidsmerke */ timestamp= getname (f); for (st = first_stamp; st != NULL; st = st->next) if (st->timestamp == timestamp) goto found; st = (struct stamp *) obstack_alloc (&osExtspec, sizeof (struct stamp)); st->timestamp = timestamp; st->next = first_stamp; st->lest_inn = FALSE; st->filename = filename; first_stamp = st; found: if (st->filename != filename) merror (11, filename); st->lest_inn = TRUE; /* Leser inn liste med tidsmerker */ while (getc (f) == ' ') { char *localTimestamp= getname (f); char *localFilename= getname (f); for (st = first_stamp; st != NULL; st = st->next) if (st->timestamp == localTimestamp) goto find_next; st = (struct stamp *) obstack_alloc (&osExtspec, sizeof (struct stamp)); st->timestamp = localTimestamp; st->next = first_stamp; st->lest_inn = FALSE; st->filename = localFilename; first_stamp = st; find_next:; if (st->filename != localFilename) merror (11, localFilename); } while (nextdecl (f, filename, timestamp)); fclose (f); return (timestamp); } /****************************************************************************** LESINN_EXTERNAL_SPEC */ lesinn_external_spec (ident, filename, kind) char *ident; char *filename; char kind; { char *hprefquantident; struct BLOCK *hcblock; struct DECL *hclastdecl, *rd; hprefquantident = prefquantident; hcblock = cblock; hclastdecl = cblock->lastparloc; if (filename == NULL) filename = genatrfilenamefromid (ident); else filename = genatrfilenamefromfilename (filename); if (!external_is_in (ident, kind)) { if (lesinn (filename) == NULL) { merror (3, filename); return; } } /* Denne modulen skal ha categ=CEXTRMAIN */ if (hclastdecl == NULL) rd = hcblock->parloc; else rd = hclastdecl; for (; rd != NULL && rd->ident != ident; rd = rd->next); if (rd != NULL) rd->categ = CEXTRMAIN; prefquantident = hprefquantident; } static char link; /****************************************************************************** WRITE_INDENTATION */ write_indentation (f, level) FILE *f; int level; { int i; fprintf (f, "\n"); for (i=1; i<=level; i++) fprintf (f, " "); } /****************************************************************************** WRITE_CHAR_MIF */ static write_char_mif (f, c) FILE *f; unsigned char c; { if ((isprint (c) #if ISO_LATIN || c >= 160 #endif ) && c != '!' && c != '"') fprintf (f, "= '%c'", c); else fprintf (f, "= '!%d!'", c); } /****************************************************************************** WRITE_TEXT_MIF */ static write_text_mif (f, s) FILE *f; unsigned char *s; { int i; fprintf (f, "= \""); for (i = 0; s[i]; i++) if (s[i] == '\\') { char j = 0; j = j * 8 + s[++i] - '0'; j = j * 8 + s[++i] - '0'; j = j * 8 + s[++i] - '0'; if (j == ' ') putc (' ', f); else fprintf (f, "!%d!", j); } else putc (s[i], f); putc ('"', f); } /****************************************************************************** WRITE_DECL_MIF */ static write_decl_mif (f, rd, level) FILE *f; struct DECL *rd; int level; { if (rd->kind == KBLOKK || rd->kind == KPRBLK || rd->kind == KFOR || rd->kind == KINSP) return; if (level == 0) { int i; fprintf (f, "\n\n%% **************************************" "************************************* %%\n%% "); for (i= 75-strlen(rd->ident); i>0; i--)fprintf (f, " "); fprintf (f, "%s %%", rd->ident); } write_indentation (f, level); switch(rd->categ) { case CVALUE: fprintf (f, "value: "); break; case CNAME: fprintf (f, "name: "); break; case CVAR: fprintf (f, "var: "); break; case CEXTR: break; case CEXTRMAIN: break; case CEXTROUT: break; case CHIDEN: fprintf (f, "hidden "); break; case CPROT: fprintf (f, "protected "); break; case CHIPRO: fprintf (f, "hidden proteced "); break; case CCPROC: fprintf (f, "external C procedure %s is " ,rd->descr->rtname); break; } switch(rd->type) { case TINTG: fprintf (f, "integer "); break; case TREAL: fprintf (f, "real "); break; break; case TBOOL: fprintf (f, "boolean "); break; case TCHAR: fprintf (f, "character "); break; case TLABEL: if (rd->kind == KARRAY) fprintf (f, "switch "); else if (rd->categ != CLOCAL) fprintf (f, "label "); break; case TTEXT: fprintf (f, "text "); break; case TREF: fprintf (f, "ref (%s) ", rd->prefqual->ident); break; case TERROR: break; case TVARARGS: break; } switch(rd->kind) { case KARRAY: if (rd->type != TLABEL) fprintf (f, "array "); break; case KPROC: fprintf (f, "procedure "); break; case KCLASS: if (rd->prefqual != NULL && rd->prefqual != commonprefiks) /* Prefiks klassens navn eller kvalifikasjon */ fprintf (f, "%s ", rd->prefqual->ident); fprintf (f, "class "); break; } fprintf (f, "%s", rd->ident); if (rd->categ == CEXTR || rd->categ == CEXTRMAIN) { fprintf (f, "= \"%s %s\"", rd->descr->timestamp, rd->descr->filename); } else if (rd->kind == KPROC || rd->kind == KCLASS) { struct DECL *rdv; struct BLOCK *rb; struct DECL *rdx; rb = rd->descr; if (rd->categ == CEXTROUT) rd->categ = CEXTR; /* evt. parametere */ fprintf (f, " ("); for (rdx = rb->parloc; rdx != NULL && (rdx->categ == CDEFLT || rdx->categ == CNAME || rdx->categ == CVAR || rdx->categ == CVALUE) ; rdx = rdx->next) write_decl_mif (f, rdx, level+1); fprintf (f, ")"); switch (rd->categ) { case CDEFLT: case CNAME: case CVAR: case CVALUE: case CVIRT: break; default: fprintf (f, ";"); } #if 0 /* Fornest,Connest,blno,ent */ if (rb->quant.kind == KCLASS) fprintf (f, "\n%% f_c_b_e %d %d %d %d", rb->fornest, rb->connest, rb->blno, rb->ent); #endif if (rb->quant.kind == KCLASS) { int i; write_indentation (f, level); fprintf (f, "virtual:"); /* evt. virtuelle spesifiksajoner , men bare de som er spesifisert */ /* i denne klassen. Ikke de akkumulerte. De akkumuleres opp av */ /* sjekkdekl senere */ i = (rb->quant.plev > 0) ? rb->quant.prefqual->descr->navirt + rb->quant.prefqual->descr->navirtlab : 0; for (rdv = rb->virt; i-- > 0; rdv = rdv->next); for (; rdv != NULL; rdv = rdv->next) write_decl_mif (f, rdv, level+1); /* evt. spesifikasjoner av hidden og protected. */ for (rdv = rb->hiprot; rdv != NULL; rdv = rdv->next) write_decl_mif (f, rdv, level+1); write_indentation (f, level); fprintf (f, "begin"); /* Lokale deklarasjoner NB Forutsetter at rdx peker p} forste * deklarasjon */ for (; rdx != NULL; rdx = rdx->next) write_decl_mif (f, rdx, level+1); write_indentation (f, level); fprintf (f, "end"); } } else { #if 0 if (rd->type == TLABEL) fprintf (f, "\n%% ENT %d", rd->plev); #endif if (rd->categ == CCONST) if (rd->type == TTEXT) write_text_mif (f, rd->value.tval.txt); else if (rd->type == TREAL) { char s[100]; int i; sprintf (s, "= %.16le", rd->value.rval); for (i=0; s[i]; i++) if (s[i]=='e') { s[i]='&'; break; } fprintf (f, s); } else if (rd->type == TCHAR) write_char_mif (f, rd->value.ival); else fprintf (f, "= %d", rd->value.ival); if (rd->kind == KARRAY && rd->type != TLABEL) { int i; fprintf (f, "( "); for (i=2; i<= rd->dim; i++) fprintf (f, ", "); fprintf (f, ")"); } } switch (rd->categ) { case CDEFLT: case CNAME: case CVAR: case CVALUE: if (rd->next!=NULL && (rd->next->categ == CDEFLT || rd->next->categ == CNAME || rd->next->categ == CVAR || rd->next->categ == CVALUE)) fprintf(f, ", "); break; case CLOCAL: if (rd->type == TLABEL && rd->kind == KSIMPLE) { fprintf (f, ":"); break; } default: fprintf (f, ";"); } } /****************************************************************************** WRITE_ALL_MIF */ write_all_mif () { /* Trenger ikke skrive ut lokale deklarasjoner i procedyrer */ struct DECL *rd; struct stamp *st; FILE *f; char hcateg; if ((f = fopen (mifcodename, "w")) == NULL) merror (9, mifcodename); /* Skriver f|rst ut identifikasjon til find */ fprintf (f, "%% Cim_mif"); #if 0 /* Skriver ut tidsmerke */ fprintf (f, "\n%%timestamp %s", timestamp); /* Skriver ut tidsmerke til alle moduler */ for (st = first_stamp; st != NULL; st = st->next) fprintf (f, "\n%% timestamp_other_module %s %s" ,st->timestamp, st->filename); #endif for (rd = sblock->parloc; rd != NULL; rd = rd->next) if (rd->categ == CEXTR) /* OK */ ; else if (rd->categ == CEXTRMAIN) { rd->categ = CEXTR; write_decl_mif (f, rd, 0); } else { hcateg = rd->categ; if (rd->categ != CCPROC) rd->categ = CEXTROUT; if (rd->kind == KCLASS || rd->kind == KPROC) write_decl_mif (f, rd, 0); rd->categ = hcateg; } fprintf (f, "\n\n%%eof\n"); fclose (f); } /****************************************************************************** WRITE_DECL_EXT */ static write_decl_ext (f, rd) FILE *f; struct DECL *rd; { if (rd->kind == KBLOKK || rd->kind == KPRBLK || rd->kind == KFOR || rd->kind == KINSP) ; else if (rd->categ == CEXTR || rd->categ == CEXTRMAIN) fprintf (f, "&%c%c%s %s %s\n", rd->type, rd->kind ,rd->ident, rd->descr->timestamp, rd->descr->filename); else if (rd->kind == KPROC || rd->kind == KCLASS) { struct DECL *rdv; struct BLOCK *rb; rb = rd->descr; if (rd->categ == CEXTROUT) rd->categ = CEXTR; /* Skriver ut */ fprintf (f, "%c%c%c%s ", rd->categ, rd->type, rd->kind, rd->ident); if (rd->prefqual != NULL && rd->prefqual != commonprefiks) /* Prefiks klassens navn eller kvalifikasjon */ fprintf (f, "%c%s ", PREFIKS_MARKER, rd->prefqual->ident); else if (rd->categ == CCPROC) /* C-navnet */ fprintf (f, "%c%s ", CPROC_MARKER ,rd->descr->rtname); else fprintf (f, "%c", NO_MARKER); /* Fornest,Connest,blno,ent */ if (rb->quant.kind == KCLASS) fprintf (f, "%d %d ", rb->fornest, rb->connest); fprintf (f, "%d %d", rb->blno, rb->ent); /* evt. parametere */ for (rd = rb->parloc; rd != NULL && (rd->categ == CDEFLT || rd->categ == CNAME || rd->categ == CVAR || rd->categ == CVALUE) ; rd = rd->next) write_decl_ext (f, rd); if (rb->quant.kind == KCLASS) { int i; /* evt. virtuelle spesifiksajoner , men bare de som er spesifisert */ /* i denne klassen. Ikke de akkumulerte. De akkumuleres opp av */ /* sjekkdekl senere */ i = (rb->quant.plev > 0) ? rb->quant.prefqual->descr->navirt + rb->quant.prefqual->descr->navirtlab : 0; for (rdv = rb->virt; i-- > 0; rdv = rdv->next); for (; rdv != NULL; rdv = rdv->next) write_decl_ext (f, rdv); /* evt. spesifikasjoner av hidden og protected. */ for (rdv = rb->hiprot; rdv != NULL; rdv = rdv->next) write_decl_ext (f, rdv); /* Lokale deklarasjoner. NB Forutsetter at rd peker p} forste * deklarasjon */ for (; rd != NULL; rd = rd->next) write_decl_ext (f, rd); } fprintf (f, "%c", ENDOF_CLASS_PROC_FILE); } else { fprintf (f, "%c%c%c%s ", rd->categ, rd->type, rd->kind, rd->ident); if (rd->type == TREF) fprintf (f, "%s ", rd->prefqual->ident); else if (rd->type == TLABEL) fprintf (f, "%d", rd->plev); if (rd->categ == CCONST) if (rd->type == TTEXT) fprintf (f, "%d %s " ,strlen (rd->value.tval.txt) ,rd->value.tval.txt); else if (rd->type == TREAL) fprintf (f, "%.16e ", rd->value.rval); else fprintf (f, "%d ", rd->value.ival); if (rd->kind == KARRAY) fprintf (f, "%c", (rd->dim + ((short) '0'))); } } /****************************************************************************** WRITE_ALL_EXT */ write_all_ext () { /* Trenger ikke skrive ut lokale deklarasjoner i procedyrer */ struct DECL *rd; struct stamp *st; FILE *f; char hcateg; #if OPEN_FILE_IN_BINARY_MODE if ((f = fopen (extcodename, "wb")) == NULL) #else if ((f = fopen (extcodename, "w")) == NULL) #endif merror (9, extcodename); /* Skriver f|rst ut identifikasjon til find */ fprintf (f, "/*Cim_atr*/\n"); /* Skriver ut tidsmerke */ fprintf (f, "%s\n", timestamp); /* Skriver ut tidsmerke til alle moduler */ for (st = first_stamp; st != NULL; st = st->next) fprintf (f, " %s %s\n" ,st->timestamp, st->filename); fprintf (f, "\n"); for (rd = sblock->parloc; rd != NULL; rd = rd->next) if (rd->categ == CEXTR) /* OK */ ; else if (rd->categ == CEXTRMAIN) { rd->categ = CEXTR; write_decl_ext (f, rd); } else { hcateg = rd->categ; if (rd->categ != CCPROC) rd->categ = CEXTROUT; if (rd->kind == KCLASS || rd->kind == KPROC) write_decl_ext (f, rd); rd->categ = hcateg; } fprintf (f, "%c", ENDOF_CLASS_PROC_FILE); fclose (f); if (option_write_mif) write_all_mif(); } /****************************************************************************** MORE_MODULES */ more_modules () { FILE *f; struct stamp *st; char *localTimestamp; for (st = first_stamp; st != NULL; st = st->next) if (st->lest_inn == FALSE && (f = fopen (st->filename, #if OPEN_FILE_IN_BINARY_MODE "rb" #else "r" #endif )) != NULL) { char *newlink_moduler; char r_buff[12]; /* Leser identifikasjon , som alltid ligger f|rst p} filen */ r_buff[0] = '\0'; fscanf (f, "%11s\n", r_buff); if (strcmp (r_buff, "/*Cim_atr*/")) merror (5, st->filename); /* Leser tidsmerke */ localTimestamp= getname (f); if (localTimestamp == st->timestamp) { if (option_verbose) fprintf (stderr, "Reading atr-file %s\n", st->filename); insert_name_in_linklist (transform_name (st->filename, ".atr", ".o"), TRUE); } } }