/* * common.c - stuff used by all programs */ static char *rcsid_common_c = "$Id: common.c,v 2.0 1992/09/13 05:02:44 rosenkra Exp $"; /* * $Log: common.c,v $ * Revision 2.0 1992/09/13 05:02:44 rosenkra * total rewrite. this if first rev of this file. * * */ #include #include #include #include "whatis.h" extern int debugging; /*------------------------------*/ /* parse_record */ /*------------------------------*/ /* * macros to make parsing easier */ #define EOS '\0' #define NL '\n' #define FIELDSEP '%' #define ITEMSEP ',' #define END_OF_STRING(c) (c==EOS || c==NL) #define END_OF_FIELD(c) (c==FIELDSEP) #define END_OF_ITEM(c) (c==ITEMSEP) #define ADVANCE_FIELD \ while(!END_OF_STRING(*ps) && !END_OF_FIELD(*ps)){ps++;} \ if(END_OF_STRING(*ps)){*ps=EOS;return(lastone?0:1);} \ *ps++ = EOS; #define ADVANCE_ITEM \ while(!END_OF_STRING(*ps) && !END_OF_ITEM(*ps) && !END_OF_FIELD(*ps)){ps++;} \ if(END_OF_STRING(*ps)){*ps=EOS;return(lastone?0:1);} \ if(END_OF_FIELD(*ps)){*ps++ = EOS;break;} \ *ps++ = EOS; int parse_record (char *raw, struct rec *r) { /* * parse record. caller provides raw record and space for parsed * structure. ret 0 if all ok, else 1 (incomplete record, etc). * raw input is a null terminated string (with/without newline). */ char *ps = raw; int i; int lastone = 0; /* * set up default (empty) */ r->name = NULL; r->alias[0] = NULL; r->alias[1] = NULL; r->section = NULL; r->subsect = NULL; r->desc = NULL; r->xref[0] = NULL; r->xref[1] = NULL; r->keyw[0] = NULL; r->keyw[1] = NULL; /* * read name (required!) */ r->name = ps; ADVANCE_FIELD; /* * read any aliases (optional) */ if (ps[0] == '_' && (END_OF_FIELD(ps[1]) || END_OF_STRING(ps[1]))) { r->alias[0] = NULL; ADVANCE_FIELD; } else { for (i = 0; i < MAX_ALIAS-1; i++) { if (*ps == EOS) { r->alias[i] = NULL; return (1); } r->alias[i] = ps; r->alias[i+1] = NULL; ADVANCE_ITEM; } } /* * read section (required!) */ r->section = ps; ADVANCE_FIELD; /* * read subsection (optional) */ r->subsect = ps; ADVANCE_FIELD; if (r->subsect[0] == '_') r->subsect = NULL; /* * read description (required) */ r->desc = ps; ADVANCE_FIELD; /* * read any xrefs (optional) */ if (ps[0] == '_' && (END_OF_FIELD(ps[1]) || END_OF_STRING(ps[1]))) { r->xref[0] = NULL; ADVANCE_FIELD; } else { for (i = 0; i < MAX_XREF-1; i++) { if (*ps == EOS) { r->xref[i] = NULL; return (1); } r->xref[i] = ps; r->xref[i+1] = NULL; ADVANCE_ITEM; } } /* * read any keywords (optional) */ lastone = 1; if (ps[0] == '_' && (END_OF_FIELD(ps[1]) || END_OF_STRING(ps[1]))) { r->keyw[0] = NULL; return (1); } else { for (i = 0; i < MAX_KEYW-1; i++) { if (*ps == EOS) { r->keyw[i] = NULL; return (0); } r->keyw[i] = ps; r->keyw[i+1] = NULL; ADVANCE_ITEM; } } return (0); } /*------------------------------*/ /* print_record */ /*------------------------------*/ void print_record (int verbose, struct rec *r) { /* * print record. one line, just: * * name(sect[subsect]) - description. * * if verbose, add aliases, see also, and keywords, if any */ int i; if (r->name) printf ("%s", r->name); if (r->section) { printf ("(%s", r->section); if (r->subsect) printf ("%s", r->subsect); printf (") -"); } else printf (" -"); if (r->desc) printf (" %s\n", r->desc); else printf (" unknown (no description in database)\n"); if (!verbose) return; if (r->alias[0] != NULL) { printf ("\tprimary manpage:\n"); for (i = 0; r->alias[i] != NULL; i++) printf ("\t\t%s\n", r->alias[i]); } if (r->xref[0] != NULL) { printf ("\tsee also:\n"); for (i = 0; r->xref[i] != NULL; i++) printf ("\t\t%s\n", r->xref[i]); } if (r->keyw[0] != NULL) { printf ("\tkeywords:\n"); for (i = 0; r->keyw[i] != NULL; i++) printf ("\t\t%s\n", r->keyw[i]); } printf ("\n"); return; } #ifdef CHECK_MAGIC /*------------------------------*/ /* check_magic */ /*------------------------------*/ int check_magic (void) { /* * check magic "number" of file. if ok, return 0. else 1. * should be first line of file. check only MAGIC_CHECK_LEN bytes. */ char buf[REC_SIZE]; fgets (buf, REC_SIZE-1, stdin); if (feof (stdin)) return (1); if (debugging) fprintf (stderr, "magic: %s", buf); if (!strncmp (buf, MAGIC, MAGIC_CHECK_LEN)) return (0); return (1); } #endif /*CHECK_MAGIC*/