]> git.proxmox.com Git - mirror_edk2.git/blob - BeagleBoardPkg/Tools/replace.c
6a1dad4408018f4a2735f23eae73f5cee82c28f8
[mirror_edk2.git] / BeagleBoardPkg / Tools / replace.c
1 //
2 // Quick hack to work around not having sed, or any other reasonable
3 // way to edit a file from a script on Windows......
4 //
5 // Copyright (c) 2010, Apple Inc. All rights reserved.<BR>
6 //
7 // SPDX-License-Identifier: BSD-2-Clause-Patent
8 //
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <limits.h>
13
14 #define TRUE 1
15 #define FALSE 0
16
17 typedef struct {
18 char *Match;
19 int MatchSize;
20 char *Replace;
21 } MATCH_PAIR;
22
23 void
24 Usage (char *Name)
25 {
26 printf ("\n%s OldFile NewFile MatchString ReplaceString [MatchString2 ReplaceString2]*\n", Name);
27 printf (" OldFile - Must be arg[1] File to search for MatchStrings\n");
28 printf (" NewFile - Must be arg[2] File where MatchString has been replaced with ReplaceString\n");
29 printf (" MatchString & ReplaceString. Required arguments.\n");
30 printf (" More MatchString/ReplaceString pairs are supported.\n");
31 }
32
33 //
34 // argv[1] - Old File
35 // argv[2] - New File
36 // argv[3+n] - Match String
37 // argv[4+n] - Replace string
38 int
39 main (int argc, char **argv)
40 {
41 FILE *In, *Out;
42 char *Key, *Replace;
43 int c, i, n, Len, MaxLenKey = 0, MinLenKey = INT_MAX;
44 unsigned long InFileSize, InFilePos;
45 MATCH_PAIR *Match;
46 int MaxMatch;
47 int ReadCount;
48 int Found;
49
50 if (argc < 5) {
51 fprintf (stderr, "Need at least two files and one Match/Replacement string pair\n");
52 Usage (argv[0]);
53 return -1;
54 } else if ((argc % 2) == 0) {
55 fprintf (stderr, "Match and Replace string must come in pairs\n");
56 return -4;
57 }
58
59 In = fopen (argv[1], "r");
60 fseek (In, 0, SEEK_END);
61 InFileSize = ftell (In);
62 if (InFileSize == 0) {
63 fprintf (stderr, "Could not open %s\n", argv[1]);
64 return -6;
65 }
66 fseek (In, 0, SEEK_SET);
67
68
69 Out = fopen (argv[2], "w+");
70 if ((In == NULL) || (Out == NULL)) {
71 fprintf (stderr, "Could not open %s\n", argv[2]);
72 return -2;
73 }
74
75 MaxMatch = (argc - 2)/2;
76 Match = calloc (MaxMatch, sizeof (MATCH_PAIR));
77 if (Match == NULL) {
78 return -7;
79 }
80
81 for (n=0; n < MaxMatch; n++) {
82 Match[n].Match = argv[3 + n*2];
83 Match[n].MatchSize = strlen (argv[3 + n*2]);
84 Match[n].Replace = argv[3 + n*2 + 1];
85 if (Match[n].MatchSize > MaxLenKey) {
86 // Max size of match/replace string pair
87 MaxLenKey = Match[n].MatchSize;
88 }
89 if (Match[n].MatchSize < MinLenKey) {
90 MinLenKey = Match[n].MatchSize;
91 }
92 }
93
94 Key = malloc (MaxLenKey);
95 if (Key == NULL) {
96 return -5;
97 }
98
99 // Search for a match by reading every possition of the file
100 // into a buffer that is as big as the maximum search key size.
101 // Then we can search the keys for a match. If no match
102 // copy the old file character to the new file. If it is a match
103 // then copy the replacement string into the output file.
104 // This code assumes the file system is smart and caches the
105 // file in a buffer. So all the reads don't really hit the disk.
106 InFilePos = 0;
107 while (InFilePos < (InFileSize - MinLenKey)) {
108 fseek (In, InFilePos, SEEK_SET);
109 ReadCount = fread (Key, 1, MaxLenKey, In);
110 for (i = 0, Found = FALSE;i < MaxMatch; i++) {
111 if (ReadCount >= Match[i].MatchSize) {
112 if (!memcmp (Key, Match[i].Match, Match[i].MatchSize)) {
113 InFilePos += (Match[i].MatchSize - 1);
114 fputs (Match[i].Replace, Out);
115 Found = TRUE;
116 break;
117 }
118 }
119 }
120 if (!Found) {
121 fputc (Key[0], Out);
122 }
123
124 InFilePos++;
125 }
126
127 // We stoped searching when we got to the point that we could no longer match.
128 // So the last few bytes of the file are not copied in the privous loop
129 fseek (In, InFilePos, SEEK_SET);
130 while ((c = fgetc (In)) != EOF) {
131 fputc (c, Out);
132 }
133
134 fclose (In);
135 fclose (Out);
136 free (Key);
137 free (Match);
138 return 0;
139 }
140