bdba48079379b6c1c0f919c8809293d6fc45e840
[platform/upstream/bash.git] / newversion.c
1 /* Simple program to make new version numbers for the shell.
2    Big deal, but it was getting out of hand to do everything
3    in the makefile. */
4
5 /* Copyright (C) 1989 Free Software Foundation, Inc.
6
7 This file is part of GNU Bash, the Bourne Again SHell.
8
9 Bash is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 1, or (at your option) any later
12 version.
13
14 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License along
20 with Bash; see the file COPYING.  If not, write to the Free Software
21 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
22
23 #include <sys/types.h>
24 #include "posixstat.h"
25 #include <stdio.h>
26
27 char *progname;
28 char *dir;
29
30 FILE *must_open ();
31
32 main (argc, argv)
33      int argc;
34      char **argv;
35 {
36   FILE *file;
37   float distver = 0.0;
38   int buildver = 0, patchlevel = 0;
39   int dist = 0, build = 0, patch = 0;
40   int dist_inc = 0, build_inc = 0, patch_inc = 0;
41   int dot_dist_needs_making = 0;
42   int arg_index = 1;
43   struct stat sb;
44
45   progname = argv[0];
46
47   while (arg_index < argc && argv[arg_index][0] == '-')
48     {
49       if (strcmp (argv[arg_index], "-dist") == 0)
50         {
51           dist++;
52           dist_inc++;
53         }
54       else if (strcmp (argv[arg_index], "-build") == 0)
55         {
56           build++;
57           build_inc++;
58         }
59       else if (strcmp (argv[arg_index], "-patch") == 0)
60         {
61           patch++;
62           patch_inc++;
63         }
64       else if (strcmp (argv[arg_index], "-dir") == 0)
65         {
66           dir = argv[++arg_index];
67           if (dir == 0)
68             {
69               fprintf (stderr, "%s: `-dir' requires an argument\n", progname);
70               exit (1);
71             }
72           if (stat (dir, &sb) < 0)
73             {
74               fprintf (stderr, "%s: cannot stat %s\n", progname, dir);
75               exit (1);
76             }
77           if ((sb.st_mode & S_IFMT) != S_IFDIR)
78             {
79               fprintf (stderr, "%s: not a directory\n", progname);
80               exit (1);
81             }
82         }
83       else
84         {
85           fprintf (stderr, "%s: unknown option: %s\n", progname, argv[arg_index]);
86           fprintf (stderr, "usage: %s [-dist|-patch|-build] [-dir directory]\n", progname);
87           exit (1);
88         }
89       arg_index++;
90     }
91
92   if (get_float_from_file (".distribution", &distver) == 0)
93     dot_dist_needs_making++;
94
95   if (get_int_from_file (".patchlevel", &patchlevel) == 0)
96     {
97       patchlevel = 0;
98       patch_inc = 0;
99     }
100
101   if (get_int_from_file (".build", &buildver) == 0)
102     buildver = 0;
103
104   /* Setting distribution version. */
105   if (dist && arg_index < argc)
106     if (sscanf (argv[arg_index], "%f", &distver) != 1)
107       {
108         fprintf (stderr, "%s: Bad input `%s'.  Expected float value for -dist.\n",
109                  progname, argv[arg_index]);
110         exit (1);
111       }
112     else
113       {
114         arg_index++;
115         dist_inc = 0;
116       }
117
118   /* Setting patchlevel via argument. */
119   if (patch && arg_index < argc)
120     if (sscanf (argv[arg_index], "%d", &patchlevel) != 1)
121       {
122         fprintf (stderr, "%s: Bad input `%s'.  Expected int value for -patch.\n",
123                  progname, argv[arg_index]);
124         exit (1);
125       }
126     else
127       {
128         arg_index++;
129         patch_inc = 0;
130       }
131     
132   if (build && arg_index < argc)
133     if (sscanf (argv[arg_index], "%d", &buildver) != 1)
134       {
135         fprintf (stderr, "%s: Bad input `%s'.  Expected int value for -build.\n",
136                  progname, argv[arg_index]);
137         exit (1);
138       }
139     else
140       {
141         arg_index++;
142         build_inc = 0;
143       }
144
145   if (dot_dist_needs_making && !distver)
146     {
147       fprintf (stderr, "%s: There is no `.distribution' file to infer from.\n", progname);
148       exit (1);
149     }
150
151   if (dist_inc)
152     distver = distver + 0.01;
153
154   if (patch_inc)
155     patchlevel++;
156
157   if (build_inc)
158     buildver++;
159
160   file = must_open ("newversion.h", "w");
161
162   /* Output the leading comment. */
163   fprintf (file, 
164 "/* Version control for the shell.  This file gets changed when you say\n\
165    `make newversion' to the Makefile.  It is created by newversion.aux. */\n");
166
167   fprintf (file, "\n/* The distribution version number of this shell. */\n");
168   fprintf (file, "#define DISTVERSION \"%.2f\"\n", distver);
169
170   fprintf (file, "\n/* The patch level of this version of the shell. */\n");
171   fprintf (file, "#define PATCHLEVEL %d\n", patchlevel);
172
173   fprintf (file, "\n/* The last built version of this shell. */\n");
174   fprintf (file, "#define BUILDVERSION %d\n", buildver);
175
176   fprintf (file, "\n/* A version string for use by sccs and the what command. */\n\n");
177   fprintf (file, "#define SCCSVERSION \"@(#)Bash version %.2f.%d(%d) GNU\"\n\n",
178     distver, patchlevel, buildver);
179
180   fclose (file);
181
182   file = must_open (".build", "w");
183   fprintf (file, "%d\n", buildver);
184   fclose (file);
185
186   /* Making a new distribution. */
187   if (dist)
188     {
189       file = must_open (".distribution", "w");
190       fprintf (file, "%.2f\n", distver);
191       fclose (file);
192     }
193
194   /* Releasing a new patch level. */
195   if (patch)
196     {
197       file = must_open (".patchlevel", "w");
198       fprintf (file, "%d\n", patchlevel);
199       fclose (file);
200     }
201
202   exit (0);
203 }
204
205 char *
206 makename (fn)
207      char *fn;
208 {
209   char *ret;
210   int dlen = 0;
211
212   if (dir)
213     dlen = strlen (dir) + 1;
214   ret = (char *)malloc (dlen + strlen (fn) + 1);
215   if (ret == 0)
216     {
217       fprintf (stderr, "%s: malloc failed\n", progname);
218       exit (1);
219     }
220   if (dir)
221     sprintf (ret, "%s/%s", dir, fn);
222   else
223     strcpy (ret, fn);
224
225   return ret;
226 }
227
228 get_float_from_file (filename, var)
229      char *filename;
230      float *var;
231 {
232   FILE *stream;
233   int result;
234   char *name;
235
236   name = makename (filename);
237   stream = fopen (name, "r");
238   free (name);
239   if (stream == (FILE *)NULL)
240     return (0);
241   result = fscanf (stream, "%f\n", var);
242   fclose (stream);
243   return (result == 1);
244 }
245
246 get_int_from_file (filename, var)
247      char *filename;
248      int *var;
249 {
250   FILE *stream;
251   int result;
252   char *name;
253
254   name = makename (filename);
255   stream = fopen (name, "r");
256   free (name);
257   if (stream == (FILE *)NULL)
258     return (0);
259   result = fscanf (stream, "%d\n", var);
260   fclose (stream);
261   return (result == 1);
262 }
263
264 FILE *
265 must_open (name, mode)
266      char *name, *mode;
267 {
268   FILE *temp = fopen (name, mode);
269
270   if (!temp)
271     {
272       fprintf (stderr, "%s: Cannot open `%s' for mode `%s'.\n",
273                progname, name, mode);
274       fprintf
275         (stderr,
276          "Perhaps you don't have %s permission to the file or directory.\n",
277          (strcmp (mode, "w") == 0) ? "write" : "read");
278       exit (3);
279     }
280   return (temp);
281 }