1/*
2   pl.m
3
4   This file is the main driver for the plist parsing program.
5
6   Copyright (C) 1996,1999,2000 Free Software Foundation, Inc.
7
8   Author: Gregory John Casamento
9   Date: 17 Jan 2000
10
11   This file is part of the GNUstep Project
12
13   This program is free software; you can redistribute it and/or
14   modify it under the terms of the GNU General Public License
15   as published by the Free Software Foundation; either
16   version 3 of the License, or (at your option) any later version.
17
18   You should have received a copy of the GNU General Public
19   License along with this program; see the file COPYINGv3.
20   If not, write to the Free Software Foundation,
21   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22
23*/
24
25#import	"common.h"
26
27#import	"Foundation/NSArray.h"
28#import	"Foundation/NSAutoreleasePool.h"
29#import	"Foundation/NSData.h"
30#import	"Foundation/NSException.h"
31#import	"Foundation/NSFileHandle.h"
32#import	"Foundation/NSFileManager.h"
33#import	"Foundation/NSPathUtilities.h"
34#import	"Foundation/NSProcessInfo.h"
35#import	"Foundation/NSUserDefaults.h"
36
37void create_output(id propertyList)
38{
39  NSFileHandle *fileHandle = nil;
40  NSProcessInfo *processInfo = [NSProcessInfo processInfo];
41  NSArray *arguments = [processInfo arguments];
42  NSUInteger outputIndex = 0;
43
44  // insert your code here
45  outputIndex = [arguments indexOfObject: @"-output"];
46  if (outputIndex == NSNotFound)
47    {
48      const char *buffer = [[propertyList description] cString];
49      NSData *outputData;
50
51      outputData = [NSData dataWithBytes: buffer length: strlen(buffer)];
52      // setup the file handle.
53      fileHandle = [NSFileHandle fileHandleWithStandardOutput];
54      // Send the data to stdout
55      [fileHandle writeData: outputData];
56      puts("\n");
57    }
58  else
59    {
60      NSData *serializedData = nil;
61      NSFileManager *fileManager = [NSFileManager defaultManager];
62
63      // Write in the serialized plist.
64      serializedData = [NSSerializer serializePropertyList: propertyList];
65      [fileManager createFileAtPath: [arguments objectAtIndex: outputIndex+1]
66			   contents: serializedData
67			 attributes: nil];
68    }
69}
70
71id process_plist(NSData *inputData)
72{
73  id propertyList = nil;
74  NSString *string = nil;
75
76  // Initialize a string with the contents of the file.
77  string = [NSString stringWithUTF8String: (char *)[inputData bytes]];
78
79  // Convert the string into a property list.  If there is a parsing error
80  // the property list interpreter will throw an exception.
81  NS_DURING
82      propertyList = [string propertyList];
83  NS_HANDLER
84      NSLog(@"%@", localException);
85  NS_ENDHANDLER
86
87  // return the results
88  return propertyList;
89}
90
91NSData *read_input()
92{
93  NSData *inputData = nil;
94  NSFileHandle *fileHandle = nil;
95  NSProcessInfo *processInfo = [NSProcessInfo processInfo];
96  NSArray *arguments = [processInfo arguments];
97  NSUInteger inputIndex = 0;
98
99  // insert your code here
100  inputIndex = [arguments indexOfObject: @"-input"];
101  if (inputIndex == NSNotFound)
102    {
103      // setup the file handle.
104      fileHandle = [NSFileHandle fileHandleWithStandardInput];
105      // Read in the input from the file.
106      inputData = [fileHandle readDataToEndOfFile];
107    }
108  else
109    {
110      NSData *serializedData = nil;
111      id propertyList = nil;
112      char *buffer = 0;
113
114      // set up the file handle.
115      fileHandle = [NSFileHandle fileHandleForReadingAtPath:
116	[arguments objectAtIndex: inputIndex+1]];
117      // read in the serialized plist.
118      serializedData = [fileHandle readDataToEndOfFile];
119      [fileHandle closeFile];
120      propertyList = [NSDeserializer deserializePropertyListFromData:
121	serializedData mutableContainers: NO];
122      if (propertyList != nil)
123	{
124	  buffer = (char *)[[propertyList description] cString];
125	  inputData = [NSData dataWithBytes: buffer length: strlen(buffer)];
126	}
127      else
128	{
129	  NSLog(@"%@ is not a serialized property list.",
130	    [arguments objectAtIndex: inputIndex+1]);
131	}
132    }
133
134  return inputData;
135}
136
137int main (int argc, const char *argv[])
138{
139  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
140  NSData *inputData = nil;
141  id propertyList = nil;
142
143  // put your code here.
144  if (argc == 1 || argc == 3|| argc == 5)
145    {
146      inputData = read_input();
147      if (inputData != nil)
148	{
149	  // If the input data was sucessfully read...
150	  propertyList = process_plist( inputData );
151	  if (propertyList != nil)
152	    {
153	      // If the property list was okay...
154	      create_output( propertyList );
155	    }
156	}
157    }
158  else
159    {
160      puts("pl {-input <serialized_file>} {-output <serialized_file>}");
161      puts(
162  "   - Reads an ASCII property list from standard in, or a serialized one");
163      puts("     if -input is specified.");
164      puts(
165  "   - Writes an ASCII propert list to standard out, or a serialized one");
166      puts("     if -output is specified.");
167    }
168
169  [pool drain];
170  exit(0);       // insure the process exit status is 0
171  return 0;      // ...and make main fit the ANSI spec.
172}
173