Date:2011-05-18 06:15:03 (12 years 4 months ago)
Author:Neil Stockbridge
Commit:4b5bd45caa1ddd157e54197578b0b4f6a17d05bb
Message:The source files are now under revision control

Files: Makefile (1 diff)
src/Makefile (1 diff)
src/main.c (1 diff)

Change Details

Makefile
1
2#.SILENT:
3
4all:
5    $(MAKE) -C src/
6
7clean:
8    $(MAKE) -C src/ clean
9
src/Makefile
1
2PROJECT = man
3#DEBUG = -g
4
5CC = gcc
6
7ifndef CFLAGS
8CFLAGS = -Os -Wall $(DEBUG) -DDEBUG
9endif
10
11ifndef STRIP
12STRIP=strip
13endif
14
15PARTS = main.o
16
17.c.o:
18    $(RM) $@
19# $(CC) -MM $(CFLAGS) $*.c
20    $(CC) -c $(CFLAGS) $*.c
21
22.SILENT:
23
24# Targets...
25
26all: $(PROJECT)
27
28$(PROJECT): $(PARTS)
29    $(CC) $(LDFLAGS) $(LIBS) $(DEBUG) -o $(PROJECT) $(PARTS)
30    $(STRIP) $(PROJECT)
31
32clean:
33    rm -f *.o $(PROJECT)
34
src/main.c
1
2#include <stdio.h> // for fprintf
3#include <stdlib.h> // for getenv
4#include <unistd.h> // for access
5
6
7typedef int bool;
8#define FALSE 0
9#define TRUE 1
10
11#define LENGTH_OF(a) ( sizeof(a) / sizeof(a[0]) )
12
13
14#define ANY_SECTION 0
15
16
17// This is for different forms that man page file names can take such as:
18// + time.2
19// + time.2.gz
20//
21typedef struct
22{
23  char *name_template;
24  char *emitter;
25}
26Form;
27
28
29int main( int argc, char **argv)
30{
31  // Parse the command-line
32  if ( argc < 2 || 3 < argc)
33  {
34    fprintf( stderr, "Use: %s [section] page\n", argv[0]);
35    return 1;
36  }
37
38  int section;
39  char *page;
40
41  if ( 2 == argc)
42  {
43    page = argv[ 1];
44    section = ANY_SECTION;
45  }
46  else {
47    section = atoi( argv[1]);
48    page = argv[ 2];
49  }
50
51  // Parse the MANPATH
52  char *man_path_s = getenv("MANPATH");
53  if ( ! man_path_s)
54    man_path_s = "/usr/share/man";
55  #define MAX_MAN_PATH_ITEMS 32
56  char *man_path_item[ MAX_MAN_PATH_ITEMS];
57  int man_path_items = 0;
58  // Split the colon separated MANPATH in to discrete strings
59  char *cursor = man_path_s;
60  bool fresh_item = TRUE;
61  while( *cursor != '\0')
62  {
63    if ( fresh_item)
64    {
65      if ( man_path_items < MAX_MAN_PATH_ITEMS)
66        man_path_item[ man_path_items++] = cursor;
67      fresh_item = FALSE;
68    }
69    if ( ':' == *cursor)
70    {
71      *cursor = '\0';
72      fresh_item = TRUE;
73    }
74    cursor += 1;
75  }
76
77  // Go through every item on MANPATH
78  int mpi;
79  for ( mpi = 0; mpi < man_path_items; ++ mpi)
80  {
81    char *man_dir = man_path_item[ mpi];
82
83    // Go through sections 1..9 or just the specified section
84    int min_s = ANY_SECTION == section ? 1 : section;
85    int max_s = ANY_SECTION == section ? 9 : section;
86    int s;
87    for ( s = min_s; s <= max_s; ++ s)
88    {
89      // If the named man page exists in this (MANPATH item, section) then
90      // display it
91      char path_to_file[ 256];
92      Form form[] = {
93        {"%s/man%i/%s.%i", emitter:"cat"},
94        {"%s/man%i/%s.%i.gz", emitter:"zcat"},
95      };
96      char cmd[ 512] = {'\0'};
97      int i;
98      for ( i = 0; i < LENGTH_OF(form); ++ i)
99      {
100        Form f = form[ i];
101
102        snprintf( path_to_file, sizeof(path_to_file), f.name_template, man_dir, s, page, s);
103        if ( ! access( path_to_file, R_OK))
104        {
105          snprintf( cmd, sizeof(cmd), "%s %s | mandoc | less", f.emitter, path_to_file);
106          break;
107        }
108      }
109
110      if ( cmd[0] != '\0')
111      {
112        system( cmd);
113        return 0;
114      }
115    }
116  }
117
118  fprintf( stderr, "No manual entry for %s\n", page);
119  return 1;
120}
121

Archive Download the corresponding diff file

Branches:
master



interactive