Subject: v07i096: Decomposing termcaps Newsgroups: mod.sources Approved: mirror!rs Submitted by: Arnold D. Robbins Mod.sources: Volume 7, Issue 96 Archive-name: determcap Here is a program I wrote while converting from 4.2 to 4.3. I have always wanted something like it. I hope that the rest of the net may find it useful. There is no makefile as it is only a single C source file. I did write a man page though. Arnold Robbins Emory University Computing Center [ I wrote a Makefile, and added the quick hack of a mkdir() subroutine for them that's need it. --r$ ] #! /bin/sh # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # If all goes well, you will see the message "End of shell archive." # Contents: Makefile determcap.8 determcap.c PATH=/bin:/usr/bin:/usr/ucb; export PATH echo shar: extracting "'Makefile'" '(263 characters)' if test -f 'Makefile' ; then echo shar: will not over-write existing file "'Makefile'" else sed 's/^X//' >Makefile <<'@//E*O*F Makefile//' X# If you don't have a mkdir(2) or a mkdir(3), enable this next line. X#DIR = -DNEED_MKDIR_SUB XCFLAGS = -O $(DIR) X Xdetermcap: determcap X $(CC) $(CFLAGS) -o determcap determcap.c X Xinstall: determcap X @echo Copy determcap and determcap.8 to appropriate directories @//E*O*F Makefile// if test 263 -ne "`wc -c <'Makefile'`"; then echo shar: error transmitting "'Makefile'" '(should have been 263 characters)' fi fi # end of overwriting check echo shar: extracting "'determcap.8'" '(1491 characters)' if test -f 'determcap.8' ; then echo shar: will not over-write existing file "'determcap.8'" else sed 's/^X//' >determcap.8 <<'@//E*O*F determcap.8//' X.TH DETERMCAP 8 local X.SH NAME Xdetermcap \- split a termcap database into directories and files X.SH SYNOPSIS X.B determcap X[ X.B verbose X] < termcap_file X.SH DESCRIPTION X.I Determcap Xis a very simple C program that reads a X.I termcap (5) Xdatabase on its standard input. XIn the directory where it is run X.I determcap Xwill produce a new directory for each terminal type entry in the termcap Xfile. XInside each such directory, there will be a file with the name of each Xcapability, and the termcap field for that capability will be in the file. XFor each comment block, there will be a file named X.BI comment. N Xwhere X.I N Xrepresents the fact that this was the X.IR N 'th Xcomment block in the input. XThese files should be removed. X.PP X.I Determcap Xfinds its use in comparing different termcap databases. XTwo databases can be decomposed in two different directories, and then X.IR diff (1) Xcan be used via the X.B \-r X(recursive) option to compare the two databases. X.PP XIf given an argument, X.I determcap Xwill print out what it is parsing as it goes. X.PP XYour termcap file must not have any problems in it. XAll continuation lines must end in a \e. XThere can be no duplicate terminal entries (i.e. entries with the same name). X.SH SEE ALSO X.IR termcap (5) X.SH DIAGNOSTICS XSelf explanatory. X.SH BUGS X.PP XQuits at the first sign of trouble. X.PP XShould not bother to save the comments. X.PP XCan be very disk-space intensive. X.PP XNot exactly blindingly fast. X.SH AUTHOR XArnold Robbins X.br Xarnold@emory.edu @//E*O*F determcap.8// if test 1491 -ne "`wc -c <'determcap.8'`"; then echo shar: error transmitting "'determcap.8'" '(should have been 1491 characters)' fi fi # end of overwriting check echo shar: extracting "'determcap.c'" '(3025 characters)' if test -f 'determcap.c' ; then echo shar: will not over-write existing file "'determcap.c'" else sed 's/^X//' >determcap.c <<'@//E*O*F determcap.c//' X#include X#include X Xchar tbuf[BUFSIZ * 16]; /* really big */ Xchar *input (); XFILE *fp; Xint verbose = 0; X Xmain (argc, argv) Xint argc; Xchar **argv; X{ X verbose = (argc > 1); X X while (input (tbuf) != NULL) X { X if (tbuf[0] == '#') X comment (); X else X entry (); X } X} X Xint usebuf = 0; X Xchar *input (bp) Xchar *bp; X{ X if (! usebuf) X return (gets (bp)); X else X { X usebuf = 0; X return (tbuf); X } X} X Xcomment () X{ X static int com_no = 1; X char name[20]; X X sprintf (name, "comment.%d", com_no++); X if ((fp = fopen (name, "w")) == NULL) X { X fflush (stdout); X fprintf (stderr, "%s: could not open\n", name); X exit (1); X } X X do X { X fprintf (fp, "%s\n", tbuf); X if (input (tbuf) == NULL) X { X fclose (fp); X exit (0); X } X } while (tbuf[0] == '#'); X X /* at this point, a non-comment is in the buffer */ X usebuf = 1; X fclose (fp); X} X Xchar *getname (); Xchar *getentry (); X Xentry () X{ X int end = strlen (tbuf) - 1; X char *name, *fullname, *cp, *state; X char *index (); X X /* first, get the entire entry */ X while (tbuf[end] == '\\') X { X if (input (& tbuf[end]) == NULL) X { X fflush (stdout); X fprintf (stderr, "stdin ended with a '\\\\'\n"); X exit (1); X } X end = strlen (tbuf) - 1; X } X /* now pull it apart */ X X state = tbuf; X fullname = getentry (& state); X name = getname (fullname); X X if (verbose) X printf ("%s\n", name); X X dodir (name); X X if ((fp = fopen (name, "w")) == NULL) X { X fflush (stdout); X fprintf (stderr, "%s: could not open\n", name); X exit (1); X } X fprintf (fp, "%s\n", fullname); X fclose (fp); X X while (cp = getentry (& state)) X doentry (cp); X X if (chdir ("..") < 0) X { X perror ("chdir(\"..\")"); X exit (1); X } X} X Xchar *getname (cp) Xregister char *cp; X{ X static char shortname[100]; X register int i = 0; X X while (*cp != '|') X cp++; X X for (cp++; *cp != '|' && *cp != ':'; cp++) X shortname[i++] = *cp; X shortname[i] = '\0'; X X return (shortname); X} X Xchar *getentry (state) Xregister char **state; X{ X char *cp; X X if (!state || ! *state || ! **state) X return (NULL); X X while (**state == '\t' || **state == ':') X (*state)++; X X cp = *state; X X while (**state && **state != ':') X (*state)++; X X **state = '\0'; X (*state)++; X X if (verbose) X printf ("\t'%s'\n", cp); X X return (cp); X} X Xdodir (dir) Xchar *dir; X{ X char buf[100]; X X if (mkdir (dir, 0755) < 0) X { X sprintf (buf, "mkdir (\"%s\")", dir); X perror (buf); X exit (1); X } X if (chdir (dir) < 0) X { X sprintf (buf, "chdir (\"%s\")", dir); X perror (buf); X exit (1); X } X} X Xdoentry (cp) Xchar *cp; X{ X char name[3]; X X name[0] = cp[0]; X name[1] = cp[1]; X name[2] = '\0'; X X if ((fp = fopen (name, "w")) == NULL) X { X fflush (stdout); X fprintf (stderr, "%s: could not open\n", name); X exit (1); X } X X fprintf (fp, "%s\n", cp); X fclose (fp); X} X X#ifdef NEED_MKDIR_SUB Xint Xmkdir(p, u) X char *p; X int u; X{ X char buff[BUFSIZ]; X X /* By playing with UMASK you can skip the chmod, but so it goes. */ X (void)sprintf(buff, "mkdir %s && chmod %o %s", p, u, p); X return(system(buff) ? -1 : 0); X} X#endif /* NEED_MKDIR_SUB */ @//E*O*F determcap.c// if test 3025 -ne "`wc -c <'determcap.c'`"; then echo shar: error transmitting "'determcap.c'" '(should have been 3025 characters)' fi fi # end of overwriting check echo shar: "End of shell archive." exit 0