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