Minor tweak
[mozilla-1.9.git] / config / mantomak.c
blobe43744385803ad8ca4a260847b1c62679d57f0b3
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include <stdio.h>
39 #include <string.h>
40 #include <stdlib.h>
41 #include <ctype.h>
43 #define DEFAULT_MANIFEST_EXT ".mn"
44 #define DEFAULT_MAKEFILE_EXT ".win"
46 typedef struct char_list_struct {
47 char *m_pString;
48 struct char_list_struct *m_pNext;
49 } char_list;
51 typedef struct macro_list_struct {
52 char *m_pMacro;
53 char_list *m_pValue;
54 struct macro_list_struct *m_pNext;
55 } macro_list;
57 void help(void);
58 char *input_filename(const char *);
59 char *output_filename(const char *, const char *);
60 int input_to_output(FILE *, FILE *);
61 int output_rules(FILE *);
62 int output_end(FILE *);
63 int buffer_to_output(char *, FILE *);
64 macro_list *extract_macros(char *);
65 char *find_macro(char *, char **);
66 void add_macro(char *, macro_list **);
67 int macro_length(char *);
68 int value_length(char *);
69 void add_values(char *, char_list **);
70 char *skip_white(char *);
71 int write_macros(macro_list *, FILE *);
72 int write_values(char_list *, FILE *, int);
73 void free_macro_list(macro_list *);
74 void free_char_list(char_list *);
75 void morph_macro(macro_list **, char *, char *, char *);
76 void slash_convert(macro_list *, char *);
77 int explicit_rules(macro_list *, char *, FILE *);
78 void create_classroot(macro_list **ppList );
80 int main(int argc, char *argv[])
82 int iOS = 0;
83 char *pInputFile = NULL;
84 char *pOutputFile = NULL;
86 /* Figure out arguments.
87 * [REQUIRED] First argument is input file.
88 * [OPTIONAL] Second argument is output file.
90 if(argc > 1) {
91 FILE *pInputStream = NULL;
92 FILE *pOutputStream = NULL;
94 /* Form respective filenames.
96 pInputFile = input_filename(argv[1]);
97 pOutputFile = output_filename(pInputFile, argc > 2 ? argv[2] : NULL);
99 if(pInputFile == NULL) {
100 fprintf(stderr, "MANTOMAK: Unable to form input filename\n");
101 iOS = 1;
103 else {
104 pInputStream = fopen(pInputFile, "rb");
105 if(pInputStream == NULL) {
106 fprintf(stderr, "MANTOMAK: Unable to open input file %s\n", pInputFile);
107 iOS = 1;
110 if(pOutputFile == NULL) {
111 fprintf(stderr, "MANTOMAK: Unable to form output filename\n");
112 iOS = 1;
114 else if(pInputStream != NULL) {
115 pOutputStream = fopen(pOutputFile, "wt");
116 if(pOutputStream == NULL) {
117 fprintf(stderr, "MANTOMAK: Unable to open output file %s\n", pOutputFile);
118 iOS = 1;
122 /* Only do the real processing if our error code is not
123 * already set.
125 if(iOS == 0) {
126 iOS = input_to_output(pInputStream, pOutputStream);
129 if(pInputStream != NULL) {
130 fclose(pInputStream);
131 pInputStream = NULL;
133 if(pOutputStream != NULL) {
134 fclose(pOutputStream);
135 pOutputStream = NULL;
138 else {
139 help();
140 iOS = 1;
143 if(pInputFile) {
144 free(pInputFile);
145 pInputFile = NULL;
147 if(pOutputFile) {
148 free(pOutputFile);
149 pOutputFile = NULL;
152 return(iOS);
155 void help(void)
157 fprintf(stderr, "USAGE:\tmantomak.exe InputFile [OutputFile]\n\n");
158 fprintf(stderr, "InputFile:\tManifest file. If without extension, \"%s\" assumed.\n", DEFAULT_MANIFEST_EXT);
159 fprintf(stderr, "OutputFile:\tNMake file. If not present, \"InputFile%s\" assumed.\n", DEFAULT_MAKEFILE_EXT);
162 char *input_filename(const char *pInputFile)
164 char aResult[_MAX_PATH];
165 char aDrive[_MAX_DRIVE];
166 char aDir[_MAX_DIR];
167 char aName[_MAX_FNAME];
168 char aExt[_MAX_EXT];
170 if(pInputFile == NULL) {
171 return(NULL);
174 _splitpath(pInputFile, aDrive, aDir, aName, aExt);
176 if(aExt[0] == '\0') {
177 /* No extension provided.
178 * Use the default.
180 strcpy(aExt, DEFAULT_MANIFEST_EXT);
183 aResult[0] = '\0';
184 _makepath(aResult, aDrive, aDir, aName, aExt);
186 if(aResult[0] == '\0') {
187 return(NULL);
189 else {
190 return(strdup(aResult));
194 char *output_filename(const char *pInputFile, const char *pOutputFile)
196 char aResult[_MAX_PATH];
197 char aDrive[_MAX_DRIVE];
198 char aDir[_MAX_DIR];
199 char aName[_MAX_FNAME];
200 char aExt[_MAX_EXT];
202 if(pOutputFile != NULL) {
203 return(strdup(pOutputFile));
206 /* From here on out, we have to create our own filename,
207 * implied from the input file name.
210 if(pInputFile == NULL) {
211 return(NULL);
214 _splitpath(pInputFile, aDrive, aDir, aName, aExt);
215 strcpy(aExt, DEFAULT_MAKEFILE_EXT);
217 aResult[0] = '\0';
218 _makepath(aResult, aDrive, aDir, aName, aExt);
220 if(aResult[0] == '\0') {
221 return(NULL);
223 else {
224 return(strdup(aResult));
228 int input_to_output(FILE *pInput, FILE *pOutput)
230 char *pHog = NULL;
231 long lSize = 0;
232 int iRetval = 0;
234 /* Read the entire file into memory.
236 fseek(pInput, 0, SEEK_END);
237 lSize = ftell(pInput);
238 fseek(pInput, 0, SEEK_SET);
240 pHog = (char *)malloc(lSize + 1);
241 if(pHog) {
242 *(pHog + lSize) = '\0';
243 fread(pHog, lSize, 1, pInput);
245 iRetval = buffer_to_output(pHog, pOutput);
247 free(pHog);
248 pHog = NULL;
250 else {
251 fprintf(stderr, "MANTOMAK: Out of Memory....\n");
252 iRetval = 1;
255 return(iRetval);
258 int output_rules(FILE *pOutput)
260 int iRetval = 0;
262 if(EOF ==
263 fputs("\n"
264 "!if \"$(MANIFEST_LEVEL)\"==\"RULES\""
265 "\n",
266 pOutput))
268 fprintf(stderr, "MANTOMAK: Error writing to file....\n");
269 iRetval = 1;
271 return(iRetval);
274 int output_end(FILE *pOutput)
276 int iRetval = 0;
278 if(EOF ==
279 fputs("\n"
280 "!endif"
281 "\n",
282 pOutput))
284 fprintf(stderr, "MANTOMAK: Error writing to file....\n");
285 iRetval = 1;
287 return(iRetval);
291 int buffer_to_output(char *pBuffer, FILE *pOutput)
293 int iRetval = 0;
294 macro_list *pMacros = NULL;
296 /* Tokenize the macros and their corresponding values.
298 pMacros = extract_macros(pBuffer);
299 if(pMacros != NULL) {
300 /* Perform forward to backslash conversion on those macros known to be
301 * path information only.
303 slash_convert(pMacros, "JBOOTDIRS");
304 slash_convert(pMacros, "JDIRS");
305 slash_convert(pMacros, "DEPTH");
306 slash_convert(pMacros, "NS_DEPTH");
307 slash_convert(pMacros, "PACKAGE");
308 slash_convert(pMacros, "JMC_GEN_DIR");
309 slash_convert(pMacros, "DIST_PUBLIC");
311 /* Process some of the macros, and convert them
312 * into different macros with different data.
314 morph_macro(&pMacros, "JMC_GEN", "JMC_HEADERS", "$(JMC_GEN_DIR)\\%s.h");
315 morph_macro(&pMacros, "JMC_GEN", "JMC_STUBS", "$(JMC_GEN_DIR)\\%s.c");
316 morph_macro(&pMacros, "JMC_GEN", "JMC_OBJS", ".\\$(OBJDIR)\\%s.obj");
317 morph_macro(&pMacros, "CSRCS", "C_OBJS", ".\\$(OBJDIR)\\%s.obj");
318 morph_macro(&pMacros, "CPPSRCS", "CPP_OBJS", ".\\$(OBJDIR)\\%s.obj");
319 morph_macro(&pMacros, "REQUIRES", "LINCS", "-I$(XPDIST)\\public\\%s");
321 create_classroot( &pMacros );
323 /* Output the Macros and the corresponding values.
325 iRetval = write_macros(pMacros, pOutput);
327 /* Output rule file inclusion
329 if(iRetval == 0) {
330 iRetval = output_rules(pOutput);
333 /* Output explicit build rules/dependencies for JMC_GEN.
335 if(iRetval == 0) {
336 iRetval = explicit_rules(pMacros, "JMC_GEN", pOutput);
339 if(iRetval == 0) {
340 iRetval = output_end(pOutput);
342 /* Free off the macro list.
344 free_macro_list(pMacros);
345 pMacros = NULL;
348 return(iRetval);
351 int explicit_rules(macro_list *pList, char *pMacro, FILE *pOutput)
353 int iRetval = 0;
354 macro_list *pEntry = NULL;
356 if(pList == NULL || pMacro == NULL || pOutput == NULL) {
357 return(0);
360 /* Find macro of said name.
361 * Case insensitive.
363 pEntry = pList;
364 while(pEntry) {
365 if(stricmp(pEntry->m_pMacro, pMacro) == 0) {
366 break;
369 pEntry = pEntry->m_pNext;
372 if(pEntry) {
373 /* Decide style of rule depending on macro name.
375 if(stricmp(pEntry->m_pMacro, "JMC_GEN") == 0) {
376 char_list *pNames = NULL;
377 char *pModuleName = NULL;
378 char *pClassName = NULL;
380 pNames = pEntry->m_pValue;
381 while(pNames) {
382 pModuleName = pNames->m_pString;
383 pClassName = pModuleName + 1;
385 fprintf(pOutput, "$(JMC_GEN_DIR)\\%s.h", pModuleName);
386 fprintf(pOutput, ": ");
387 fprintf(pOutput, "$(JMCSRCDIR)\\%s.class", pClassName);
388 fprintf(pOutput, "\n ");
389 fprintf(pOutput, "$(JMC) -d $(JMC_GEN_DIR) -interface $(JMC_GEN_FLAGS) $(?F:.class=)");
390 fprintf(pOutput, "\n");
392 fprintf(pOutput, "$(JMC_GEN_DIR)\\%s.c", pModuleName);
393 fprintf(pOutput, ": ");
394 fprintf(pOutput, "$(JMCSRCDIR)\\%s.class", pClassName);
395 fprintf(pOutput, "\n ");
396 fprintf(pOutput, "$(JMC) -d $(JMC_GEN_DIR) -module $(JMC_GEN_FLAGS) $(?F:.class=)");
397 fprintf(pOutput, "\n");
399 pNames = pNames->m_pNext;
402 else {
403 /* Don't know how to format macro.
405 iRetval = 69;
409 return(iRetval);
412 void slash_convert(macro_list *pList, char *pMacro)
414 macro_list *pEntry = NULL;
416 if(pList == NULL || pMacro == NULL) {
417 return;
420 /* Find macro of said name.
421 * Case insensitive.
423 pEntry = pList;
424 while(pEntry) {
425 if(stricmp(pEntry->m_pMacro, pMacro) == 0) {
426 break;
429 pEntry = pEntry->m_pNext;
432 if(pEntry) {
433 char *pConvert = NULL;
434 char_list *pValue = pEntry->m_pValue;
436 while(pValue) {
437 pConvert = pValue->m_pString;
438 while(pConvert && *pConvert) {
439 if(*pConvert == '/') {
440 *pConvert = '\\';
442 pConvert++;
444 pValue = pValue->m_pNext;
449 void morph_macro(macro_list **ppList, char *pMacro, char *pMorph, char *pPrintf)
451 macro_list *pEntry = NULL;
453 if(ppList == NULL || pMacro == NULL || pMorph == NULL || pPrintf == NULL) {
454 return;
457 /* Find macro of said name.
458 * Case insensitive.
460 pEntry = *ppList;
461 while(pEntry) {
462 if(stricmp(pEntry->m_pMacro, pMacro) == 0) {
463 break;
466 pEntry = pEntry->m_pNext;
469 if(pEntry) {
470 char_list *pFilename = NULL;
471 char aPath[_MAX_PATH];
472 char aDrive[_MAX_DRIVE];
473 char aDir[_MAX_DIR];
474 char aFName[_MAX_FNAME];
475 char aExt[_MAX_EXT];
476 char *pBuffer = NULL;
478 /* Start with buffer size needed.
479 * We expand this as we go along if needed.
481 pBuffer = (char *)malloc(strlen(pMorph) + 2);
482 strcpy(pBuffer, pMorph);
483 strcat(pBuffer, "=");
485 /* Go through each value, converting over to new macro.
487 pFilename = pEntry->m_pValue;
488 while(pFilename) {
489 _splitpath(pFilename->m_pString, aDrive, aDir, aFName, aExt);
491 /* Expand buffer by required amount.
493 sprintf(aPath, pPrintf, aFName);
494 strcat(aPath, " ");
495 pBuffer = (char *)realloc(pBuffer, _msize(pBuffer) + strlen(aPath));
496 strcat(pBuffer, aPath);
498 pFilename = pFilename->m_pNext;
501 /* Add the macro.
503 add_macro(pBuffer, ppList);
505 free(pBuffer);
506 pBuffer = NULL;
510 void create_classroot(macro_list **ppList )
512 char cwd[512];
513 int i, i2;
514 macro_list *pEntry = NULL;
515 macro_list *pE;
517 /* Find macro of said name.
518 * Case insensitive.
520 pEntry = *ppList;
521 while(pEntry) {
522 if(stricmp(pEntry->m_pMacro, "PACKAGE") == 0) {
523 break;
526 pEntry = pEntry->m_pNext;
529 if(pEntry == 0 || pEntry->m_pValue == 0 || pEntry->m_pValue->m_pString == 0) {
530 return;
533 _getcwd( cwd, 512 );
535 i = strlen( pEntry->m_pValue->m_pString );
536 i2 = strlen( cwd );
538 cwd[i2-i-1] = 0;
540 pE = NULL;
541 pE = (macro_list *)calloc(sizeof(macro_list),1);
542 pE->m_pMacro = strdup("CLASSROOT");
543 pE->m_pValue = (char_list *)calloc(sizeof(char_list),1);
544 pE->m_pValue->m_pString = strdup(cwd);
546 while(*ppList) {
547 ppList = &((*ppList)->m_pNext);
549 *ppList = pE;
553 int write_macros(macro_list *pList, FILE *pOutput)
555 int iRetval = 0;
556 int iLineLength = 0;
558 if(pList == NULL || pOutput == NULL) {
559 return(0);
562 if(EOF ==
563 fputs("\n"
564 "!if \"$(MANIFEST_LEVEL)\"==\"MACROS\""
565 "\n",
566 pOutput))
568 fprintf(stderr, "MANTOMAK: Error writing to file....\n");
569 return(1);
572 while(pList) {
573 int bIgnoreForWin16 = 0;
575 /* The following macros should not be emitted for Win16 */
576 if (0 == strcmp(pList->m_pMacro, "LINCS")) {
577 bIgnoreForWin16 = 1;
581 if (bIgnoreForWin16) {
582 if(0 > fprintf(pOutput, "!if \"$(MOZ_BITS)\" != \"16\"\n")) {
583 fprintf(stderr, "MANTOMAK: Error writing to file....\n");
584 iRetval = 1;
585 break;
589 if(0 > fprintf(pOutput, "%s=", pList->m_pMacro)) {
590 fprintf(stderr, "MANTOMAK: Error writing to file....\n");
591 iRetval = 1;
592 break;
594 iLineLength += strlen(pList->m_pMacro) + 1;
596 iRetval = write_values(pList->m_pValue, pOutput, iLineLength);
597 if(iRetval) {
598 break;
601 if(EOF == fputc('\n', pOutput)) {
602 fprintf(stderr, "MANTOMAK: Error writing to file....\n");
603 iRetval = 1;
604 break;
606 iLineLength = 0;
608 pList = pList->m_pNext;
610 if (bIgnoreForWin16) {
611 if(0 > fprintf(pOutput, "!endif\n")) {
612 fprintf(stderr, "MANTOMAK: Error writing to file....\n");
613 iRetval = 1;
614 break;
616 bIgnoreForWin16 = 0;
620 if(EOF ==
621 fputs("\n"
622 "!endif"
623 "\n",
624 pOutput))
626 fprintf(stderr, "MANTOMAK: Error writing to file....\n");
627 return(1);
629 return(iRetval);
632 int write_values(char_list *pList, FILE *pOutput, int iLineLength)
634 int iRetval = 0;
636 if(pList == NULL || pOutput == NULL) {
637 return(0);
640 while(pList) {
641 if(iLineLength == 0) {
642 if(EOF == fputs(" ", pOutput)) {
643 fprintf(stderr, "MANTOMAK: Error writing to file....\n");
644 iRetval = 1;
645 break;
647 iLineLength += 4;
649 if(0 > fprintf(pOutput, "%s ", pList->m_pString)) {
650 fprintf(stderr, "MANTOMAK: Error writing to file....\n");
651 iRetval = 1;
652 break;
654 iLineLength += strlen(pList->m_pString) + 1;
656 else if(iLineLength + strlen(pList->m_pString) > 72) {
657 if(EOF == fputs("\\\n", pOutput)) {
658 fprintf(stderr, "MANTOMAK: Error writing to file....\n");
659 iRetval = 1;
660 break;
662 iLineLength = 0;
663 continue;
665 else {
666 if(0 > fprintf(pOutput, "%s ", pList->m_pString)) {
667 fprintf(stderr, "MANTOMAK: Error writing to file....\n");
668 iRetval = 1;
669 break;
671 iLineLength += strlen(pList->m_pString) + 1;
674 pList = pList->m_pNext;
677 return(iRetval);
680 macro_list *extract_macros(char *pBuffer)
682 macro_list *pRetval = NULL;
683 char *pTraverse = NULL;
684 char *pMacro = NULL;
686 pTraverse = pBuffer;
687 while(pTraverse) {
688 pMacro = NULL;
689 pTraverse = find_macro(pTraverse, &pMacro);
690 if(pMacro) {
691 add_macro(pMacro, &pRetval);
695 return(pRetval);
698 void add_macro(char *pString, macro_list **ppList)
700 macro_list *pEntry = NULL;
701 int iLength = 0;
703 if(pString == NULL || *pString == '\0' || ppList == NULL) {
704 return;
707 /* Allocate a new list entry for the macro.
709 pEntry = (macro_list *)calloc(1, sizeof(macro_list));
711 /* Very first part of the string is the macro name.
712 * How long is it?
714 iLength = macro_length(pString);
715 pEntry->m_pMacro = (char *)calloc(iLength + 1, 1);
716 strncpy(pEntry->m_pMacro, pString, iLength);
718 /* Skip to the values.
719 * These are always on the right side of an '='
721 pString = strchr(pString, '=');
722 if(pString) {
723 pString++;
725 add_values(pString, &(pEntry->m_pValue));
727 /* Add the macro to the end of the macro list.
729 while(*ppList) {
730 ppList = &((*ppList)->m_pNext);
732 *ppList = pEntry;
735 void add_values(char *pString, char_list **ppList)
737 char_list **ppTraverse = NULL;
738 char_list *pEntry = NULL;
739 int iLength = 0;
740 int iBackslash = 0;
742 if(pString == NULL || *pString == '\0' || ppList == NULL) {
743 return;
746 while(pString) {
747 /* Find start of value.
749 iBackslash = 0;
750 while(*pString) {
751 if(*pString == '\\') {
752 iBackslash++;
754 else if(*pString == '\n') {
755 if(iBackslash == 0) {
756 /* End of values.
757 * Setting to NULL gets out of all loops.
759 pString = NULL;
760 break;
762 iBackslash = 0;
764 else if(!isspace(*pString)) {
765 /* Backslashes part of string.
766 * This screws up if a backslash is in the middle of the string.
768 pString -= iBackslash;
769 break;
772 pString++;
774 if(pString == NULL || *pString == '\0') {
775 break;
778 /* Do not honor anything beginning with a #
780 if(*pString == '#') {
781 /* End of line.
783 while(*pString && *pString != '\n') {
784 pString++;
786 continue;
789 /* Very first part of the string is value name.
790 * How long is it?
792 iLength = value_length(pString);
794 /* Do not honor $(NULL)
796 if(_strnicmp(pString, "$(NULL)", 7) == 0) {
797 pString += iLength;
798 continue;
801 /* Allocate a new list entry for the next value.
803 pEntry = (char_list *)calloc(1, sizeof(char_list));
805 pEntry->m_pString = (char *)calloc(iLength + 1, 1);
806 strncpy(pEntry->m_pString, pString, iLength);
808 /* Add new value entry to the end of the list.
810 ppTraverse = ppList;
811 while(*ppTraverse) {
812 ppTraverse = &((*ppTraverse)->m_pNext);
814 *ppTraverse = pEntry;
816 /* Go on to next value.
818 pString += iLength;
822 char *find_macro(char *pBuffer, char **ppMacro)
824 char *pRetval = NULL;
825 int iBackslash = 0;
827 if(pBuffer == NULL || ppMacro == NULL) {
828 return(NULL);
831 /* Skip any whitespace in the buffer.
832 * If comments need to be skipped also, this is the place.
834 while(1) {
835 while(*pBuffer && isspace(*pBuffer)) {
836 pBuffer++;
838 if(*pBuffer == '#') {
839 /* Go to the end of the line, it's a comment.
841 while(*pBuffer && *pBuffer != '\n') {
842 pBuffer++;
845 continue;
847 break;
850 if(*pBuffer) {
851 /* Should be at the start of a macro.
853 *ppMacro = pBuffer;
856 /* Find the end of the macro for the return value.
857 * This is the end of a line which does not contain a backslash at the end.
859 while(*pBuffer) {
860 if(*pBuffer == '\\') {
861 iBackslash++;
863 else if(*pBuffer == '\n') {
864 if(iBackslash == 0) {
865 pRetval = pBuffer + 1;
866 break;
868 iBackslash = 0;
870 else if(!isspace(*pBuffer)) {
871 iBackslash = 0;
874 pBuffer++;
877 return(pRetval);
880 int macro_length(char *pMacro)
882 int iRetval = 0;
884 if(pMacro == NULL) {
885 return(0);
888 /* Length is no big deal.
889 * Problem is finding the end:
890 * whitespace
891 * '='
893 while(*pMacro) {
894 if(*pMacro == '=') {
895 break;
897 else if(isspace(*pMacro)) {
898 break;
901 pMacro++;
902 iRetval++;
905 return(iRetval);
908 int value_length(char *pValue)
910 int iRetval = 0;
912 if(pValue == NULL) {
913 return(0);
916 /* Length is no big deal.
917 * Problem is finding the end:
918 * whitespace
919 * '\\'whitespace
921 while(*pValue) {
922 if(*pValue == '\\') {
923 char *pFindNewline = pValue + 1;
924 /* If whitespace to end of line, break here.
926 while(isspace(*pFindNewline)) {
927 if(*pFindNewline == '\n') {
928 break;
930 pFindNewline++;
932 if(*pFindNewline == '\n') {
933 break;
936 else if(isspace(*pValue)) {
937 break;
940 pValue++;
941 iRetval++;
944 return(iRetval);
947 char *skip_white(char *pString)
949 if(pString == NULL) {
950 return(NULL);
953 while(*pString && isspace(*pString)) {
954 pString++;
957 return(pString);
960 void free_macro_list(macro_list *pList)
962 macro_list *pFree = NULL;
964 if(pList == NULL) {
965 return;
968 while(pList) {
969 pFree = pList;
970 pList = pList->m_pNext;
972 pFree->m_pNext = NULL;
974 free_char_list(pFree->m_pValue);
975 pFree->m_pValue = NULL;
977 free(pFree->m_pMacro);
978 pFree->m_pMacro = NULL;
980 free(pFree);
981 pFree = NULL;
985 void free_char_list(char_list *pList)
987 char_list *pFree = NULL;
989 if(pList == NULL) {
990 return;
993 while(pList) {
994 pFree = pList;
995 pList = pList->m_pNext;
997 pFree->m_pNext = NULL;
999 free(pFree->m_pString);
1000 pFree->m_pString = NULL;
1002 free(pFree);
1003 pFree = NULL;