This is parseobjc.c in view mode; [Download] [Up]
/* docgen Objective C Document Generator Copyright (C) 1995 Bill Bereza. 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; either version 2 of the License, or (at your option) any later version. 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. Email: berezaw@river.it.gvsu.edu S-mail: Bill Bereza 9526 Judson Rd. Ravenna, MI 49451-9427 */ /* docgen Objective C Document Generator * Copyright (c) 1994 Bill Bereza * * $Log: parseobjc.c,v $ * Revision 1.23 96/01/07 01:30:15 berezaw * additions for 0.3.2 * * Revision 1.22 95/07/26 22:28:40 berezaw * *** empty log message *** * * Revision 1.21 95/07/26 21:46:22 berezaw * * * Revision 1.20 95/07/26 19:51:03 berezaw * *** empty log message *** * * Revision 1.19 95/07/26 17:50:25 berezaw * *** empty log message *** * * Revision 1.18 95/07/26 16:17:31 berezaw * 0.3.1 * * Revision 1.17 95/07/21 22:56:33 berezaw * *** empty log message *** * * Revision 1.16 95/07/21 21:40:15 berezaw * *** empty log message *** * * Revision 1.15 95/07/16 19:19:05 berezaw * * bug fix found by pburka * * Revision ???? 95/04/26 14:16:15 pburka * added check to see if the interface declares * an empty block of ivars ('{ }'). Previously, * this resulted in an unexpected eof; now it just * gives a friendly message, just as if the braces * hadn't been there at all * * Revision 1.14 95/03/02 03:44:46 berezaw * using GNU regex library * rewrote recmp() as docgen_recmp() * added GPL stuff to each file * increase rev. to 0.1.9 * * Revision 1.13 95/02/02 18:32:13 berezaw * 0.1.7, fixed problems with skipping lines * in odd classes * * Revision 1.12 95/02/02 17:57:20 berezaw * fixed class description printing * * Revision 1.11 95/02/02 15:21:58 berezaw * 0.1.6 * * Revision 1.10 95/02/01 16:41:28 berezaw * fixed protocol parsing * * Revision 1.9 95/01/31 18:28:40 berezaw * * added 0.1.5 stuff * * Revision 1.8 95/01/30 14:11:19 berezaw * fixed fancy text * * Revision 1.7 95/01/29 01:51:26 berezaw * reused code from parsemethods to create general * comment printing function to handle italicizing * variable names, and to eventually handle fancy * text * * Revision 1.6 95/01/28 23:21:53 berezaw * nicer copyright check. * * Revision 1.5 95/01/26 15:27:29 berezaw * added rtfproth for protocols * * Revision 1.4 95/01/26 05:35:10 berezaw * handles copyrights better * * Revision 1.3 94/11/28 12:08:34 berezaw * *** empty log message *** * * * @(#)1.2 * $Id: parseobjc.c,v 1.23 96/01/07 01:30:15 berezaw Exp $ */ #include "parsers.h" #define CLOSEALL \ if(fflush(RTFf) == EOF) if(V_BADERR) perror("Something wouldn't flush : Try using a plunger");\ if(fclose(Hf) == EOF) if(V_BADERR) perror("I couldn't close the header file. Pray.");\ if(fclose(Mf) == EOF) if(V_BADERR) perror("I couldn't close the .m file. Pray.");\ if(fclose(RTFf) == EOF) if(V_BADERR) perror("I couldn't close the RTF file. Pray.");\ if(fFQh) free(fFQh);\ freedstr(GLOB_istring) int parseobjc(char *FQm, char *FQh, char *FQrtf, char *hdir) { FILE *Hf, *Mf, *RTFf; char errmess[1024]; char *hline, *mline, *stringptr; ofiletype fty; char *hpath, *honepath, *fFQh=NULL, *fhname; fpos_t currPos; char pathsep[]=":"; DSTRING *dhname; #ifndef NODEBUG if(V_USELESS) printf("parseobjc(%s, %s, %s, %s)\n", FQm, FQh, FQrtf, hdir); #endif /* Open all files, return on error */ Hf=fopen(FQh,"r"); if(!Hf) { dhname=dstrarr(hdir); hpath=arrdstr(dhname); freedstr(dhname); if(!hpath) { sprintf(errmess, "%.1023s", FQh); if(V_STAT) perror(errmess); return -1; } strcpy(hpath, hdir); fhname=strrchr(FQh,'/'); if(!fhname) fhname=FQh; else fhname++; honepath=strtok(hpath, pathsep); if(GLOB_recurs) { while(honepath && !fFQh) { fFQh=findfile(fhname, honepath); honepath=strtok(NULL, pathsep); } if(fFQh) { Hf=fopen(fFQh, "r"); } } else while(honepath && !Hf) { fFQh=dirfile(honepath, fhname); if(fFQh) { Hf=fopen(fFQh, "r"); if(!Hf) { free(fFQh); fFQh=NULL; } } honepath=strtok(NULL, pathsep); } free(hpath); if(fFQh) FQh=fFQh; } if(Hf == NULL) { sprintf(errmess, "%.1023s", FQh); if(V_STAT) perror(errmess); return -1; } if((Mf=fopen(FQm, "r")) == NULL) { sprintf(errmess, "%.1023s", FQm); perror(errmess); if(fclose(Hf) == EOF) if(V_BADERR) perror("I couldn't close the header file. Pray."); return -1; } if((RTFf=fopen(FQrtf, "w")) == NULL) { sprintf(errmess, "%.1023s", FQrtf); perror(errmess); if(fclose(Hf) == EOF) if(V_BADERR) perror("I couldn't close the header file. Pray."); if(fclose(Mf) == EOF) if(V_BADERR) perror("I couldn't close the .m file. Pray."); return -1; } #ifndef NODEBUG if(V_STAT) fprintf(stderr,"All files opened : Begin parsing\n.m\t:%s\n.h\t:%s\n.rtf\t:%s\n", FQm, FQh, FQrtf); #endif [myForm setOfile:RTFf]; GLOB_istring=initdstr(); dstrarrcat(GLOB_istring, DEFITAL); #ifdef OBJC [myForm putHead]; #else fputhead(RTFf); #endif mline=fgetdline(Mf); /* go to @implementation line in the .m */ while(docgen_recmp(IMPLEM, mline) && !feof(Mf)) { free(mline); mline=fgetdline(Mf); /* if the first non-blank line in .m matches the copyright * pattern, then get it */ if(!docgen_recmp(CPEXP, mline) || !docgen_recmp(CPEXPII, mline)) { #ifdef OBJC [myForm putCPHead]; #else fputcphead(RTFf); #endif if(docgen_recmp(CPEXPII, mline)) { free(mline); mline=fgetdline(Mf); #ifdef OBJC [myForm putLine:mline]; #else fputline(RTFf, mline); #endif } else { #ifdef OBJC [myForm putLine:strstr(mline, "Copy")]; #else fputline(RTFf, strstr(mline, "Copy")); #endif } while(docgen_recmp(WHITEXP, mline) && !feof(Mf)) { free(mline); mline=fgetdline(Mf); if(!docgen_recmp("^ *\\*", mline)) { #ifdef OBJC [myForm putLine:strstr(mline, "*")+1]; #else fputline(RTFf, strstr(mline,"*")+1); #endif } else { #ifdef OBJC [myForm putLine:mline]; #else fputline(RTFf, mline); #endif } } } } /* while(docgen_recmp */ /* read to the @interface line in the .h file */ hline=fgetdline(Hf); while(!feof(Hf) && docgen_recmp(INTERFACE, hline)) { free(hline); hline=fgetdline(Hf); } if(feof(Hf)) { /* since all these eof error blocks are so * similar I was thinking of having another * function, but I don't like closing * files outside of the function they were * opened in. And a goto or macro wouldn't * handle all the different cases */ free(hline); free(mline); if(V_ERR) fprintf(stderr,"Unexpected end of file in %s\n", FQh); CLOSEALL; return -1; } #ifdef OBJC [myForm putStart]; #else fputstart(RTFf); #endif /* check for wether we're dealing with a Class or * Category */ if(strstr(hline, CLASSCHK) != NULL) fty=class; else if(strstr(hline, CATCHK) != NULL) fty=category; else { fty=none; #ifndef NODEBUG if(V_STAT) fprintf(stderr,"%s is neither a Class or a Category\n",FQh); #endif } /* If strtok fails on this first pass * then exit with an error. */ if(fty!=none) { if((stringptr=strtok(hline, INTTOK)) == NULL) { free(hline); free(mline); if(V_ERR) fprintf(stderr, "Improper @interface description in\n%s\n", FQh); CLOSEALL; return -1; } else stringptr=strtok(NULL, INTTOK); /* Output the Inherits From: , Category Of: messages */ if(fty==class) { #ifdef OBJC [myForm putLine:stringptr]; #else fputline(RTFf, stringptr); #endif stringptr=strtok(NULL, INTTOK); #ifdef OBJC [myForm putInheritHeader]; #else fputinherith(RTFf); #endif if(stringptr != NULL) { char *pro, *as; pro=strtok(NULL, "<"); fprintf(RTFf, "%s", stringptr); traceinheritance(RTFf, hdir, stringptr); #ifdef OBJC [myForm putLine:" "]; #else fputline(RTFf," "); #endif if(pro) { as=strchr(pro, '>'); if(as) *as='\0'; #ifdef OBJC [myForm putConformHeader:pro]; #else fputconformh(RTFf, pro); #endif } } else #ifdef OBJC [myForm putLine:"No Inheritance"]; #else fputline(RTFf, "No Inheritance"); #endif if(!GLOB_decdir) { char *z=strstr(FQm, "./"); if(!z) z=FQm; else z+=2; #ifdef OBJC [myForm putInheritTail:z]; #else fputinheritt(RTFf, z); #endif } else { char buff[strlen(GLOB_decdir) + strlen(FQm) + 2]; sprintf (buff, "%s/%s", GLOB_decdir, strrchr(FQm, '/') + 1); #ifdef OBJC [myForm putInheritTail:buff]; #else fputinheritt(RTFf, buff); #endif } } else { char *as, *cof; cof=stringptr; stringptr=strtok(NULL, INTTOK); if(stringptr!=NULL) { as=strchr(stringptr,')'); *as='\0'; } #ifdef OBJC [myForm putLine:stringptr]; [myForm putCategoryHeader]; #else fputline(RTFf, stringptr); fputcath(RTFf); #endif if(stringptr != NULL) { char *pro; pro=strtok(NULL, "< "); fprintf(RTFf,"%s", cof); traceinheritance(RTFf, hdir, cof); #ifdef OBJC [myForm putLine:" "]; #else fputline(RTFf, " "); #endif if(pro) { as=strchr(pro, '>'); if(as) *as='\0'; #ifdef OBJC [myForm putConformHeader:pro]; #else fputconformh(RTFf, pro); #endif } } else #ifdef OBJC [myForm putLine:"No Category"]; #else fputline(RTFf, "No Category"); #endif if(!GLOB_decdir) { char *z=strstr(FQm, "./"); if(!z) z=FQm; else z+=2; #ifdef OBJC [myForm putCategoryTail:z]; #else fputcatt(RTFf, z); #endif } else { char buff[strlen(GLOB_decdir) + strlen(FQm) + 2]; sprintf (buff, "%s/%s", GLOB_decdir, strrchr(FQm, '/') + 1); #ifdef OBJC [myForm putCategoryTail:buff]; #else fputcatt(RTFf, buff); #endif } } } if(feof(Mf)) { free(hline); free(mline); if(V_ERR) fprintf(stderr,"Unexpected end of file in %s\n", FQm); CLOSEALL; return -1; } free(mline); /* go to the next non-blank line in the .m */ fgetpos(Mf, &currPos); mline=fgetdline(Mf); while(!docgen_recmp(WHITEXP, mline) && !feof(Mf)) { fgetpos(Mf, &currPos); free(mline); mline=fgetdline(Mf); } /* print out the description text, if any */ if(!docgen_recmp(STARTEXP, mline)) { if(GLOB_firstcomm) parsecomments(RTFf, mline+2, NULL); if(docgen_recmp(STOPEXP, mline)) { free(mline); fgetpos(Mf, &currPos); mline=fgetdline(Mf); while(docgen_recmp(STOPEXP, mline) && !feof(Mf)) { parsecomments(RTFf, mline, NULL); free(mline); fgetpos(Mf, &currPos); mline=fgetdline(Mf); } } } if(feof(Mf)) { free(hline); free(mline); if(V_ERR) fprintf(stderr,"Unexpected end of file in %s\n", FQm); CLOSEALL; return -1; } /* If this is a class, print out I-Var info */ if(fty==class) { free(hline); hline=fgetdline(Hf); while(docgen_recmp(IVARBEG, hline) && !feof(Hf) && docgen_recmp(METHEXP, hline)) { free(hline); hline=fgetdline(Hf); } if(!feof(Hf)) { if(docgen_recmp(IVARBEG, hline) || !docgen_recmp(IVARNONE, hline)) { if(V_ERR) fprintf(stderr,"%s is a Class file with no i-vars!\n", FQh); } else if(parseivars(RTFf, Hf, FQh)<0) { free(hline); free(mline); if(V_ERR) fprintf(stderr,"Problem while parsing i-vars\n"); CLOSEALL; return -1; } #ifdef OBJC [myForm putMethodType]; #else fputmethodtype(RTFf); #endif parsemethodtype(Hf, RTFf, hline); } else { if(V_ERR) fprintf(stderr,"No methods or i-vars in %s\n", FQh); } } /* done with class file */ /* Methods */ parsemethods(Mf, RTFf, mline, currPos); /* Flush and close all files */ #ifdef OBJC [myForm putLine:" "]; [myForm putEof]; #else fputline(RTFf, " "); fputeof(RTFf); #endif CLOSEALL; #ifndef NODEBUG if(V_STAT) printf("parseobjc: returning success\n"); #endif return 0; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.