1 /* This file is part of the gf2x library.
2
3 Copyright 2007, 2008, 2009, 2010, 2013, 2015
4 Richard Brent, Pierrick Gaudry, Emmanuel Thome', Paul Zimmermann
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of either:
8 - If the archive contains a file named toom-gpl.c (not a trivial
9 placeholder), the GNU General Public License as published by the Free
10 Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12 - If the archive contains a file named toom-gpl.c which is a trivial
13 placeholder, the GNU Lesser General Public License as published by
14 the Free Software Foundation; either version 2.1 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful, but WITHOUT
18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 FITNESS FOR A PARTICULAR PURPOSE. See the license text for more details.
20
21 You should have received a copy of the GNU General Public License as
22 well as the GNU Lesser General Public License along with this program;
23 see the files COPYING and COPYING.LIB. If not, write to the Free
24 Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 02110-1301, USA.
26 */
27
28 /* Helper program for rewriting headers after tuning. */
29
30 #define _GNU_SOURCE
31
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include "replace.h"
37
set_hash_define_int(struct hash_define * ptr,const char * name,int x)38 void set_hash_define_int(struct hash_define * ptr, const char * name, int x)
39 {
40 ptr->identifier = strdup(name);
41 ptr->string = malloc(32);
42 snprintf(ptr->string, 32, "%d", x);
43 }
44
set_hash_define(struct hash_define * ptr,const char * name,const char * v)45 void set_hash_define(struct hash_define * ptr, const char * name, const char *v)
46 {
47 ptr->identifier = strdup(name);
48 ptr->string = strdup(v);
49 unsigned long l = strlen(ptr->string);
50 for( ; l && isspace(ptr->string[l-1]) ; l--);
51 ptr->string[l] = '\0';
52 }
53
54
55 typedef int (*sortfunc_t) (const void *, const void *);
cmp_hash_define(struct hash_define * a,struct hash_define * b)56 int cmp_hash_define(struct hash_define * a, struct hash_define * b)
57 {
58 return strcmp(a->identifier, b->identifier);
59 }
search_hash_define(const char * a,struct hash_define * b)60 int search_hash_define(const char * a, struct hash_define * b)
61 {
62 return strcmp(a, b->identifier);
63 }
64
65
replace(struct hash_define * ptr,unsigned long n,const char * fname)66 void replace(struct hash_define * ptr, unsigned long n, const char * fname)
67 {
68
69 qsort(ptr, n, sizeof(struct hash_define), (sortfunc_t) & cmp_hash_define);
70
71 FILE * fi, * fo;
72 char * fname_out;
73 size_t sl = strlen(fname)+10;
74 char buffer[1024];
75 char id[80];
76
77 fname_out = malloc(sl);
78 snprintf(fname_out,sl,"%s.new",fname);
79
80 fi = fopen(fname, "r");
81 fo = fopen(fname_out, "w");
82
83 for (;!feof(fi);) {
84 const char * x, *y;
85 if (fgets(buffer, sizeof(buffer), fi) == NULL) {
86 /* EOF, most certainly */
87 break;
88 }
89 #define IS_HDEFINE(X) (strncmp(X,"#define",7) == 0)
90 #define IS_HUNDEF(X) (strncmp(X,"#undef",6) == 0)
91 if (!(IS_HDEFINE(buffer) || IS_HUNDEF(buffer))) {
92 fputs(buffer, fo);
93 continue;
94 }
95 x = buffer;
96 for(;*x && !isspace(*x);x++);
97 for(;*x && isspace(*x);x++);
98 for(y=x;*y&&!isspace(*y);y++);
99 strncpy(id,x,y-x);
100 id[y-x]='\0';
101 /* identifier is id */
102 struct hash_define * loc;
103 loc = bsearch(id, ptr, n, sizeof(struct hash_define), (sortfunc_t) & search_hash_define);
104 if (loc == NULL) {
105 fputs(buffer, fo);
106 continue;
107 }
108 if (loc->string[0] == '\0') {
109 fprintf(stderr,
110 "Error: replacement string %s used twice!\n",
111 loc->identifier);
112 exit(1);
113 }
114 for( ;; ) {
115 x = buffer + strlen(buffer) - 1;
116 for( ; (x - buffer >= 0) && isspace(*x) ; x--);
117 /* If the current line was followed by a backslash, gobble
118 * the following line as well.
119 */
120 if ((x - buffer >= 0) && *x != '\\')
121 break;
122 /* It's normally an error to arrive here, although there's
123 * not much questioning as to what to do in such a situation
124 */
125 if (fgets(buffer, sizeof(buffer), fi) == NULL)
126 break;
127 }
128
129 fprintf(fo,"#define %s\t\t%s\n", id, loc->string);
130 loc->string[0]='\0';
131 }
132 for(unsigned long i = 0 ; i < n ; i++) {
133 struct hash_define * loc = ptr + i;
134 if (loc->string[0] != '\0') {
135 fprintf(stderr, "Warning: replacement string %s not used ; value:\n%s\n", loc->identifier, loc->string);
136 }
137 }
138
139 fclose(fi);
140 fclose(fo);
141 rename(fname_out, fname);
142 }
143